[med-svn] [last-align] 05/08: Imported Upstream version 731

Andreas Tille tille at debian.org
Sat Mar 12 07:09:46 UTC 2016


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository last-align.

commit e2f7df726b2014aa2a33eebae3e982119edc007b
Author: Andreas Tille <tille at debian.org>
Date:   Sat Mar 12 07:57:46 2016 +0100

    Imported Upstream version 731
---
 ChangeLog.txt                          |   109 +-
 doc/bisulfite.html                     |    12 +-
 doc/bisulfite.txt                      |    13 +-
 doc/last-tuning.html                   |    76 +-
 doc/last-tuning.txt                    |    63 +-
 doc/last.html                          |    23 +-
 doc/last.txt                           |    22 +-
 doc/lastal.html                        |    30 +-
 doc/lastal.txt                         |    31 +-
 doc/lastdb.html                        |    18 +
 doc/lastdb.txt                         |    20 +
 makefile                               |     2 +-
 scripts/maf-convert                    |    95 +-
 src/Alignment.hh                       |    15 +-
 src/AlignmentWrite.cc                  |    25 +-
 src/CyclicSubsetSeed.cc                |     2 +-
 src/CyclicSubsetSeed.hh                |    21 +
 src/LastalArguments.cc                 |    25 +-
 src/LastalArguments.hh                 |     3 +
 src/LastdbArguments.cc                 |    21 +-
 src/LastdbArguments.hh                 |     3 +
 src/Mmap.hh                            |    14 +-
 src/MultiSequence.cc                   |     2 +-
 src/MultiSequence.hh                   |    23 +-
 src/MultiSequenceQual.cc               |    10 +-
 src/SubsetMinimizerFinder.cc           |    49 +
 src/SubsetMinimizerFinder.hh           |    52 +
 src/SubsetSuffixArray.cc               |    31 +-
 src/SubsetSuffixArray.hh               |     8 +-
 src/SubsetSuffixArraySort.cc           |    19 +-
 src/VectorOrMmap.hh                    |     4 +-
 src/alp/njn_dynprogprob.cpp            |   590 +-
 src/alp/njn_ioutil.cpp                 |   334 +-
 src/alp/njn_localmaxstat.hpp           |   396 +-
 src/alp/njn_random.cpp                 |   204 +-
 src/alp/njn_random.hpp                 |   110 +-
 src/alp/njn_uniform.hpp                |   152 +-
 src/alp/sls_alignment_evaluer.cpp      |  2300 +--
 src/alp/sls_alignment_evaluer.hpp      |   420 +-
 src/alp/sls_alp.cpp                    |  4732 +++----
 src/alp/sls_alp.hpp                    |   728 +-
 src/alp/sls_alp_data.cpp               |  3326 ++---
 src/alp/sls_alp_data.hpp               |  1874 +--
 src/alp/sls_alp_sim.cpp                |  9098 ++++++------
 src/alp/sls_alp_sim.hpp                |  1158 +-
 src/alp/sls_basic.cpp                  |   344 +-
 src/alp/sls_basic.hpp                  |   424 +-
 src/alp/sls_falp_alignment_evaluer.cpp |  2140 +--
 src/alp/sls_falp_alignment_evaluer.hpp |   374 +-
 src/alp/sls_fsa1.cpp                   | 23178 +++++++++++++++----------------
 src/alp/sls_fsa1.hpp                   |  2832 ++--
 src/alp/sls_fsa1_parameters.cpp        |  3624 ++---
 src/alp/sls_fsa1_parameters.hpp        |   452 +-
 src/alp/sls_fsa1_pvalues.cpp           |  2696 ++--
 src/alp/sls_fsa1_pvalues.hpp           |   686 +-
 src/alp/sls_fsa1_utils.cpp             |  4400 +++---
 src/alp/sls_fsa1_utils.hpp             |  2274 +--
 src/alp/sls_pvalues.cpp                |  2694 ++--
 src/alp/sls_pvalues.hpp                |   652 +-
 src/fileMap.cc                         |     8 +-
 src/fileMap.hh                         |     6 +-
 src/lastal.cc                          |   155 +-
 src/lastdb.cc                          |   162 +-
 src/makefile                           |    40 +-
 src/threadUtil.hh                      |    38 +
 src/version.hh                         |     2 +-
 66 files changed, 36988 insertions(+), 36456 deletions(-)

diff --git a/ChangeLog.txt b/ChangeLog.txt
index cc70c9a..401615e 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,8 +1,115 @@
+2016-03-11  Martin C. Frith  <Martin C. Frith>
+
+	* doc/last-tuning.txt, doc/lastal.txt, doc/lastdb.txt,
+	src/LastalArguments.cc, src/LastdbArguments.cc, src/lastal.cc, test
+	/last-test.out, test/last-test.sh:
+	Added minimizer doc & test, tweaked lastal verbose messages.
+	[323c152700e9] [tip]
+
+2016-03-10  Martin C. Frith  <Martin C. Frith>
+
+	* src/LastalArguments.cc, src/lastal.cc, test/last-test.out:
+	Made lastal's informational messages less verbose.
+	[c4a1a839f250]
+
+	* src/CyclicSubsetSeed.hh, src/SubsetSuffixArray.cc,
+	src/SubsetSuffixArray.hh, src/lastdb.cc:
+	Maybe reduced lastdb's memory use in some cases.
+	[811b0eaa631a]
+
+	* src/lastdb.cc:
+	Refactoring.
+	[864cd331324f]
+
+	* doc/lastdb.txt, src/LastdbArguments.cc, src/LastdbArguments.hh,
+	src/lastdb.cc, src/makefile:
+	Added -P multi-thread option to lastdb (for tantan only, so far).
+	[6b028abf6969]
+
+	* src/lastal.cc, src/makefile, src/threadUtil.hh:
+	Refactoring.
+	[2ad307f63f32]
+
+	* src/LastalArguments.cc, src/LastalArguments.hh,
+	src/LastdbArguments.cc, src/LastdbArguments.hh, src/lastal.cc,
+	src/lastdb.cc:
+	Get the program name for error/warning/help messages from the
+	command line.
+	[565f7858e80f]
+
+2016-03-09  Martin C. Frith  <Martin C. Frith>
+
+	* src/MultiSequence.hh, src/lastal.cc:
+	Refactoring.
+	[1bdaa28a80c8]
+
+	* src/lastdb.cc:
+	Re-ordered some lastdb computations.
+	[63c3bff61406]
+
+	* src/Mmap.hh, src/MultiSequence.cc, src/MultiSequence.hh,
+	src/MultiSequenceQual.cc, src/SubsetSuffixArraySort.cc,
+	src/VectorOrMmap.hh, src/fileMap.cc, src/fileMap.hh:
+	Refactoring.
+	[b87ee4885cad]
+
+	* src/LastalArguments.cc, src/LastalArguments.hh,
+	src/LastdbArguments.cc, src/LastdbArguments.hh,
+	src/SubsetMinimizerFinder.cc, src/SubsetMinimizerFinder.hh,
+	src/SubsetSuffixArray.cc, src/SubsetSuffixArray.hh, src/lastal.cc,
+	src/lastdb.cc, src/makefile:
+	Added minimizers (undocumented for now).
+	[737a3da90ac8]
+
+2016-03-08  Martin C. Frith  <Martin C. Frith>
+
+	* doc/bisulfite.txt, doc/last-tuning.txt, doc/last.txt,
+	src/CyclicSubsetSeed.cc, src/SubsetSuffixArray.cc, src/lastal.cc,
+	src/lastdb.cc:
+	Refactoring & doc updates.
+	[de73bebc7110]
+
+2016-02-15  Martin C. Frith  <Martin C. Frith>
+
+	* src/CyclicSubsetSeed.hh, src/SubsetSuffixArraySort.cc:
+	Refactoring.
+	[30acd9c613ab]
+
+	* scripts/maf-convert, test/maf-convert-test.out:
+	Made maf-convert -> sam indicate mismatches.
+	[78178e514854]
+
+	* scripts/maf-convert:
+	Made maf-convert -> sam check if the alignment is pair-wise.
+	[91f69e34ec9e]
+
+2016-02-05  Martin C. Frith  <Martin C. Frith>
+
+	* doc/lastal.txt, src/Alignment.hh, src/AlignmentWrite.cc,
+	src/LastalArguments.cc, src/lastal.cc, test/last-test.out, test
+	/last-test.sh:
+	Added BlastTab+ output option to lastal.
+	[7cc4399c5980]
+
+	* src/Alignment.hh, src/AlignmentWrite.cc, test/last-test.out:
+	Slightly changed the sort order for lastal BlastTab output.
+	[749f3855f465]
+
+2016-01-25  Martin C. Frith  <Martin C. Frith>
+
+	* src/lastal.cc:
+	Made multi-thread lastal start writing output sooner.
+	[0410af8bd5db]
+
+	* doc/last.txt, doc/lastal.txt, makefile, src/lastal.cc, src/makefile:
+	Made it usable with old compilers that lack C++11.
+	[9bed0a398a5e]
+
 2015-12-16  Martin C. Frith  <Martin C. Frith>
 
 	* doc/FAQ.txt:
 	FAQ update (thanks: Torben Nielsen).
-	[2011b377a29a] [tip]
+	[2011b377a29a]
 
 	* src/lastal.cc:
 	Made lastal write its output ASAP.
diff --git a/doc/bisulfite.html b/doc/bisulfite.html
index ba293a2..929db70 100644
--- a/doc/bisulfite.html
+++ b/doc/bisulfite.html
@@ -318,6 +318,13 @@ table.field-list { border: thin solid green }
 <div class="document" id="aligning-bisulfite-converted-dna-reads-to-a-genome">
 <h1 class="title">Aligning bisulfite-converted DNA reads to a genome</h1>
 
+<div class="section" id="the-easy-way">
+<h2>The easy way</h2>
+<p>Use <a class="reference external" href="http://epigenome.cbrc.jp/bisulfighter">Bisulfighter</a>, which
+wraps LAST.</p>
+</div>
+<div class="section" id="the-hard-way">
+<h2>The hard way</h2>
 <p>Bisulfite is used to detect methylated cytosines.  It converts
 unmethylated Cs to Ts, but it leaves methylated Cs intact.  If we then
 sequence the DNA and align it to a reference genome, we can infer
@@ -359,7 +366,7 @@ last-bisulfite.sh my_f my_r reads.fastq > results.maf
 parallel-fastq "last-bisulfite.sh my_f my_r" < reads.fastq > results.maf
 </pre>
 <div class="section" id="tips">
-<h2>Tips</h2>
+<h3>Tips</h3>
 <ul>
 <li><p class="first">To go faster, try gapless alignment (add -j1 to the lastal options).
 Often, this is only minusculely less accurate than gapped alignment.</p>
@@ -373,7 +380,7 @@ ln -f my_f.tis my_r.tis
 </ul>
 </div>
 <div class="section" id="paired-end-dna-reads">
-<h2>Paired-end DNA reads</h2>
+<h3>Paired-end DNA reads</h3>
 <p>You can align paired-end reads by combining the preceding recipe with
 the one in <a class="reference external" href="last-pair-probs.html">last-pair-probs.html</a>.  This gets a bit complicated, so
 we provide a last-bisulfite-paired script in the examples directory.
@@ -391,5 +398,6 @@ parallel to be installed.  You are encouraged to customize this
 script.</p>
 </div>
 </div>
+</div>
 </body>
 </html>
diff --git a/doc/bisulfite.txt b/doc/bisulfite.txt
index 8104b84..b3a28f1 100644
--- a/doc/bisulfite.txt
+++ b/doc/bisulfite.txt
@@ -1,6 +1,15 @@
 Aligning bisulfite-converted DNA reads to a genome
 ==================================================
 
+The easy way
+------------
+
+Use `Bisulfighter <http://epigenome.cbrc.jp/bisulfighter>`_, which
+wraps LAST.
+
+The hard way
+------------
+
 Bisulfite is used to detect methylated cytosines.  It converts
 unmethylated Cs to Ts, but it leaves methylated Cs intact.  If we then
 sequence the DNA and align it to a reference genome, we can infer
@@ -44,7 +53,7 @@ You can parallelize it like this::
   parallel-fastq "last-bisulfite.sh my_f my_r" < reads.fastq > results.maf
 
 Tips
-----
+~~~~
 
 * To go faster, try gapless alignment (add -j1 to the lastal options).
   Often, this is only minusculely less accurate than gapped alignment.
@@ -55,7 +64,7 @@ Tips
     ln -f my_f.tis my_r.tis
 
 Paired-end DNA reads
---------------------
+~~~~~~~~~~~~~~~~~~~~
 
 You can align paired-end reads by combining the preceding recipe with
 the one in `<last-pair-probs.html>`_.  This gets a bit complicated, so
diff --git a/doc/last-tuning.html b/doc/last-tuning.html
index 9c5f033..047f87b 100644
--- a/doc/last-tuning.html
+++ b/doc/last-tuning.html
@@ -318,8 +318,8 @@ table.field-list { border: thin solid green }
 <div class="document" id="last-performance-tuning">
 <h1 class="title">LAST Performance Tuning</h1>
 
-<p>This document tells you how to make LAST <strong>faster</strong>, at a cost in
-sensitivity or memory use, or <strong>more sensitive</strong>, at a cost in speed.</p>
+<p>This document tells you how to trade-off <strong>speed</strong>, <strong>sensitivity</strong>,
+and <strong>memory and disk usage</strong>.</p>
 <p>Ideally, the default settings would always work well.  Unfortunately,
 there is too great a variety of challenging alignment tasks, and the
 LAST developers lack experience with most of them.</p>
@@ -327,31 +327,62 @@ LAST developers lack experience with most of them.</p>
 It is wrong to say "LAST is faster but less sensitive than method X",
 or "slower but more sensitive than method Y", without varying the
 defaults.</p>
+<div class="section" id="sparsity-options">
+<h2>Sparsity options</h2>
+<p>It's advisable to use at most one sparsity option: combining them will
+likely give poor sensitivity.</p>
+<div class="section" id="lastal-k">
+<h3>lastal -k</h3>
+<p>By default lastal looks for initial matches starting at every position
+in the query sequence(s), but -k2 makes it check every 2nd position,
+-k3 every 3rd position, etc.  Compared to the other sparsity options,
+this <strong>increases speed</strong> the most while <strong>reducing sensitivity</strong> the
+least.</p>
+</div>
 <div class="section" id="lastdb-w">
-<h2>lastdb -w</h2>
-<p>This option <strong>reduces memory and disk usage</strong>.  It makes lastdb and
-probably lastal <strong>faster</strong>.  By default lastdb indexes every position
-in the sequence(s), but -w2 makes it index every 2nd position, -w3
-every 3rd position, etc.  This may <strong>reduce sensitivity</strong>, but not
-necessarily, because LAST uses initial matches that are sufficiently
-rare, and by ignoring some matches the remaining ones become rarer.</p>
+<h3>lastdb -w</h3>
+<p>By default lastdb indexes every position in the reference sequence(s),
+but -w2 makes it index every 2nd position, -w3 every 3rd position,
+etc.  Compared to the other sparsity options, this <strong>decreases memory
+and disk use</strong> the most while reducing sensitivity the least.</p>
+<p>This has a complex effect on the speed and sensitivity of lastal.
+LAST uses initial matches that are sufficiently rare: this option
+makes it lose some matches (because those positions are not indexed),
+but gain others (because they are rarer).  In practice, small values
+of w (e.g. 2) sometimes make lastal slower and more sensitive, but
+very large values will eventually reduce sensitivity.</p>
 <p>Among other aligners, MegaBLAST indexes every 5th position, and BLAT
 indexes every 11th position.</p>
 </div>
+<div class="section" id="id1">
+<h3>lastdb -W</h3>
+<p>This makes LAST check for initial matches starting at only some
+positions, in both query and reference.  This <strong>decreases memory and
+disk use</strong>, and <strong>increases speed</strong> of lastdb and lastal, but
+<strong>reduces sensitivity</strong>.</p>
+<p>Specifically, this makes LAST look for initial matches starting only
+at positions that are "minimum" in any window of W consecutive
+positions.  "Minimum" means that the sequence starting here is
+alphabetically earliest.</p>
+<p>The fraction of positions that are "minimum" is roughly: 2 / (W + 1).</p>
+</div>
+</div>
+<div class="section" id="other-options">
+<h2>Other options</h2>
 <div class="section" id="lastdb-i">
-<h2>lastdb -i</h2>
+<h3>lastdb -i</h3>
 <p>This option <strong>makes lastdb faster</strong>, but disables some lastal options.
 If lastdb is too slow, try -i10.</p>
 </div>
 <div class="section" id="lastdb-c">
-<h2>lastdb -C</h2>
+<h3>lastdb -C</h3>
 <p>This option may make lastal a bit <strong>faster</strong>, but <strong>uses more memory
 and disk</strong>, and makes lastdb slower.  If these downsides are no
 problem, you may as well try it.  -C3 is fastest (at least sometimes)
 but uses most memory, -C2 is almost as fast.</p>
 </div>
 <div class="section" id="lastal-m">
-<h2>lastal -m</h2>
+<h3>lastal -m</h3>
 <p>This option <strong>trades speed for sensitivity</strong>.  It sets the rareness
 limit for initial matches: initial matches are lengthened until they
 occur at most this many times in the lastdb volume.  The default is
@@ -359,23 +390,15 @@ occur at most this many times in the lastdb volume.  The default is
 initial matches.</p>
 </div>
 <div class="section" id="lastal-l">
-<h2>lastal -l</h2>
+<h3>lastal -l</h3>
 <p>This option makes lastal <strong>faster</strong> but <strong>less sensitive</strong>.  It sets
 the minimum length of initial matches, e.g. -l50 means length 50.
 (The default is 1).  This can make it <em>much</em> faster, and the
 sensitivity is adequate if the alignments contain long, gapless,
 high-identity matches.</p>
 </div>
-<div class="section" id="lastal-k">
-<h2>lastal -k</h2>
-<p>This option makes lastal <strong>faster</strong> but <strong>less sensitive</strong>.  By
-default lastal looks for initial matches starting at every position in
-the query sequence(s), but -k2 makes it check every 2nd position, -k3
-every 3rd position, etc.  Be careful about combining this with lastdb
-option -w.</p>
-</div>
 <div class="section" id="lastal-x">
-<h2>lastal -x</h2>
+<h3>lastal -x</h3>
 <p>This option can make lastal <strong>faster</strong> but <strong>less sensitive</strong>.  It
 sets the maximum score drop in alignments, in the gapped extension
 phase.  Lower values make it faster, by quitting unpromising
@@ -386,27 +409,28 @@ after "x=", e.g. by running lastal with no queries.  Then try, say,
 halving it.</p>
 </div>
 <div class="section" id="lastal-c">
-<h2>lastal -C</h2>
+<h3>lastal -C</h3>
 <p>This option (gapless alignment culling) can make lastal <strong>faster</strong> but
 <strong>less sensitive</strong>.  It can also <strong>reduce redundant output</strong>.  For
 example, -C2 makes it discard alignments (before gapped extension)
 whose query coordinates lie in those of 2 or more stronger alignments.</p>
 </div>
 <div class="section" id="lastal-j1">
-<h2>lastal -j1</h2>
+<h3>lastal -j1</h3>
 <p>This option requests <strong>gapless</strong> alignment, which is <strong>faster</strong>.  (You
 could get the same effect by using very high gap costs, but -j1 is
 faster because it skips the gapping phase entirely.)</p>
 </div>
 <div class="section" id="lastal-f">
-<h2>lastal -f</h2>
+<h3>lastal -f</h3>
 <p>Option -fTAB <strong>reduces the output size</strong>, which can improve speed.</p>
 </div>
 <div class="section" id="repeat-masking">
-<h2>Repeat masking</h2>
+<h3>Repeat masking</h3>
 <p>This can make LAST <strong>much faster</strong>, produce <strong>less output</strong>, and
 reduce memory and disk usage.  Please see <a class="reference external" href="last-repeats.html">last-repeats.html</a>.</p>
 </div>
 </div>
+</div>
 </body>
 </html>
diff --git a/doc/last-tuning.txt b/doc/last-tuning.txt
index 7e497f8..f3fc430 100644
--- a/doc/last-tuning.txt
+++ b/doc/last-tuning.txt
@@ -1,8 +1,8 @@
 LAST Performance Tuning
 =======================
 
-This document tells you how to make LAST **faster**, at a cost in
-sensitivity or memory use, or **more sensitive**, at a cost in speed.
+This document tells you how to trade-off **speed**, **sensitivity**,
+and **memory and disk usage**.
 
 Ideally, the default settings would always work well.  Unfortunately,
 there is too great a variety of challenging alignment tasks, and the
@@ -13,19 +13,57 @@ It is wrong to say "LAST is faster but less sensitive than method X",
 or "slower but more sensitive than method Y", without varying the
 defaults.
 
+Sparsity options
+~~~~~~~~~~~~~~~~
+
+It's advisable to use at most one sparsity option: combining them will
+likely give poor sensitivity.
+
+lastal -k
+---------
+
+By default lastal looks for initial matches starting at every position
+in the query sequence(s), but -k2 makes it check every 2nd position,
+-k3 every 3rd position, etc.  Compared to the other sparsity options,
+this **increases speed** the most while **reducing sensitivity** the
+least.
+
 lastdb -w
 ---------
 
-This option **reduces memory and disk usage**.  It makes lastdb and
-probably lastal **faster**.  By default lastdb indexes every position
-in the sequence(s), but -w2 makes it index every 2nd position, -w3
-every 3rd position, etc.  This may **reduce sensitivity**, but not
-necessarily, because LAST uses initial matches that are sufficiently
-rare, and by ignoring some matches the remaining ones become rarer.
+By default lastdb indexes every position in the reference sequence(s),
+but -w2 makes it index every 2nd position, -w3 every 3rd position,
+etc.  Compared to the other sparsity options, this **decreases memory
+and disk use** the most while reducing sensitivity the least.
+
+This has a complex effect on the speed and sensitivity of lastal.
+LAST uses initial matches that are sufficiently rare: this option
+makes it lose some matches (because those positions are not indexed),
+but gain others (because they are rarer).  In practice, small values
+of w (e.g. 2) sometimes make lastal slower and more sensitive, but
+very large values will eventually reduce sensitivity.
 
 Among other aligners, MegaBLAST indexes every 5th position, and BLAT
 indexes every 11th position.
 
+lastdb -W
+---------
+
+This makes LAST check for initial matches starting at only some
+positions, in both query and reference.  This **decreases memory and
+disk use**, and **increases speed** of lastdb and lastal, but
+**reduces sensitivity**.
+
+Specifically, this makes LAST look for initial matches starting only
+at positions that are "minimum" in any window of W consecutive
+positions.  "Minimum" means that the sequence starting here is
+alphabetically earliest.
+
+The fraction of positions that are "minimum" is roughly: 2 / (W + 1).
+
+Other options
+~~~~~~~~~~~~~
+
 lastdb -i
 ---------
 
@@ -58,15 +96,6 @@ the minimum length of initial matches, e.g. -l50 means length 50.
 sensitivity is adequate if the alignments contain long, gapless,
 high-identity matches.
 
-lastal -k
----------
-
-This option makes lastal **faster** but **less sensitive**.  By
-default lastal looks for initial matches starting at every position in
-the query sequence(s), but -k2 makes it check every 2nd position, -k3
-every 3rd position, etc.  Be careful about combining this with lastdb
-option -w.
-
 lastal -x
 ---------
 
diff --git a/doc/last.html b/doc/last.html
index 863847e..7c0f7f7 100644
--- a/doc/last.html
+++ b/doc/last.html
@@ -335,6 +335,8 @@ sequences.</p>
 </li>
 <li><p class="first">Do split and spliced alignment.</p>
 </li>
+<li><p class="first">Train alignment parameters for unusual kinds of sequence (e.g. nanopore).</p>
+</li>
 </ul>
 <div class="section" id="requirements">
 <h2>Requirements</h2>
@@ -352,8 +354,25 @@ compile the programs, type:</p>
 <pre class="literal-block">
 make
 </pre>
-<p>Optionally, copy the programs and scripts to a standard "bin"
-directory (using "sudo" to request administrator permissions):</p>
+<p>If your compiler is really old, you might get an error message like
+this:</p>
+<pre class="literal-block">
+unrecognized command line option "-std=c++11"
+</pre>
+<p>In that case, you can compile like this (which will disable
+multi-threading):</p>
+<pre class="literal-block">
+make CXXFLAGS=-O3
+</pre>
+<p>Or you can specify another compiler like this:</p>
+<pre class="literal-block">
+make CXX=MyOtherCompiler
+</pre>
+</div>
+<div class="section" id="install-optional">
+<h2>Install (optional)</h2>
+<p>You can copy the programs and scripts to a standard "bin" directory
+(using "sudo" to request administrator permissions):</p>
 <pre class="literal-block">
 sudo make install
 </pre>
diff --git a/doc/last.txt b/doc/last.txt
index 0d1b569..70123f1 100644
--- a/doc/last.txt
+++ b/doc/last.txt
@@ -12,6 +12,7 @@ genomes and/or large numbers of DNA reads).  It can:
 * Calculate the likelihood of chance similarities between random
   sequences.
 * Do split and spliced alignment.
+* Train alignment parameters for unusual kinds of sequence (e.g. nanopore).
 
 Requirements
 ------------
@@ -32,8 +33,25 @@ compile the programs, type::
 
   make
 
-Optionally, copy the programs and scripts to a standard "bin"
-directory (using "sudo" to request administrator permissions)::
+If your compiler is really old, you might get an error message like
+this::
+
+  unrecognized command line option "-std=c++11"
+
+In that case, you can compile like this (which will disable
+multi-threading)::
+
+  make CXXFLAGS=-O3
+
+Or you can specify another compiler like this::
+
+  make CXX=MyOtherCompiler
+
+Install (optional)
+------------------
+
+You can copy the programs and scripts to a standard "bin" directory
+(using "sudo" to request administrator permissions)::
 
   sudo make install
 
diff --git a/doc/lastal.html b/doc/lastal.html
index 23eaf02..52bd570 100644
--- a/doc/lastal.html
+++ b/doc/lastal.html
@@ -399,7 +399,7 @@ gamma-centroid or LAMA (OFF by default).</p>
 <tr><td class="option-group">
 <kbd><span class="option">-f <var>NAME</var></span></kbd></td>
 <td><p class="first">Choose the output format.  The NAME is not case-sensitive.</p>
-<p>MAF format looks like this:</p>
+<p><strong>MAF</strong> format looks like this:</p>
 <pre class="literal-block">
 a score=15 EG2=4.7e+04 E=2.6e-05
 s chr3 9 23 + 939557 TTTGGGAGTTGAAGTTTTCGCCC
@@ -411,7 +411,7 @@ spanned by the alignment, the strand, the sequence length, and
 the aligned letters.  The start coordinates are zero-based.  If
 the strand is "-", the start coordinate is in the reverse
 strand.</p>
-<p>The same alignment in TAB format looks like this:</p>
+<p>The same alignment in <strong>TAB</strong> format looks like this:</p>
 <pre class="literal-block">
 15 chr3 9 23 + 939557 seqA 2 21 + 25 17,2:0,4 EG2=4.7e+04 E=2.6e-05
 </pre>
@@ -419,16 +419,19 @@ strand.</p>
 the alignment.  In this case, we have a block of size 17, then
 an offset of size 2 in the upper sequence and 0 in the lower
 sequence, then a block of size 4.</p>
-<p>The same alignment in BlastTab format looks like this:</p>
+<p>The same alignment in <strong>BlastTab</strong> format looks like this:</p>
 <pre class="literal-block">
 seqA chr3 86.96 23 1 1 3 23 10 32 2.6e-05 44.3
 </pre>
 <p>The fields are: query name, reference name, percent identity,
 alignment length, mismatches, gap opens, query start, query end,
 reference start, reference end, E-value, bit score.  The start
-coordinates are one-based.  <strong>Warning:</strong> this is a lossy format,
-because it does not show gap positions.  <strong>Warning:</strong> the other
+coordinates are one-based.  <em>Warning:</em> this is a lossy format,
+because it does not show gap positions.  <em>Warning:</em> the other
 LAST programs cannot read this format.</p>
+<p><strong>BlastTab+</strong> format is the same as BlastTab, with 2 extra
+columns at the end: length of query sequence and length of
+reference sequence.  More columns might be added in future.</p>
 <p class="last">For backwards compatibility, a NAME of 0 means TAB and 1 means
 MAF.</p>
 </td></tr>
@@ -620,6 +623,12 @@ query (P Berman et al. 2000, J Comput Biol 7:293-302).</td></tr>
 <td>Look for initial matches starting only at every STEP-th position
 in the query.  This makes lastal faster but less sensitive.</td></tr>
 <tr><td class="option-group">
+<kbd><span class="option">-W <var>SIZE</var></span></kbd></td>
+<td>Look for initial matches starting only at query positions that
+are "minimum" in any window of SIZE consecutive positions (see
+<a class="reference external" href="lastdb.html">lastdb.html</a>).  By default, this parameter takes the same
+value as was used for lastdb -W.</td></tr>
+<tr><td class="option-group">
 <kbd><span class="option">-i <var>BYTES</var></span></kbd></td>
 <td><p class="first">Search queries in batches of at most this many bytes.  If a
 single sequence exceeds this amount, however, it is not split.
@@ -632,9 +641,10 @@ volume will be read into memory once per query batch.</p>
 <tr><td class="option-group">
 <kbd><span class="option">-P <var>THREADS</var></span></kbd></td>
 <td>Divide the work between this number of threads running in
-parallel.  0 means use a number suggested by your computer.
-Single query sequences are not divided between threads, so you
-need multiple queries per batch for this option to take effect.</td></tr>
+parallel.  0 means use as many threads as your computer claims
+it can handle simultaneously.  Single query sequences are not
+divided between threads, so you need multiple queries per batch
+for this option to take effect.</td></tr>
 <tr><td class="option-group">
 <kbd><span class="option">-R <var>DIGITS</var></span></kbd></td>
 <td><p class="first">Specify lowercase-marking of repeats, by two digits (e.g. "-R 01"),
@@ -781,7 +791,7 @@ generalized affine gap costs.  They are:</p>
 PSSMs, for the queries.  0 means read queries in fasta format
 (without quality scores); 1 means fastq-sanger format; 2 means
 fastq-solexa format; 3 means fastq-illumina format; 4 means prb
-format; 5 means read PSSMs.  (Warning: Illumina data is not
+format; 5 means read PSSMs.  (<em>Warning</em>: Illumina data is not
 necessarily in fastq-illumina format; it is often in
 fastq-sanger format.)</p>
 <p>The fastq formats look like this:</p>
@@ -825,7 +835,7 @@ contain the position-specific scores.  Any letters not specified
 by any column will get the lowest score in each row.  This
 format is a simplified version of PSI-BLAST's ASCII format: the
 non-simplified version is allowed too.</p>
-<p class="last">Warning: lastal cannot directly calculate E-values for PSSMs.
+<p class="last"><em>Warning</em>: lastal cannot directly calculate E-values for PSSMs.
 The E-values (and the default value of -y) are determined by the
 otherwise-unused match and mismatch scores (options -r -q and
 -p).  There is evidence these E-values will be accurate if the
diff --git a/doc/lastal.txt b/doc/lastal.txt
index cc4f414..2d289e9 100644
--- a/doc/lastal.txt
+++ b/doc/lastal.txt
@@ -67,7 +67,7 @@ Cosmetic options
   -f NAME
       Choose the output format.  The NAME is not case-sensitive.
 
-      MAF format looks like this::
+      **MAF** format looks like this::
 
         a score=15 EG2=4.7e+04 E=2.6e-05
         s chr3 9 23 + 939557 TTTGGGAGTTGAAGTTTTCGCCC
@@ -80,7 +80,7 @@ Cosmetic options
       the strand is "-", the start coordinate is in the reverse
       strand.
 
-      The same alignment in TAB format looks like this::
+      The same alignment in **TAB** format looks like this::
 
         15 chr3 9 23 + 939557 seqA 2 21 + 25 17,2:0,4 EG2=4.7e+04 E=2.6e-05
 
@@ -89,17 +89,21 @@ Cosmetic options
       an offset of size 2 in the upper sequence and 0 in the lower
       sequence, then a block of size 4.
 
-      The same alignment in BlastTab format looks like this::
+      The same alignment in **BlastTab** format looks like this::
 
         seqA chr3 86.96 23 1 1 3 23 10 32 2.6e-05 44.3
 
       The fields are: query name, reference name, percent identity,
       alignment length, mismatches, gap opens, query start, query end,
       reference start, reference end, E-value, bit score.  The start
-      coordinates are one-based.  **Warning:** this is a lossy format,
-      because it does not show gap positions.  **Warning:** the other
+      coordinates are one-based.  *Warning:* this is a lossy format,
+      because it does not show gap positions.  *Warning:* the other
       LAST programs cannot read this format.
 
+      **BlastTab+** format is the same as BlastTab, with 2 extra
+      columns at the end: length of query sequence and length of
+      reference sequence.  More columns might be added in future.
+
       For backwards compatibility, a NAME of 0 means TAB and 1 means
       MAF.
 
@@ -265,6 +269,12 @@ Miscellaneous options
       Look for initial matches starting only at every STEP-th position
       in the query.  This makes lastal faster but less sensitive.
 
+  -W SIZE
+      Look for initial matches starting only at query positions that
+      are "minimum" in any window of SIZE consecutive positions (see
+      `<lastdb.html>`_).  By default, this parameter takes the same
+      value as was used for lastdb -W.
+
   -i BYTES
       Search queries in batches of at most this many bytes.  If a
       single sequence exceeds this amount, however, it is not split.
@@ -277,9 +287,10 @@ Miscellaneous options
 
   -P THREADS
       Divide the work between this number of threads running in
-      parallel.  0 means use a number suggested by your computer.
-      Single query sequences are not divided between threads, so you
-      need multiple queries per batch for this option to take effect.
+      parallel.  0 means use as many threads as your computer claims
+      it can handle simultaneously.  Single query sequences are not
+      divided between threads, so you need multiple queries per batch
+      for this option to take effect.
 
   -R DIGITS
       Specify lowercase-marking of repeats, by two digits (e.g. "-R 01"),
@@ -413,7 +424,7 @@ Miscellaneous options
       PSSMs, for the queries.  0 means read queries in fasta format
       (without quality scores); 1 means fastq-sanger format; 2 means
       fastq-solexa format; 3 means fastq-illumina format; 4 means prb
-      format; 5 means read PSSMs.  (Warning: Illumina data is not
+      format; 5 means read PSSMs.  (*Warning*: Illumina data is not
       necessarily in fastq-illumina format; it is often in
       fastq-sanger format.)
 
@@ -462,7 +473,7 @@ Miscellaneous options
       format is a simplified version of PSI-BLAST's ASCII format: the
       non-simplified version is allowed too.
 
-      Warning: lastal cannot directly calculate E-values for PSSMs.
+      *Warning*: lastal cannot directly calculate E-values for PSSMs.
       The E-values (and the default value of -y) are determined by the
       otherwise-unused match and mismatch scores (options -r -q and
       -p).  There is evidence these E-values will be accurate if the
diff --git a/doc/lastdb.html b/doc/lastdb.html
index dfc16c5..aeb828d 100644
--- a/doc/lastdb.html
+++ b/doc/lastdb.html
@@ -414,6 +414,18 @@ usage of lastdb and lastal, and it makes lastdb faster.  Its
 effect on the speed and sensitivity of lastal is not entirely
 clear.</td></tr>
 <tr><td class="option-group">
+<kbd><span class="option">-W <var>SIZE</var></span></kbd></td>
+<td><p class="first">Allow initial matches to start only at positions that are
+"minimum" in any window of SIZE consecutive positions.
+"Minimum" means that the sequence starting here is
+alphabetically earliest.</p>
+<p>The "alphabetical" order depends on the <a class="reference external" href="last-seeds.html">seed pattern</a>.  The letter order is determined by the
+order of the letter groups, and letters in the same group are
+considered equivalent.</p>
+<p class="last">The fraction of positions that are "minimum" is roughly: 2 /
+(SIZE + 1).</p>
+</td></tr>
+<tr><td class="option-group">
 <kbd><span class="option">-s <var>BYTES</var></span></kbd></td>
 <td><p class="first">Limit memory usage, by splitting the output files into smaller
 "volumes" if necessary.  This will limit the memory usage of
@@ -465,6 +477,12 @@ by options from a <a class="reference external" href="last-matrices.html">scorin
 lastal command line.</p>
 </td></tr>
 <tr><td class="option-group">
+<kbd><span class="option">-P <var>THREADS</var></span></kbd></td>
+<td>Divide the work between this number of threads running in
+parallel.  0 means use as many threads as your computer claims
+it can handle simultaneously.  Currently, multi-threading is
+used for tantan masking only.</td></tr>
+<tr><td class="option-group">
 <kbd><span class="option">-a <var>SYMBOLS</var></span></kbd></td>
 <td>Specify your own alphabet, e.g. "-a 0123".  The default (DNA)
 alphabet is equivalent to "-a ACGT".  The protein alphabet (-p)
diff --git a/doc/lastdb.txt b/doc/lastdb.txt
index cc16b26..32a530c 100644
--- a/doc/lastdb.txt
+++ b/doc/lastdb.txt
@@ -78,6 +78,20 @@ Advanced Options
       effect on the speed and sensitivity of lastal is not entirely
       clear.
 
+  -W SIZE
+      Allow initial matches to start only at positions that are
+      "minimum" in any window of SIZE consecutive positions.
+      "Minimum" means that the sequence starting here is
+      alphabetically earliest.
+
+      The "alphabetical" order depends on the `seed pattern
+      <last-seeds.html>`_.  The letter order is determined by the
+      order of the letter groups, and letters in the same group are
+      considered equivalent.
+
+      The fraction of positions that are "minimum" is roughly: 2 /
+      (SIZE + 1).
+
   -s BYTES      
       Limit memory usage, by splitting the output files into smaller
       "volumes" if necessary.  This will limit the memory usage of
@@ -134,6 +148,12 @@ Advanced Options
       by options from a `scoring scheme <last-matrices.html>`_ or the
       lastal command line.
 
+  -P THREADS
+      Divide the work between this number of threads running in
+      parallel.  0 means use as many threads as your computer claims
+      it can handle simultaneously.  Currently, multi-threading is
+      used for tantan masking only.
+
   -a SYMBOLS
       Specify your own alphabet, e.g. "-a 0123".  The default (DNA)
       alphabet is equivalent to "-a ACGT".  The protein alphabet (-p)
diff --git a/makefile b/makefile
index d314c8d..545a6b9 100644
--- a/makefile
+++ b/makefile
@@ -1,4 +1,4 @@
-CXXFLAGS = -O3 -std=c++11 -pthread
+CXXFLAGS = -O3 -std=c++11 -pthread -DHAS_CXX_THREADS
 all:
 	@cd src && $(MAKE) CXXFLAGS="$(CXXFLAGS)"
 
diff --git a/scripts/maf-convert b/scripts/maf-convert
index 42b7542..8a67408 100755
--- a/scripts/maf-convert
+++ b/scripts/maf-convert
@@ -305,12 +305,19 @@ def cigarParts(beg, alignmentColumns, end):
     if beg: yield str(beg) + "H"
 
     # (doesn't handle translated alignments)
+    # uses "read-ahead" technique, aiming to be as fast as possible:
     isActive = True
     for x, y in alignmentColumns: break
     else: isActive = False
     while isActive:
         size = 1
-        if x == "-":
+        if x == y:  # xxx assumes no gap-gap columns, ignores ambiguous bases
+            for x, y in alignmentColumns:
+                if x != y: break
+                size += 1
+            else: isActive = False
+            yield str(size) + "="
+        elif x == "-":
             for x, y in alignmentColumns:
                 if x != "-": break
                 size += 1
@@ -324,10 +331,10 @@ def cigarParts(beg, alignmentColumns, end):
             yield str(size) + "D"
         else:
             for x, y in alignmentColumns:
-                if x == "-" or y == "-": break
+                if x == y or x == "-" or y == "-": break
                 size += 1
             else: isActive = False
-            yield str(size) + "M"
+            yield str(size) + "X"
 
     if end: yield str(end) + "H"
 
@@ -349,56 +356,54 @@ def writeSam(maf, rg):
         elif i.startswith("mismap="):
             mapq = mapqFromProb(i[7:])
 
-    head, tail = sLines[0], sLines[1:]
-
-    s, rName, rStart, rAlnSize, rStrand, rSeqSize, rAlnString = head
+    if len(sLines) != 2:
+        raise Exception("for SAM, each alignment must have 2 sequences")
+    rFields, qFields = sLines
+    s, rName, rStart, rAlnSize, rStrand, rSeqSize, rAlnString = rFields
+    s, qName, qStart, qAlnSize, qStrand, qSeqSize, qAlnString = qFields
     if rStrand != "+":
         raise Exception("for SAM, the 1st strand in each alignment must be +")
     pos = str(int(rStart) + 1)  # convert to 1-based coordinate
 
-    for s, qName, qStart, qAlnSize, qStrand, qSeqSize, qAlnString in tail:
-        alignmentColumns = zip(rAlnString.upper(), qAlnString.upper())
+    alignmentColumns = zip(rAlnString.upper(), qAlnString.upper())
 
-        qStart = int(qStart)
-        qRevStart = int(qSeqSize) - qStart - int(qAlnSize)
-        cigar = "".join(cigarParts(qStart, iter(alignmentColumns), qRevStart))
+    qStart = int(qStart)
+    qRevStart = int(qSeqSize) - qStart - int(qAlnSize)
+    cigar = "".join(cigarParts(qStart, iter(alignmentColumns), qRevStart))
 
-        seq = deleted(qAlnString, "-")
+    seq = deleted(qAlnString, "-")
 
+    if qLines and qLines[-1][1] == qName:
+        qual = ''.join(j
+                       for i, j in izip(qAlnString, qLines[-1][2]) if i != "-")
+    else:
         qual = "*"
-        if qLines:
-            q, qualityName, qualityString = qLines[0]
-            # don't try to handle multiple alignments for now (YAGNI):
-            if len(qLines) > 1 or len(tail) > 1 or qualityName != qName:
-                raise Exception("can't interpret the quality data")
-            qual = ''.join(j for i, j in izip(qAlnString, qualityString)
-                           if i != "-")
-
-        # It's hard to get all the pair info, so this is very
-        # incomplete, but hopefully good enough.
-        # I'm not sure whether to add 2 and/or 8 to flag.
-        if qName.endswith("/1"):
-            qName = qName[:-2]
-            if qStrand == "+": flag = "99"  # 1 + 2 + 32 + 64
-            else:              flag = "83"  # 1 + 2 + 16 + 64
-        elif qName.endswith("/2"):
-            qName = qName[:-2]
-            if qStrand == "+": flag = "163"  # 1 + 2 + 32 + 128
-            else:              flag = "147"  # 1 + 2 + 16 + 128
-        else:
-            if qStrand == "+": flag = "0"
-            else:              flag = "16"
-
-        editDistance = sum(1 for x, y in alignmentColumns if x != y)
-        # no special treatment of ambiguous bases: might be a minor bug
-        editDistance = "NM:i:" + str(editDistance)
-
-        outWords = [qName, flag, rName, pos, mapq, cigar, "*\t0\t0", seq, qual]
-        outWords.append(editDistance)
-        if score: outWords.append(score)
-        if evalue: outWords.append(evalue)
-        if rg: outWords.append(rg)
-        print "\t".join(outWords)
+
+    # It's hard to get all the pair info, so this is very
+    # incomplete, but hopefully good enough.
+    # I'm not sure whether to add 2 and/or 8 to flag.
+    if qName.endswith("/1"):
+        qName = qName[:-2]
+        if qStrand == "+": flag = "99"  # 1 + 2 + 32 + 64
+        else:              flag = "83"  # 1 + 2 + 16 + 64
+    elif qName.endswith("/2"):
+        qName = qName[:-2]
+        if qStrand == "+": flag = "163"  # 1 + 2 + 32 + 128
+        else:              flag = "147"  # 1 + 2 + 16 + 128
+    else:
+        if qStrand == "+": flag = "0"
+        else:              flag = "16"
+
+    editDistance = sum(1 for x, y in alignmentColumns if x != y)
+    # no special treatment of ambiguous bases: might be a minor bug
+    editDistance = "NM:i:" + str(editDistance)
+
+    outWords = [qName, flag, rName, pos, mapq, cigar, "*\t0\t0", seq, qual]
+    outWords.append(editDistance)
+    if score: outWords.append(score)
+    if evalue: outWords.append(evalue)
+    if rg: outWords.append(rg)
+    print "\t".join(outWords)
 
 ##### Routines for converting to BLAST-like format: #####
 
diff --git a/src/Alignment.hh b/src/Alignment.hh
index d6c59e0..2ebf602 100644
--- a/src/Alignment.hh
+++ b/src/Alignment.hh
@@ -30,14 +30,18 @@ struct AlignmentText {
   SegmentPair::indexT queryBeg;
   SegmentPair::indexT queryEnd;
   int score;
+  SegmentPair::indexT alnSize;
+  SegmentPair::indexT matches;
   char *text;  // seems to be a bit faster than std::vector<char>
 
   AlignmentText() {}
 
   AlignmentText(size_t queryNumIn, size_t queryBegIn, size_t queryEndIn,
-		char strandIn, int scoreIn, char *textIn) :
+		char strandIn, int scoreIn,
+		size_t alnSizeIn, size_t matchesIn, char *textIn) :
     strandNum(queryNumIn * 2 + (strandIn == '-')),
-    queryBeg(queryBegIn), queryEnd(queryEndIn), score(scoreIn), text(textIn) {}
+    queryBeg(queryBegIn), queryEnd(queryEndIn), score(scoreIn),
+    alnSize(alnSizeIn), matches(matchesIn), text(textIn) {}
 
   size_t queryNum() const { return strandNum / 2; }
 
@@ -46,6 +50,10 @@ struct AlignmentText {
     if (queryNum() != r.queryNum()) return queryNum() < r.queryNum();
     if (score      != r.score     ) return score      > r.score;
 
+    // Requested by JGI:
+    if (alnSize    != r.alnSize   ) return alnSize    > r.alnSize;
+    if (matches    != r.matches   ) return matches    > r.matches;
+
     // Break ties, to make the sort order exactly reproducible:
     return std::strcmp(text, r.text) < 0;
   }
@@ -139,7 +147,8 @@ struct Alignment{
 			      size_t seqNum2, char strand,
 			      const uchar* seqData2,
 			      bool isTranslated, const Alphabet& alph,
-			      const LastEvaluer& evaluer) const;
+			      const LastEvaluer& evaluer,
+			      bool isExtraColumns) const;
 
   size_t numColumns( size_t frameSize ) const;
 
diff --git a/src/AlignmentWrite.cc b/src/AlignmentWrite.cc
index f426341..bfbd53e 100644
--- a/src/AlignmentWrite.cc
+++ b/src/AlignmentWrite.cc
@@ -100,12 +100,12 @@ AlignmentText Alignment::write(const MultiSequence& seq1,
   if( format == 'm' )
     return writeMaf( seq1, seq2, seqNum2, strand, seqData2,
 		     isTranslated, alph, evaluer, extras );
-  if( format == 'b' )
-    return writeBlastTab( seq1, seq2, seqNum2, strand, seqData2,
-			  isTranslated, alph, evaluer );
-  else
+  if( format == 't' )
     return writeTab( seq1, seq2, seqNum2, strand,
 		     isTranslated, evaluer, extras );
+  else
+    return writeBlastTab( seq1, seq2, seqNum2, strand, seqData2,
+			  isTranslated, alph, evaluer, format == 'B' );
 }
 
 static size_t alignedColumnCount(const std::vector<SegmentPair> &blocks) {
@@ -226,7 +226,7 @@ AlignmentText Alignment::writeTab(const MultiSequence& seq1,
   w.copy(tags, tagLen);
   w << '\0';
 
-  return AlignmentText(seqNum2, alnBeg2, alnEnd2, strand, score, text);
+  return AlignmentText(seqNum2, alnBeg2, alnEnd2, strand, score, 0, 0, text);
 }
 
 static void putLeft(Writer &w, const std::string &t, size_t width) {
@@ -391,7 +391,7 @@ AlignmentText Alignment::writeMaf(const MultiSequence& seq1,
   *dest++ = '\n';  // blank line afterwards
   *dest++ = '\0';
 
-  return AlignmentText(seqNum2, alnBeg2, alnEnd2, strand, score, text);
+  return AlignmentText(seqNum2, alnBeg2, alnEnd2, strand, score, 0, 0, text);
 }
 
 AlignmentText Alignment::writeBlastTab(const MultiSequence& seq1,
@@ -399,17 +399,20 @@ AlignmentText Alignment::writeBlastTab(const MultiSequence& seq1,
 				       size_t seqNum2, char strand,
 				       const uchar* seqData2,
 				       bool isTranslated, const Alphabet& alph,
-				       const LastEvaluer& evaluer) const {
+				       const LastEvaluer& evaluer,
+				       bool isExtraColumns) const {
   size_t alnBeg1 = beg1();
   size_t alnEnd1 = end1();
   size_t seqNum1 = seq1.whichSequence(alnBeg1);
   size_t seqStart1 = seq1.seqBeg(seqNum1);
+  size_t seqLen1 = seq1.seqLen(seqNum1);
 
   size_t size2 = seq2.padLen(seqNum2);
   size_t frameSize2 = isTranslated ? (size2 / 3) : 0;
   size_t alnBeg2 = aaToDna( beg2(), frameSize2 );
   size_t alnEnd2 = aaToDna( end2(), frameSize2 );
   size_t seqStart2 = seq2.seqBeg(seqNum2) - seq2.padBeg(seqNum2);
+  size_t seqLen2 = seq2.seqLen(seqNum2);
 
   size_t alnSize = numColumns( frameSize2 );
   size_t matches = matchCount( blocks, seq1.seqReader(), seqData2,
@@ -446,18 +449,20 @@ AlignmentText Alignment::writeBlastTab(const MultiSequence& seq1,
   FloatText ev;
   FloatText bs;
   if( evaluer.isGood() ){
-    size_t seqLen2 = seq2.seqLen(seqNum2);
     double area = evaluer.area( score, seqLen2 );
     double epa = evaluer.evaluePerArea( score );
     double bitScore = evaluer.bitScore( score );
     ev.set("%.2g", area * epa);
     bs.set("%.3g", bitScore);
   }
+  IntText s1(seqLen1);
+  IntText s2(seqLen2);
 
   size_t s =
     n2.size() + n1.size() + mp.size() + as.size() + mm.size() + go.size() +
     b2.size() + e2.size() + b1.size() + e1.size() + 10;
   if (evaluer.isGood()) s += ev.size() + bs.size() + 2;
+  if (isExtraColumns)   s += s1.size() + s2.size() + 2;
 
   char *text = new char[s + 1];
   Writer w(text);
@@ -465,9 +470,11 @@ AlignmentText Alignment::writeBlastTab(const MultiSequence& seq1,
   w << n2 << t << n1 << t << mp << t << as << t << mm << t << go << t
     << b2 << t << e2 << t << b1 << t << e1;
   if (evaluer.isGood()) w << t << ev << t << bs;
+  if (isExtraColumns)   w << t << s2 << t << s1;
   w << '\n' << '\0';
 
-  return AlignmentText(seqNum2, alnBeg2, alnEnd2, strand, score, text);
+  return AlignmentText(seqNum2, alnBeg2, alnEnd2, strand, score,
+		       alnSize, matches, text);
 }
 
 size_t Alignment::numColumns( size_t frameSize ) const{
diff --git a/src/CyclicSubsetSeed.cc b/src/CyclicSubsetSeed.cc
index 0a4ed63..8017fde 100644
--- a/src/CyclicSubsetSeed.cc
+++ b/src/CyclicSubsetSeed.cc
@@ -19,7 +19,7 @@
 using namespace cbrc;
 
 std::string CyclicSubsetSeed::stringFromName( const std::string& name ){
-  for( std::size_t i = 0; i < COUNTOF(subsetSeeds); ++i )
+  for( size_t i = 0; i < COUNTOF(subsetSeeds); ++i )
     if( name == subsetSeeds[i].name )
       return subsetSeeds[i].text;
 
diff --git a/src/CyclicSubsetSeed.hh b/src/CyclicSubsetSeed.hh
index 20b986b..cd947ed 100644
--- a/src/CyclicSubsetSeed.hh
+++ b/src/CyclicSubsetSeed.hh
@@ -62,6 +62,11 @@ public:
 
   void clear() { subsetLists.clear(); subsetMaps.clear(); }
 
+  void swap( CyclicSubsetSeed& x ){
+    subsetLists.swap( x.subsetLists );
+    subsetMaps.swap( x.subsetMaps );
+  }
+
   // Seed letters are case-sensitive.
   void init( const std::vector< std::string >& seedAlphabet,
 	     const std::string& pattern,
@@ -106,6 +111,22 @@ public:
     return x - MAX_LETTERS;
   }
 
+  // Checks whether text1 is lexicographically less than text2, when
+  // applying the cyclic subset seed pattern to both.  The "startMap"
+  // argument enables us to start in the middle of the seed pattern.
+  bool isLess(const uchar *text1, const uchar *text2,
+	      const uchar *startMap) const {
+    while (true) {
+      uchar x = startMap[*text1];
+      uchar y = startMap[*text2];
+      if (x != y) return x < y;
+      if (x == DELIMITER) return false;
+      ++text1;
+      ++text2;
+      startMap = nextMap(startMap);
+    }
+  }
+
 private:
   std::vector< std::vector<std::string> > subsetLists;
   std::vector<uchar> subsetMaps;
diff --git a/src/LastalArguments.cc b/src/LastalArguments.cc
index a4098b9..375c2f7 100644
--- a/src/LastalArguments.cc
+++ b/src/LastalArguments.cc
@@ -36,6 +36,7 @@ static char parseOutputFormat( const char* text ){
   if( s == "tab" || s == "0" ) return 't';
   if( s == "maf" || s == "1" ) return 'm';
   if( s == "blasttab" )        return 'b';
+  if( s == "blasttab+" )       return 'B';
   return 0;
 }
 
@@ -74,6 +75,7 @@ LastalArguments::LastalArguments() :
   cullingLimitForGaplessAlignments(0),
   cullingLimitForFinalAlignments(0),
   queryStep(1),
+  minimizerWindow(0),  // depends on the reference's minimizer window
   batchSize(0),  // depends on the outputType, and voluming
   numOfThreads(1),
   maxRepeatDistance(1000),  // sufficiently conservative?
@@ -83,8 +85,9 @@ LastalArguments::LastalArguments() :
   verbosity(0){}
 
 void LastalArguments::fromArgs( int argc, char** argv, bool optionsOnly ){
-  std::string usage =
-      "Usage: lastal [options] lastdb-name fasta-sequence-file(s)";
+  programName = argv[0];
+  std::string usage = "Usage: " + std::string(programName) +
+    " [options] lastdb-name fasta-sequence-file(s)";
 
   std::string help = usage + "\n\
 Find local sequence alignments.\n\
@@ -114,7 +117,7 @@ Cosmetic options (default settings):\n\
 -h, --help: show all options and their default settings, and exit\n\
 -V, --version: show version information, and exit\n\
 -v: be verbose: write messages about what lastal is doing\n\
--f: output format: TAB, MAF, BlastTab (MAF)\n\
+-f: output format: TAB, MAF, BlastTab, BlastTab+ (MAF)\n\
 \n\
 Miscellaneous options (default settings):\n\
 -s: strand: 0=reverse, 1=forward, 2=both (2 for DNA, 1 for protein)\n\
@@ -130,8 +133,9 @@ Miscellaneous options (default settings):\n\
 -n: maximum gapless alignments per query position (infinity if m=0, else m)\n\
 -C: omit gapless alignments in >= C others with > score-per-length (off)\n\
 -K: omit alignments whose query range lies in >= K others with > score (off)\n\
--k: step-size along the query sequence ("
+-k: use initial matches starting at every k-th position in each query ("
     + stringify(queryStep) + ")\n\
+-W: use \"minimum\" positions in sliding windows of W consecutive positions\n\
 -i: query batch size (8 KiB, unless there is > 1 thread or lastdb volume)\n\
 -P: number of parallel threads ("
     + stringify(numOfThreads) + ")\n\
@@ -159,7 +163,7 @@ LAST home page: http://last.cbrc.jp/\n\
   optind = 1;  // allows us to scan arguments more than once(???)
   int c;
   const char optionString[] = "hVvf:" "r:q:p:a:b:A:B:c:F:x:y:z:d:e:" "D:E:"
-    "s:S:T:m:l:L:n:C:K:k:i:P:R:u:w:t:g:G:j:Q:";
+    "s:S:T:m:l:L:n:C:K:k:W:i:P:R:u:w:t:g:G:j:Q:";
   while( (c = myGetopt(argc, argv, optionString)) != -1 ){
     switch(c){
     case 'h':
@@ -277,6 +281,9 @@ LAST home page: http://last.cbrc.jp/\n\
       unstringify( queryStep, optarg );
       if( queryStep <= 0 ) badopt( c, optarg );
       break;
+    case 'W':
+      unstringify( minimizerWindow, optarg );  // allow 0, meaning "default"
+      break;
     case 'i':
       unstringifySize( batchSize, optarg );
       if( batchSize <= 0 ) badopt( c, optarg );  // 0 means "not specified"
@@ -385,6 +392,7 @@ void LastalArguments::setDefaultsFromAlphabet( bool isDna, bool isProtein,
 					       int refTantanSetting,
                                                bool isCaseSensitiveSeeds,
 					       bool isVolumes,
+					       indexT refMinimizerWindow,
 					       unsigned realNumOfThreads ){
   if( strand < 0 ) strand = (isDna || isTranslated()) ? 2 : 1;
 
@@ -449,12 +457,16 @@ void LastalArguments::setDefaultsFromAlphabet( bool isDna, bool isProtein,
     else
       batchSize = 0x8000000;  // 128 Mbytes
     // (should we reduce the 128 Mbytes, for fewer out-of-memory errors?)
+    if( verbosity )
+      std::cerr << programName << ": batch size=" << batchSize << '\n';
   }
 
   if( maxGaplessAlignmentsPerQueryPosition == 0 )
     maxGaplessAlignmentsPerQueryPosition =
       (oneHitMultiplicity > 0) ? oneHitMultiplicity : -1;
 
+  if( minimizerWindow == 0 ) minimizerWindow = refMinimizerWindow;
+
   if( isTranslated() && frameshiftCost < gapExtendCost )
     ERR( "the frameshift cost must not be less than the gap extension cost" );
 
@@ -558,7 +570,8 @@ void LastalArguments::writeCommented( std::ostream& stream ) const{
   if( cullingLimitForFinalAlignments )
     stream << " K=" << cullingLimitForFinalAlignments;
   stream << " k=" << queryStep;
-  stream << " i=" << batchSize;
+  if( minimizerWindow > 1 )
+    stream << " W=" << minimizerWindow;
   stream << " w=" << maxRepeatDistance;
   stream << " t=" << temperature;
   if( outputType > 4 && outputType < 7 )
diff --git a/src/LastalArguments.hh b/src/LastalArguments.hh
index 2cc4f5b..9418db1 100644
--- a/src/LastalArguments.hh
+++ b/src/LastalArguments.hh
@@ -38,6 +38,7 @@ struct LastalArguments{
 				double numLettersInReference,
 				bool isKeepRefLowercase, int refTantanSetting,
                                 bool isCaseSensitiveSeeds, bool isVolumes,
+				indexT refMinimizerWindow,
 				unsigned realNumOfThreads );
   void setDefaultsFromMatrix( double lambda, int minScore );
 
@@ -87,6 +88,7 @@ struct LastalArguments{
   size_t cullingLimitForGaplessAlignments;
   size_t cullingLimitForFinalAlignments;
   indexT queryStep;
+  indexT minimizerWindow;
   indexT batchSize;  // approx size of query sequences to scan in 1 batch
   unsigned numOfThreads;
   indexT maxRepeatDistance;  // suppress repeats <= this distance apart
@@ -96,6 +98,7 @@ struct LastalArguments{
   int verbosity;
 
   // positional arguments:
+  const char* programName;
   std::string lastdbName;
   int inputStart;  // index in argv of first input filename
 };
diff --git a/src/LastdbArguments.cc b/src/LastdbArguments.cc
index 3f7e841..c274142 100644
--- a/src/LastdbArguments.cc
+++ b/src/LastdbArguments.cc
@@ -33,6 +33,8 @@ LastdbArguments::LastdbArguments() :
   seedPatterns(0),
   volumeSize(-1),
   indexStep(1),
+  minimizerWindow(1),
+  numOfThreads(1),
   subsetSeedFile(""),
   userAlphabet(""),
   minSeedLimit(0),
@@ -43,8 +45,10 @@ LastdbArguments::LastdbArguments() :
   inputFormat(sequenceFormat::fasta){}
 
 void LastdbArguments::fromArgs( int argc, char** argv, bool isOptionsOnly ){
+  programName = argv[0];
   std::string usage = "\
-Usage: lastdb [options] output-name fasta-sequence-file(s)\n\
+Usage: " + std::string(programName) +
+    " [options] output-name fasta-sequence-file(s)\n\
 Prepare sequences for subsequent alignment with lastal.\n\
 \n\
 Main Options:\n\
@@ -62,8 +66,12 @@ Advanced Options (default settings):\n\
 -s: volume size (unlimited)\n\
 -m: seed pattern (non-DNA: 1)\n\
 -u: seeding scheme (DNA: YASS)\n\
--w: index step ("
+-w: use initial matches starting at every w-th position in each sequence ("
     + stringify(indexStep) + ")\n\
+-W: use \"minimum\" positions in sliding windows of W consecutive positions ("
+    + stringify(minimizerWindow) + ")\n\
+-P: number of parallel threads ("
+    + stringify(numOfThreads) + ")\n\
 -a: user-defined alphabet\n\
 -i: minimum limit on initial matches per query position ("
     + stringify(minSeedLimit) + ")\n\
@@ -80,7 +88,7 @@ LAST home page: http://last.cbrc.jp/\n\
 
   optind = 1;  // allows us to scan arguments more than once(???)
   int c;
-  while( (c = myGetopt(argc, argv, "hVpR:cm:s:w:u:a:i:b:C:xvQ:")) != -1 ) {
+  while( (c = myGetopt(argc, argv, "hVpR:cm:s:w:W:P:u:a:i:b:C:xvQ:")) != -1 ) {
     switch(c){
     case 'h':
       std::cout << help;
@@ -113,6 +121,13 @@ LAST home page: http://last.cbrc.jp/\n\
       unstringify( indexStep, optarg );
       if( indexStep < 1 ) badopt( c, optarg );
       break;
+    case 'W':
+      unstringify( minimizerWindow, optarg );
+      if( minimizerWindow < 1 ) badopt( c, optarg );
+      break;
+    case 'P':
+      unstringify( numOfThreads, optarg );
+      break;
     case 'u':
       subsetSeedFile = optarg;
       break;
diff --git a/src/LastdbArguments.hh b/src/LastdbArguments.hh
index 45c13b6..73018af 100644
--- a/src/LastdbArguments.hh
+++ b/src/LastdbArguments.hh
@@ -38,6 +38,8 @@ struct LastdbArguments{
   std::vector< std::string > seedPatterns;
   size_t volumeSize;  // type?
   indexT indexStep;
+  indexT minimizerWindow;
+  unsigned numOfThreads;
   std::string subsetSeedFile;
   std::string userAlphabet;
   indexT minSeedLimit;
@@ -48,6 +50,7 @@ struct LastdbArguments{
   sequenceFormat::Enum inputFormat;
 
   // positional arguments:
+  const char* programName;
   std::string lastdbName;
   int inputStart;  // index in argv of first input filename
 };
diff --git a/src/Mmap.hh b/src/Mmap.hh
index 6185d4d..043c962 100644
--- a/src/Mmap.hh
+++ b/src/Mmap.hh
@@ -26,7 +26,7 @@ public:
   // Make an Mmap with s items from a file.  Throws an exception if it
   // fails to read the file.  If s is zero, it doesn't try to read the
   // file.
-  Mmap( const std::string& fileName, std::size_t s )
+  Mmap( const std::string& fileName, size_t s )
     : begin_(0), end_(0) { open( fileName, s ); }
 
   // Release the mapping, if not empty.
@@ -35,7 +35,7 @@ public:
   // Map s items from a file.  Throws an exception if it fails to read
   // the file.  If s is zero, it doesn't try to read the file.
   // If a file is already being mapped, closes it first.
-  void open( const std::string& fileName, std::size_t s );
+  void open( const std::string& fileName, size_t s );
 
   // Release the mapping, if not empty.  This makes the Mmap empty.
   void close();
@@ -43,11 +43,11 @@ public:
   // Standard functions to access the stuff in the container.
   const T* begin() const { return begin_; }
   const T* end() const { return end_; }
-  std::size_t size() const { return end_ - begin_; }
+  size_t size() const { return end_ - begin_; }
   bool empty() const { return end_ == 0; }
   const T& front() const { return *begin_; }
   const T& back() const { return *(end_ - 1); }
-  const T& operator[]( std::size_t i ) const { return begin_[i]; }
+  const T& operator[]( size_t i ) const { return begin_[i]; }
 
   void swap( Mmap& m ){
     std::swap( begin_, m.begin_ );
@@ -64,10 +64,10 @@ private:
 };
 
 template<typename T>
-void Mmap<T>::open( const std::string& fileName, std::size_t s ){
+void Mmap<T>::open( const std::string& fileName, size_t s ){
   close();
 
-  std::size_t bytes = s * sizeof(T);
+  size_t bytes = s * sizeof(T);
 
   if( bytes / sizeof(T) < s )  // check for overflow
     throw std::runtime_error( "can't map " + stringify(s) +
@@ -82,7 +82,7 @@ void Mmap<T>::open( const std::string& fileName, std::size_t s ){
 
 template<typename T>
 void Mmap<T>::close(){
-  std::size_t bytes = size() * sizeof(T);
+  size_t bytes = size() * sizeof(T);
   closeFileMap( begin_, bytes );
   begin_ = 0;
   end_ = 0;
diff --git a/src/MultiSequence.cc b/src/MultiSequence.cc
index 7636963..df27f2e 100644
--- a/src/MultiSequence.cc
+++ b/src/MultiSequence.cc
@@ -29,7 +29,7 @@ void MultiSequence::reinitForAppending(){
 }
 
 void MultiSequence::fromFiles( const std::string& baseName, indexT seqCount,
-                               std::size_t qualitiesPerLetter ){
+                               size_t qualitiesPerLetter ){
   ends.m.open( baseName + ".ssp", seqCount + 1 );
   seq.m.open( baseName + ".tis", ends.m.back() );
   nameEnds.m.open( baseName + ".sds", seqCount + 1 );
diff --git a/src/MultiSequence.hh b/src/MultiSequence.hh
index 6534edc..0c8dab6 100644
--- a/src/MultiSequence.hh
+++ b/src/MultiSequence.hh
@@ -30,7 +30,7 @@ class MultiSequence{
 
   // read seqCount finished sequences, and their names, from binary files
   void fromFiles( const std::string& baseName, indexT seqCount,
-                  std::size_t qualitiesPerLetter );
+                  size_t qualitiesPerLetter );
 
   // write all the finished sequences and their names to binary files
   void toFiles( const std::string& baseName ) const;
@@ -68,7 +68,7 @@ class MultiSequence{
   indexT finishedSize() const{ return ends.back(); }
 
   // total length of finished and unfinished sequences plus delimiters
-  std::size_t unfinishedSize() const{ return seq.size(); }
+  size_t unfinishedSize() const{ return seq.size(); }
 
   // which sequence is the coordinate in?
   indexT whichSequence( indexT coordinate ) const;
@@ -104,7 +104,7 @@ class MultiSequence{
 
   // How many quality scores are there per letter?  There might be
   // none at all, one per letter, or several (e.g. 4) per letter.
-  std::size_t qualsPerLetter() const { return qualityScoresPerLetter; }
+  size_t qualsPerLetter() const { return qualityScoresPerLetter; }
 
  private:
   indexT padSize;  // number of delimiter chars between sequences
@@ -122,7 +122,7 @@ class MultiSequence{
   // Qphred = -10*log10(p)
   // Qsolexa = -10*log10(p/(1-p))
   VectorOrMmap<uchar> qualityScores;
-  std::size_t qualityScoresPerLetter;
+  size_t qualityScoresPerLetter;
 
   // read a FASTA header: read the whole line but store just the first word
   std::istream& readFastaName( std::istream& stream );
@@ -137,5 +137,20 @@ class MultiSequence{
   bool isFinishable( indexT maxSeqLen ) const;
 };
 
+// Divide the sequences into a given number of roughly-equally-sized
+// chunks, and return the first sequence in the Nth chunk.
+inline size_t firstSequenceInChunk(const MultiSequence &m,
+				   size_t numOfChunks, size_t chunkNum) {
+  size_t numOfSeqs = m.finishedSequences();
+  size_t beg = m.seqBeg(0);
+  size_t end = m.padEnd(numOfSeqs - 1) - 1;
+  unsigned long long len = end - beg;  // try to avoid overflow
+  size_t pos = beg + len * chunkNum / numOfChunks;
+  size_t seqNum = m.whichSequence(pos);
+  size_t begDistance = pos - m.seqBeg(seqNum);
+  size_t endDistance = m.padEnd(seqNum) - pos;
+  return (begDistance < endDistance) ? seqNum : seqNum + 1;
+}
+
 }  // end namespace cbrc
 #endif  // MULTISEQUENCE_HH
diff --git a/src/MultiSequenceQual.cc b/src/MultiSequenceQual.cc
index 3c46912..8e33f84 100644
--- a/src/MultiSequenceQual.cc
+++ b/src/MultiSequenceQual.cc
@@ -61,8 +61,8 @@ std::istream&
 MultiSequence::appendFromPrb( std::istream& stream, indexT maxSeqLen,
 			      unsigned alphSize, const uchar decode[] ){
   const uchar padQualityScore = 64;  // should never be used, but a valid value
-  std::size_t qualPadSize = padSize * alphSize;
-  std::size_t qualSize = seq.v.size() * alphSize;
+  size_t qualPadSize = padSize * alphSize;
+  size_t qualSize = seq.v.size() * alphSize;
 
   // initForAppending:
   qualityScoresPerLetter = alphSize;
@@ -81,7 +81,7 @@ MultiSequence::appendFromPrb( std::istream& stream, indexT maxSeqLen,
     if( !stream ) return stream;
 
     // give the sequence a boring name:
-    static std::size_t lineCount = 0;
+    static size_t lineCount = 0;
     std::string name = stringify( ++lineCount );
     addName(name);
 
@@ -148,8 +148,8 @@ std::istream&
 MultiSequence::appendFromPssm( std::istream& stream, indexT maxSeqLen,
                                const uchar* lettersToNumbers,
                                bool isMaskLowercase ){
-  std::size_t pssmPadSize = padSize * scoreMatrixRowSize;
-  std::size_t pssmSize = seq.v.size() * scoreMatrixRowSize;
+  size_t pssmPadSize = padSize * scoreMatrixRowSize;
+  size_t pssmSize = seq.v.size() * scoreMatrixRowSize;
 
   // initForAppending:
   if( pssm.empty() )
diff --git a/src/SubsetMinimizerFinder.cc b/src/SubsetMinimizerFinder.cc
new file mode 100644
index 0000000..ef7540d
--- /dev/null
+++ b/src/SubsetMinimizerFinder.cc
@@ -0,0 +1,49 @@
+// Copyright 2016 Martin C. Frith
+
+#include "SubsetMinimizerFinder.hh"
+#include "CyclicSubsetSeed.hh"
+
+namespace cbrc {
+
+void SubsetMinimizerFinder::init(const CyclicSubsetSeed &seed,
+				 const uchar *text,
+				 size_t beg,
+				 size_t end) {
+  const uchar *m = seed.firstMap();
+  while (beg < end && m[text[beg]] == CyclicSubsetSeed::DELIMITER) ++beg;
+  minima.assign(1, beg);
+}
+
+bool SubsetMinimizerFinder::isMinimizer(const CyclicSubsetSeed &seed,
+					const uchar *text,
+					size_t pos,
+					size_t end,
+					size_t window) {
+  const uchar *subsetMap = seed.firstMap();
+
+  while (true) {
+    size_t currentMinimum = minima[0];
+    if (currentMinimum > pos) return false;
+    if (currentMinimum == pos) return true;
+    size_t newPos = minima.back() + 1;
+    if (newPos == end) return false;
+    const uchar *newText = text + newPos;
+    if (subsetMap[*newText] == CyclicSubsetSeed::DELIMITER) {
+      init(seed, text, newPos + 1, end);
+      continue;
+    }
+    size_t stop = (newPos - currentMinimum >= window);
+    size_t i = minima.size();
+    while (i > stop) {
+      size_t oldPos = minima[i - 1];
+      const uchar *oldText = text + oldPos;
+      if (!seed.isLess(newText, oldText, subsetMap)) break;
+      --i;
+    }
+    minima.resize(i);
+    if (stop) minima.erase(minima.begin());
+    minima.push_back(newPos);
+  }
+}
+
+}
diff --git a/src/SubsetMinimizerFinder.hh b/src/SubsetMinimizerFinder.hh
new file mode 100644
index 0000000..11d6ed2
--- /dev/null
+++ b/src/SubsetMinimizerFinder.hh
@@ -0,0 +1,52 @@
+// Copyright 2016 Martin C. Frith
+
+// This class finds suffixes of a text that are "subset minimizers".
+
+// Here, a minimizer is a suffix that is the lexicographic minimum of
+// the suffixes that start in some range [max(i - window + 1, beg), i]
+// for any i in [beg, end).
+
+// "Subset" means that the lexicographic comparison is done on
+// suffixes transformed according to a CyclicSubsetSeed.
+
+// Usage:
+
+// First call "init" to prepare for range [beg, end) in a given text.
+
+// Then repeatedly call isMinimizer, to check whether the suffix
+// starting at "pos" is a minimizer.  The suffixes must be checked in
+// order: specifically, each value of pos must be >= beg and all
+// previous values of pos.
+
+#ifndef SUBSET_MINIMIZER_FINDER_HH
+#define SUBSET_MINIMIZER_FINDER_HH
+
+#include <vector>
+#include <stddef.h>  // size_t
+
+namespace cbrc {
+
+typedef unsigned char uchar;
+
+class CyclicSubsetSeed;
+
+class SubsetMinimizerFinder {
+public:
+  void init(const CyclicSubsetSeed &seed,
+	    const uchar *text,
+	    size_t beg,
+	    size_t end);
+
+   bool isMinimizer(const CyclicSubsetSeed &seed,
+		    const uchar *text,
+		    size_t pos,
+		    size_t end,
+		    size_t window);
+
+private:
+  std::vector<size_t> minima;
+};
+
+}
+
+#endif
diff --git a/src/SubsetSuffixArray.cc b/src/SubsetSuffixArray.cc
index 3eff05d..880c36c 100644
--- a/src/SubsetSuffixArray.cc
+++ b/src/SubsetSuffixArray.cc
@@ -1,6 +1,7 @@
 // Copyright 2008, 2009, 2010, 2013, 2014 Martin C. Frith
 
 #include "SubsetSuffixArray.hh"
+#include "SubsetMinimizerFinder.hh"
 #include "io.hh"
 #include <cassert>
 #include <cstdio>  // remove
@@ -8,23 +9,27 @@
 
 using namespace cbrc;
 
-void SubsetSuffixArray::addPositions( const uchar* text,
-				      indexT beg, indexT end, indexT step ){
-  assert( step > 0 );
-  const uchar* subsetMap = seed.firstMap();
-
-  for( indexT i = beg; i < end; i += step ){
-    if( subsetMap[ text[i] ] < CyclicSubsetSeed::DELIMITER ){
-      suffixArray.v.push_back(i);
+void SubsetSuffixArray::addPositions(const uchar* text, indexT beg, indexT end,
+				     indexT step, indexT minimizerWindow) {
+  if (beg >= end) return;
+  assert(step > 0);
+  const uchar *subsetMap = seed.firstMap();
+  SubsetMinimizerFinder f;
+  f.init(seed, text, beg, end);
+
+  while (true) {
+    if (minimizerWindow > 1) {
+      if (f.isMinimizer(seed, text, beg, end, minimizerWindow))
+	suffixArray.v.push_back(beg);
+    } else {
+      if (subsetMap[text[beg]] < CyclicSubsetSeed::DELIMITER)
+	suffixArray.v.push_back(beg);
     }
-    if( i + step < i ) break;  // avoid overflow
+    if (end - beg <= step) break;  // avoid overflow
+    beg += step;
   }
 }
 
-void SubsetSuffixArray::clearPositions(){
-  suffixArray.v.clear();
-}
-
 void SubsetSuffixArray::fromFiles( const std::string& baseName,
 				   bool isMaskLowercase,
 				   const uchar letterCode[] ){
diff --git a/src/SubsetSuffixArray.hh b/src/SubsetSuffixArray.hh
index c33841d..c77c858 100644
--- a/src/SubsetSuffixArray.hh
+++ b/src/SubsetSuffixArray.hh
@@ -38,7 +38,10 @@ public:
   // Add every step-th text position in the range [beg,end).
   // Positions starting with delimiters aren't added.
   // The positions aren't sorted.
-  void addPositions( const uchar* text, indexT beg, indexT end, indexT step );
+  // If minimizerWindow > 1 then the positions are added only if they
+  // are "minimizers" for the given window and seed pattern.
+  void addPositions( const uchar* text, indexT beg, indexT end,
+		     indexT step, indexT minimizerWindow );
 
   // Sort the suffix array (but don't make the buckets).
   void sortIndex( const uchar* text,
@@ -50,9 +53,6 @@ public:
   // the number of suffix array entries.
   void makeBuckets( const uchar* text, indexT bucketDepth );
 
-  // Clear the positions, so we can add new positions from scratch.
-  void clearPositions();
-
   void fromFiles( const std::string& baseName,
 		  bool isMaskLowercase, const uchar letterCode[] );
 
diff --git a/src/SubsetSuffixArraySort.cc b/src/SubsetSuffixArraySort.cc
index 8d4248d..e460b8c 100644
--- a/src/SubsetSuffixArraySort.cc
+++ b/src/SubsetSuffixArraySort.cc
@@ -22,19 +22,12 @@ namespace{
 static void insertionSort( const uchar* text, const CyclicSubsetSeed& seed,
 			   indexT* beg, indexT* end, const uchar* subsetMap ){
   for( indexT* i = beg+1; i < end; ++i ){
+    const uchar* newText = text + *i;
     for( indexT* j = i; j > beg; --j ){
-      const uchar* s = text + *(j-1);
-      const uchar* t = text + *j;
-      const uchar* m = subsetMap;
-
-      while( m[ *s ] == m[ *t ] && m[ *s ] < CyclicSubsetSeed::DELIMITER ){
-        ++s;
-        ++t;
-        m = seed.nextMap(m);
-      }
-
-      if( m[ *s ] <= m[ *t ] ) break;
-      std::iter_swap( j, j-1 );
+      indexT* k = j - 1;
+      const uchar* oldText = text + *k;
+      if( !seed.isLess( newText, oldText, subsetMap ) ) break;
+      std::iter_swap( j, k );
     }
   }
 }
@@ -263,7 +256,7 @@ void SubsetSuffixArray::radixSortN( const uchar* text, const uchar* subsetMap,
   for( indexT* i = beg; i < end; /* noop */ ){
     uchar oracle[256];
     uchar* oracleEnd =
-      oracle + std::min( sizeof(oracle), std::size_t(end - i) );
+      oracle + std::min( sizeof(oracle), size_t(end - i) );
     for( uchar* j = oracle; j < oracleEnd; ++j )
       *j = subsetMap[ text[ *i++ ] ];
     for( uchar* j = oracle; j < oracleEnd; ++j )
diff --git a/src/VectorOrMmap.hh b/src/VectorOrMmap.hh
index 62eddba..b6b3ab4 100644
--- a/src/VectorOrMmap.hh
+++ b/src/VectorOrMmap.hh
@@ -19,14 +19,14 @@ struct VectorOrMmap{
   const T* begin() const { return v.empty() ? m.begin() : &v.front();    }
   const T* end()   const { return v.empty() ? m.end()   : &v.back() + 1; }
 
-  std::size_t size() const { return v.empty() ? m.size() : v.size(); }
+  size_t size() const { return v.empty() ? m.size() : v.size(); }
 
   bool empty() const { return v.empty() && m.empty(); }
 
   const T& front() const { return v.empty() ? m.front() : v.front(); }
   const T& back()  const { return v.empty() ? m.back()  : v.back();  }
 
-  const T& operator[](std::size_t i) const { return v.empty() ? m[i] : v[i]; }
+  const T& operator[](size_t i) const { return v.empty() ? m[i] : v[i]; }
 };
 
 }  // end namespace
diff --git a/src/alp/njn_dynprogprob.cpp b/src/alp/njn_dynprogprob.cpp
index dc88f1e..b0a594a 100644
--- a/src/alp/njn_dynprogprob.cpp
+++ b/src/alp/njn_dynprogprob.cpp
@@ -1,295 +1,295 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: njn_dynprogprob.cpp
-
-Author: John Spouge
-
-Contents: 
-
-******************************************************************************/
-
-#include <assert.h>
-
-#include "njn_dynprogprob.hpp"
-#include "njn_memutil.hpp"
-
-using namespace Njn;
-
-
-const size_t DynProgProb::ARRAY_CAPACITY = 256;
-
-void DynProgProb::init (size_t arrayCapacity_) // range for d_array_p [0,1][0...arrayCapacity_ - 1]
-{
-    if (arrayCapacity_ > 0) 
-    {
-	for (size_t i = 0; i < 2; i++) 
-	{
-	    d_array_p [i] = new double [arrayCapacity_];
-	    MemUtil::memZero (d_array_p [i], sizeof (double) * arrayCapacity_);
-	}
-    }
-
-    d_arrayCapacity = arrayCapacity_;
-}
-
-void DynProgProb::free2 ()
-{
-    if (getArrayCapacity () > 0) 
-    {
-	for (size_t i = 0; i < 2; i++) 
-	{
-	    delete [] d_array_p [i]; d_array_p [i] = 0;
-	}
-    }
-
-    d_arrayCapacity = 0;
-}
-
-void DynProgProb::clear (
-long int valueBegin_, // lower limit for long int values in the array (an offset)
-size_t arrayCapacity_) // new array capacity 
-// resets the computation
-{
-    free2 ();
-    init (arrayCapacity_);
-    d_valueBegin = valueBegin_;
-    d_step = 0;
-}
-
-void DynProgProb::clear ( // initializes the "probabilities" with non-negative weights
-long int valueLower_, // lower long int value corresponding to the "probability" array
-long int valueUpper_, // one beyond present upper long int value corresponding to the "probability" array
-const double *prob_) // "probabilities" prob [valueLower_, valueUpper_) corresponding to the long ints
-{
-	assert ((! prob_ && valueLower_ <= 0 && 0 <= valueUpper_) || 
-		/*sls added "("*/(prob_ && valueLower_ < valueUpper_)/*sls added ")"*/ );
-
-    if (prob_) 
-    {
-	for (size_t i = 0; i < static_cast <size_t> (valueUpper_ - valueLower_); i++) 
-	{
-	    assert (0.0 <= prob_ [i]);
-	}
-
-	clear (valueLower_, static_cast <size_t> (valueUpper_ - valueLower_));
-
-	d_valueLower = valueLower_;
-	d_valueUpper = valueUpper_;
-	MemUtil::memCpy (d_array_p [0], prob_, sizeof (double) * getArrayCapacity ());
-
-	return;
-    }
-
-    if (valueLower_ == 0 && valueUpper_ == 0) 
-    {
-	clear (-static_cast <long int> (ARRAY_CAPACITY / 2) + 1, ARRAY_CAPACITY);
-    } 
-    else 
-    {
-	clear (valueLower_, static_cast <size_t> (valueUpper_ - valueLower_));
-    }
-
-    d_valueLower = 0;
-    d_valueUpper = 1;
-    d_array_p [0][getArrayPos (0)] = 1.0;
-
-    return;
-}
-
-void DynProgProb::copy (
-size_t step_, // current index : starts at 0 
-const double *const *array_, // two corresponding arrays of probabilities 
-size_t arrayCapacity_, // present capacity of the array
-long int valueBegin_, // lower limit for long int values in the array (an offset)
-long int valueLower_, // present lower long int value in the array
-long int valueUpper_, // one beyond present upper long int value in the array
-ValueFct *newStateFct_, // function for updating dynamic programming values
-size_t dimInputProb_, 
-const double *inputProb_) // array of input states : d_inputProb_p [0...dimStateProb - 1]
-{
-    if (arrayCapacity_ != getArrayCapacity ()) 
-    {
-	free2 ();
-	init (arrayCapacity_);
-    }
-
-    d_step = step_;
-    for (size_t i = 0; i < 2; i++) 
-    {
-	if (getArrayCapacity () > 0) MemUtil::memCpy (d_array_p [i], array_ [i], sizeof (double) * getArrayCapacity ());
-    }
-
-    d_valueBegin = valueBegin_;
-    d_valueLower = valueLower_;
-    d_valueUpper = valueUpper_;
-
-    setValueFct (newStateFct_);
-    setInput (dimInputProb_, inputProb_);
-}
-
-void DynProgProb::initInput (size_t dimInputProb_) // array of input states : d_inputProb_p [0...dimStateProb - 1]
-{
-    if (dimInputProb_ > 0) 
-    {
-	d_inputProb_p = new double [dimInputProb_];
-	MemUtil::memZero (d_inputProb_p, sizeof (double) * dimInputProb_);
-    }
-
-    d_dimInputProb = dimInputProb_;
-}
-
-void DynProgProb::freeInput ()
-{
-    if (getDimInputProb () > 0) 
-    {
-	delete [] d_inputProb_p; d_inputProb_p = 0;
-    }
-
-    d_dimInputProb = 0;
-}
-
-void DynProgProb::setInput (
-size_t dimInputProb_, 
-const double *inputProb_) // array of input states : d_inputProb_p [0...dimStateProb - 1]
-{
-    if (dimInputProb_ != getDimInputProb ()) 
-    {
-	freeInput ();
-	initInput (dimInputProb_);
-    }
-
-    if (getDimInputProb () > 0) MemUtil::memCpy (d_inputProb_p, inputProb_, sizeof (double) * getDimInputProb ());
-}
-
-void DynProgProb::update () // updates dynamic prog probs 
-{
-    assert (getValueFct ());
-    assert (getDimInputProb ());
-    assert (getInputProb ());
-
-    const size_t ARRAY_FAC = 2;
-    assert (1 < ARRAY_FAC);
-
-    long int i = 0;
-    size_t j = 0;
-
-    const double *oldArray = 0;
-    double *array = 0;
-    long int value = 0;
-    long int valueBegin = 0;
-    long int valueLower = 0;
-    long int valueUpper = 0;
-    /*sls deleted size_t arrayPos = 0;*/
-
-    oldArray = d_array_p [d_step % 2];
-    array = d_array_p [(d_step + 1) % 2];
-    valueLower = LONG_MAX;
-    valueUpper = LONG_MIN;
-
-    MemUtil::memZero (array, sizeof (double) * getArrayCapacity ());
-
-    for (i = getValueLower (); i < getValueUpper (); i++) 
-    {
-	if (oldArray [getArrayPos (i)] == 0.0) continue;
-
-	for (j = 0; j < getDimInputProb (); j++) 
-	{
-	    if (getInputProb () [j] == 0.0) continue;
-
-	    // adjust the reserve, if necessary	    
-	    value = getValueFct () (i, j);
-	    while (value < getValueBegin () || getValueEnd () <= value) {
-	    valueBegin = getValueBegin ();
-	    if (value < getValueBegin ()) valueBegin -= (ARRAY_FAC - 1) * getArrayCapacity ();
-	    reserve (ARRAY_FAC * getArrayCapacity ());
-	    setValueBegin (valueBegin);
-	    oldArray = d_array_p [d_step % 2];
-	    array = d_array_p [(d_step + 1) % 2];
-	    }
-
-	    if (value < valueLower) valueLower = value;
-	    if (valueUpper < value) valueUpper = value;
-
-	    // add the probability
-	    assert (getValueBegin () <= i);
-	    assert (i < getValueEnd ());
-	    array [getArrayPos (value)] += oldArray [getArrayPos (i)] * getInputProb () [j];
-	}
-    }
-
-    d_valueLower = valueLower;
-    d_valueUpper = valueUpper + 1;
-    d_step++;
-}
-
-void DynProgProb::reserve (size_t arrayCapacity_) // new array capacity
-// increases capacity of and copies d_array_p, while updating other variables
-{
-    assert (getArrayCapacity () < arrayCapacity_);
-
-    double *array = new double [getArrayCapacity ()];
-
-    for (size_t i = 0; i < 2; i++) 
-    {
-	MemUtil::memCpy (array, d_array_p [i], sizeof (double) * getArrayCapacity ());
-	delete [] d_array_p [i]; d_array_p [i] = 0;
-	d_array_p [i] = new double [arrayCapacity_];
-	MemUtil::memZero (d_array_p [i], sizeof (double) * arrayCapacity_);
-	MemUtil::memCpy (d_array_p [i], array, sizeof (double) * getArrayCapacity ());
-    }
-
-    d_arrayCapacity = arrayCapacity_;
-
-    delete [] array; array = 0;
-}
-
-void DynProgProb::setValueBegin (long int valueBegin_)
-// resets the offset d_valueBegin
-// assert (valueBegin_ <= getValueBegin ()) : enlarge the array only 
-// assert (offSet < getArrayCapacity ());
-{
-    assert (valueBegin_ <= getValueBegin ());
-    size_t offSet = static_cast <size_t> (getValueBegin () - valueBegin_);
-    if (offSet == 0) return; // nothing to do
-
-    assert (offSet < getArrayCapacity ());
-
-    double *array = new double [getArrayCapacity ()];
-
-    for (size_t i = 0; i < 2; i++) 
-    {
-	MemUtil::memCpy (array, d_array_p [i], sizeof (double) * getArrayCapacity ());
-	MemUtil::memZero (d_array_p [i], sizeof (double) * getArrayCapacity ());
-	MemUtil::memCpy (d_array_p [i] + offSet, array, sizeof (double) * (getArrayCapacity () - offSet));
-    }
-
-    delete [] array; array = 0;
-
-    d_valueBegin = valueBegin_;
-}
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: njn_dynprogprob.cpp
+
+Author: John Spouge
+
+Contents: 
+
+******************************************************************************/
+
+#include <assert.h>
+
+#include "njn_dynprogprob.hpp"
+#include "njn_memutil.hpp"
+
+using namespace Njn;
+
+
+const size_t DynProgProb::ARRAY_CAPACITY = 256;
+
+void DynProgProb::init (size_t arrayCapacity_) // range for d_array_p [0,1][0...arrayCapacity_ - 1]
+{
+    if (arrayCapacity_ > 0) 
+    {
+	for (size_t i = 0; i < 2; i++) 
+	{
+	    d_array_p [i] = new double [arrayCapacity_];
+	    MemUtil::memZero (d_array_p [i], sizeof (double) * arrayCapacity_);
+	}
+    }
+
+    d_arrayCapacity = arrayCapacity_;
+}
+
+void DynProgProb::free2 ()
+{
+    if (getArrayCapacity () > 0) 
+    {
+	for (size_t i = 0; i < 2; i++) 
+	{
+	    delete [] d_array_p [i]; d_array_p [i] = 0;
+	}
+    }
+
+    d_arrayCapacity = 0;
+}
+
+void DynProgProb::clear (
+long int valueBegin_, // lower limit for long int values in the array (an offset)
+size_t arrayCapacity_) // new array capacity 
+// resets the computation
+{
+    free2 ();
+    init (arrayCapacity_);
+    d_valueBegin = valueBegin_;
+    d_step = 0;
+}
+
+void DynProgProb::clear ( // initializes the "probabilities" with non-negative weights
+long int valueLower_, // lower long int value corresponding to the "probability" array
+long int valueUpper_, // one beyond present upper long int value corresponding to the "probability" array
+const double *prob_) // "probabilities" prob [valueLower_, valueUpper_) corresponding to the long ints
+{
+	assert ((! prob_ && valueLower_ <= 0 && 0 <= valueUpper_) || 
+		/*sls added "("*/(prob_ && valueLower_ < valueUpper_)/*sls added ")"*/ );
+
+    if (prob_) 
+    {
+	for (size_t i = 0; i < static_cast <size_t> (valueUpper_ - valueLower_); i++) 
+	{
+	    assert (0.0 <= prob_ [i]);
+	}
+
+	clear (valueLower_, static_cast <size_t> (valueUpper_ - valueLower_));
+
+	d_valueLower = valueLower_;
+	d_valueUpper = valueUpper_;
+	MemUtil::memCpy (d_array_p [0], prob_, sizeof (double) * getArrayCapacity ());
+
+	return;
+    }
+
+    if (valueLower_ == 0 && valueUpper_ == 0) 
+    {
+	clear (-static_cast <long int> (ARRAY_CAPACITY / 2) + 1, ARRAY_CAPACITY);
+    } 
+    else 
+    {
+	clear (valueLower_, static_cast <size_t> (valueUpper_ - valueLower_));
+    }
+
+    d_valueLower = 0;
+    d_valueUpper = 1;
+    d_array_p [0][getArrayPos (0)] = 1.0;
+
+    return;
+}
+
+void DynProgProb::copy (
+size_t step_, // current index : starts at 0 
+const double *const *array_, // two corresponding arrays of probabilities 
+size_t arrayCapacity_, // present capacity of the array
+long int valueBegin_, // lower limit for long int values in the array (an offset)
+long int valueLower_, // present lower long int value in the array
+long int valueUpper_, // one beyond present upper long int value in the array
+ValueFct *newStateFct_, // function for updating dynamic programming values
+size_t dimInputProb_, 
+const double *inputProb_) // array of input states : d_inputProb_p [0...dimStateProb - 1]
+{
+    if (arrayCapacity_ != getArrayCapacity ()) 
+    {
+	free2 ();
+	init (arrayCapacity_);
+    }
+
+    d_step = step_;
+    for (size_t i = 0; i < 2; i++) 
+    {
+	if (getArrayCapacity () > 0) MemUtil::memCpy (d_array_p [i], array_ [i], sizeof (double) * getArrayCapacity ());
+    }
+
+    d_valueBegin = valueBegin_;
+    d_valueLower = valueLower_;
+    d_valueUpper = valueUpper_;
+
+    setValueFct (newStateFct_);
+    setInput (dimInputProb_, inputProb_);
+}
+
+void DynProgProb::initInput (size_t dimInputProb_) // array of input states : d_inputProb_p [0...dimStateProb - 1]
+{
+    if (dimInputProb_ > 0) 
+    {
+	d_inputProb_p = new double [dimInputProb_];
+	MemUtil::memZero (d_inputProb_p, sizeof (double) * dimInputProb_);
+    }
+
+    d_dimInputProb = dimInputProb_;
+}
+
+void DynProgProb::freeInput ()
+{
+    if (getDimInputProb () > 0) 
+    {
+	delete [] d_inputProb_p; d_inputProb_p = 0;
+    }
+
+    d_dimInputProb = 0;
+}
+
+void DynProgProb::setInput (
+size_t dimInputProb_, 
+const double *inputProb_) // array of input states : d_inputProb_p [0...dimStateProb - 1]
+{
+    if (dimInputProb_ != getDimInputProb ()) 
+    {
+	freeInput ();
+	initInput (dimInputProb_);
+    }
+
+    if (getDimInputProb () > 0) MemUtil::memCpy (d_inputProb_p, inputProb_, sizeof (double) * getDimInputProb ());
+}
+
+void DynProgProb::update () // updates dynamic prog probs 
+{
+    assert (getValueFct ());
+    assert (getDimInputProb ());
+    assert (getInputProb ());
+
+    const size_t ARRAY_FAC = 2;
+    assert (1 < ARRAY_FAC);
+
+    long int i = 0;
+    size_t j = 0;
+
+    const double *oldArray = 0;
+    double *array = 0;
+    long int value = 0;
+    long int valueBegin = 0;
+    long int valueLower = 0;
+    long int valueUpper = 0;
+    /*sls deleted size_t arrayPos = 0;*/
+
+    oldArray = d_array_p [d_step % 2];
+    array = d_array_p [(d_step + 1) % 2];
+    valueLower = LONG_MAX;
+    valueUpper = LONG_MIN;
+
+    MemUtil::memZero (array, sizeof (double) * getArrayCapacity ());
+
+    for (i = getValueLower (); i < getValueUpper (); i++) 
+    {
+	if (oldArray [getArrayPos (i)] == 0.0) continue;
+
+	for (j = 0; j < getDimInputProb (); j++) 
+	{
+	    if (getInputProb () [j] == 0.0) continue;
+
+	    // adjust the reserve, if necessary	    
+	    value = getValueFct () (i, j);
+	    while (value < getValueBegin () || getValueEnd () <= value) {
+	    valueBegin = getValueBegin ();
+	    if (value < getValueBegin ()) valueBegin -= (ARRAY_FAC - 1) * getArrayCapacity ();
+	    reserve (ARRAY_FAC * getArrayCapacity ());
+	    setValueBegin (valueBegin);
+	    oldArray = d_array_p [d_step % 2];
+	    array = d_array_p [(d_step + 1) % 2];
+	    }
+
+	    if (value < valueLower) valueLower = value;
+	    if (valueUpper < value) valueUpper = value;
+
+	    // add the probability
+	    assert (getValueBegin () <= i);
+	    assert (i < getValueEnd ());
+	    array [getArrayPos (value)] += oldArray [getArrayPos (i)] * getInputProb () [j];
+	}
+    }
+
+    d_valueLower = valueLower;
+    d_valueUpper = valueUpper + 1;
+    d_step++;
+}
+
+void DynProgProb::reserve (size_t arrayCapacity_) // new array capacity
+// increases capacity of and copies d_array_p, while updating other variables
+{
+    assert (getArrayCapacity () < arrayCapacity_);
+
+    double *array = new double [getArrayCapacity ()];
+
+    for (size_t i = 0; i < 2; i++) 
+    {
+	MemUtil::memCpy (array, d_array_p [i], sizeof (double) * getArrayCapacity ());
+	delete [] d_array_p [i]; d_array_p [i] = 0;
+	d_array_p [i] = new double [arrayCapacity_];
+	MemUtil::memZero (d_array_p [i], sizeof (double) * arrayCapacity_);
+	MemUtil::memCpy (d_array_p [i], array, sizeof (double) * getArrayCapacity ());
+    }
+
+    d_arrayCapacity = arrayCapacity_;
+
+    delete [] array; array = 0;
+}
+
+void DynProgProb::setValueBegin (long int valueBegin_)
+// resets the offset d_valueBegin
+// assert (valueBegin_ <= getValueBegin ()) : enlarge the array only 
+// assert (offSet < getArrayCapacity ());
+{
+    assert (valueBegin_ <= getValueBegin ());
+    size_t offSet = static_cast <size_t> (getValueBegin () - valueBegin_);
+    if (offSet == 0) return; // nothing to do
+
+    assert (offSet < getArrayCapacity ());
+
+    double *array = new double [getArrayCapacity ()];
+
+    for (size_t i = 0; i < 2; i++) 
+    {
+	MemUtil::memCpy (array, d_array_p [i], sizeof (double) * getArrayCapacity ());
+	MemUtil::memZero (d_array_p [i], sizeof (double) * getArrayCapacity ());
+	MemUtil::memCpy (d_array_p [i] + offSet, array, sizeof (double) * (getArrayCapacity () - offSet));
+    }
+
+    delete [] array; array = 0;
+
+    d_valueBegin = valueBegin_;
+}
+
diff --git a/src/alp/njn_ioutil.cpp b/src/alp/njn_ioutil.cpp
index bc021ef..98848cf 100644
--- a/src/alp/njn_ioutil.cpp
+++ b/src/alp/njn_ioutil.cpp
@@ -1,167 +1,167 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: njn_ioutil.cpp
-
-Author: John Spouge
-
-Contents: 
-
-******************************************************************************/
-
-#include <math.h>
-
-#include <assert.h>
-#include "njn_ioutil.hpp"
-#include <iostream>
-#include <fstream>
-
-
-using namespace std;
-using namespace Njn;
-using namespace IoUtil;
-
-
-
-   const Format FORMAT = HUMAN;
-   Format format1 = HUMAN;
-
-   const char TERMINATOR = '!';
-   char terminator = TERMINATOR;
-
-
-Format IoUtil::getFormat ()
-{
-   return format1;
-}
-
-void IoUtil::setFormat (Format format_)
-{
-   format1 = format_;
-}
-
-Format IoUtil::clearFormat ()
-{
-   return format1 = FORMAT;
-}
-
-char IoUtil::getTerminator ()
-{
-   return terminator;
-}
-
-void IoUtil::setTerminator (char t_)
-{
-   terminator = t_;
-}
-
-char IoUtil::clearTerminator ()
-{
-   return terminator = TERMINATOR;
-}
-
-void IoUtil::abort ()
-{
-   exit (1);
-}
-
-void IoUtil::abort (const string &s_)
-{
-   cerr << s_ << endl;
-   IoUtil::abort ();
-}
-
-istream &IoUtil::getLine ( 
-istream &in_, // input filestream
-string &str_, // string before '!' from next line
-const char t_) // termination character (could be '\n')
-{ // behaves like getline (in_, str_) but throws away the string after first character t_ && skips lines of white space
-
-   assert (t_ != '\0');
-
-   if (! in_) return in_;
-
-   const char *pbuf = 0;
-
-   while (getline (in_, str_)) {
-      for (pbuf = str_.c_str (); *pbuf != '\0' && isspace (*pbuf); pbuf++); // advance past white space
-      if (*pbuf != '\0' && *pbuf != t_) break; // skip lines full of white space
-   }
-
-   if (t_ != '\n') {
-      size_t pos = str_.find (t_, 0);
-      if (pos < str_.size ()) str_.erase (pos, str_.size ());
-   }
-
-   return in_; // buf is empty and eof is reached 
-}
-
-istream &IoUtil::getLine ( 
-istream &in_, // input filestream
-stringstream &sstr_, // sstr_ contains the string before '!' from next line
-const char t_) // termination character (could be '\n')
-{ // behaves like getline (in_, str_) but throws away the string after first character t_ && skips lines of white space
-
-   string s;
-
-   IoUtil::getLine (in_, s, t_);
-   sstr_.clear ();
-   sstr_.str ("");
-   sstr_ << s;
-   sstr_.clear ();
-
-   return in_;
-}
-
-std::istream &IoUtil::in (
-std::istream &in_,
-double &x_)
-{
-    string s;
-    in_ >> s;
-
-    for (string::iterator i = s.begin (); i != s.end (); i++) *i = /*sls added (char)*/(char) tolower (*i);
-
-    if (s == "1.#inf")
-    {
-        x_ = HUGE_VAL;   
-    }
-    else if (s == "nan")
-    {
-        x_ = HUGE_VAL;   
-    }
-    else
-    {
-        stringstream str (s);
-        str >> x_;
-
-        if (str.fail ()) in_.setstate (ios_base::failbit);
-    }
-
-    return in_;
-}
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: njn_ioutil.cpp
+
+Author: John Spouge
+
+Contents: 
+
+******************************************************************************/
+
+#include <math.h>
+
+#include <assert.h>
+#include "njn_ioutil.hpp"
+#include <iostream>
+#include <fstream>
+
+
+using namespace std;
+using namespace Njn;
+using namespace IoUtil;
+
+
+
+   const Format FORMAT = HUMAN;
+   Format format1 = HUMAN;
+
+   const char TERMINATOR = '!';
+   char terminator = TERMINATOR;
+
+
+Format IoUtil::getFormat ()
+{
+   return format1;
+}
+
+void IoUtil::setFormat (Format format_)
+{
+   format1 = format_;
+}
+
+Format IoUtil::clearFormat ()
+{
+   return format1 = FORMAT;
+}
+
+char IoUtil::getTerminator ()
+{
+   return terminator;
+}
+
+void IoUtil::setTerminator (char t_)
+{
+   terminator = t_;
+}
+
+char IoUtil::clearTerminator ()
+{
+   return terminator = TERMINATOR;
+}
+
+void IoUtil::abort ()
+{
+   exit (1);
+}
+
+void IoUtil::abort (const string &s_)
+{
+   cerr << s_ << endl;
+   IoUtil::abort ();
+}
+
+istream &IoUtil::getLine ( 
+istream &in_, // input filestream
+string &str_, // string before '!' from next line
+const char t_) // termination character (could be '\n')
+{ // behaves like getline (in_, str_) but throws away the string after first character t_ && skips lines of white space
+
+   assert (t_ != '\0');
+
+   if (! in_) return in_;
+
+   const char *pbuf = 0;
+
+   while (getline (in_, str_)) {
+      for (pbuf = str_.c_str (); *pbuf != '\0' && isspace (*pbuf); pbuf++); // advance past white space
+      if (*pbuf != '\0' && *pbuf != t_) break; // skip lines full of white space
+   }
+
+   if (t_ != '\n') {
+      size_t pos = str_.find (t_, 0);
+      if (pos < str_.size ()) str_.erase (pos, str_.size ());
+   }
+
+   return in_; // buf is empty and eof is reached 
+}
+
+istream &IoUtil::getLine ( 
+istream &in_, // input filestream
+stringstream &sstr_, // sstr_ contains the string before '!' from next line
+const char t_) // termination character (could be '\n')
+{ // behaves like getline (in_, str_) but throws away the string after first character t_ && skips lines of white space
+
+   string s;
+
+   IoUtil::getLine (in_, s, t_);
+   sstr_.clear ();
+   sstr_.str ("");
+   sstr_ << s;
+   sstr_.clear ();
+
+   return in_;
+}
+
+std::istream &IoUtil::in (
+std::istream &in_,
+double &x_)
+{
+    string s;
+    in_ >> s;
+
+    for (string::iterator i = s.begin (); i != s.end (); i++) *i = /*sls added (char)*/(char) tolower (*i);
+
+    if (s == "1.#inf")
+    {
+        x_ = HUGE_VAL;   
+    }
+    else if (s == "nan")
+    {
+        x_ = HUGE_VAL;   
+    }
+    else
+    {
+        stringstream str (s);
+        str >> x_;
+
+        if (str.fail ()) in_.setstate (ios_base::failbit);
+    }
+
+    return in_;
+}
+
diff --git a/src/alp/njn_localmaxstat.hpp b/src/alp/njn_localmaxstat.hpp
index 6c63392..2b985c3 100644
--- a/src/alp/njn_localmaxstat.hpp
+++ b/src/alp/njn_localmaxstat.hpp
@@ -1,198 +1,198 @@
-#ifndef INCLUDED_NJN_LOCALMAXSTAT
-#define INCLUDED_NJN_LOCALMAXSTAT
-
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: njn_localmaxstat.hpp
-
-Author: John Spouge
-
-Contents: Random walk parameters
-
-******************************************************************************/
-
-#include <math.h>
-#include <vector>
-#include <assert.h>
-#include <ostream>
-
-
-
-namespace Njn {
-
-
-    class LocalMaxStat { 
-
-    // calculates the statistical parameters for the local maximum in a random walk
-    //
-    // The scores are uniqued and 
-    //    with the correspondence to probabilities maintained, placed in ascending order.
-
-      public:
-
-      // The following subroutines control the time for the dynamic programming computation.
-      // The default time_ = 0.0 permits the computation to run forever.
-      static void setTime (double time_ = 0.0) {assert (time_ >= 0.0); s_time = time_;} // set time for the dynamic programming computation
-      static double getTime () {return s_time;} // get time for the dynamic programming computation
-      // For an object o, 
-      //    if the computation is terminated before it finishes, 
-      //    o.getTerminated () == true. 
-
-      inline LocalMaxStat ( 
-      size_t dimension_ = 0, // #(distinct values)          
-      const long int *score_ = 0, // scores in increasing order
-      const double *prob_ = 0) // probability of corresponding value  
-      :  d_dimension (0), d_score_p (0), d_prob_p (0),
-         d_lambda (0.0), d_k (0.0), d_c (0.0), d_thetaMin (0.0), d_rMin (0.0), 
-         d_delta (0), d_thetaMinusDelta (0.0),
-         d_mu (0.0), d_sigma (0.0), d_muAssoc (0.0), d_sigmaAssoc (0.0),
-         d_meanWDLE (0.0), d_terminated (false)
-      {
-         copy (dimension_, score_, prob_);
-      }
-
-      inline LocalMaxStat (const LocalMaxStat &localMaxStat_) // random walk parameters
-      :  d_dimension (0), d_score_p (0), d_prob_p (0),
-         d_lambda (0.0), d_k (0.0), d_c (0.0), d_thetaMin (0.0), d_rMin (0.0), 
-         d_delta (0), d_thetaMinusDelta (0.0),
-         d_mu (0.0), d_sigma (0.0), d_muAssoc (0.0), d_sigmaAssoc (0.0),
-         d_meanWDLE (0.0), d_terminated (false)
-      {
-         copy (localMaxStat_);
-      }
-
-      inline ~LocalMaxStat () {free2 ();}
-
-      inline operator bool () // ? is the object ready for computation ?
-      const {
-         return d_dimension != 0;
-      }
-
-      inline LocalMaxStat &operator= (const LocalMaxStat &localMaxStat_) // random walk parameters
-      {
-         if (this != &localMaxStat_) copy (localMaxStat_);
-         return *this;
-      }
-
-      void copy (
-      size_t dimension_, // #(distinct values) of scores & probabilities (which are paired)         
-      const long int *score_, // scores in increasing order
-      const double *prob_); // probabilities
-
-      inline void copy (const LocalMaxStat &localMaxStat_)
-      {
-         copy (localMaxStat_.getDimension (), localMaxStat_.getScore (), localMaxStat_.getProb (),
-               localMaxStat_.getLambda (), localMaxStat_.getK (), localMaxStat_.getC (), 
-               localMaxStat_.getThetaMin (), localMaxStat_.getRMin (),
-               localMaxStat_.getDelta (), localMaxStat_.getThetaMinusDelta (),
-               localMaxStat_.getMu (), localMaxStat_.getSigma (), localMaxStat_.getMuAssoc (), localMaxStat_.getSigmaAssoc (),
-               localMaxStat_.getMeanWDLE (), localMaxStat_.getTerminated ());  
-      }
-
-      void copy (
-      size_t dimension_, // #(distinct values) of scores & probabilities (which are paired)         
-      const long int *score_, // scores in increasing order
-      const double *prob_, // probabilities
-      double lambda_, // lambda for associated random walk
-      double k_, // k for random walk : exponential prefactor
-      double c_, // c for random walk : exponential prefactor (global alignment)
-      double thetaMin_, // theta for minimum expectation (exp (theta * score))
-      double rMin_, // minimum expectation (exp (theta * score))
-      long int delta_, // span 
-      double thetaMinusDelta_, // renewal span parameter
-      double mu_, // step mean for random walk
-      double sigma_, // step standard deviation for random walk
-      double muAssoc_, // step mean for associated random walk (relative entropy)
-      double sigmaAssoc_, // step standard deviation for associated random walk
-      double meanDLE_, // expected renewal length
-      bool terminated_ = false); // ? Was the dynamic programming computation terminated prematurely ?
-
-      inline std::ostream &out (std::ostream &ostr_) const {return ostr_;} // output
-
-      double getR (double theta_) const; // r (theta_) : dominant eigenvalue for theta_
-
-      double getA () const {return getMuAssoc () == 0 ? HUGE_VAL : 1.0 / getMuAssoc ();} // expected [length / y] for achieving y
-
-      double getAlpha () const {return getSigmaAssoc () * getSigmaAssoc () * getA () * getA () * getA ();} // var [length] / y for achieving y
-
-      inline size_t getDimension () const {return d_dimension;} // #(distinct values) of scores & probabilities (which are paired)         
-      inline const long int *getScore () const {return d_score_p;} // scores in increasing order
-      inline const double *getProb () const {return d_prob_p;} // probabilities
-      inline double getLambda () const {return d_lambda;} // lambda for associated random walk
-      inline double getK () const {return d_k;} // k for random walk : exponential prefactor
-      inline double getC () const {return d_c;} // c for random walk : exponential prefactor (global alignment)
-      inline double getThetaMin () const {return d_thetaMin;} // theta for minimum expectation (exp (theta * score))
-      inline double getRMin () const {return d_rMin;} // minimum expectation (exp (theta * score))
-      inline long int getDelta () const {return d_delta;} // span
-      inline double getThetaMinusDelta () const {return d_thetaMinusDelta;} // renewal span parameter
-      inline double getMu () const {return d_mu;} // step mean for random walk
-      inline double getSigma () const {return d_sigma;} // step standard deviation for random walk
-      inline double getMuAssoc () const {return d_muAssoc;} // step mean for associated random walk (relative entropy)
-      inline double getSigmaAssoc () const {return d_sigmaAssoc;} // step standard deviation for associated random walk
-      inline double getMeanWDLE () const {return d_meanWDLE;} // expected renewal length for weak ladder epochs
-      inline bool getTerminated () const {return d_terminated;} // ? Was the dynamic programming computation terminated prematurely ?
-
-      private:
-
-      // random walk distribution
-      size_t d_dimension; // #(distinct values) of scores & probabilities (which are paired)         
-      long int *d_score_p; // scores in increasing order
-      double *d_prob_p; // probabilities
-      
-      // Karlin-Altschul parameters
-      double d_lambda; // lambda for associated random walk
-      double d_k; // k for random walk : exponential prefactor
-      double d_c; // c for random walk : exponential prefactor (global alignment)
-      double d_thetaMin; // theta for minimum expectation (exp (theta * score))
-      double d_rMin; // minimum expectation (exp (theta * score))
-      long int d_delta; // span 
-      double d_thetaMinusDelta; // renewal span parameter
-      double d_mu; // step mean for random walk
-      double d_sigma; // step standard deviation for random walk
-      double d_muAssoc; // step mean for associated random walk (relative entropy)
-      double d_sigmaAssoc; // step standard deviation for associated random walk
-      double d_meanWDLE; // expected renewal length for weak ladder epochs
-      bool d_terminated; // ? Was the dynamic programming computation terminated prematurely ?
-
-      void init (size_t dimension_);
-      void free2 ();
-
-      void clear ();
-
-      void dynProgCalc ();
-      // k for random walk : exponential prefactor 
-      // expected renewal length for weak ladder epochs
-
-      static double s_time;
-
-    };
-
-}
-
-#endif 
-
+#ifndef INCLUDED_NJN_LOCALMAXSTAT
+#define INCLUDED_NJN_LOCALMAXSTAT
+
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: njn_localmaxstat.hpp
+
+Author: John Spouge
+
+Contents: Random walk parameters
+
+******************************************************************************/
+
+#include <math.h>
+#include <vector>
+#include <assert.h>
+#include <ostream>
+
+
+
+namespace Njn {
+
+
+    class LocalMaxStat { 
+
+    // calculates the statistical parameters for the local maximum in a random walk
+    //
+    // The scores are uniqued and 
+    //    with the correspondence to probabilities maintained, placed in ascending order.
+
+      public:
+
+      // The following subroutines control the time for the dynamic programming computation.
+      // The default time_ = 0.0 permits the computation to run forever.
+      static void setTime (double time_ = 0.0) {assert (time_ >= 0.0); s_time = time_;} // set time for the dynamic programming computation
+      static double getTime () {return s_time;} // get time for the dynamic programming computation
+      // For an object o, 
+      //    if the computation is terminated before it finishes, 
+      //    o.getTerminated () == true. 
+
+      inline LocalMaxStat ( 
+      size_t dimension_ = 0, // #(distinct values)          
+      const long int *score_ = 0, // scores in increasing order
+      const double *prob_ = 0) // probability of corresponding value  
+      :  d_dimension (0), d_score_p (0), d_prob_p (0),
+         d_lambda (0.0), d_k (0.0), d_c (0.0), d_thetaMin (0.0), d_rMin (0.0), 
+         d_delta (0), d_thetaMinusDelta (0.0),
+         d_mu (0.0), d_sigma (0.0), d_muAssoc (0.0), d_sigmaAssoc (0.0),
+         d_meanWDLE (0.0), d_terminated (false)
+      {
+         copy (dimension_, score_, prob_);
+      }
+
+      inline LocalMaxStat (const LocalMaxStat &localMaxStat_) // random walk parameters
+      :  d_dimension (0), d_score_p (0), d_prob_p (0),
+         d_lambda (0.0), d_k (0.0), d_c (0.0), d_thetaMin (0.0), d_rMin (0.0), 
+         d_delta (0), d_thetaMinusDelta (0.0),
+         d_mu (0.0), d_sigma (0.0), d_muAssoc (0.0), d_sigmaAssoc (0.0),
+         d_meanWDLE (0.0), d_terminated (false)
+      {
+         copy (localMaxStat_);
+      }
+
+      inline ~LocalMaxStat () {free2 ();}
+
+      inline operator bool () // ? is the object ready for computation ?
+      const {
+         return d_dimension != 0;
+      }
+
+      inline LocalMaxStat &operator= (const LocalMaxStat &localMaxStat_) // random walk parameters
+      {
+         if (this != &localMaxStat_) copy (localMaxStat_);
+         return *this;
+      }
+
+      void copy (
+      size_t dimension_, // #(distinct values) of scores & probabilities (which are paired)         
+      const long int *score_, // scores in increasing order
+      const double *prob_); // probabilities
+
+      inline void copy (const LocalMaxStat &localMaxStat_)
+      {
+         copy (localMaxStat_.getDimension (), localMaxStat_.getScore (), localMaxStat_.getProb (),
+               localMaxStat_.getLambda (), localMaxStat_.getK (), localMaxStat_.getC (), 
+               localMaxStat_.getThetaMin (), localMaxStat_.getRMin (),
+               localMaxStat_.getDelta (), localMaxStat_.getThetaMinusDelta (),
+               localMaxStat_.getMu (), localMaxStat_.getSigma (), localMaxStat_.getMuAssoc (), localMaxStat_.getSigmaAssoc (),
+               localMaxStat_.getMeanWDLE (), localMaxStat_.getTerminated ());  
+      }
+
+      void copy (
+      size_t dimension_, // #(distinct values) of scores & probabilities (which are paired)         
+      const long int *score_, // scores in increasing order
+      const double *prob_, // probabilities
+      double lambda_, // lambda for associated random walk
+      double k_, // k for random walk : exponential prefactor
+      double c_, // c for random walk : exponential prefactor (global alignment)
+      double thetaMin_, // theta for minimum expectation (exp (theta * score))
+      double rMin_, // minimum expectation (exp (theta * score))
+      long int delta_, // span 
+      double thetaMinusDelta_, // renewal span parameter
+      double mu_, // step mean for random walk
+      double sigma_, // step standard deviation for random walk
+      double muAssoc_, // step mean for associated random walk (relative entropy)
+      double sigmaAssoc_, // step standard deviation for associated random walk
+      double meanDLE_, // expected renewal length
+      bool terminated_ = false); // ? Was the dynamic programming computation terminated prematurely ?
+
+      inline std::ostream &out (std::ostream &ostr_) const {return ostr_;} // output
+
+      double getR (double theta_) const; // r (theta_) : dominant eigenvalue for theta_
+
+      double getA () const {return getMuAssoc () == 0 ? HUGE_VAL : 1.0 / getMuAssoc ();} // expected [length / y] for achieving y
+
+      double getAlpha () const {return getSigmaAssoc () * getSigmaAssoc () * getA () * getA () * getA ();} // var [length] / y for achieving y
+
+      inline size_t getDimension () const {return d_dimension;} // #(distinct values) of scores & probabilities (which are paired)         
+      inline const long int *getScore () const {return d_score_p;} // scores in increasing order
+      inline const double *getProb () const {return d_prob_p;} // probabilities
+      inline double getLambda () const {return d_lambda;} // lambda for associated random walk
+      inline double getK () const {return d_k;} // k for random walk : exponential prefactor
+      inline double getC () const {return d_c;} // c for random walk : exponential prefactor (global alignment)
+      inline double getThetaMin () const {return d_thetaMin;} // theta for minimum expectation (exp (theta * score))
+      inline double getRMin () const {return d_rMin;} // minimum expectation (exp (theta * score))
+      inline long int getDelta () const {return d_delta;} // span
+      inline double getThetaMinusDelta () const {return d_thetaMinusDelta;} // renewal span parameter
+      inline double getMu () const {return d_mu;} // step mean for random walk
+      inline double getSigma () const {return d_sigma;} // step standard deviation for random walk
+      inline double getMuAssoc () const {return d_muAssoc;} // step mean for associated random walk (relative entropy)
+      inline double getSigmaAssoc () const {return d_sigmaAssoc;} // step standard deviation for associated random walk
+      inline double getMeanWDLE () const {return d_meanWDLE;} // expected renewal length for weak ladder epochs
+      inline bool getTerminated () const {return d_terminated;} // ? Was the dynamic programming computation terminated prematurely ?
+
+      private:
+
+      // random walk distribution
+      size_t d_dimension; // #(distinct values) of scores & probabilities (which are paired)         
+      long int *d_score_p; // scores in increasing order
+      double *d_prob_p; // probabilities
+      
+      // Karlin-Altschul parameters
+      double d_lambda; // lambda for associated random walk
+      double d_k; // k for random walk : exponential prefactor
+      double d_c; // c for random walk : exponential prefactor (global alignment)
+      double d_thetaMin; // theta for minimum expectation (exp (theta * score))
+      double d_rMin; // minimum expectation (exp (theta * score))
+      long int d_delta; // span 
+      double d_thetaMinusDelta; // renewal span parameter
+      double d_mu; // step mean for random walk
+      double d_sigma; // step standard deviation for random walk
+      double d_muAssoc; // step mean for associated random walk (relative entropy)
+      double d_sigmaAssoc; // step standard deviation for associated random walk
+      double d_meanWDLE; // expected renewal length for weak ladder epochs
+      bool d_terminated; // ? Was the dynamic programming computation terminated prematurely ?
+
+      void init (size_t dimension_);
+      void free2 ();
+
+      void clear ();
+
+      void dynProgCalc ();
+      // k for random walk : exponential prefactor 
+      // expected renewal length for weak ladder epochs
+
+      static double s_time;
+
+    };
+
+}
+
+#endif 
+
diff --git a/src/alp/njn_random.cpp b/src/alp/njn_random.cpp
index 32892ce..2207f7c 100644
--- a/src/alp/njn_random.cpp
+++ b/src/alp/njn_random.cpp
@@ -1,102 +1,102 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: njn_random.cpp
-
-Author: John Spouge
-
-Contents: Additive random number generator
-
-//	Modelled after "Algorithm A" in
-//	D.E. Knuth (1981) The art of computer programming, volume 2, page 27.
-
-//	7/26/90 Warren Gish
-
-******************************************************************************/
-
-
-
-#include "njn_random.hpp"
-#include <cstring>
-
-using namespace Njn;
-
-
-namespace {
-
-	const size_t r_off = 12;
-
-	long	state [33] = {
-	static_cast <long> (0xd53f1852),  static_cast <long> (0xdfc78b83),  static_cast <long> (0x4f256096),  static_cast <long> (0xe643df7),
-	static_cast <long> (0x82c359bf),  static_cast <long> (0xc7794dfa),  static_cast <long> (0xd5e9ffaa),  static_cast <long> (0x2c8cb64a),
-	static_cast <long> (0x2f07b334),  static_cast <long> (0xad5a7eb5),  static_cast <long> (0x96dc0cde),  static_cast <long> (0x6fc24589),
-	static_cast <long> (0xa5853646),  static_cast <long> (0xe71576e2),  static_cast <long> (0xdae30df),   static_cast <long> (0xb09ce711),
-	static_cast <long> (0x5e56ef87),  static_cast <long> (0x4b4b0082),  static_cast <long> (0x6f4f340e),  static_cast <long> (0xc5bb17e8),
-	static_cast <long> (0xd788d765),  static_cast <long> (0x67498087),  static_cast <long> (0x9d7aba26),  static_cast <long> (0x261351d4),
-	static_cast <long> (0x411ee7ea),  static_cast <long> (0x393a263),   static_cast <long> (0x2c5a5835),  static_cast <long> (0xc115fcd8),
-	static_cast <long> (0x25e9132c),  static_cast <long> (0xd0c6e906),  static_cast <long> (0xc2bc5b2d),  static_cast <long> (0x6c065c98),
-	static_cast <long> (0x6e37bd55)};
-
-   long	*rJ = &state [r_off];
-	long	*rK = &state [sizeof state / sizeof *state - 1];
-
-}
-void Random::seed (long x)
-{
-	register size_t i;
-
-	state [0] = x;
-   
-   // linear congruential initializer
-	for (i = 1; i < sizeof state / sizeof *state; ++i) {
-		state [i] = 1103515245 * state [i - 1] + 12345;
-	}
-
-	rJ = &state [r_off];
-	rK = &state [sizeof state / sizeof *state - 1];
-
-	for (i = 0; i < 10 * sizeof state / sizeof *state; ++i) number ();
-}
-
-long Random::number () // uniform random x : 0 <= x <= exp2 (31) - 1
-
-{
-	register long	r;
-
-	r = *rK;
-	r += *rJ--;
-	*rK-- = r;
-
-   if (rK < state) {
-		rK = &state [sizeof state / sizeof *state - 1];
-   } else if (rJ < state) {
-			rJ = &state [sizeof state / sizeof *state - 1];
-   }
-	
-   return (r >> 1) &0x7fffffff; // discard the least-random bit
-}
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: njn_random.cpp
+
+Author: John Spouge
+
+Contents: Additive random number generator
+
+//	Modelled after "Algorithm A" in
+//	D.E. Knuth (1981) The art of computer programming, volume 2, page 27.
+
+//	7/26/90 Warren Gish
+
+******************************************************************************/
+
+
+
+#include "njn_random.hpp"
+#include <cstring>
+
+using namespace Njn;
+
+
+namespace {
+
+	const size_t r_off = 12;
+
+	long	state [33] = {
+	static_cast <long> (0xd53f1852),  static_cast <long> (0xdfc78b83),  static_cast <long> (0x4f256096),  static_cast <long> (0xe643df7),
+	static_cast <long> (0x82c359bf),  static_cast <long> (0xc7794dfa),  static_cast <long> (0xd5e9ffaa),  static_cast <long> (0x2c8cb64a),
+	static_cast <long> (0x2f07b334),  static_cast <long> (0xad5a7eb5),  static_cast <long> (0x96dc0cde),  static_cast <long> (0x6fc24589),
+	static_cast <long> (0xa5853646),  static_cast <long> (0xe71576e2),  static_cast <long> (0xdae30df),   static_cast <long> (0xb09ce711),
+	static_cast <long> (0x5e56ef87),  static_cast <long> (0x4b4b0082),  static_cast <long> (0x6f4f340e),  static_cast <long> (0xc5bb17e8),
+	static_cast <long> (0xd788d765),  static_cast <long> (0x67498087),  static_cast <long> (0x9d7aba26),  static_cast <long> (0x261351d4),
+	static_cast <long> (0x411ee7ea),  static_cast <long> (0x393a263),   static_cast <long> (0x2c5a5835),  static_cast <long> (0xc115fcd8),
+	static_cast <long> (0x25e9132c),  static_cast <long> (0xd0c6e906),  static_cast <long> (0xc2bc5b2d),  static_cast <long> (0x6c065c98),
+	static_cast <long> (0x6e37bd55)};
+
+   long	*rJ = &state [r_off];
+	long	*rK = &state [sizeof state / sizeof *state - 1];
+
+}
+void Random::seed (long x)
+{
+	register size_t i;
+
+	state [0] = x;
+   
+   // linear congruential initializer
+	for (i = 1; i < sizeof state / sizeof *state; ++i) {
+		state [i] = 1103515245 * state [i - 1] + 12345;
+	}
+
+	rJ = &state [r_off];
+	rK = &state [sizeof state / sizeof *state - 1];
+
+	for (i = 0; i < 10 * sizeof state / sizeof *state; ++i) number ();
+}
+
+long Random::number () // uniform random x : 0 <= x <= exp2 (31) - 1
+
+{
+	register long	r;
+
+	r = *rK;
+	r += *rJ--;
+	*rK-- = r;
+
+   if (rK < state) {
+		rK = &state [sizeof state / sizeof *state - 1];
+   } else if (rJ < state) {
+			rJ = &state [sizeof state / sizeof *state - 1];
+   }
+	
+   return (r >> 1) &0x7fffffff; // discard the least-random bit
+}
+
diff --git a/src/alp/njn_random.hpp b/src/alp/njn_random.hpp
index 50564e3..d3c265b 100644
--- a/src/alp/njn_random.hpp
+++ b/src/alp/njn_random.hpp
@@ -1,55 +1,55 @@
-#ifndef INCLUDED_NJN_RANDOM
-#define INCLUDED_NJN_RANDOM
-
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: njn_random.hpp
-
-Author: John Spouge
-
-Contents: Random no. seeder and generator
-
-******************************************************************************/
-
-
-namespace Njn {
-
-   namespace Random {
-
-      const long SEED = 31415; // default random seed
-
-      void seed (long n); // provides seed for random numbers
-
-      long number (); // returns random numbers
-
-   }
-
-}
-
-#endif //! INCLUDED
-
+#ifndef INCLUDED_NJN_RANDOM
+#define INCLUDED_NJN_RANDOM
+
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: njn_random.hpp
+
+Author: John Spouge
+
+Contents: Random no. seeder and generator
+
+******************************************************************************/
+
+
+namespace Njn {
+
+   namespace Random {
+
+      const long SEED = 31415; // default random seed
+
+      void seed (long n); // provides seed for random numbers
+
+      long number (); // returns random numbers
+
+   }
+
+}
+
+#endif //! INCLUDED
+
diff --git a/src/alp/njn_uniform.hpp b/src/alp/njn_uniform.hpp
index 1080d12..b7bb71e 100644
--- a/src/alp/njn_uniform.hpp
+++ b/src/alp/njn_uniform.hpp
@@ -1,76 +1,76 @@
-#ifndef INCLUDED_NJN_UNIFORM
-#define INCLUDED_NJN_UNIFORM
-
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: njn_uniform.hpp
-
-Author: John Spouge
-
-Contents: 
-
-******************************************************************************/
-
-
-
-#include "njn_random.hpp"
-
-#include <assert.h>
-
-
-namespace Njn {
-
-   namespace Uniform { // uniform distribution 
-
-      template <typename T>
-      inline T variate (T a_ = static_cast <T> (0.0), T b_= static_cast <T> (1.0)); // returns uniform random variate [a_, b_) 
-
-      template <typename T>
-      inline T standardVariate ();
-
-//
-// There are no more declarations beyond this point.
-//
-      template <typename T>
-      T variate (T a_, T b_)
-      {
-         assert (a_ != b_);
-
-         //if (b_ < a_) std::swap <T> (a_, b_); // a_ < b_
-		 if (b_ < a_) std::swap (a_, b_); // a_ < b_/*sls deleted <T>*/
-
-         long random = 0;
-         while ((random = Njn::Random::number ()) == 0x7fffffff);
-
-         return a_ + static_cast <T> ((b_ - a_) * static_cast <double> (Random::number ()) / static_cast <double> (0x7fffffff)); 
-      }
-   }
-}
-
-#endif //! INCLUDED
-
+#ifndef INCLUDED_NJN_UNIFORM
+#define INCLUDED_NJN_UNIFORM
+
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: njn_uniform.hpp
+
+Author: John Spouge
+
+Contents: 
+
+******************************************************************************/
+
+
+
+#include "njn_random.hpp"
+
+#include <assert.h>
+
+
+namespace Njn {
+
+   namespace Uniform { // uniform distribution 
+
+      template <typename T>
+      inline T variate (T a_ = static_cast <T> (0.0), T b_= static_cast <T> (1.0)); // returns uniform random variate [a_, b_) 
+
+      template <typename T>
+      inline T standardVariate ();
+
+//
+// There are no more declarations beyond this point.
+//
+      template <typename T>
+      T variate (T a_, T b_)
+      {
+         assert (a_ != b_);
+
+         //if (b_ < a_) std::swap <T> (a_, b_); // a_ < b_
+		 if (b_ < a_) std::swap (a_, b_); // a_ < b_/*sls deleted <T>*/
+
+         long random = 0;
+         while ((random = Njn::Random::number ()) == 0x7fffffff);
+
+         return a_ + static_cast <T> ((b_ - a_) * static_cast <double> (Random::number ()) / static_cast <double> (0x7fffffff)); 
+      }
+   }
+}
+
+#endif //! INCLUDED
+
diff --git a/src/alp/sls_alignment_evaluer.cpp b/src/alp/sls_alignment_evaluer.cpp
index 54641ef..8fd6f1a 100644
--- a/src/alp/sls_alignment_evaluer.cpp
+++ b/src/alp/sls_alignment_evaluer.cpp
@@ -1,1150 +1,1150 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_alignment_evaluer.cpp
-
-Author: Sergey Sheetlin
-
-Contents: library functions of main routines
-
-******************************************************************************/
-
-
-#include "sls_alignment_evaluer.hpp"
-
-#include "sls_alp.hpp"
-#include "sls_alp_data.hpp"
-#include "sls_alp_regression.hpp"
-#include "sls_alp_sim.hpp"
-#include "njn_localmaxstatmatrix.hpp"
-#include "njn_localmaxstatutil.hpp"
-
-using namespace std;
-
-
-namespace Sls {
-
-// Write the parameters:
-std::ostream &operator<<(std::ostream &s_,
-const AlignmentEvaluer &g_)
-{
-
-	if(!pvalues::assert_Gumbel_parameters(
-	g_.d_params)||!g_.isGood())
-	{
-		throw error("Error - the Gumbel parameters are not defined properly in the function \"std::ostream &operator<<\"\n",1);
-	};
-
-	s_<<g_.d_params;
-	return s_;
-}
-
-// Read the parameters:
-std::istream &operator>>(std::istream &s_,
-AlignmentEvaluer &g_)
-{
-	try
-	{
-		g_.d_params.d_params_flag=false;
-		s_>>g_.d_params;
-		g_.d_params.d_params_flag=true;
-
-		//precompute intercepts
-		pvalues::compute_intercepts(g_.d_params);
-
-		if(!pvalues::assert_Gumbel_parameters(
-		g_.d_params)||!g_.isGood())
-		{
-			g_.d_params.d_params_flag=false;
-		};
-
-		return s_;
-	}
-	catch (...)
-	{ 
-		g_.d_params.d_params_flag=false;
-		throw;
-	};
-}
-
-//check correctness of the input parameters for gapless alignment
-void AlignmentEvaluer::assert_Gapless_input_parameters(
-long alphabetSize_,//a number of letters in the alphabet
-const double *letterFreqs1_,//background frequencies of letters in sequence #1
-const double *letterFreqs2_,//background frequencies of letters in sequence #2
-double *&letterFreqs1_normalized_,//normalized background frequencies of letters in sequence #1
-double *&letterFreqs2_normalized_,//normalized background frequencies of letters in sequence #2
-const string function_name_)//"assert_Gapless_input_parameters" is called from "function_name_" function
-{
-	if(!(alphabetSize_>0))
-	{
-		d_params.d_params_flag=false;
-		throw error("Error - the parameter \"alphabetSize_\" in the function \""+function_name_+"\" must be positive\n",1);
-	};
-
-	long int i;
-
-	double sum1=0;
-	for(i=0;i<alphabetSize_;i++)
-	{
-		if(letterFreqs1_[i]<0)
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the value \"letterFreqs1_["+alp_data::long_to_string(i)+"]\" in the function \""+function_name_+"\" must be non-negative\n",1);
-		};
-		sum1+=letterFreqs1_[i];
-	};
-
-	if(sum1<=0)
-	{
-		throw error("Error - sum of the frequencies \"letterFreqs1_\" is non-positive in the function \""+function_name_+"\"\n",1);
-	};
-
-	letterFreqs1_normalized_=new double[alphabetSize_];
-	alp_data::assert_mem(letterFreqs1_normalized_);
-
-
-	for(i=0;i<alphabetSize_;i++)
-	{
-		letterFreqs1_normalized_[i]=letterFreqs1_[i]/sum1;
-	};
-
-	double sum2=0;
-	for(i=0;i<alphabetSize_;i++)
-	{
-		if(letterFreqs2_[i]<0)
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the value \"letterFreqs2_["+alp_data::long_to_string(i)+"]\" in the function \""+function_name_+"\" must be non-negative\n",1);
-		};
-		sum2+=letterFreqs2_[i];
-	};
-
-	if(sum2<=0)
-	{
-		throw error("Error - sum of the frequencies \"letterFreqs2_\" is non-positive in the function \""+function_name_+"\"\n",1);
-	};
-	letterFreqs2_normalized_=new double[alphabetSize_];
-	alp_data::assert_mem(letterFreqs1_normalized_);
-
-	for(i=0;i<alphabetSize_;i++)
-	{
-		letterFreqs2_normalized_[i]=letterFreqs2_[i]/sum2;
-	};
-
-}
-
-
-//Computes gapless Gumbel parameters:
-void AlignmentEvaluer::initGapless(long alphabetSize_,//a number of letters in the alphabet
-const long *const *substitutionScoreMatrix_,//scoring matrix
-const double *letterFreqs1_,//background frequencies of letters in sequence #1
-const double *letterFreqs2_,//background frequencies of letters in sequence #2
-double max_time_)//maximum allowed calculation time in seconds
-{
-
-	try
-	{
-		
-
-		double CurrentTime1;
-		Sls::alp_data::get_current_time(CurrentTime1);
-
-		//check correctness of the input parameters for gapless alignment
-		string function_name="void AlignmentEvaluer::initGapless";
-		double *letterFreqs1_normalized=NULL;//normalized background frequencies of letters in sequence #1
-		double *letterFreqs2_normalized=NULL;//normalized background frequencies of letters in sequence #2
-
-		assert_Gapless_input_parameters(
-		alphabetSize_,//a number of letters in the alphabet
-		letterFreqs1_,//background frequencies of letters in sequence #1
-		letterFreqs2_,//background frequencies of letters in sequence #2
-		letterFreqs1_normalized,//normalized background frequencies of letters in sequence #1
-		letterFreqs2_normalized,//normalized background frequencies of letters in sequence #2
-		function_name);//"assert_Gapless_input_parameters" is called from "function_name_" function
-
-		
-		if(max_time_<=0)
-		{
-			max_time_=60;
-		};
-
-		d_params.d_params_flag=false;
-
-		Njn::LocalMaxStatMatrix local_max_stat_matrix(alphabetSize_,
-							  substitutionScoreMatrix_,
-							  letterFreqs1_normalized,
-							  letterFreqs2_normalized,
-							  alphabetSize_,
-							  max_time_);
-
-		if(local_max_stat_matrix.getTerminated()) 
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-
-		//calculation of a and sigma
-		double calculation_error=1e-6;
-
-		d_params.gapless_alpha = local_max_stat_matrix.getAlpha ();
-		d_params.gapless_alpha=alp_data::Tmax(d_params.gapless_alpha,0.0);
-		d_params.gapless_alpha_error = calculation_error;
-
-		d_params.gapless_a = local_max_stat_matrix.getA ();
-		d_params.gapless_a=alp_data::Tmax(d_params.gapless_a,0.0);
-		d_params.gapless_a_error = calculation_error;
-
-		//calculation of all required parameters for a gapless case
-		d_params.G=0;
-		d_params.G1=0;
-		d_params.G2=0;
-
-		d_params.lambda = local_max_stat_matrix.getLambda ();
-		d_params.lambda_error = calculation_error;
-
-		d_params.K = local_max_stat_matrix.getK ();
-		d_params.K_error = calculation_error;
-			
-		d_params.C = local_max_stat_matrix.getC ();;
-		d_params.C_error = calculation_error;
-
-		d_params.sigma = d_params.gapless_alpha;
-		d_params.sigma_error = calculation_error;
-
-		d_params.alpha_I = d_params.gapless_alpha;
-		d_params.alpha_I_error = calculation_error;
-
-		d_params.alpha_J = d_params.gapless_alpha;
-		d_params.alpha_J_error = calculation_error;
-
-		d_params.a_I = d_params.gapless_a;
-		d_params.a_I_error = calculation_error;
-
-		d_params.a_J = d_params.gapless_a;
-		d_params.a_J_error = calculation_error;
-
-
-		std::vector<double > sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.lambda;
-		sbs_arrays[1]=d_params.lambda + calculation_error;
-
-		d_params.m_LambdaSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.K;
-		sbs_arrays[1]=d_params.K+calculation_error;
-
-		d_params.m_KSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.C;
-		sbs_arrays[1]=d_params.C+calculation_error;
-
-		d_params.m_CSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.sigma;
-		sbs_arrays[1]=d_params.sigma + calculation_error;
-
-		d_params.m_SigmaSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.alpha_I;
-		sbs_arrays[1]=d_params.alpha_I + calculation_error;
-
-		d_params.m_AlphaISbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.alpha_J;
-		sbs_arrays[1]=d_params.alpha_J + calculation_error;
-
-		d_params.m_AlphaJSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.a_I;
-		sbs_arrays[1]=d_params.a_I + calculation_error;
-
-		d_params.m_AISbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.a_J;
-		sbs_arrays[1]=d_params.a_J + calculation_error;
-
-		d_params.m_AJSbs=sbs_arrays;
-
-		d_params.a 
-			= (d_params.a_I + d_params.a_J) * 0.5;
-
-		d_params.a_error = (d_params.a_I_error
-						+ d_params.a_J_error)*0.5;
-		
-		d_params.alpha = (d_params.alpha_I
-						+ d_params.alpha_J) * 0.5;
-
-		d_params.alpha_error = (d_params.alpha_I_error
-						+ d_params.alpha_J_error) * 0.5;
-
-		d_params.d_params_flag=true;
-
-		//precompute intercepts
-		pvalues::compute_intercepts(d_params);
-
-		if(!pvalues::assert_Gumbel_parameters(
-		d_params)||!isGood())
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void AlignmentEvaluer::initGapless\"\n",1);
-		};
-
-		delete[]letterFreqs1_normalized;
-		delete[]letterFreqs2_normalized;
-
-		double CurrentTime2;
-		Sls::alp_data::get_current_time(CurrentTime2);
-		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
-
-	}
-	catch (...)
-	{ 
-		d_params.d_params_flag=false;
-		throw;
-	};
-
-}
-
-//Computes gapped Gumbel parameters:
-//The NCBI convention is used for penalizing a gap:
-//For example, a gap of length k is penalized as gapOpen1_+k*gapEpen1_ for sequence #1
-//if max_time_<=0 then d_gapped_computation_parameters will be used;
-//d_gapped_computation_parameters.d_parameters_flag must be true in this case
-//every execution of initGapped with max_time_>0 rewrites d_gapped_computation_parameters by the actual values
-void AlignmentEvaluer::initGapped(long alphabetSize_,//a number of letters in the alphabet
-const long *const *substitutionScoreMatrix_,//scoring matrix
-const double *letterFreqs1_,//background frequencies of letters in sequence #1
-const double *letterFreqs2_,//background frequencies of letters in sequence #2
-long gapOpen1_,//gap opening penalty for sequence #1
-long gapEpen1_,//gap extension penalty for sequence #1
-long gapOpen2_,//gap opening penalty for sequence #2
-long gapEpen2_,//gap extension penalty for sequence #2
-bool insertions_after_deletions_,//if true, then insertions after deletions are permitted
-double eps_lambda_,//relative error for the parameter lambda
-double eps_K_,//relative error for the parameter K
-double max_time_,//maximum allowed calculation time in seconds
-double max_mem_,//maximum allowed memory usage in Mb
-long randomSeed_)//randomizaton seed
-{
-
-	struct_for_randomization *randomization_parameters=NULL;
-	try
-	{
-
-		double CurrentTime1;
-		Sls::alp_data::get_current_time(CurrentTime1);
-
-		//check correctness of the input parameters for gapless alignment
-		string function_name="void AlignmentEvaluer::initGapped";
-		double *letterFreqs1_normalized=NULL;//normalized background frequencies of letters in sequence #1
-		double *letterFreqs2_normalized=NULL;//normalized background frequencies of letters in sequence #2
-		assert_Gapless_input_parameters(
-		alphabetSize_,//a number of letters in the alphabet
-		letterFreqs1_,//background frequencies of letters in sequence #1
-		letterFreqs2_,//background frequencies of letters in sequence #2
-		letterFreqs1_normalized,//normalized background frequencies of letters in sequence #1
-		letterFreqs2_normalized,//normalized background frequencies of letters in sequence #2
-		function_name);//"assert_Gapless_input_parameters" is called from "function_name_" function
-
-		if(!(gapEpen1_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"gapEpen1_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(gapEpen2_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"gapEpen2_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(eps_lambda_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"eps_lambda_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(eps_K_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"eps_K_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(max_mem_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"max_mem_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		d_params.d_params_flag=false;
-
-		//Gapless parameters calculation
-		double GaplessTimePortion=0.5;
-		double GaplessCalculationTime=max_time_;
-
-		if(max_time_<=0)
-		{
-			GaplessCalculationTime=120;//the time is set to 120 seconds if not set as an input
-		};
-
-		//Gapless calculation may take only a portion of maximum allowed calculation time in the case of gapped calculation 
-		GaplessCalculationTime*=GaplessTimePortion;
-
-
-		
-		Njn::LocalMaxStatMatrix local_max_stat_matrix(alphabetSize_,
-							  substitutionScoreMatrix_,
-							  letterFreqs1_normalized,
-							  letterFreqs2_normalized,
-							  alphabetSize_,
-							  GaplessCalculationTime);
-
-		if(local_max_stat_matrix.getTerminated()) 
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-		//calculation of a and sigma
-		double calculation_error=1e-6;
-
-		d_params.gapless_alpha = local_max_stat_matrix.getAlpha ();
-		d_params.gapless_alpha=alp_data::Tmax(d_params.gapless_alpha,0.0);
-		d_params.gapless_alpha_error = calculation_error;
-
-		d_params.gapless_a = local_max_stat_matrix.getA ();
-		d_params.gapless_a=alp_data::Tmax(d_params.gapless_a,0.0);
-		d_params.gapless_a_error = calculation_error;
-
-
-		double CurrentTimeGaplessPreliminary;
-		Sls::alp_data::get_current_time(CurrentTimeGaplessPreliminary);
-		double GaplessPreliminaryTime=CurrentTimeGaplessPreliminary-CurrentTime1;
-
-		//the choice for the importance sampling
-		long int gapOpen=alp_data::Tmin(gapOpen1_,gapOpen2_);
-		long int gapEpen=alp_data::Tmin(gapEpen1_,gapEpen2_);
-
-		if(max_time_<=0)
-		{
-			if(d_gapped_computation_parameters.d_parameters_flag)
-			{
-				randomization_parameters=new struct_for_randomization;
-
-				randomization_parameters->d_first_stage_preliminary_realizations_numbers_ALP=
-					d_gapped_computation_parameters.d_first_stage_preliminary_realizations_numbers_ALP;
-
-				randomization_parameters->d_preliminary_realizations_numbers_ALP=
-					d_gapped_computation_parameters.d_preliminary_realizations_numbers_ALP;
-
-				randomization_parameters->d_preliminary_realizations_numbers_killing=
-					d_gapped_computation_parameters.d_preliminary_realizations_numbers_killing;
-
-				randomization_parameters->d_random_seed=randomSeed_;
-
-				randomization_parameters->d_total_realizations_number_with_ALP=
-					d_gapped_computation_parameters.d_total_realizations_number_with_ALP;
-
-				randomization_parameters->d_total_realizations_number_with_killing=
-					d_gapped_computation_parameters.d_total_realizations_number_with_killing;
-
-			}
-			else
-			{
-				throw error("Error - d_gapped_computation_parameters must be defined before calling AlignmentEvaluer::initGapped with max_time_<=0\n",1);
-			};
-		};
-
-		Sls::alp_data data_obj(//constructor
-		randomSeed_,//randomization number
-		randomization_parameters,//if not NULL, sets d_rand_flag to true and initializes d_rand_all
-
-		gapOpen,//gap opening penalty
-		gapOpen1_,//gap opening penalty for a gap in the sequence #1
-		gapOpen2_,//gap opening penalty for a gap in the sequence #2
-
-		gapEpen,//gap extension penalty
-		gapEpen1_,//gap extension penalty for a gap in the sequence #1
-		gapEpen2_,//gap extension penalty for a gap in the sequence #2
-
-		alphabetSize_,
-		substitutionScoreMatrix_,
-		letterFreqs1_normalized,
-		letterFreqs2_normalized,
-
-		max_time_,//maximum allowed calculation time in seconds
-		max_mem_,//maximum allowed memory usage in MB
-		eps_lambda_,//relative error for lambda calculation
-		eps_K_,//relative error for K calculation
-		insertions_after_deletions_,//if true, then insertions after deletions are allowed
-		d_gapped_computation_parameters.d_max_time_for_quick_tests,//maximum allowed calculation time in seconds for quick tests
-		d_gapped_computation_parameters.d_max_time_with_computation_parameters);//maximum allowed time in seconds for the whole computation
-
-
-
-		data_obj.d_max_time=Sls::alp_data::Tmax((1.0-GaplessTimePortion)*data_obj.d_max_time,data_obj.d_max_time-GaplessPreliminaryTime);
-
-		Sls::alp_sim sim_obj(&data_obj);
-
-		if(max_time_>0)
-		{
-			d_gapped_computation_parameters.d_parameters_flag=true;
-			
-			d_gapped_computation_parameters.d_first_stage_preliminary_realizations_numbers_ALP=
-				sim_obj.d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP;
-
-			d_gapped_computation_parameters.d_preliminary_realizations_numbers_ALP=
-				sim_obj.d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP;
-
-			d_gapped_computation_parameters.d_preliminary_realizations_numbers_killing=
-				sim_obj.d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing;
-
-			d_gapped_computation_parameters.d_total_realizations_number_with_ALP=
-				sim_obj.d_alp_data->d_rand_all->d_total_realizations_number_with_ALP;
-
-			d_gapped_computation_parameters.d_total_realizations_number_with_killing=
-				sim_obj.d_alp_data->d_rand_all->d_total_realizations_number_with_killing;
-		};
-
-		sim_obj.m_GaplessAlpha = d_params.gapless_alpha;
-		sim_obj.m_GaplessAlphaError = d_params.gapless_alpha_error;
-
-		sim_obj.m_GaplessA = d_params.gapless_a;
-		sim_obj.m_GaplessAError = d_params.gapless_a_error;
-
-		
-		sim_obj.m_G1=gapOpen1_+gapEpen1_;
-		sim_obj.m_G2=gapOpen2_+gapEpen2_;
-		sim_obj.m_G=alp_data::Tmin(sim_obj.m_G1,sim_obj.m_G2);
-
-		//------------------------------------------------------------------
-
-		d_params.G=sim_obj.m_G;
-		d_params.G1=sim_obj.m_G1;
-		d_params.G2=sim_obj.m_G2;
-
-		d_params.lambda = sim_obj.m_Lambda;
-		d_params.lambda_error = sim_obj.m_LambdaError;
-
-		d_params.K = sim_obj.m_K;
-		d_params.K_error = sim_obj.m_KError;
-			
-		d_params.C = sim_obj.m_C;
-		d_params.C_error = sim_obj.m_CError;
-
-		d_params.sigma = sim_obj.m_Sigma;
-		d_params.sigma_error = sim_obj.m_SigmaError;
-
-		d_params.alpha_I = sim_obj.m_AlphaI;
-		d_params.alpha_I_error = sim_obj.m_AlphaIError;
-
-		d_params.alpha_J = sim_obj.m_AlphaJ;
-		d_params.alpha_J_error = sim_obj.m_AlphaJError;
-
-		d_params.a_I = sim_obj.m_AI;
-		d_params.a_I_error = sim_obj.m_AIError;
-
-		d_params.a_J = sim_obj.m_AJ;
-		d_params.a_J_error = sim_obj.m_AJError;
-
-
-		d_params.m_LambdaSbs=sim_obj.m_LambdaSbs;
-
-		d_params.m_KSbs=sim_obj.m_KSbs;
-
-		d_params.m_CSbs=sim_obj.m_CSbs;
-
-		d_params.m_SigmaSbs=sim_obj.m_SigmaSbs;
-
-		d_params.m_AlphaISbs=sim_obj.m_AlphaISbs;
-
-		d_params.m_AlphaJSbs=sim_obj.m_AlphaJSbs;
-
-		d_params.m_AISbs=sim_obj.m_AISbs;
-
-		d_params.m_AJSbs=sim_obj.m_AJSbs;
-
-
-		d_params.a 
-			= (d_params.a_I + d_params.a_J) * 0.5;
-
-		d_params.a_error = (d_params.a_I_error
-						+ d_params.a_J_error)*0.5;
-		
-		d_params.alpha = (d_params.alpha_I
-						+ d_params.alpha_J) * 0.5;
-
-		d_params.alpha_error = (d_params.alpha_I_error
-						+ d_params.alpha_J_error) * 0.5;
-
-		d_params.d_params_flag=true;
-
-		//precompute intercepts
-		pvalues::compute_intercepts(d_params);
-
-		double CurrentTime2;
-		Sls::alp_data::get_current_time(CurrentTime2);
-		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
-		delete randomization_parameters;randomization_parameters=NULL;
-
-		if(!pvalues::assert_Gumbel_parameters(
-		d_params)||!isGood())
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void AlignmentEvaluer::initGapped\"\n",1);
-		};
-
-		delete[]letterFreqs1_normalized;
-		delete[]letterFreqs2_normalized;
-
-
-	}
-	catch (...)
-	{ 
-		delete randomization_parameters;randomization_parameters=NULL;
-		d_params.d_params_flag=false;
-		throw;
-	};
-}
-
-//Initializes Gumbel parameters using precalculated values:
-void AlignmentEvaluer::initParameters(
-const AlignmentEvaluerParameters &parameters_)
-{
-	try
-	{
-		double CurrentTime1;
-		Sls::alp_data::get_current_time(CurrentTime1);
-
-		d_params.d_params_flag=false;
-
-		double calculation_error=1e-6;
-
-		d_params.lambda=parameters_.d_lambda;
-		d_params.lambda_error=calculation_error;
-
-		d_params.C=0;
-		d_params.C_error=0;
-
-
-		d_params.K=parameters_.d_k;
-		d_params.K_error=calculation_error;
-
-		d_params.a_I=parameters_.d_a2;
-		d_params.a_I_error=calculation_error;
-
-		d_params.a_J=parameters_.d_a1;
-		d_params.a_J_error=calculation_error;
-
-		d_params.sigma=parameters_.d_sigma;
-		d_params.sigma_error=calculation_error;
-
-		d_params.alpha_I=parameters_.d_alpha2;
-		d_params.alpha_I_error=calculation_error;
-
-		d_params.alpha_J=parameters_.d_alpha1;
-		d_params.alpha_J_error=calculation_error;
-
-		d_params.a=0.5*(parameters_.d_a1+parameters_.d_a2);
-		d_params.a_error=calculation_error;
-
-		d_params.alpha=0.5*(parameters_.d_alpha1+parameters_.d_alpha2);
-		d_params.alpha_error=calculation_error;
-
-		d_params.gapless_a=0;
-		d_params.gapless_a_error=0;
-
-		d_params.gapless_alpha=0;
-		d_params.gapless_alpha_error=0;
-
-		d_params.G=0;
-		d_params.G1=0;
-		d_params.G2=0;
-
-		//intercepts
-		d_params.b_I=parameters_.d_b2;
-		d_params.b_I_error=calculation_error;
-
-		d_params.b_J=parameters_.d_b1;
-		d_params.b_J_error=calculation_error;
-
-		d_params.beta_I=parameters_.d_beta2;
-		d_params.beta_I_error=calculation_error;
-
-		d_params.beta_J=parameters_.d_beta1;
-		d_params.beta_J_error=calculation_error;
-
-		d_params.tau=parameters_.d_tau;
-		d_params.tau_error=calculation_error;
-
-
-		//arrays initialization
-		std::vector<double > sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.lambda;
-		sbs_arrays[1]=d_params.lambda + calculation_error;
-
-		d_params.m_LambdaSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.K;
-		sbs_arrays[1]=d_params.K+calculation_error;
-
-		d_params.m_KSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.C;
-		sbs_arrays[1]=d_params.C+calculation_error;
-
-		d_params.m_CSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.sigma;
-		sbs_arrays[1]=d_params.sigma + calculation_error;
-
-		d_params.m_SigmaSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.alpha_I;
-		sbs_arrays[1]=d_params.alpha_I + calculation_error;
-
-		d_params.m_AlphaISbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.alpha_J;
-		sbs_arrays[1]=d_params.alpha_J + calculation_error;
-
-		d_params.m_AlphaJSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.a_I;
-		sbs_arrays[1]=d_params.a_I + calculation_error;
-
-		d_params.m_AISbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.a_J;
-		sbs_arrays[1]=d_params.a_J + calculation_error;
-
-		d_params.m_AJSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.b_J;
-		sbs_arrays[1]=d_params.b_J + calculation_error;
-
-		d_params.m_BJSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.b_I;
-		sbs_arrays[1]=d_params.b_I + calculation_error;
-
-		d_params.m_BISbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.beta_J;
-		sbs_arrays[1]=d_params.beta_J + calculation_error;
-
-		d_params.m_BetaJSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.beta_I;
-		sbs_arrays[1]=d_params.beta_I + calculation_error;
-
-		d_params.m_BetaISbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.tau;
-		sbs_arrays[1]=d_params.tau + calculation_error;
-
-		d_params.m_TauSbs=sbs_arrays;
-
-
-		d_params.d_params_flag=true;//if true, then the parameters are defined and P-values can be calculated
-
-		pvalues::compute_tmp_values(d_params);
-
-		double CurrentTime2;
-		Sls::alp_data::get_current_time(CurrentTime2);
-		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
-
-		if(!pvalues::assert_Gumbel_parameters(
-		d_params)||!isGood())
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void AlignmentEvaluer::initParameters\"\n",1);
-		};
-	}
-	catch (...)
-	{ 
-		d_params.d_params_flag=false;
-		throw;
-	};
-	
-}
-
-void AlignmentEvaluer::initParameters(
-const AlignmentEvaluerParametersWithErrors &parameters_)
-{
-	try
-	{
-		double CurrentTime1;
-		Sls::alp_data::get_current_time(CurrentTime1);
-
-		d_params.d_params_flag=false;
-
-		long int array_dim=20;
-
-		long int seed_tmp=12345;
-		srand(seed_tmp);
-
-
-		d_params.lambda=parameters_.d_lambda;
-		d_params.lambda_error=parameters_.d_lambda_error;
-
-		d_params.C=0;
-		d_params.C_error=0;
-
-
-		d_params.K=parameters_.d_k;
-		d_params.K_error=parameters_.d_k_error;
-
-		d_params.a_I=parameters_.d_a2;
-		d_params.a_I_error=parameters_.d_a2_error;
-
-		d_params.a_J=parameters_.d_a1;
-		d_params.a_J_error=parameters_.d_a1_error;
-
-		d_params.sigma=parameters_.d_sigma;
-		d_params.sigma_error=parameters_.d_sigma_error;
-
-		d_params.alpha_I=parameters_.d_alpha2;
-		d_params.alpha_I_error=parameters_.d_alpha2_error;
-
-		d_params.alpha_J=parameters_.d_alpha1;
-		d_params.alpha_J_error=parameters_.d_alpha1_error;
-
-		d_params.a=0.5*(parameters_.d_a1+parameters_.d_a2);
-		d_params.a_error=0.5*(parameters_.d_a1_error+parameters_.d_a2_error);
-
-		d_params.alpha=0.5*(parameters_.d_alpha1+parameters_.d_alpha2);
-		d_params.alpha_error=0.5*(parameters_.d_alpha1_error+parameters_.d_alpha2_error);
-
-		d_params.gapless_a=0;
-		d_params.gapless_a_error=0;
-
-		d_params.gapless_alpha=0;
-		d_params.gapless_alpha_error=0;
-
-		d_params.G=0;
-		d_params.G1=0;
-		d_params.G2=0;
-
-		d_params.m_CalcTime=0;
-
-
-		//intercepts
-		d_params.b_I=parameters_.d_b2;
-		d_params.b_I_error=parameters_.d_b2_error;
-
-		d_params.b_J=parameters_.d_b1;
-		d_params.b_J_error=parameters_.d_b1_error;
-
-		d_params.beta_I=parameters_.d_beta2;
-		d_params.beta_I_error=parameters_.d_beta2_error;
-
-		d_params.beta_J=parameters_.d_beta1;
-		d_params.beta_J_error=parameters_.d_beta1_error;
-
-		d_params.tau=parameters_.d_tau;
-		d_params.tau_error=parameters_.d_tau_error;
-
-		double sqrt_array_dim=sqrt((double)array_dim);
-
-		d_params.m_LambdaSbs.clear();
-		d_params.m_KSbs.clear();
-		d_params.m_CSbs.clear();
-
-		d_params.m_SigmaSbs.clear();
-
-		d_params.m_AlphaISbs.clear();
-		d_params.m_AlphaJSbs.clear();
-
-		d_params.m_AISbs.clear();
-		d_params.m_AJSbs.clear();
-
-		d_params.m_BISbs.clear();
-		d_params.m_BJSbs.clear();
-
-		d_params.m_BetaISbs.clear();
-		d_params.m_BetaJSbs.clear();
-
-		d_params.m_TauSbs.clear();
-
-		long int i;
-		for(i=0;i<array_dim;i++)
-		{
-			d_params.m_LambdaSbs.push_back(d_params.lambda+d_params.lambda_error*pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_KSbs.push_back(d_params.K+d_params.K_error*pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_CSbs.push_back(0);
-
-			d_params.m_SigmaSbs.push_back(d_params.sigma+d_params.sigma_error*pvalues::standard_normal()*sqrt_array_dim);
-
-			d_params.m_AlphaISbs.push_back(d_params.alpha_I+d_params.alpha_I_error*pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_AlphaJSbs.push_back(d_params.alpha_J+d_params.alpha_J_error*pvalues::standard_normal()*sqrt_array_dim);
-
-			d_params.m_AISbs.push_back(d_params.a_I+d_params.a_I_error*pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_AJSbs.push_back(d_params.a_J+d_params.a_J_error*pvalues::standard_normal()*sqrt_array_dim);
-
-			d_params.m_BISbs.push_back(d_params.b_I+d_params.b_I_error*pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_BJSbs.push_back(d_params.b_J+d_params.b_J_error*pvalues::standard_normal()*sqrt_array_dim);
-
-			d_params.m_BetaISbs.push_back(d_params.beta_I+d_params.beta_I_error*pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_BetaJSbs.push_back(d_params.beta_J+d_params.beta_J_error*pvalues::standard_normal()*sqrt_array_dim);
-
-			d_params.m_TauSbs.push_back(d_params.tau+d_params.tau_error*pvalues::standard_normal()*sqrt_array_dim);
-		};
-
-		d_params.d_params_flag=true;//if true, then the parameters are defined and P-values can be calculated
-
-		pvalues::compute_tmp_values(d_params);
-
-		double CurrentTime2;
-		Sls::alp_data::get_current_time(CurrentTime2);
-		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
-
-		if(!pvalues::assert_Gumbel_parameters(
-		d_params)||!isGood())
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void AlignmentEvaluer::initParameters\"\n",1);
-		};
-	}
-	catch (...)
-	{ 
-		d_params.d_params_flag=false;
-		throw;
-	};
-	
-}
-
-double AlignmentEvaluer::area(double score_,//pairwise alignment score
-double seqlen1_,//length of sequence #1
-double seqlen2_) const//length of sequence #2
-{
-	if(seqlen1_<=0||seqlen2_<=0)
-	{
-		throw error("Error - seqlen1_<=0 or seq2en1_<=0 in \"double AlignmentEvaluer::area\"\n",2);
-	};
-
-	if(!isGood())
-	{
-		throw error("Unexpected error - the Gumbel parameters are not defined properly in \"double AlignmentEvaluer::area\"\n",1);
-	};
-
-	static Sls::pvalues pvalues_obj;
-
-	double P;
-	double E;
-	double area_res;
-	bool area_is_1_flag=false;
-	bool compute_only_area=true;
-
-	pvalues_obj.get_appr_tail_prob_with_cov_without_errors(
-	d_params,
-	pvalues_obj.blast,
-	score_,
-	seqlen2_,
-	seqlen1_,
-
-	P,
-
-	E,
-
-	area_res,
-	pvalues_obj.a_normal,
-	pvalues_obj.b_normal,
-	pvalues_obj.h_normal,
-	pvalues_obj.N_normal,
-	pvalues_obj.p_normal,
-	area_is_1_flag,
-	compute_only_area);
-
-
-	return area_res;
-
-}
-
-void AlignmentEvaluer::calc(double score_,//pairwise alignment score
-double seqlen1_,//length of sequence #1
-double seqlen2_,//length of sequence #2
-double &pvalue_,//resulted P-value
-double &pvalueErr_,//P-value error
-double &evalue_,//resulted E-value
-double &evalueErr_) const//E-value error
-{
-	if(seqlen1_<=0||seqlen2_<=0)
-	{
-		throw error("Error - seqlen1_<=0 or seqlen2_<=0 in \"double AlignmentEvaluer::calc\"\n",2);
-	};
-
-	if(!isGood())
-	{
-		throw error("Unexpected error - the Gumbel parameters are not defined properly in \"double AlignmentEvaluer::calc\"\n",1);
-	};
-
-	static Sls::pvalues pvalues_obj;
-
-	pvalues_obj.calculate_P_values(
-		score_, seqlen2_, seqlen1_,
-		d_params, 
-		pvalue_,
-		pvalueErr_,
-		evalue_,
-		evalueErr_);
-}
-
-void AlignmentEvaluer::calc(double score_,//pairwise alignment score
-double seqlen1_,//length of sequence #1
-double seqlen2_,//length of sequence #2
-double &pvalue_,//resulted P-value
-double &evalue_) const//resulted E-value
-{
-
-	if(seqlen1_<=0||seqlen2_<=0)
-	{
-		throw error("Error - seqlen1_<=0 or seqlen2_<=0 in \"double AlignmentEvaluer::calc\"\n",2);
-	};
-
-	if(!isGood())
-	{
-		throw error("Unexpected error - d_params is not defined in \"double AlignmentEvaluer::calc\"\n",1);
-	};
-
-	static Sls::pvalues pvalues_obj;
-
-
-	bool area_is_1_flag=false;
-
-	double area;
-
-
-	pvalues_obj.get_appr_tail_prob_with_cov_without_errors(
-	d_params,
-	pvalues_obj.blast,
-	score_,
-	seqlen2_,
-	seqlen1_,
-
-	pvalue_,
-
-	evalue_,
-
-	area,
-	pvalues_obj.a_normal,
-	pvalues_obj.b_normal,
-	pvalues_obj.h_normal,
-	pvalues_obj.N_normal,
-	pvalues_obj.p_normal,
-	area_is_1_flag);
-
-	
-
-}
-
-void AlignmentEvaluer::set_gapped_computation_parameters_simplified(
-double max_time_,//maximum allowed time in seconds for the whole computation
-long number_of_samples_,//number of realization for the main stage
-long number_of_samples_for_preliminary_stages_)//number of realization for the preliminary stages
-{
-
-	if(number_of_samples_<=0||number_of_samples_for_preliminary_stages_<=0)
-	{
-		throw error("Error - number_of_samples_<=0 or number_of_samples_for_preliminary_stages_<=0 in \"void AlignmentEvaluer::set_gapped_computation_parameters_simplified\"\n",2);
-	};
-
-	d_gapped_computation_parameters.d_first_stage_preliminary_realizations_numbers_ALP.resize(1);
-	d_gapped_computation_parameters.d_first_stage_preliminary_realizations_numbers_ALP[0]=number_of_samples_for_preliminary_stages_;
-	d_gapped_computation_parameters.d_preliminary_realizations_numbers_ALP.resize(1);
-	d_gapped_computation_parameters.d_preliminary_realizations_numbers_ALP[0]=number_of_samples_for_preliminary_stages_;
-	d_gapped_computation_parameters.d_preliminary_realizations_numbers_killing.resize(1);
-	d_gapped_computation_parameters.d_preliminary_realizations_numbers_killing[0]=number_of_samples_for_preliminary_stages_;
-	d_gapped_computation_parameters.d_total_realizations_number_with_ALP=number_of_samples_;
-	d_gapped_computation_parameters.d_total_realizations_number_with_killing=number_of_samples_;
-	d_gapped_computation_parameters.d_parameters_flag=true;
-	d_gapped_computation_parameters.d_max_time_with_computation_parameters=max_time_;
-	if(max_time_>0)
-	{
-		d_gapped_computation_parameters.d_max_time_for_quick_tests=0.5*max_time_*(double)quick_tests_trials_number/(double)(quick_tests_trials_number+number_of_samples_+number_of_samples_for_preliminary_stages_);
-	}
-	else
-	{
-		d_gapped_computation_parameters.d_max_time_for_quick_tests=-1;
-	};
-}
-
-void AlignmentEvaluer::gapped_computation_parameters_clear()
-{
-	d_gapped_computation_parameters.d_first_stage_preliminary_realizations_numbers_ALP.clear();
-	d_gapped_computation_parameters.d_preliminary_realizations_numbers_ALP.clear();
-	d_gapped_computation_parameters.d_preliminary_realizations_numbers_killing.clear();
-	d_gapped_computation_parameters.d_parameters_flag=false;
-	d_gapped_computation_parameters.d_max_time_for_quick_tests=-1;
-	d_gapped_computation_parameters.d_max_time_with_computation_parameters=-1;
-}
-
-
-}
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_alignment_evaluer.cpp
+
+Author: Sergey Sheetlin
+
+Contents: library functions of main routines
+
+******************************************************************************/
+
+
+#include "sls_alignment_evaluer.hpp"
+
+#include "sls_alp.hpp"
+#include "sls_alp_data.hpp"
+#include "sls_alp_regression.hpp"
+#include "sls_alp_sim.hpp"
+#include "njn_localmaxstatmatrix.hpp"
+#include "njn_localmaxstatutil.hpp"
+
+using namespace std;
+
+
+namespace Sls {
+
+// Write the parameters:
+std::ostream &operator<<(std::ostream &s_,
+const AlignmentEvaluer &g_)
+{
+
+	if(!pvalues::assert_Gumbel_parameters(
+	g_.d_params)||!g_.isGood())
+	{
+		throw error("Error - the Gumbel parameters are not defined properly in the function \"std::ostream &operator<<\"\n",1);
+	};
+
+	s_<<g_.d_params;
+	return s_;
+}
+
+// Read the parameters:
+std::istream &operator>>(std::istream &s_,
+AlignmentEvaluer &g_)
+{
+	try
+	{
+		g_.d_params.d_params_flag=false;
+		s_>>g_.d_params;
+		g_.d_params.d_params_flag=true;
+
+		//precompute intercepts
+		pvalues::compute_intercepts(g_.d_params);
+
+		if(!pvalues::assert_Gumbel_parameters(
+		g_.d_params)||!g_.isGood())
+		{
+			g_.d_params.d_params_flag=false;
+		};
+
+		return s_;
+	}
+	catch (...)
+	{ 
+		g_.d_params.d_params_flag=false;
+		throw;
+	};
+}
+
+//check correctness of the input parameters for gapless alignment
+void AlignmentEvaluer::assert_Gapless_input_parameters(
+long alphabetSize_,//a number of letters in the alphabet
+const double *letterFreqs1_,//background frequencies of letters in sequence #1
+const double *letterFreqs2_,//background frequencies of letters in sequence #2
+double *&letterFreqs1_normalized_,//normalized background frequencies of letters in sequence #1
+double *&letterFreqs2_normalized_,//normalized background frequencies of letters in sequence #2
+const string function_name_)//"assert_Gapless_input_parameters" is called from "function_name_" function
+{
+	if(!(alphabetSize_>0))
+	{
+		d_params.d_params_flag=false;
+		throw error("Error - the parameter \"alphabetSize_\" in the function \""+function_name_+"\" must be positive\n",1);
+	};
+
+	long int i;
+
+	double sum1=0;
+	for(i=0;i<alphabetSize_;i++)
+	{
+		if(letterFreqs1_[i]<0)
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the value \"letterFreqs1_["+alp_data::long_to_string(i)+"]\" in the function \""+function_name_+"\" must be non-negative\n",1);
+		};
+		sum1+=letterFreqs1_[i];
+	};
+
+	if(sum1<=0)
+	{
+		throw error("Error - sum of the frequencies \"letterFreqs1_\" is non-positive in the function \""+function_name_+"\"\n",1);
+	};
+
+	letterFreqs1_normalized_=new double[alphabetSize_];
+	alp_data::assert_mem(letterFreqs1_normalized_);
+
+
+	for(i=0;i<alphabetSize_;i++)
+	{
+		letterFreqs1_normalized_[i]=letterFreqs1_[i]/sum1;
+	};
+
+	double sum2=0;
+	for(i=0;i<alphabetSize_;i++)
+	{
+		if(letterFreqs2_[i]<0)
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the value \"letterFreqs2_["+alp_data::long_to_string(i)+"]\" in the function \""+function_name_+"\" must be non-negative\n",1);
+		};
+		sum2+=letterFreqs2_[i];
+	};
+
+	if(sum2<=0)
+	{
+		throw error("Error - sum of the frequencies \"letterFreqs2_\" is non-positive in the function \""+function_name_+"\"\n",1);
+	};
+	letterFreqs2_normalized_=new double[alphabetSize_];
+	alp_data::assert_mem(letterFreqs1_normalized_);
+
+	for(i=0;i<alphabetSize_;i++)
+	{
+		letterFreqs2_normalized_[i]=letterFreqs2_[i]/sum2;
+	};
+
+}
+
+
+//Computes gapless Gumbel parameters:
+void AlignmentEvaluer::initGapless(long alphabetSize_,//a number of letters in the alphabet
+const long *const *substitutionScoreMatrix_,//scoring matrix
+const double *letterFreqs1_,//background frequencies of letters in sequence #1
+const double *letterFreqs2_,//background frequencies of letters in sequence #2
+double max_time_)//maximum allowed calculation time in seconds
+{
+
+	try
+	{
+		
+
+		double CurrentTime1;
+		Sls::alp_data::get_current_time(CurrentTime1);
+
+		//check correctness of the input parameters for gapless alignment
+		string function_name="void AlignmentEvaluer::initGapless";
+		double *letterFreqs1_normalized=NULL;//normalized background frequencies of letters in sequence #1
+		double *letterFreqs2_normalized=NULL;//normalized background frequencies of letters in sequence #2
+
+		assert_Gapless_input_parameters(
+		alphabetSize_,//a number of letters in the alphabet
+		letterFreqs1_,//background frequencies of letters in sequence #1
+		letterFreqs2_,//background frequencies of letters in sequence #2
+		letterFreqs1_normalized,//normalized background frequencies of letters in sequence #1
+		letterFreqs2_normalized,//normalized background frequencies of letters in sequence #2
+		function_name);//"assert_Gapless_input_parameters" is called from "function_name_" function
+
+		
+		if(max_time_<=0)
+		{
+			max_time_=60;
+		};
+
+		d_params.d_params_flag=false;
+
+		Njn::LocalMaxStatMatrix local_max_stat_matrix(alphabetSize_,
+							  substitutionScoreMatrix_,
+							  letterFreqs1_normalized,
+							  letterFreqs2_normalized,
+							  alphabetSize_,
+							  max_time_);
+
+		if(local_max_stat_matrix.getTerminated()) 
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+
+		//calculation of a and sigma
+		double calculation_error=1e-6;
+
+		d_params.gapless_alpha = local_max_stat_matrix.getAlpha ();
+		d_params.gapless_alpha=alp_data::Tmax(d_params.gapless_alpha,0.0);
+		d_params.gapless_alpha_error = calculation_error;
+
+		d_params.gapless_a = local_max_stat_matrix.getA ();
+		d_params.gapless_a=alp_data::Tmax(d_params.gapless_a,0.0);
+		d_params.gapless_a_error = calculation_error;
+
+		//calculation of all required parameters for a gapless case
+		d_params.G=0;
+		d_params.G1=0;
+		d_params.G2=0;
+
+		d_params.lambda = local_max_stat_matrix.getLambda ();
+		d_params.lambda_error = calculation_error;
+
+		d_params.K = local_max_stat_matrix.getK ();
+		d_params.K_error = calculation_error;
+			
+		d_params.C = local_max_stat_matrix.getC ();;
+		d_params.C_error = calculation_error;
+
+		d_params.sigma = d_params.gapless_alpha;
+		d_params.sigma_error = calculation_error;
+
+		d_params.alpha_I = d_params.gapless_alpha;
+		d_params.alpha_I_error = calculation_error;
+
+		d_params.alpha_J = d_params.gapless_alpha;
+		d_params.alpha_J_error = calculation_error;
+
+		d_params.a_I = d_params.gapless_a;
+		d_params.a_I_error = calculation_error;
+
+		d_params.a_J = d_params.gapless_a;
+		d_params.a_J_error = calculation_error;
+
+
+		std::vector<double > sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.lambda;
+		sbs_arrays[1]=d_params.lambda + calculation_error;
+
+		d_params.m_LambdaSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.K;
+		sbs_arrays[1]=d_params.K+calculation_error;
+
+		d_params.m_KSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.C;
+		sbs_arrays[1]=d_params.C+calculation_error;
+
+		d_params.m_CSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.sigma;
+		sbs_arrays[1]=d_params.sigma + calculation_error;
+
+		d_params.m_SigmaSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.alpha_I;
+		sbs_arrays[1]=d_params.alpha_I + calculation_error;
+
+		d_params.m_AlphaISbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.alpha_J;
+		sbs_arrays[1]=d_params.alpha_J + calculation_error;
+
+		d_params.m_AlphaJSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.a_I;
+		sbs_arrays[1]=d_params.a_I + calculation_error;
+
+		d_params.m_AISbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.a_J;
+		sbs_arrays[1]=d_params.a_J + calculation_error;
+
+		d_params.m_AJSbs=sbs_arrays;
+
+		d_params.a 
+			= (d_params.a_I + d_params.a_J) * 0.5;
+
+		d_params.a_error = (d_params.a_I_error
+						+ d_params.a_J_error)*0.5;
+		
+		d_params.alpha = (d_params.alpha_I
+						+ d_params.alpha_J) * 0.5;
+
+		d_params.alpha_error = (d_params.alpha_I_error
+						+ d_params.alpha_J_error) * 0.5;
+
+		d_params.d_params_flag=true;
+
+		//precompute intercepts
+		pvalues::compute_intercepts(d_params);
+
+		if(!pvalues::assert_Gumbel_parameters(
+		d_params)||!isGood())
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void AlignmentEvaluer::initGapless\"\n",1);
+		};
+
+		delete[]letterFreqs1_normalized;
+		delete[]letterFreqs2_normalized;
+
+		double CurrentTime2;
+		Sls::alp_data::get_current_time(CurrentTime2);
+		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
+
+	}
+	catch (...)
+	{ 
+		d_params.d_params_flag=false;
+		throw;
+	};
+
+}
+
+//Computes gapped Gumbel parameters:
+//The NCBI convention is used for penalizing a gap:
+//For example, a gap of length k is penalized as gapOpen1_+k*gapEpen1_ for sequence #1
+//if max_time_<=0 then d_gapped_computation_parameters will be used;
+//d_gapped_computation_parameters.d_parameters_flag must be true in this case
+//every execution of initGapped with max_time_>0 rewrites d_gapped_computation_parameters by the actual values
+void AlignmentEvaluer::initGapped(long alphabetSize_,//a number of letters in the alphabet
+const long *const *substitutionScoreMatrix_,//scoring matrix
+const double *letterFreqs1_,//background frequencies of letters in sequence #1
+const double *letterFreqs2_,//background frequencies of letters in sequence #2
+long gapOpen1_,//gap opening penalty for sequence #1
+long gapEpen1_,//gap extension penalty for sequence #1
+long gapOpen2_,//gap opening penalty for sequence #2
+long gapEpen2_,//gap extension penalty for sequence #2
+bool insertions_after_deletions_,//if true, then insertions after deletions are permitted
+double eps_lambda_,//relative error for the parameter lambda
+double eps_K_,//relative error for the parameter K
+double max_time_,//maximum allowed calculation time in seconds
+double max_mem_,//maximum allowed memory usage in Mb
+long randomSeed_)//randomizaton seed
+{
+
+	struct_for_randomization *randomization_parameters=NULL;
+	try
+	{
+
+		double CurrentTime1;
+		Sls::alp_data::get_current_time(CurrentTime1);
+
+		//check correctness of the input parameters for gapless alignment
+		string function_name="void AlignmentEvaluer::initGapped";
+		double *letterFreqs1_normalized=NULL;//normalized background frequencies of letters in sequence #1
+		double *letterFreqs2_normalized=NULL;//normalized background frequencies of letters in sequence #2
+		assert_Gapless_input_parameters(
+		alphabetSize_,//a number of letters in the alphabet
+		letterFreqs1_,//background frequencies of letters in sequence #1
+		letterFreqs2_,//background frequencies of letters in sequence #2
+		letterFreqs1_normalized,//normalized background frequencies of letters in sequence #1
+		letterFreqs2_normalized,//normalized background frequencies of letters in sequence #2
+		function_name);//"assert_Gapless_input_parameters" is called from "function_name_" function
+
+		if(!(gapEpen1_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"gapEpen1_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(gapEpen2_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"gapEpen2_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(eps_lambda_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"eps_lambda_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(eps_K_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"eps_K_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(max_mem_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"max_mem_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		d_params.d_params_flag=false;
+
+		//Gapless parameters calculation
+		double GaplessTimePortion=0.5;
+		double GaplessCalculationTime=max_time_;
+
+		if(max_time_<=0)
+		{
+			GaplessCalculationTime=120;//the time is set to 120 seconds if not set as an input
+		};
+
+		//Gapless calculation may take only a portion of maximum allowed calculation time in the case of gapped calculation 
+		GaplessCalculationTime*=GaplessTimePortion;
+
+
+		
+		Njn::LocalMaxStatMatrix local_max_stat_matrix(alphabetSize_,
+							  substitutionScoreMatrix_,
+							  letterFreqs1_normalized,
+							  letterFreqs2_normalized,
+							  alphabetSize_,
+							  GaplessCalculationTime);
+
+		if(local_max_stat_matrix.getTerminated()) 
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+		//calculation of a and sigma
+		double calculation_error=1e-6;
+
+		d_params.gapless_alpha = local_max_stat_matrix.getAlpha ();
+		d_params.gapless_alpha=alp_data::Tmax(d_params.gapless_alpha,0.0);
+		d_params.gapless_alpha_error = calculation_error;
+
+		d_params.gapless_a = local_max_stat_matrix.getA ();
+		d_params.gapless_a=alp_data::Tmax(d_params.gapless_a,0.0);
+		d_params.gapless_a_error = calculation_error;
+
+
+		double CurrentTimeGaplessPreliminary;
+		Sls::alp_data::get_current_time(CurrentTimeGaplessPreliminary);
+		double GaplessPreliminaryTime=CurrentTimeGaplessPreliminary-CurrentTime1;
+
+		//the choice for the importance sampling
+		long int gapOpen=alp_data::Tmin(gapOpen1_,gapOpen2_);
+		long int gapEpen=alp_data::Tmin(gapEpen1_,gapEpen2_);
+
+		if(max_time_<=0)
+		{
+			if(d_gapped_computation_parameters.d_parameters_flag)
+			{
+				randomization_parameters=new struct_for_randomization;
+
+				randomization_parameters->d_first_stage_preliminary_realizations_numbers_ALP=
+					d_gapped_computation_parameters.d_first_stage_preliminary_realizations_numbers_ALP;
+
+				randomization_parameters->d_preliminary_realizations_numbers_ALP=
+					d_gapped_computation_parameters.d_preliminary_realizations_numbers_ALP;
+
+				randomization_parameters->d_preliminary_realizations_numbers_killing=
+					d_gapped_computation_parameters.d_preliminary_realizations_numbers_killing;
+
+				randomization_parameters->d_random_seed=randomSeed_;
+
+				randomization_parameters->d_total_realizations_number_with_ALP=
+					d_gapped_computation_parameters.d_total_realizations_number_with_ALP;
+
+				randomization_parameters->d_total_realizations_number_with_killing=
+					d_gapped_computation_parameters.d_total_realizations_number_with_killing;
+
+			}
+			else
+			{
+				throw error("Error - d_gapped_computation_parameters must be defined before calling AlignmentEvaluer::initGapped with max_time_<=0\n",1);
+			};
+		};
+
+		Sls::alp_data data_obj(//constructor
+		randomSeed_,//randomization number
+		randomization_parameters,//if not NULL, sets d_rand_flag to true and initializes d_rand_all
+
+		gapOpen,//gap opening penalty
+		gapOpen1_,//gap opening penalty for a gap in the sequence #1
+		gapOpen2_,//gap opening penalty for a gap in the sequence #2
+
+		gapEpen,//gap extension penalty
+		gapEpen1_,//gap extension penalty for a gap in the sequence #1
+		gapEpen2_,//gap extension penalty for a gap in the sequence #2
+
+		alphabetSize_,
+		substitutionScoreMatrix_,
+		letterFreqs1_normalized,
+		letterFreqs2_normalized,
+
+		max_time_,//maximum allowed calculation time in seconds
+		max_mem_,//maximum allowed memory usage in MB
+		eps_lambda_,//relative error for lambda calculation
+		eps_K_,//relative error for K calculation
+		insertions_after_deletions_,//if true, then insertions after deletions are allowed
+		d_gapped_computation_parameters.d_max_time_for_quick_tests,//maximum allowed calculation time in seconds for quick tests
+		d_gapped_computation_parameters.d_max_time_with_computation_parameters);//maximum allowed time in seconds for the whole computation
+
+
+
+		data_obj.d_max_time=Sls::alp_data::Tmax((1.0-GaplessTimePortion)*data_obj.d_max_time,data_obj.d_max_time-GaplessPreliminaryTime);
+
+		Sls::alp_sim sim_obj(&data_obj);
+
+		if(max_time_>0)
+		{
+			d_gapped_computation_parameters.d_parameters_flag=true;
+			
+			d_gapped_computation_parameters.d_first_stage_preliminary_realizations_numbers_ALP=
+				sim_obj.d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP;
+
+			d_gapped_computation_parameters.d_preliminary_realizations_numbers_ALP=
+				sim_obj.d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP;
+
+			d_gapped_computation_parameters.d_preliminary_realizations_numbers_killing=
+				sim_obj.d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing;
+
+			d_gapped_computation_parameters.d_total_realizations_number_with_ALP=
+				sim_obj.d_alp_data->d_rand_all->d_total_realizations_number_with_ALP;
+
+			d_gapped_computation_parameters.d_total_realizations_number_with_killing=
+				sim_obj.d_alp_data->d_rand_all->d_total_realizations_number_with_killing;
+		};
+
+		sim_obj.m_GaplessAlpha = d_params.gapless_alpha;
+		sim_obj.m_GaplessAlphaError = d_params.gapless_alpha_error;
+
+		sim_obj.m_GaplessA = d_params.gapless_a;
+		sim_obj.m_GaplessAError = d_params.gapless_a_error;
+
+		
+		sim_obj.m_G1=gapOpen1_+gapEpen1_;
+		sim_obj.m_G2=gapOpen2_+gapEpen2_;
+		sim_obj.m_G=alp_data::Tmin(sim_obj.m_G1,sim_obj.m_G2);
+
+		//------------------------------------------------------------------
+
+		d_params.G=sim_obj.m_G;
+		d_params.G1=sim_obj.m_G1;
+		d_params.G2=sim_obj.m_G2;
+
+		d_params.lambda = sim_obj.m_Lambda;
+		d_params.lambda_error = sim_obj.m_LambdaError;
+
+		d_params.K = sim_obj.m_K;
+		d_params.K_error = sim_obj.m_KError;
+			
+		d_params.C = sim_obj.m_C;
+		d_params.C_error = sim_obj.m_CError;
+
+		d_params.sigma = sim_obj.m_Sigma;
+		d_params.sigma_error = sim_obj.m_SigmaError;
+
+		d_params.alpha_I = sim_obj.m_AlphaI;
+		d_params.alpha_I_error = sim_obj.m_AlphaIError;
+
+		d_params.alpha_J = sim_obj.m_AlphaJ;
+		d_params.alpha_J_error = sim_obj.m_AlphaJError;
+
+		d_params.a_I = sim_obj.m_AI;
+		d_params.a_I_error = sim_obj.m_AIError;
+
+		d_params.a_J = sim_obj.m_AJ;
+		d_params.a_J_error = sim_obj.m_AJError;
+
+
+		d_params.m_LambdaSbs=sim_obj.m_LambdaSbs;
+
+		d_params.m_KSbs=sim_obj.m_KSbs;
+
+		d_params.m_CSbs=sim_obj.m_CSbs;
+
+		d_params.m_SigmaSbs=sim_obj.m_SigmaSbs;
+
+		d_params.m_AlphaISbs=sim_obj.m_AlphaISbs;
+
+		d_params.m_AlphaJSbs=sim_obj.m_AlphaJSbs;
+
+		d_params.m_AISbs=sim_obj.m_AISbs;
+
+		d_params.m_AJSbs=sim_obj.m_AJSbs;
+
+
+		d_params.a 
+			= (d_params.a_I + d_params.a_J) * 0.5;
+
+		d_params.a_error = (d_params.a_I_error
+						+ d_params.a_J_error)*0.5;
+		
+		d_params.alpha = (d_params.alpha_I
+						+ d_params.alpha_J) * 0.5;
+
+		d_params.alpha_error = (d_params.alpha_I_error
+						+ d_params.alpha_J_error) * 0.5;
+
+		d_params.d_params_flag=true;
+
+		//precompute intercepts
+		pvalues::compute_intercepts(d_params);
+
+		double CurrentTime2;
+		Sls::alp_data::get_current_time(CurrentTime2);
+		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
+		delete randomization_parameters;randomization_parameters=NULL;
+
+		if(!pvalues::assert_Gumbel_parameters(
+		d_params)||!isGood())
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void AlignmentEvaluer::initGapped\"\n",1);
+		};
+
+		delete[]letterFreqs1_normalized;
+		delete[]letterFreqs2_normalized;
+
+
+	}
+	catch (...)
+	{ 
+		delete randomization_parameters;randomization_parameters=NULL;
+		d_params.d_params_flag=false;
+		throw;
+	};
+}
+
+//Initializes Gumbel parameters using precalculated values:
+void AlignmentEvaluer::initParameters(
+const AlignmentEvaluerParameters &parameters_)
+{
+	try
+	{
+		double CurrentTime1;
+		Sls::alp_data::get_current_time(CurrentTime1);
+
+		d_params.d_params_flag=false;
+
+		double calculation_error=1e-6;
+
+		d_params.lambda=parameters_.d_lambda;
+		d_params.lambda_error=calculation_error;
+
+		d_params.C=0;
+		d_params.C_error=0;
+
+
+		d_params.K=parameters_.d_k;
+		d_params.K_error=calculation_error;
+
+		d_params.a_I=parameters_.d_a2;
+		d_params.a_I_error=calculation_error;
+
+		d_params.a_J=parameters_.d_a1;
+		d_params.a_J_error=calculation_error;
+
+		d_params.sigma=parameters_.d_sigma;
+		d_params.sigma_error=calculation_error;
+
+		d_params.alpha_I=parameters_.d_alpha2;
+		d_params.alpha_I_error=calculation_error;
+
+		d_params.alpha_J=parameters_.d_alpha1;
+		d_params.alpha_J_error=calculation_error;
+
+		d_params.a=0.5*(parameters_.d_a1+parameters_.d_a2);
+		d_params.a_error=calculation_error;
+
+		d_params.alpha=0.5*(parameters_.d_alpha1+parameters_.d_alpha2);
+		d_params.alpha_error=calculation_error;
+
+		d_params.gapless_a=0;
+		d_params.gapless_a_error=0;
+
+		d_params.gapless_alpha=0;
+		d_params.gapless_alpha_error=0;
+
+		d_params.G=0;
+		d_params.G1=0;
+		d_params.G2=0;
+
+		//intercepts
+		d_params.b_I=parameters_.d_b2;
+		d_params.b_I_error=calculation_error;
+
+		d_params.b_J=parameters_.d_b1;
+		d_params.b_J_error=calculation_error;
+
+		d_params.beta_I=parameters_.d_beta2;
+		d_params.beta_I_error=calculation_error;
+
+		d_params.beta_J=parameters_.d_beta1;
+		d_params.beta_J_error=calculation_error;
+
+		d_params.tau=parameters_.d_tau;
+		d_params.tau_error=calculation_error;
+
+
+		//arrays initialization
+		std::vector<double > sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.lambda;
+		sbs_arrays[1]=d_params.lambda + calculation_error;
+
+		d_params.m_LambdaSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.K;
+		sbs_arrays[1]=d_params.K+calculation_error;
+
+		d_params.m_KSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.C;
+		sbs_arrays[1]=d_params.C+calculation_error;
+
+		d_params.m_CSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.sigma;
+		sbs_arrays[1]=d_params.sigma + calculation_error;
+
+		d_params.m_SigmaSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.alpha_I;
+		sbs_arrays[1]=d_params.alpha_I + calculation_error;
+
+		d_params.m_AlphaISbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.alpha_J;
+		sbs_arrays[1]=d_params.alpha_J + calculation_error;
+
+		d_params.m_AlphaJSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.a_I;
+		sbs_arrays[1]=d_params.a_I + calculation_error;
+
+		d_params.m_AISbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.a_J;
+		sbs_arrays[1]=d_params.a_J + calculation_error;
+
+		d_params.m_AJSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.b_J;
+		sbs_arrays[1]=d_params.b_J + calculation_error;
+
+		d_params.m_BJSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.b_I;
+		sbs_arrays[1]=d_params.b_I + calculation_error;
+
+		d_params.m_BISbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.beta_J;
+		sbs_arrays[1]=d_params.beta_J + calculation_error;
+
+		d_params.m_BetaJSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.beta_I;
+		sbs_arrays[1]=d_params.beta_I + calculation_error;
+
+		d_params.m_BetaISbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.tau;
+		sbs_arrays[1]=d_params.tau + calculation_error;
+
+		d_params.m_TauSbs=sbs_arrays;
+
+
+		d_params.d_params_flag=true;//if true, then the parameters are defined and P-values can be calculated
+
+		pvalues::compute_tmp_values(d_params);
+
+		double CurrentTime2;
+		Sls::alp_data::get_current_time(CurrentTime2);
+		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
+
+		if(!pvalues::assert_Gumbel_parameters(
+		d_params)||!isGood())
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void AlignmentEvaluer::initParameters\"\n",1);
+		};
+	}
+	catch (...)
+	{ 
+		d_params.d_params_flag=false;
+		throw;
+	};
+	
+}
+
+void AlignmentEvaluer::initParameters(
+const AlignmentEvaluerParametersWithErrors &parameters_)
+{
+	try
+	{
+		double CurrentTime1;
+		Sls::alp_data::get_current_time(CurrentTime1);
+
+		d_params.d_params_flag=false;
+
+		long int array_dim=20;
+
+		long int seed_tmp=12345;
+		srand(seed_tmp);
+
+
+		d_params.lambda=parameters_.d_lambda;
+		d_params.lambda_error=parameters_.d_lambda_error;
+
+		d_params.C=0;
+		d_params.C_error=0;
+
+
+		d_params.K=parameters_.d_k;
+		d_params.K_error=parameters_.d_k_error;
+
+		d_params.a_I=parameters_.d_a2;
+		d_params.a_I_error=parameters_.d_a2_error;
+
+		d_params.a_J=parameters_.d_a1;
+		d_params.a_J_error=parameters_.d_a1_error;
+
+		d_params.sigma=parameters_.d_sigma;
+		d_params.sigma_error=parameters_.d_sigma_error;
+
+		d_params.alpha_I=parameters_.d_alpha2;
+		d_params.alpha_I_error=parameters_.d_alpha2_error;
+
+		d_params.alpha_J=parameters_.d_alpha1;
+		d_params.alpha_J_error=parameters_.d_alpha1_error;
+
+		d_params.a=0.5*(parameters_.d_a1+parameters_.d_a2);
+		d_params.a_error=0.5*(parameters_.d_a1_error+parameters_.d_a2_error);
+
+		d_params.alpha=0.5*(parameters_.d_alpha1+parameters_.d_alpha2);
+		d_params.alpha_error=0.5*(parameters_.d_alpha1_error+parameters_.d_alpha2_error);
+
+		d_params.gapless_a=0;
+		d_params.gapless_a_error=0;
+
+		d_params.gapless_alpha=0;
+		d_params.gapless_alpha_error=0;
+
+		d_params.G=0;
+		d_params.G1=0;
+		d_params.G2=0;
+
+		d_params.m_CalcTime=0;
+
+
+		//intercepts
+		d_params.b_I=parameters_.d_b2;
+		d_params.b_I_error=parameters_.d_b2_error;
+
+		d_params.b_J=parameters_.d_b1;
+		d_params.b_J_error=parameters_.d_b1_error;
+
+		d_params.beta_I=parameters_.d_beta2;
+		d_params.beta_I_error=parameters_.d_beta2_error;
+
+		d_params.beta_J=parameters_.d_beta1;
+		d_params.beta_J_error=parameters_.d_beta1_error;
+
+		d_params.tau=parameters_.d_tau;
+		d_params.tau_error=parameters_.d_tau_error;
+
+		double sqrt_array_dim=sqrt((double)array_dim);
+
+		d_params.m_LambdaSbs.clear();
+		d_params.m_KSbs.clear();
+		d_params.m_CSbs.clear();
+
+		d_params.m_SigmaSbs.clear();
+
+		d_params.m_AlphaISbs.clear();
+		d_params.m_AlphaJSbs.clear();
+
+		d_params.m_AISbs.clear();
+		d_params.m_AJSbs.clear();
+
+		d_params.m_BISbs.clear();
+		d_params.m_BJSbs.clear();
+
+		d_params.m_BetaISbs.clear();
+		d_params.m_BetaJSbs.clear();
+
+		d_params.m_TauSbs.clear();
+
+		long int i;
+		for(i=0;i<array_dim;i++)
+		{
+			d_params.m_LambdaSbs.push_back(d_params.lambda+d_params.lambda_error*pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_KSbs.push_back(d_params.K+d_params.K_error*pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_CSbs.push_back(0);
+
+			d_params.m_SigmaSbs.push_back(d_params.sigma+d_params.sigma_error*pvalues::standard_normal()*sqrt_array_dim);
+
+			d_params.m_AlphaISbs.push_back(d_params.alpha_I+d_params.alpha_I_error*pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_AlphaJSbs.push_back(d_params.alpha_J+d_params.alpha_J_error*pvalues::standard_normal()*sqrt_array_dim);
+
+			d_params.m_AISbs.push_back(d_params.a_I+d_params.a_I_error*pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_AJSbs.push_back(d_params.a_J+d_params.a_J_error*pvalues::standard_normal()*sqrt_array_dim);
+
+			d_params.m_BISbs.push_back(d_params.b_I+d_params.b_I_error*pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_BJSbs.push_back(d_params.b_J+d_params.b_J_error*pvalues::standard_normal()*sqrt_array_dim);
+
+			d_params.m_BetaISbs.push_back(d_params.beta_I+d_params.beta_I_error*pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_BetaJSbs.push_back(d_params.beta_J+d_params.beta_J_error*pvalues::standard_normal()*sqrt_array_dim);
+
+			d_params.m_TauSbs.push_back(d_params.tau+d_params.tau_error*pvalues::standard_normal()*sqrt_array_dim);
+		};
+
+		d_params.d_params_flag=true;//if true, then the parameters are defined and P-values can be calculated
+
+		pvalues::compute_tmp_values(d_params);
+
+		double CurrentTime2;
+		Sls::alp_data::get_current_time(CurrentTime2);
+		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
+
+		if(!pvalues::assert_Gumbel_parameters(
+		d_params)||!isGood())
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void AlignmentEvaluer::initParameters\"\n",1);
+		};
+	}
+	catch (...)
+	{ 
+		d_params.d_params_flag=false;
+		throw;
+	};
+	
+}
+
+double AlignmentEvaluer::area(double score_,//pairwise alignment score
+double seqlen1_,//length of sequence #1
+double seqlen2_) const//length of sequence #2
+{
+	if(seqlen1_<=0||seqlen2_<=0)
+	{
+		throw error("Error - seqlen1_<=0 or seq2en1_<=0 in \"double AlignmentEvaluer::area\"\n",2);
+	};
+
+	if(!isGood())
+	{
+		throw error("Unexpected error - the Gumbel parameters are not defined properly in \"double AlignmentEvaluer::area\"\n",1);
+	};
+
+	static Sls::pvalues pvalues_obj;
+
+	double P;
+	double E;
+	double area_res;
+	bool area_is_1_flag=false;
+	bool compute_only_area=true;
+
+	pvalues_obj.get_appr_tail_prob_with_cov_without_errors(
+	d_params,
+	pvalues_obj.blast,
+	score_,
+	seqlen2_,
+	seqlen1_,
+
+	P,
+
+	E,
+
+	area_res,
+	pvalues_obj.a_normal,
+	pvalues_obj.b_normal,
+	pvalues_obj.h_normal,
+	pvalues_obj.N_normal,
+	pvalues_obj.p_normal,
+	area_is_1_flag,
+	compute_only_area);
+
+
+	return area_res;
+
+}
+
+void AlignmentEvaluer::calc(double score_,//pairwise alignment score
+double seqlen1_,//length of sequence #1
+double seqlen2_,//length of sequence #2
+double &pvalue_,//resulted P-value
+double &pvalueErr_,//P-value error
+double &evalue_,//resulted E-value
+double &evalueErr_) const//E-value error
+{
+	if(seqlen1_<=0||seqlen2_<=0)
+	{
+		throw error("Error - seqlen1_<=0 or seqlen2_<=0 in \"double AlignmentEvaluer::calc\"\n",2);
+	};
+
+	if(!isGood())
+	{
+		throw error("Unexpected error - the Gumbel parameters are not defined properly in \"double AlignmentEvaluer::calc\"\n",1);
+	};
+
+	static Sls::pvalues pvalues_obj;
+
+	pvalues_obj.calculate_P_values(
+		score_, seqlen2_, seqlen1_,
+		d_params, 
+		pvalue_,
+		pvalueErr_,
+		evalue_,
+		evalueErr_);
+}
+
+void AlignmentEvaluer::calc(double score_,//pairwise alignment score
+double seqlen1_,//length of sequence #1
+double seqlen2_,//length of sequence #2
+double &pvalue_,//resulted P-value
+double &evalue_) const//resulted E-value
+{
+
+	if(seqlen1_<=0||seqlen2_<=0)
+	{
+		throw error("Error - seqlen1_<=0 or seqlen2_<=0 in \"double AlignmentEvaluer::calc\"\n",2);
+	};
+
+	if(!isGood())
+	{
+		throw error("Unexpected error - d_params is not defined in \"double AlignmentEvaluer::calc\"\n",1);
+	};
+
+	static Sls::pvalues pvalues_obj;
+
+
+	bool area_is_1_flag=false;
+
+	double area;
+
+
+	pvalues_obj.get_appr_tail_prob_with_cov_without_errors(
+	d_params,
+	pvalues_obj.blast,
+	score_,
+	seqlen2_,
+	seqlen1_,
+
+	pvalue_,
+
+	evalue_,
+
+	area,
+	pvalues_obj.a_normal,
+	pvalues_obj.b_normal,
+	pvalues_obj.h_normal,
+	pvalues_obj.N_normal,
+	pvalues_obj.p_normal,
+	area_is_1_flag);
+
+	
+
+}
+
+void AlignmentEvaluer::set_gapped_computation_parameters_simplified(
+double max_time_,//maximum allowed time in seconds for the whole computation
+long number_of_samples_,//number of realization for the main stage
+long number_of_samples_for_preliminary_stages_)//number of realization for the preliminary stages
+{
+
+	if(number_of_samples_<=0||number_of_samples_for_preliminary_stages_<=0)
+	{
+		throw error("Error - number_of_samples_<=0 or number_of_samples_for_preliminary_stages_<=0 in \"void AlignmentEvaluer::set_gapped_computation_parameters_simplified\"\n",2);
+	};
+
+	d_gapped_computation_parameters.d_first_stage_preliminary_realizations_numbers_ALP.resize(1);
+	d_gapped_computation_parameters.d_first_stage_preliminary_realizations_numbers_ALP[0]=number_of_samples_for_preliminary_stages_;
+	d_gapped_computation_parameters.d_preliminary_realizations_numbers_ALP.resize(1);
+	d_gapped_computation_parameters.d_preliminary_realizations_numbers_ALP[0]=number_of_samples_for_preliminary_stages_;
+	d_gapped_computation_parameters.d_preliminary_realizations_numbers_killing.resize(1);
+	d_gapped_computation_parameters.d_preliminary_realizations_numbers_killing[0]=number_of_samples_for_preliminary_stages_;
+	d_gapped_computation_parameters.d_total_realizations_number_with_ALP=number_of_samples_;
+	d_gapped_computation_parameters.d_total_realizations_number_with_killing=number_of_samples_;
+	d_gapped_computation_parameters.d_parameters_flag=true;
+	d_gapped_computation_parameters.d_max_time_with_computation_parameters=max_time_;
+	if(max_time_>0)
+	{
+		d_gapped_computation_parameters.d_max_time_for_quick_tests=0.5*max_time_*(double)quick_tests_trials_number/(double)(quick_tests_trials_number+number_of_samples_+number_of_samples_for_preliminary_stages_);
+	}
+	else
+	{
+		d_gapped_computation_parameters.d_max_time_for_quick_tests=-1;
+	};
+}
+
+void AlignmentEvaluer::gapped_computation_parameters_clear()
+{
+	d_gapped_computation_parameters.d_first_stage_preliminary_realizations_numbers_ALP.clear();
+	d_gapped_computation_parameters.d_preliminary_realizations_numbers_ALP.clear();
+	d_gapped_computation_parameters.d_preliminary_realizations_numbers_killing.clear();
+	d_gapped_computation_parameters.d_parameters_flag=false;
+	d_gapped_computation_parameters.d_max_time_for_quick_tests=-1;
+	d_gapped_computation_parameters.d_max_time_with_computation_parameters=-1;
+}
+
+
+}
+
diff --git a/src/alp/sls_alignment_evaluer.hpp b/src/alp/sls_alignment_evaluer.hpp
index dce7b87..4a398ae 100644
--- a/src/alp/sls_alignment_evaluer.hpp
+++ b/src/alp/sls_alignment_evaluer.hpp
@@ -1,210 +1,210 @@
-#ifndef INCLUDED_SLS_ALIGNMENT_EVALUER
-#define INCLUDED_SLS_ALIGNMENT_EVALUER
-
-/* $Id: $
-* ===========================================================================
-*
-*							PUBLIC DOMAIN NOTICE
-*			   National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_alignment_evaluer.hpp
-
-Authors: Martin Frith, Sergey Sheetlin
-
-Contents: library functions of main routines
-
-******************************************************************************/
-
-#include "sls_pvalues.hpp"
-#include <math.h>
-
-namespace Sls {
-
-	class AlignmentEvaluer {
-
-	//Write the parameters:
-	friend std::ostream &operator<<(std::ostream &s_,
-			const AlignmentEvaluer &g_);
-
-	//Read the parameters:
-	friend std::istream &operator>>(std::istream &s_,
-			AlignmentEvaluer &g_);
-
-	public:
-
-	//randomization parameters
-	struct gapped_computation_parameters_struct
-	{
-		gapped_computation_parameters_struct()
-		{
-			d_parameters_flag=false;
-			d_max_time_for_quick_tests=-1;
-			d_max_time_with_computation_parameters=-1;
-		};
-
-		std::vector<long int> d_first_stage_preliminary_realizations_numbers_ALP;
-		std::vector<long int> d_preliminary_realizations_numbers_ALP;
-		std::vector<long int> d_preliminary_realizations_numbers_killing;
-		long int d_total_realizations_number_with_ALP;
-		long int d_total_realizations_number_with_killing;
-		bool d_parameters_flag;//if false then the parameters are not defined
-		double d_max_time_for_quick_tests;//maximum allowed calculation time in seconds for quick tests
-		double d_max_time_with_computation_parameters;//maximum allowed time in seconds for the whole computation
-	};
-
-
-	//Computes gapless Gumbel parameters:
-	void initGapless(long alphabetSize_,//a number of letters in the alphabet
-			const long *const *substitutionScoreMatrix_,//scoring matrix
-			const double *letterFreqs1_,//background frequencies of letters in sequence #1
-			const double *letterFreqs2_,//background frequencies of letters in sequence #2
-			double max_time_=60);//maximum allowed calculation time in seconds
-
-	//Computes gapped Gumbel parameters:
-	//The NCBI convention is used for penalizing a gap:
-	//For example, a gap of length k is penalized as gapOpen1_+k*gapEpen1_ for sequence #1
-	//if max_time_<=0 then d_gapped_computation_parameters will be used;
-	//d_gapped_computation_parameters.d_parameters_flag must be true in this case
-	//every execution of initGapped with max_time_>0 rewrites d_gapped_computation_parameters by the actual values
-	void initGapped(long alphabetSize_,//a number of letters in the alphabet
-			const long *const *substitutionScoreMatrix_,//scoring matrix
-			const double *letterFreqs1_,//background frequencies of letters in sequence #1
-			const double *letterFreqs2_,//background frequencies of letters in sequence #2
-			long gapOpen1_,//gap opening penalty for sequence #1
-			long gapEpen1_,//gap extension penalty for sequence #1
-			long gapOpen2_,//gap opening penalty for sequence #2
-			long gapEpen2_,//gap extension penalty for sequence #2
-			bool insertions_after_deletions_,//if true, then insertions after deletions are permitted
-			double eps_lambda_,//relative error for the parameter lambda
-			double eps_K_,//relative error for the parameter K
-			double max_time_,//maximum allowed calculation time in seconds; 
-			double max_mem_,//maximum allowed memory usage in Mb
-			long randomSeed_);//randomizaton seed
-
-
-	//Initializes Gumbel parameters using precalculated values:
-	void initParameters(
-	const AlignmentEvaluerParameters &parameters_);//parameters_ must be defined by the user
-
-	void initParameters(
-	const AlignmentEvaluerParametersWithErrors &parameters_);//parameters_ must be defined by the user
-
-	//Computes P-values/E-values
-	//Gumbel parameters must be defined via d_params
-	void calc(double score_,//pairwise alignment score
-			double seqlen1_,//length of sequence #1
-			double seqlen2_,//length of sequence #2
-			double &pvalue_,//resulted P-value
-			double &pvalueErr_,//P-value error
-			double &evalue_,//resulted E-value
-			double &evalueErr_) const;//E-value error
-
-	//The following routines compute P-values/E-values and related
-	//quantities quickly, without calculating errors
-
-	//Gumbel parameters must be defined via d_params
-	void calc(double score_,//pairwise alignment score
-		double seqlen1_,//length of sequence #1
-		double seqlen2_,//length of sequence #2
-		double &pvalue_,//resulted P-value
-		double &evalue_) const;//resulted E-value
-
-	double evalue(double score_,//pairwise alignment score
-			double seqlen1_,//length of sequence #1
-			double seqlen2_) const//length of sequence #2
-	{
-		return area(score_, seqlen1_, seqlen2_) * evaluePerArea(score_);
-	}
-
-	//Computes P-values from E-values
-	static double pvalue(double evalue_)
-	{
-		return sls_basic::one_minus_exp_function(-evalue_);
-	}
-
-	//The "area" is approximately seqlen1_*seqlen2_, but it is
-	//modified by a finite size correction
-	double area(double score_,//pairwise alignment score
-			double seqlen1_,//length of sequence #1
-			double seqlen2_) const;//length of sequence #2
-
-	double evaluePerArea(double score_) const
-	{
-	  return d_params.K*exp(-d_params.lambda*score_);
-	}
-
-	double bitScore(double score_) const
-	{
-		return (d_params.lambda*score_-log(d_params.K))/log(2.0);
-	}
-
-	//returns "true" if the set of parameters "d_params" is fully defined for P-value calculation
-	bool isGood() const
-	{
-		return d_params.d_params_flag;
-	}
-
-	//provides access to the set of Gumbel parameters
-	const ALP_set_of_parameters &parameters() const { return d_params; }
-
-	//provides access to the set of randomization parameters
-	const gapped_computation_parameters_struct &gapped_computation_parameters() const { return d_gapped_computation_parameters; }
-
-	//simplified setting of the computation parameters
-	void set_gapped_computation_parameters_simplified(
-		double max_time_=-1.0,//maximum allowed time in seconds for the whole computation
-		long number_of_samples_=1000,//number of realization for the main stage
-		long number_of_samples_for_preliminary_stages_=200);//number of realization for the preliminary stages
-
-	void set_gapped_computation_parameters(
-		const gapped_computation_parameters_struct &gapped_computation_parameters_)
-	{
-		d_gapped_computation_parameters=gapped_computation_parameters_;
-	};
-
-	//clear the computation parameters
-	void gapped_computation_parameters_clear();
-	
-	private:
-	//check correctness of the input parameters for gapless alignment
-	void assert_Gapless_input_parameters(
-		long alphabetSize_,//a number of letters in the alphabet
-		const double *letterFreqs1_,//background frequencies of letters in sequence #1
-		const double *letterFreqs2_,//background frequencies of letters in sequence #2
-		double *&letterFreqs1_normalized_,//normalized background frequencies of letters in sequence #1
-		double *&letterFreqs2_normalized_,//normalized background frequencies of letters in sequence #2
-		const std::string function_name_);//"assert_Gapless_input_parameters" is called from "function_name_" function
-
-	private:
-
-		ALP_set_of_parameters d_params;//set of Gumbel parameters
-
-		//generalized randomization parameters for the gapped computation
-		gapped_computation_parameters_struct d_gapped_computation_parameters;
-
-	};
-}
-
-#endif //! INCLUDED
-
+#ifndef INCLUDED_SLS_ALIGNMENT_EVALUER
+#define INCLUDED_SLS_ALIGNMENT_EVALUER
+
+/* $Id: $
+* ===========================================================================
+*
+*							PUBLIC DOMAIN NOTICE
+*			   National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_alignment_evaluer.hpp
+
+Authors: Martin Frith, Sergey Sheetlin
+
+Contents: library functions of main routines
+
+******************************************************************************/
+
+#include "sls_pvalues.hpp"
+#include <math.h>
+
+namespace Sls {
+
+	class AlignmentEvaluer {
+
+	//Write the parameters:
+	friend std::ostream &operator<<(std::ostream &s_,
+			const AlignmentEvaluer &g_);
+
+	//Read the parameters:
+	friend std::istream &operator>>(std::istream &s_,
+			AlignmentEvaluer &g_);
+
+	public:
+
+	//randomization parameters
+	struct gapped_computation_parameters_struct
+	{
+		gapped_computation_parameters_struct()
+		{
+			d_parameters_flag=false;
+			d_max_time_for_quick_tests=-1;
+			d_max_time_with_computation_parameters=-1;
+		};
+
+		std::vector<long int> d_first_stage_preliminary_realizations_numbers_ALP;
+		std::vector<long int> d_preliminary_realizations_numbers_ALP;
+		std::vector<long int> d_preliminary_realizations_numbers_killing;
+		long int d_total_realizations_number_with_ALP;
+		long int d_total_realizations_number_with_killing;
+		bool d_parameters_flag;//if false then the parameters are not defined
+		double d_max_time_for_quick_tests;//maximum allowed calculation time in seconds for quick tests
+		double d_max_time_with_computation_parameters;//maximum allowed time in seconds for the whole computation
+	};
+
+
+	//Computes gapless Gumbel parameters:
+	void initGapless(long alphabetSize_,//a number of letters in the alphabet
+			const long *const *substitutionScoreMatrix_,//scoring matrix
+			const double *letterFreqs1_,//background frequencies of letters in sequence #1
+			const double *letterFreqs2_,//background frequencies of letters in sequence #2
+			double max_time_=60);//maximum allowed calculation time in seconds
+
+	//Computes gapped Gumbel parameters:
+	//The NCBI convention is used for penalizing a gap:
+	//For example, a gap of length k is penalized as gapOpen1_+k*gapEpen1_ for sequence #1
+	//if max_time_<=0 then d_gapped_computation_parameters will be used;
+	//d_gapped_computation_parameters.d_parameters_flag must be true in this case
+	//every execution of initGapped with max_time_>0 rewrites d_gapped_computation_parameters by the actual values
+	void initGapped(long alphabetSize_,//a number of letters in the alphabet
+			const long *const *substitutionScoreMatrix_,//scoring matrix
+			const double *letterFreqs1_,//background frequencies of letters in sequence #1
+			const double *letterFreqs2_,//background frequencies of letters in sequence #2
+			long gapOpen1_,//gap opening penalty for sequence #1
+			long gapEpen1_,//gap extension penalty for sequence #1
+			long gapOpen2_,//gap opening penalty for sequence #2
+			long gapEpen2_,//gap extension penalty for sequence #2
+			bool insertions_after_deletions_,//if true, then insertions after deletions are permitted
+			double eps_lambda_,//relative error for the parameter lambda
+			double eps_K_,//relative error for the parameter K
+			double max_time_,//maximum allowed calculation time in seconds; 
+			double max_mem_,//maximum allowed memory usage in Mb
+			long randomSeed_);//randomizaton seed
+
+
+	//Initializes Gumbel parameters using precalculated values:
+	void initParameters(
+	const AlignmentEvaluerParameters &parameters_);//parameters_ must be defined by the user
+
+	void initParameters(
+	const AlignmentEvaluerParametersWithErrors &parameters_);//parameters_ must be defined by the user
+
+	//Computes P-values/E-values
+	//Gumbel parameters must be defined via d_params
+	void calc(double score_,//pairwise alignment score
+			double seqlen1_,//length of sequence #1
+			double seqlen2_,//length of sequence #2
+			double &pvalue_,//resulted P-value
+			double &pvalueErr_,//P-value error
+			double &evalue_,//resulted E-value
+			double &evalueErr_) const;//E-value error
+
+	//The following routines compute P-values/E-values and related
+	//quantities quickly, without calculating errors
+
+	//Gumbel parameters must be defined via d_params
+	void calc(double score_,//pairwise alignment score
+		double seqlen1_,//length of sequence #1
+		double seqlen2_,//length of sequence #2
+		double &pvalue_,//resulted P-value
+		double &evalue_) const;//resulted E-value
+
+	double evalue(double score_,//pairwise alignment score
+			double seqlen1_,//length of sequence #1
+			double seqlen2_) const//length of sequence #2
+	{
+		return area(score_, seqlen1_, seqlen2_) * evaluePerArea(score_);
+	}
+
+	//Computes P-values from E-values
+	static double pvalue(double evalue_)
+	{
+		return sls_basic::one_minus_exp_function(-evalue_);
+	}
+
+	//The "area" is approximately seqlen1_*seqlen2_, but it is
+	//modified by a finite size correction
+	double area(double score_,//pairwise alignment score
+			double seqlen1_,//length of sequence #1
+			double seqlen2_) const;//length of sequence #2
+
+	double evaluePerArea(double score_) const
+	{
+	  return d_params.K*exp(-d_params.lambda*score_);
+	}
+
+	double bitScore(double score_) const
+	{
+		return (d_params.lambda*score_-log(d_params.K))/log(2.0);
+	}
+
+	//returns "true" if the set of parameters "d_params" is fully defined for P-value calculation
+	bool isGood() const
+	{
+		return d_params.d_params_flag;
+	}
+
+	//provides access to the set of Gumbel parameters
+	const ALP_set_of_parameters &parameters() const { return d_params; }
+
+	//provides access to the set of randomization parameters
+	const gapped_computation_parameters_struct &gapped_computation_parameters() const { return d_gapped_computation_parameters; }
+
+	//simplified setting of the computation parameters
+	void set_gapped_computation_parameters_simplified(
+		double max_time_=-1.0,//maximum allowed time in seconds for the whole computation
+		long number_of_samples_=1000,//number of realization for the main stage
+		long number_of_samples_for_preliminary_stages_=200);//number of realization for the preliminary stages
+
+	void set_gapped_computation_parameters(
+		const gapped_computation_parameters_struct &gapped_computation_parameters_)
+	{
+		d_gapped_computation_parameters=gapped_computation_parameters_;
+	};
+
+	//clear the computation parameters
+	void gapped_computation_parameters_clear();
+	
+	private:
+	//check correctness of the input parameters for gapless alignment
+	void assert_Gapless_input_parameters(
+		long alphabetSize_,//a number of letters in the alphabet
+		const double *letterFreqs1_,//background frequencies of letters in sequence #1
+		const double *letterFreqs2_,//background frequencies of letters in sequence #2
+		double *&letterFreqs1_normalized_,//normalized background frequencies of letters in sequence #1
+		double *&letterFreqs2_normalized_,//normalized background frequencies of letters in sequence #2
+		const std::string function_name_);//"assert_Gapless_input_parameters" is called from "function_name_" function
+
+	private:
+
+		ALP_set_of_parameters d_params;//set of Gumbel parameters
+
+		//generalized randomization parameters for the gapped computation
+		gapped_computation_parameters_struct d_gapped_computation_parameters;
+
+	};
+}
+
+#endif //! INCLUDED
+
diff --git a/src/alp/sls_alp.cpp b/src/alp/sls_alp.cpp
index 62129a7..84e3a95 100644
--- a/src/alp/sls_alp.cpp
+++ b/src/alp/sls_alp.cpp
@@ -1,2366 +1,2366 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_alp.cpp
-
-Author: Sergey Sheetlin, Martin Frith
-
-Contents: Ascending ladder points simulation
-
-******************************************************************************/
-
-
-#include "sls_alp.hpp"
-
-using namespace Sls;
-
-static long int small_long=(long int)((double)LONG_MIN/2.0);
-
-
-alp::alp(//constructor
-alp_data *alp_data_
-)
-{
-	d_seqi=NULL;
-	d_seqj=NULL;
-
-	d_WS_i_const_pred=NULL;
-	d_WI_i_const_pred=NULL;
-	d_WD_i_const_pred=NULL;
-
-	d_WS_i_const_next=NULL;
-	d_WI_i_const_next=NULL;
-	d_WD_i_const_next=NULL;
-
-	d_WS_j_const_pred=NULL;
-	d_WI_j_const_pred=NULL;
-	d_WD_j_const_pred=NULL;
-
-	d_WS_j_const_next=NULL;
-	d_WI_j_const_next=NULL;
-	d_WD_j_const_next=NULL;
-
-
-	//alignment matrix 
-	d_HS_i_const_pred=NULL;
-	d_HI_i_const_pred=NULL;
-	d_HD_i_const_pred=NULL;
-	d_H_i_const_pred=NULL;
-
-	d_HS_i_const_next=NULL;
-	d_HI_i_const_next=NULL;
-	d_HD_i_const_next=NULL;
-	d_H_i_const_next=NULL;
-
-	d_HS_j_const_pred=NULL;
-	d_HI_j_const_pred=NULL;
-	d_HD_j_const_pred=NULL;
-	d_H_j_const_pred=NULL;
-
-	d_HS_j_const_next=NULL;
-	d_HI_j_const_next=NULL;
-	d_HD_j_const_next=NULL;
-	d_H_j_const_next=NULL;
-
-	d_H_edge_max=NULL;
-	d_H_I=NULL;
-	d_H_J=NULL;
-
-	d_alp=NULL;
-	d_alp_pos=NULL;
-	d_cells_counts=NULL;
-	d_alp_weights=NULL;
-	d_alp_states=NULL;
-
-	d_success=true;
-
-	d_check_time_flag=false;
-	d_time_error_flag=false;
-	d_time_limit_flag=false;
-	d_single_realiztion_calculation_flag=false;
-
-	d_alp_data=alp_data_;
-	if(!d_alp_data)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-	d_a_step=30;
-
-	try
-	{
-
-		d_is_now=true;
-		d_seqi_len=0;
-		d_seqj_len=0;
-		d_seq_a_len=0;
-		d_H_matr_a_len=0;
-		d_W_matr_a_len=0;
-		d_H_matr_len=-1;
-		d_W_matr_len=-1;
-		d_nalp=-1;
-
-		d_H_edge_max=new long int[1];
-		alp_data::assert_mem(d_H_edge_max);
-		d_H_edge_max[0]=0;
-
-		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(long int))/mb_bytes;
-
-
-		d_alp=new array_positive<long int>(d_alp_data);
-		alp_data::assert_mem(d_alp);
-
-		d_H_I=new array_positive<long int>(d_alp_data);
-		alp_data::assert_mem(d_H_I);
-
-		d_H_J=new array_positive<long int>(d_alp_data);
-		alp_data::assert_mem(d_H_J);
-
-
-		d_alp_pos=new array_positive<long int>(d_alp_data);
-		alp_data::assert_mem(d_alp_pos);
-
-		d_alp_data->d_memory_size_in_MB+=4*(double)(sizeof(array_positive<long int>))/mb_bytes;
-
-		d_alp_states=new array_positive<state*>(d_alp_data);
-		alp_data::assert_mem(d_alp_states);
-
-		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(array_positive<state*>))/mb_bytes;
-
-
-		d_alp_weights=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(d_alp_weights);
-
-		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(array_positive<double>))/mb_bytes;
-
-
-		d_cells_counts=new array<long int>(d_alp_data);
-		alp_data::assert_mem(d_cells_counts);
-
-		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(array<long int>))/mb_bytes;
-
-
-		increment_W_weights();
-		increment_H_weights_with_sentinels(0);
-	}
-	catch (...)
-	{
-		this->~alp();
-		throw;
-	};
-
-}
-
-alp::~alp()//destructor
-{
-
-	release_and_calculate_memory(d_seqi,d_seq_a_len);
-	release_and_calculate_memory(d_seqj,d_seq_a_len);
-
-
-
-	release_and_calculate_memory(d_WS_i_const_pred,d_W_matr_a_len);
-
-	release_and_calculate_memory(d_WI_i_const_pred,d_W_matr_a_len);
-
-	release_and_calculate_memory(d_WD_i_const_pred,d_W_matr_a_len);
-
-
-	release_and_calculate_memory(d_WS_i_const_next,d_W_matr_a_len);
-
-	release_and_calculate_memory(d_WI_i_const_next,d_W_matr_a_len);
-
-	release_and_calculate_memory(d_WD_i_const_next,d_W_matr_a_len);
-
-
-
-	release_and_calculate_memory(d_WS_j_const_pred,d_W_matr_a_len);
-
-	release_and_calculate_memory(d_WI_j_const_pred,d_W_matr_a_len);
-
-	release_and_calculate_memory(d_WD_j_const_pred,d_W_matr_a_len);
-
-
-	release_and_calculate_memory(d_WS_j_const_next,d_W_matr_a_len);
-
-	release_and_calculate_memory(d_WI_j_const_next,d_W_matr_a_len);
-
-	release_and_calculate_memory(d_WD_j_const_next,d_W_matr_a_len);
-
-
-
-	release_and_calculate_memory(d_HS_i_const_pred,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_HI_i_const_pred,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_HD_i_const_pred,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_H_i_const_pred,d_H_matr_a_len);
-
-
-	release_and_calculate_memory(d_HS_i_const_next,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_HI_i_const_next,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_HD_i_const_next,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_H_i_const_next,d_H_matr_a_len);
-
-
-	release_and_calculate_memory(d_HS_j_const_pred,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_HI_j_const_pred,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_HD_j_const_pred,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_H_j_const_pred,d_H_matr_a_len);
-
-
-	release_and_calculate_memory(d_HS_j_const_next,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_HI_j_const_next,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_HD_j_const_next,d_H_matr_a_len);
-
-	release_and_calculate_memory(d_H_j_const_next,d_H_matr_a_len);
-
-
-	release_and_calculate_memory(d_H_edge_max,d_H_matr_a_len+1);
-
-
-
-	
-	release_and_calculate_memory(d_alp);
-
-	release_and_calculate_memory(d_H_I);
-
-	release_and_calculate_memory(d_H_J);
-
-	release_and_calculate_memory(d_alp_pos);
-
-
-
-
-
-	long int i;
-
-	if(d_alp_states)
-	{
-		for(i=0;i<=d_nalp;i++)
-		{
-			if(i<=d_alp_states->d_dim)
-			{
-				if(d_alp_states->d_elem[i])
-				{
-
-					for(i=0;i<=d_nalp;i++)
-					{
-
-
-						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HS_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-
-						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HI_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-
-						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HD_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-
-						release_and_calculate_memory(d_alp_states->d_elem[i]->d_H_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-
-
-						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HS_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-
-						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HI_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-
-						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HD_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-
-						release_and_calculate_memory(d_alp_states->d_elem[i]->d_H_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-
-
-
-
-
-						release_and_calculate_memory(d_alp_states->d_elem[i]->d_cells_counts);
-
-						release_and_calculate_memory(d_alp_states->d_elem[i]);
-
-						
-					};
-				};
-			};
-		};
-	};
-
-	
-	release_and_calculate_memory(d_alp_states);
-
-	release_and_calculate_memory(d_alp_weights);
-
-	
-	release_and_calculate_memory(d_cells_counts);
-
-
-}
-
-void alp::partially_release_memory()
-{
-
-	
-	release_and_calculate_memory(d_seqi,d_seq_a_len);
-	release_and_calculate_memory(d_seqj,d_seq_a_len);
-
-
-	release_and_calculate_memory(d_WS_i_const_pred,d_W_matr_a_len);
-	release_and_calculate_memory(d_WI_i_const_pred,d_W_matr_a_len);
-	release_and_calculate_memory(d_WD_i_const_pred,d_W_matr_a_len);
-
-	release_and_calculate_memory(d_WS_i_const_next,d_W_matr_a_len);
-	release_and_calculate_memory(d_WI_i_const_next,d_W_matr_a_len);
-	release_and_calculate_memory(d_WD_i_const_next,d_W_matr_a_len);
-
-
-	release_and_calculate_memory(d_WS_j_const_pred,d_W_matr_a_len);
-	release_and_calculate_memory(d_WI_j_const_pred,d_W_matr_a_len);
-	release_and_calculate_memory(d_WD_j_const_pred,d_W_matr_a_len);
-
-
-	release_and_calculate_memory(d_WS_j_const_next,d_W_matr_a_len);
-	release_and_calculate_memory(d_WI_j_const_next,d_W_matr_a_len);
-	release_and_calculate_memory(d_WD_j_const_next,d_W_matr_a_len);
-
-
-
-	release_and_calculate_memory(d_HS_i_const_pred,d_H_matr_a_len);
-	release_and_calculate_memory(d_HI_i_const_pred,d_H_matr_a_len);
-	release_and_calculate_memory(d_HD_i_const_pred,d_H_matr_a_len);
-	release_and_calculate_memory(d_H_i_const_pred,d_H_matr_a_len);
-
-
-	release_and_calculate_memory(d_HS_i_const_next,d_H_matr_a_len);
-	release_and_calculate_memory(d_HI_i_const_next,d_H_matr_a_len);
-	release_and_calculate_memory(d_HD_i_const_next,d_H_matr_a_len);
-	release_and_calculate_memory(d_H_i_const_next,d_H_matr_a_len);
-
-
-
-	release_and_calculate_memory(d_HS_j_const_pred,d_H_matr_a_len);
-	release_and_calculate_memory(d_HI_j_const_pred,d_H_matr_a_len);
-	release_and_calculate_memory(d_HD_j_const_pred,d_H_matr_a_len);
-	release_and_calculate_memory(d_H_j_const_pred,d_H_matr_a_len);
-
-
-	release_and_calculate_memory(d_HS_j_const_next,d_H_matr_a_len);
-	release_and_calculate_memory(d_HI_j_const_next,d_H_matr_a_len);
-	release_and_calculate_memory(d_HD_j_const_next,d_H_matr_a_len);
-	release_and_calculate_memory(d_H_j_const_next,d_H_matr_a_len);
-
-
-
-	release_and_calculate_memory(d_H_edge_max,d_H_matr_a_len+1);
-
-
-	
-
-	long int i;
-
-	if(d_alp_states)
-	{
-		for(i=0;i<=d_nalp;i++)
-		{
-			if(i<=d_alp_states->d_dim)
-			{
-				if(d_alp_states->d_elem[i])
-				{
-
-					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HS_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HI_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HD_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-					release_and_calculate_memory(d_alp_states->d_elem[i]->d_H_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-
-					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HS_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HI_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HD_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-					release_and_calculate_memory(d_alp_states->d_elem[i]->d_H_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
-
-
-
-					release_and_calculate_memory(d_alp_states->d_elem[i]->d_cells_counts);
-				};
-			};
-
-			
-		};
-	};
-
-}
-
-
-long int alp::random_AA1()
-{
-	return d_alp_data->random_long(
-		d_alp_data->ran2(),
-		d_alp_data->d_number_of_AA,
-		d_alp_data->d_RR1_sum,
-		d_alp_data->d_RR1_sum_elements);
-}
-
-long int alp::random_AA2()
-{
-	return d_alp_data->random_long(
-		d_alp_data->ran2(),
-		d_alp_data->d_number_of_AA,
-		d_alp_data->d_RR2_sum,
-		d_alp_data->d_RR2_sum_elements);
-}
-
-bool alp::one_step_of_importance_sampling_without_weight_calculation(
-	long int d_dim1_,
-	long int d_dim2_)
-{
-	char &state_=d_IS_state;
-
-	alp_data *&las_object_=d_alp_data;
-
-	importance_sampling *&d_is_=d_alp_data->d_is;
-	long int &length1_=d_seqi_len;
-	long int &length2_=d_seqj_len;
-
-	long int *&d_seqi_rglobal_=d_seqi;
-	long int *&d_seqj_rglobal_=d_seqj;
-
-
-	bool res=true;
-
-	if(length1_==0&&length2_==0)
-	{
-		state_=alp_data::random_long(
-			las_object_->ran2(),
-			3,
-			d_is_->d_for_S,
-			d_is_->d_for_S_states);
-	};
-
-
-	if(state_=='D')
-	{
-		if(length1_==d_dim1_)
-		{
-			res=false;
-			return res;
-		};
-
-		if(length1_>d_seq_a_len-1)
-		{
-			increment_sequences();
-		};
-
-		d_seqi_rglobal_[length1_]=random_AA1();
-		length1_++;
-
-		state_=alp_data::random_long(
-			las_object_->ran2(),
-			3,
-			d_is_->d_for_D,
-			d_is_->d_for_D_states);
-		goto weight_calculation;
-	};
-
-	if(state_=='I')
-	{
-		if(length2_==d_dim2_)
-		{
-			res=false;
-			return res;
-		};
-
-		if(length2_>d_seq_a_len-1)
-		{
-			increment_sequences();
-		};
-
-
-		d_seqj_rglobal_[length2_]=random_AA2();
-		length2_++;
-
-		state_=alp_data::random_long(
-			las_object_->ran2(),
-			2,
-			d_is_->d_for_I,
-			d_is_->d_for_I_states);
-		goto weight_calculation;
-	};
-
-	if(state_=='S')
-	{
-		if(length1_==d_dim1_||length2_==d_dim2_)
-		{
-			res=false;
-			return res;
-		};
-		q_elem pair=alp_data::random_long(
-			las_object_->ran2(),
-			d_is_->d_is_number_of_AA*d_is_->d_is_number_of_AA,
-			d_is_->d_elements_values,
-			d_is_->d_elements);
-
-		if(length1_>d_seq_a_len-1||length2_>d_seq_a_len-1)
-		{
-			increment_sequences();
-		};
-
-		d_seqi_rglobal_[length1_]=pair.d_a;
-		d_seqj_rglobal_[length2_]=pair.d_b;
-
-		
-
-		length1_++;
-		length2_++;
-
-		state_=alp_data::random_long(
-			las_object_->ran2(),
-			3,
-			d_is_->d_for_S,
-			d_is_->d_for_S_states);
-		goto weight_calculation;
-	};
-
-weight_calculation:
-//----deleted-------
-return res;
-
-}
-
-void alp::increment_sequences()
-{
-	long int *d_seqi_new=NULL;
-	long int *d_seqj_new=NULL;
-
-	try
-	{
-
-		d_seq_a_len+=d_a_step;
-
-		d_seqi_new=new long int[d_seq_a_len];
-		alp_data::assert_mem(d_seqi_new);
-
-		d_seqj_new=new long int[d_seq_a_len];
-		alp_data::assert_mem(d_seqj_new);
-
-		long int i;
-		for(i=0;i<d_seqi_len;i++)
-		{
-			d_seqi_new[i]=d_seqi[i];
-		};
-
-		for(i=0;i<d_seqj_len;i++)
-		{
-			d_seqj_new[i]=d_seqj[i];
-		};
-
-		
-		delete[]d_seqi;d_seqi=NULL;
-		delete[]d_seqj;d_seqj=NULL;
-
-
-		d_seqi=d_seqi_new;
-		d_seqj=d_seqj_new;
-
-		d_seqi_new=NULL;
-		d_seqj_new=NULL;
-
-		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(long int)*d_a_step*2)/mb_bytes;
-
-	}
-	catch (...)
-	{ 
-		delete[]d_seqi_new;d_seqi_new=NULL;
-		delete[]d_seqj_new;d_seqj_new=NULL;
-		throw;
-	};
-
-}
-
-void alp::increment_W_matrix()
-{
-	double *d_WS_i_const_pred_new=NULL;
-	double *d_WI_i_const_pred_new=NULL;
-	double *d_WD_i_const_pred_new=NULL;
-
-	double *d_WS_i_const_next_new=NULL;
-	double *d_WI_i_const_next_new=NULL;
-	double *d_WD_i_const_next_new=NULL;
-
-	double *d_WS_j_const_pred_new=NULL;
-	double *d_WI_j_const_pred_new=NULL;
-	double *d_WD_j_const_pred_new=NULL;
-
-	double *d_WS_j_const_next_new=NULL;
-	double *d_WI_j_const_next_new=NULL;
-	double *d_WD_j_const_next_new=NULL;
-
-	try
-	{
-
-		d_W_matr_a_len+=d_a_step;
-
-		//the importance sampling weights
-		d_WS_i_const_pred_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WS_i_const_pred_new);
-		d_WI_i_const_pred_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WI_i_const_pred_new);
-		d_WD_i_const_pred_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WD_i_const_pred_new);
-
-		d_WS_i_const_next_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WS_i_const_next_new);
-		d_WI_i_const_next_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WI_i_const_next_new);
-		d_WD_i_const_next_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WD_i_const_next_new);
-
-		d_WS_j_const_pred_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WS_j_const_pred_new);
-		d_WI_j_const_pred_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WI_j_const_pred_new);
-		d_WD_j_const_pred_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WD_j_const_pred_new);
-
-		d_WS_j_const_next_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WS_j_const_next_new);
-		d_WI_j_const_next_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WI_j_const_next_new);
-		d_WD_j_const_next_new=new double[d_W_matr_a_len];
-		alp_data::assert_mem(d_WD_j_const_next_new);
-
-
-
-		long int i;
-		for(i=0;i<d_W_matr_len;i++)
-		{
-			d_WS_i_const_next_new[i]=d_WS_i_const_next[i];
-			d_WI_i_const_next_new[i]=d_WI_i_const_next[i];
-			d_WD_i_const_next_new[i]=d_WD_i_const_next[i];
-
-			d_WS_j_const_next_new[i]=d_WS_j_const_next[i];
-			d_WI_j_const_next_new[i]=d_WI_j_const_next[i];
-			d_WD_j_const_next_new[i]=d_WD_j_const_next[i];
-
-		};
-
-		
-
-		for(i=0;i<d_W_matr_len-1;i++)
-		{
-			d_WS_i_const_pred_new[i]=d_WS_i_const_pred[i];
-			d_WI_i_const_pred_new[i]=d_WI_i_const_pred[i];
-			d_WD_i_const_pred_new[i]=d_WD_i_const_pred[i];
-
-			d_WS_j_const_pred_new[i]=d_WS_j_const_pred[i];
-			d_WI_j_const_pred_new[i]=d_WI_j_const_pred[i];
-			d_WD_j_const_pred_new[i]=d_WD_j_const_pred[i];
-
-		};
-
-
-		delete[]d_WS_i_const_pred;d_WS_i_const_pred=NULL;
-		delete[]d_WI_i_const_pred;d_WI_i_const_pred=NULL;
-		delete[]d_WD_i_const_pred;d_WD_i_const_pred=NULL;
-
-		delete[]d_WS_i_const_next;d_WS_i_const_next=NULL;
-		delete[]d_WI_i_const_next;d_WI_i_const_next=NULL;
-		delete[]d_WD_i_const_next;d_WD_i_const_next=NULL;
-
-		delete[]d_WS_j_const_pred;d_WS_j_const_pred=NULL;
-		delete[]d_WI_j_const_pred;d_WI_j_const_pred=NULL;
-		delete[]d_WD_j_const_pred;d_WD_j_const_pred=NULL;
-
-		delete[]d_WS_j_const_next;d_WS_j_const_next=NULL;
-		delete[]d_WI_j_const_next;d_WI_j_const_next=NULL;
-		delete[]d_WD_j_const_next;d_WD_j_const_next=NULL;
-
-		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(double)*d_a_step*12)/mb_bytes;
-
-
-		d_WS_i_const_pred=d_WS_i_const_pred_new;d_WS_i_const_pred_new=NULL;
-		d_WI_i_const_pred=d_WI_i_const_pred_new;d_WI_i_const_pred_new=NULL;
-		d_WD_i_const_pred=d_WD_i_const_pred_new;d_WD_i_const_pred_new=NULL;
-
-		d_WS_i_const_next=d_WS_i_const_next_new;d_WS_i_const_next_new=NULL;
-		d_WI_i_const_next=d_WI_i_const_next_new;d_WI_i_const_next_new=NULL;
-		d_WD_i_const_next=d_WD_i_const_next_new;d_WD_i_const_next_new=NULL;
-
-		d_WS_j_const_pred=d_WS_j_const_pred_new;d_WS_j_const_pred_new=NULL;
-		d_WI_j_const_pred=d_WI_j_const_pred_new;d_WI_j_const_pred_new=NULL;
-		d_WD_j_const_pred=d_WD_j_const_pred_new;d_WD_j_const_pred_new=NULL;
-
-
-		d_WS_j_const_next=d_WS_j_const_next_new;d_WS_j_const_next_new=NULL;
-		d_WI_j_const_next=d_WI_j_const_next_new;d_WI_j_const_next_new=NULL;
-		d_WD_j_const_next=d_WD_j_const_next_new;d_WD_j_const_next_new=NULL;
-
-		
-
-	}
-	catch (...)
-	{ 
-		delete[]d_WS_i_const_pred_new;d_WS_i_const_pred_new=NULL;
-		delete[]d_WI_i_const_pred_new;d_WI_i_const_pred_new=NULL;
-		delete[]d_WD_i_const_pred_new;d_WD_i_const_pred_new=NULL;
-
-		delete[]d_WS_i_const_next_new;d_WS_i_const_next_new=NULL;
-		delete[]d_WI_i_const_next_new;d_WI_i_const_next_new=NULL;
-		delete[]d_WD_i_const_next_new;d_WD_i_const_next_new=NULL;
-
-		delete[]d_WS_j_const_pred_new;d_WS_j_const_pred_new=NULL;
-		delete[]d_WI_j_const_pred_new;d_WI_j_const_pred_new=NULL;
-		delete[]d_WD_j_const_pred_new;d_WD_j_const_pred_new=NULL;
-
-		delete[]d_WS_j_const_next_new;d_WS_j_const_next_new=NULL;
-		delete[]d_WI_j_const_next_new;d_WI_j_const_next_new=NULL;
-		delete[]d_WD_j_const_next_new;d_WD_j_const_next_new=NULL;
-		throw;
-	};
-
-}
-
-void alp::increment_H_matrix()
-{
-
-	long int *d_HS_i_const_pred_new=NULL;
-	long int *d_HI_i_const_pred_new=NULL;
-	long int *d_HD_i_const_pred_new=NULL;
-	long int *d_H_i_const_pred_new=NULL;
-
-	long int *d_HS_i_const_next_new=NULL;
-	long int *d_HI_i_const_next_new=NULL;
-	long int *d_HD_i_const_next_new=NULL;
-	long int *d_H_i_const_next_new=NULL;
-
-	long int *d_HS_j_const_pred_new=NULL;
-	long int *d_HI_j_const_pred_new=NULL;
-	long int *d_HD_j_const_pred_new=NULL;
-	long int *d_H_j_const_pred_new=NULL;
-
-	long int *d_HS_j_const_next_new=NULL;
-	long int *d_HI_j_const_next_new=NULL;
-	long int *d_HD_j_const_next_new=NULL;
-	long int *d_H_j_const_next_new=NULL;
-
-	long int *d_H_edge_max_new=NULL;
-
-	try
-	{
-
-		d_H_matr_a_len+=d_a_step;
-
-
-		//alignment matrix 
-		d_HS_i_const_pred_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HS_i_const_pred_new);
-		d_HI_i_const_pred_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HI_i_const_pred_new);
-		d_HD_i_const_pred_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HD_i_const_pred_new);
-		d_H_i_const_pred_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_H_i_const_pred_new);
-
-		d_HS_i_const_next_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HS_i_const_next_new);
-		d_HI_i_const_next_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HI_i_const_next_new);
-		d_HD_i_const_next_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HD_i_const_next_new);
-		d_H_i_const_next_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_H_i_const_next_new);
-
-		d_HS_j_const_pred_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HS_j_const_pred_new);
-		d_HI_j_const_pred_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HI_j_const_pred_new);
-		d_HD_j_const_pred_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HD_j_const_pred_new);
-		d_H_j_const_pred_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_H_j_const_pred_new);
-
-		d_HS_j_const_next_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HS_j_const_next_new);
-		d_HI_j_const_next_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HI_j_const_next_new);
-		d_HD_j_const_next_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_HD_j_const_next_new);
-		d_H_j_const_next_new=new long int[d_H_matr_a_len];
-		alp_data::assert_mem(d_H_j_const_next_new);
-
-
-		d_H_edge_max_new=new long int[d_H_matr_a_len+1];
-		alp_data::assert_mem(d_H_edge_max_new);
-
-
-		long int i;
-		for(i=0;i<d_H_matr_len;i++)
-		{
-			d_HS_i_const_next_new[i]=d_HS_i_const_next[i];
-			d_HI_i_const_next_new[i]=d_HI_i_const_next[i];
-			d_HD_i_const_next_new[i]=d_HD_i_const_next[i];
-			d_H_i_const_next_new[i]=d_H_i_const_next[i];
-
-			d_HS_j_const_next_new[i]=d_HS_j_const_next[i];
-			d_HI_j_const_next_new[i]=d_HI_j_const_next[i];
-			d_HD_j_const_next_new[i]=d_HD_j_const_next[i];
-			d_H_j_const_next_new[i]=d_H_j_const_next[i];
-		};
-
-		for(i=0;i<d_H_matr_len-1;i++)
-		{
-			d_HS_i_const_pred_new[i]=d_HS_i_const_pred[i];
-			d_HI_i_const_pred_new[i]=d_HI_i_const_pred[i];
-			d_HD_i_const_pred_new[i]=d_HD_i_const_pred[i];
-			d_H_i_const_pred_new[i]=d_H_i_const_pred[i];
-
-			d_HS_j_const_pred_new[i]=d_HS_j_const_pred[i];
-			d_HI_j_const_pred_new[i]=d_HI_j_const_pred[i];
-			d_HD_j_const_pred_new[i]=d_HD_j_const_pred[i];
-			d_H_j_const_pred_new[i]=d_H_j_const_pred[i];
-		};
-
-
-		for(i=0;i<=d_H_matr_len;i++)
-		{
-			d_H_edge_max_new[i]=d_H_edge_max[i];
-		};
-
-		
-
-		delete[]d_HS_i_const_pred;d_HS_i_const_pred=NULL;
-		delete[]d_HI_i_const_pred;d_HI_i_const_pred=NULL;
-		delete[]d_HD_i_const_pred;d_HD_i_const_pred=NULL;
-		delete[]d_H_i_const_pred;d_H_i_const_pred=NULL;
-
-		delete[]d_HS_i_const_next;d_HS_i_const_next=NULL;
-		delete[]d_HI_i_const_next;d_HI_i_const_next=NULL;
-		delete[]d_HD_i_const_next;d_HD_i_const_next=NULL;
-		delete[]d_H_i_const_next;d_H_i_const_next=NULL;
-
-		delete[]d_HS_j_const_pred;d_HS_j_const_pred=NULL;
-		delete[]d_HI_j_const_pred;d_HI_j_const_pred=NULL;
-		delete[]d_HD_j_const_pred;d_HD_j_const_pred=NULL;
-		delete[]d_H_j_const_pred;d_H_j_const_pred=NULL;
-
-		delete[]d_HS_j_const_next;d_HS_j_const_next=NULL;
-		delete[]d_HI_j_const_next;d_HI_j_const_next=NULL;
-		delete[]d_HD_j_const_next;d_HD_j_const_next=NULL;
-		delete[]d_H_j_const_next;d_H_j_const_next=NULL;
-
-		delete[]d_H_edge_max;d_H_edge_max=NULL;
-
-		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(long int)*d_a_step*17)/mb_bytes;
-
-		d_HS_i_const_pred=d_HS_i_const_pred_new;d_HS_i_const_pred_new=NULL;
-		d_HI_i_const_pred=d_HI_i_const_pred_new;d_HI_i_const_pred_new=NULL;
-		d_HD_i_const_pred=d_HD_i_const_pred_new;d_HD_i_const_pred_new=NULL;
-		d_H_i_const_pred=d_H_i_const_pred_new;d_H_i_const_pred_new=NULL;
-
-		d_HS_i_const_next=d_HS_i_const_next_new;d_HS_i_const_next_new=NULL;
-		d_HI_i_const_next=d_HI_i_const_next_new;d_HI_i_const_next_new=NULL;
-		d_HD_i_const_next=d_HD_i_const_next_new;d_HD_i_const_next_new=NULL;
-		d_H_i_const_next=d_H_i_const_next_new;d_H_i_const_next_new=NULL;
-
-		d_HS_j_const_pred=d_HS_j_const_pred_new;d_HS_j_const_pred_new=NULL;
-		d_HI_j_const_pred=d_HI_j_const_pred_new;d_HI_j_const_pred_new=NULL;
-		d_HD_j_const_pred=d_HD_j_const_pred_new;d_HD_j_const_pred_new=NULL;
-		d_H_j_const_pred=d_H_j_const_pred_new;d_H_j_const_pred_new=NULL;
-
-		d_HS_j_const_next=d_HS_j_const_next_new;d_HS_j_const_next_new=NULL;
-		d_HI_j_const_next=d_HI_j_const_next_new;d_HI_j_const_next_new=NULL;
-		d_HD_j_const_next=d_HD_j_const_next_new;d_HD_j_const_next_new=NULL;
-		d_H_j_const_next=d_H_j_const_next_new;d_H_j_const_next_new=NULL;
-
-		d_H_edge_max=d_H_edge_max_new;d_H_edge_max_new=NULL;
-
-		
-	}
-	catch (...)
-	{ 
-		delete[]d_HS_i_const_pred_new;d_HS_i_const_pred_new=NULL;
-		delete[]d_HI_i_const_pred_new;d_HI_i_const_pred_new=NULL;
-		delete[]d_HD_i_const_pred_new;d_HD_i_const_pred_new=NULL;
-		delete[]d_H_i_const_pred_new;d_H_i_const_pred_new=NULL;
-
-		delete[]d_HS_i_const_next_new;d_HS_i_const_next_new=NULL;
-		delete[]d_HI_i_const_next_new;d_HI_i_const_next_new=NULL;
-		delete[]d_HD_i_const_next_new;d_HD_i_const_next_new=NULL;
-		delete[]d_H_i_const_next_new;d_H_i_const_next_new=NULL;
-
-		delete[]d_HS_j_const_pred_new;d_HS_j_const_pred_new=NULL;
-		delete[]d_HI_j_const_pred_new;d_HI_j_const_pred_new=NULL;
-		delete[]d_HD_j_const_pred_new;d_HD_j_const_pred_new=NULL;
-		delete[]d_H_j_const_pred_new;d_H_j_const_pred_new=NULL;
-
-		delete[]d_HS_j_const_next_new;d_HS_j_const_next_new=NULL;
-		delete[]d_HI_j_const_next_new;d_HI_j_const_next_new=NULL;
-		delete[]d_HD_j_const_next_new;d_HD_j_const_next_new=NULL;
-		delete[]d_H_j_const_next_new;d_H_j_const_next_new=NULL;
-
-		delete[]d_H_edge_max_new;d_H_edge_max_new=NULL;
-		throw;
-	};
-
-
-}
-
-void alp::increment_W_weights()
-//the function calculates weigths for d_W_matr_len increased by 1
-//assumes that letters are defined for d_W_matr_len
-{
-	if(d_W_matr_len==-1)
-	{
-		d_WS_ij_next=1.0;
-		d_WI_ij_next=0.0;
-		d_WD_ij_next=0.0;
-
-		d_W_matr_len++;
-
-		d_alp_weights->set_elem(0,1.0);
-
-		return;
-	};
-
-	if(d_seqi_len<d_W_matr_len+1||d_seqj_len<d_W_matr_len+1)
-	{
-		throw error("Unexpected error in increment_W_weights\n",4);
-	};
-
-	if(d_W_matr_len+1>d_W_matr_a_len)
-	{
-		increment_W_matrix();
-	};
-
-	d_W_matr_len++;
-	
-
-	swap(d_WS_i_const_pred,d_WS_i_const_next);
-	swap(d_WI_i_const_pred,d_WI_i_const_next);
-	swap(d_WD_i_const_pred,d_WD_i_const_next);
-
-	swap(d_WS_j_const_pred,d_WS_j_const_next);
-	swap(d_WI_j_const_pred,d_WI_j_const_next);
-	swap(d_WD_j_const_pred,d_WD_j_const_next);
-
-	d_WS_ij_pred=d_WS_ij_next;
-	d_WI_ij_pred=d_WI_ij_next;
-	d_WD_ij_pred=d_WD_ij_next;
-
-	long int d_W_matr_len_1=d_W_matr_len-1;
-	long int d_W_matr_len_2=d_W_matr_len-2;
-
-	//boundary conditions
-	importance_sampling *&d_is_tmp=d_alp_data->d_is;
-
-	d_WS_i_const_next[d_W_matr_len_1]=0;
-	d_WS_j_const_next[d_W_matr_len_1]=0;
-
-	d_WI_i_const_next[d_W_matr_len_1]=0;
-	d_WD_j_const_next[d_W_matr_len_1]=0;
-
-	double deg_tmp=degree(d_is_tmp->d_nu,d_W_matr_len_1);
-
-	d_WD_i_const_next[d_W_matr_len_1]=d_is_tmp->d_mu_DS*deg_tmp;
-	d_WI_j_const_next[d_W_matr_len_1]=d_is_tmp->d_mu_IS*deg_tmp;
-
-
-
-	long int i;
-	for(i=d_W_matr_len_2;i>=1;i--)
-	{
-		d_WS_i_const_next[i]=d_is_tmp->d_exp_s[d_seqi[d_W_matr_len_1]][d_seqj[d_W_matr_len_2-i]]*(d_is_tmp->d_eta*d_WS_i_const_pred[i]+d_is_tmp->d_mu_SI*d_WI_i_const_pred[i]+d_is_tmp->d_mu_SD*d_WD_i_const_pred[i]);
-		d_WI_i_const_next[i]=d_is_tmp->d_mu_IS*d_WS_i_const_next[i+1]+d_is_tmp->d_nu*d_WI_i_const_next[i+1]+d_is_tmp->d_mu_ID*d_WD_i_const_next[i+1];
-		d_WD_i_const_next[i]=d_is_tmp->d_mu_DS*d_WS_i_const_pred[i-1]+d_is_tmp->d_nu*d_WD_i_const_pred[i-1];
-
-		d_WS_j_const_next[i]=d_is_tmp->d_exp_s[d_seqi[d_W_matr_len_2-i]][d_seqj[d_W_matr_len_1]]*(d_is_tmp->d_eta*d_WS_j_const_pred[i]+d_is_tmp->d_mu_SI*d_WI_j_const_pred[i]+d_is_tmp->d_mu_SD*d_WD_j_const_pred[i]);
-		d_WI_j_const_next[i]=d_is_tmp->d_mu_IS*d_WS_j_const_pred[i-1]+d_is_tmp->d_nu*d_WI_j_const_pred[i-1]+d_is_tmp->d_mu_ID*d_WD_j_const_pred[i-1];
-		d_WD_j_const_next[i]=d_is_tmp->d_mu_DS*d_WS_j_const_next[i+1]+d_is_tmp->d_nu*d_WD_j_const_next[i+1];
-	};
-
-	if(d_W_matr_len>1)
-	{
-		//copy of the previous lines with a modification for i-1
-		i=0;
-		d_WS_i_const_next[i]=d_is_tmp->d_exp_s[d_seqi[d_W_matr_len_1]][d_seqj[d_W_matr_len_2-i]]*(d_is_tmp->d_eta*d_WS_i_const_pred[i]+d_is_tmp->d_mu_SI*d_WI_i_const_pred[i]+d_is_tmp->d_mu_SD*d_WD_i_const_pred[i]);
-		d_WI_i_const_next[i]=d_is_tmp->d_mu_IS*d_WS_i_const_next[i+1]+d_is_tmp->d_nu*d_WI_i_const_next[i+1]+d_is_tmp->d_mu_ID*d_WD_i_const_next[i+1];
-		d_WD_i_const_next[i]=d_is_tmp->d_mu_DS*d_WS_ij_pred+d_is_tmp->d_nu*d_WD_ij_pred;
-
-		d_WS_j_const_next[i]=d_is_tmp->d_exp_s[d_seqi[d_W_matr_len_2-i]][d_seqj[d_W_matr_len_1]]*(d_is_tmp->d_eta*d_WS_j_const_pred[i]+d_is_tmp->d_mu_SI*d_WI_j_const_pred[i]+d_is_tmp->d_mu_SD*d_WD_j_const_pred[i]);
-		d_WI_j_const_next[i]=d_is_tmp->d_mu_IS*d_WS_ij_pred+d_is_tmp->d_nu*d_WI_ij_pred+d_is_tmp->d_mu_ID*d_WD_ij_pred;
-		d_WD_j_const_next[i]=d_is_tmp->d_mu_DS*d_WS_j_const_next[i+1]+d_is_tmp->d_nu*d_WD_j_const_next[i+1];
-	};
-
-
-	d_WS_ij_next=d_is_tmp->d_exp_s[d_seqi[d_W_matr_len_1]][d_seqj[d_W_matr_len_1]]*(d_is_tmp->d_eta*d_WS_ij_pred+d_is_tmp->d_mu_SI*d_WI_ij_pred+d_is_tmp->d_mu_SD*d_WD_ij_pred);
-	d_WI_ij_next=d_is_tmp->d_mu_IS*d_WS_i_const_next[0]+d_is_tmp->d_nu*d_WI_i_const_next[0]+d_is_tmp->d_mu_ID*d_WD_i_const_next[0];
-	d_WD_ij_next=d_is_tmp->d_mu_DS*d_WS_j_const_next[0]+d_is_tmp->d_nu*d_WD_j_const_next[0];
-
-	
-
-}
-
-double alp::degree(//returns x_^n_
-double x_,
-double n_)
-{
-	if(x_<0||n_<0)
-	{
-		throw error("Error - unexpected parameter in alp::degree\n",4);
-	};
-
-	if(x_==0)
-	{
-		if(n_==0)
-		{
-			return 1.0;
-		}
-		else
-		{
-			return 0.0;
-		};
-	};
-
-	return exp(n_*log(x_));
-
-}
-
-void alp::increment_H_weights()
-{
-	if(d_alp_data->d_insertions_after_deletions)
-	{
-		increment_H_weights_with_insertions_after_deletions();
-	}
-	else
-	{
-		increment_H_weights_without_insertions_after_deletions();
-	};
-}
-
-void alp::increment_H_weights_without_insertions_after_deletions()
-//the function calculates alignment scores for d_H_matr_len increased by 1
-//assumes that letters are defined for d_H_matr_len
-{
-	if(d_H_matr_len==-1)
-	{
-		d_HS_ij_next=0;
-		d_HI_ij_next=0;
-		d_HD_ij_next=0;
-		d_H_ij_next=0;
-		d_M=0;
-
-		d_nalp=0;
-		d_alp->set_elem(0,0);
-		d_H_I->set_elem(0,0);
-		d_H_J->set_elem(0,0);
-		d_alp_pos->set_elem(0,0);
-
-		d_cells_counts->increase_elem_by_1(0);
-
-		d_H_matr_len++;
-
-		d_alp_states->set_elem(d_nalp,NULL);
-		save_state(d_alp_states->d_elem[d_nalp]);
-
-		return;
-	};
-
-	if(d_seqi_len<d_H_matr_len+1||d_seqj_len<d_H_matr_len+1)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-	if(d_H_matr_len+1>d_H_matr_a_len)
-	{
-		increment_H_matrix();
-	};
-
-	d_H_matr_len++;
-	
-
-	swap(d_HS_i_const_pred,d_HS_i_const_next);
-	swap(d_HI_i_const_pred,d_HI_i_const_next);
-	swap(d_HD_i_const_pred,d_HD_i_const_next);
-	swap(d_H_i_const_pred,d_H_i_const_next);
-
-	swap(d_HS_j_const_pred,d_HS_j_const_next);
-	swap(d_HI_j_const_pred,d_HI_j_const_next);
-	swap(d_HD_j_const_pred,d_HD_j_const_next);
-	swap(d_H_j_const_pred,d_H_j_const_next);
-
-	d_HS_ij_pred=d_HS_ij_next;
-	d_HI_ij_pred=d_HI_ij_next;
-	d_HD_ij_pred=d_HD_ij_next;
-	d_H_ij_pred=d_H_ij_next;
-
-	long int d_H_matr_len_1=d_H_matr_len-1;
-	long int d_H_matr_len_2=d_H_matr_len-2;
-
-	//boundary conditions
-	//long int gap_tmp=-d_alp_data->d_open-d_H_matr_len_1*d_alp_data->d_epen;
-		long int gap_tmp1=-d_alp_data->d_open1-d_H_matr_len_1*d_alp_data->d_epen1;
-		long int gap_tmp2=-d_alp_data->d_open2-d_H_matr_len_1*d_alp_data->d_epen2;
-
-
-	d_HS_i_const_next[d_H_matr_len_1]=small_long;
-	d_HS_j_const_next[d_H_matr_len_1]=small_long;
-
-	d_HI_i_const_next[d_H_matr_len_1]=small_long;
-	d_HD_j_const_next[d_H_matr_len_1]=small_long;
-
-
-	d_HD_i_const_next[d_H_matr_len_1]=gap_tmp1;
-	d_HI_j_const_next[d_H_matr_len_1]=gap_tmp2;
-
-	d_H_i_const_next[d_H_matr_len_1]=gap_tmp1;
-	d_H_j_const_next[d_H_matr_len_1]=gap_tmp2;
-
-	long int i;
-	for(i=d_H_matr_len_2;i>=1;i--)
-	{
-		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
-		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2);
-		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_i_const_pred[i-1]-d_alp_data->d_open1,d_HD_i_const_pred[i-1]-d_alp_data->d_epen1);
-		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
-	
-
-		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
-		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_j_const_pred[i-1]-d_alp_data->d_open2,d_HI_j_const_pred[i-1]-d_alp_data->d_epen2);
-		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
-		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
-	};
-
-	if(d_H_matr_len>1)
-	{
-		//copy of the previous lines with a modification for i-1
-		i=0;
-		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
-		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2);
-		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open1,d_HD_ij_pred-d_alp_data->d_epen1);
-		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
-	
-
-		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
-		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open2,d_HI_ij_pred-d_alp_data->d_epen2);
-		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
-		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
-	};
-
-	d_HS_ij_next=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_1]]+d_H_ij_pred;
-	d_HI_ij_next=alp_data::Tmax(d_HS_i_const_next[0]-d_alp_data->d_open2,d_HI_i_const_next[0]-d_alp_data->d_epen2);
-	d_HD_ij_next=alp_data::Tmax(d_HS_j_const_next[0]-d_alp_data->d_open1,d_HD_j_const_next[0]-d_alp_data->d_epen1);
-	d_H_ij_next=alp_data::Tmax(d_HS_ij_next,d_HI_ij_next,d_HD_ij_next);
-
-	d_cells_counts->increase_elem_by_1(d_H_ij_next);
-	for(i=0;i<=d_H_matr_len_1;i++)
-	{
-		d_cells_counts->increase_elem_by_1(d_H_i_const_next[i]);
-		d_cells_counts->increase_elem_by_1(d_H_j_const_next[i]);
-	};
-
-
-	long int tmp=d_H_ij_next;
-	for(i=0;i<=d_H_matr_len_1;i++)
-	{
-		tmp=alp_data::Tmax(tmp,d_H_i_const_next[i]);
-		tmp=alp_data::Tmax(tmp,d_H_j_const_next[i]);
-	};
-
-	d_H_edge_max[d_H_matr_len]=tmp;
-	d_M=alp_data::Tmax(tmp,d_M);
-
-	d_sentinel_i_next=d_H_matr_len_1;
-	d_sentinel_j_next=d_H_matr_len_1;
-
-
-	if(d_is_now)
-	{
-		long int i;
-		if(tmp>d_alp->d_elem[d_nalp])
-		{
-			d_nalp++;
-			d_alp->set_elem(d_nalp,tmp);
-			d_alp_pos->set_elem(d_nalp,d_H_matr_len);
-
-			d_alp_states->set_elem(d_nalp,NULL);
-			save_state(d_alp_states->d_elem[d_nalp]);
-
-		
-			long int I=-1;
-			long int J=-1;
-
-			for(i=0;i<=d_H_matr_len_1;i++)
-			{
-				if(tmp==d_H_i_const_next[i])
-				{
-					I=i;
-				};
-
-				if(tmp==d_H_j_const_next[i])
-				{
-					J=i;
-				};
-			};
-
-			d_H_I->set_elem(d_nalp,d_H_matr_len-I-1);
-			d_H_J->set_elem(d_nalp,d_H_matr_len-J-1);
-
-
-		};
-	};
-
-
-	check_time_function();
-
-
-}
-
-
-void alp::increment_H_weights_with_insertions_after_deletions()
-//the function calculates alignment scores for d_H_matr_len increased by 1
-//assumes that letters are defined for d_H_matr_len
-{
-	if(d_H_matr_len==-1)
-	{
-		d_HS_ij_next=0;
-		d_HI_ij_next=0;
-		d_HD_ij_next=0;
-		d_H_ij_next=0;
-		d_M=0;
-
-		d_nalp=0;
-		d_alp->set_elem(0,0);
-		d_H_I->set_elem(0,0);
-		d_H_J->set_elem(0,0);
-		d_alp_pos->set_elem(0,0);
-
-		d_cells_counts->increase_elem_by_1(0);
-
-		d_H_matr_len++;
-
-		d_alp_states->set_elem(d_nalp,NULL);
-		save_state(d_alp_states->d_elem[d_nalp]);
-
-		return;
-	};
-
-	if(d_seqi_len<d_H_matr_len+1||d_seqj_len<d_H_matr_len+1)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-	if(d_H_matr_len+1>d_H_matr_a_len)
-	{
-		increment_H_matrix();
-	};
-
-	d_H_matr_len++;
-	
-
-	swap(d_HS_i_const_pred,d_HS_i_const_next);
-	swap(d_HI_i_const_pred,d_HI_i_const_next);
-	swap(d_HD_i_const_pred,d_HD_i_const_next);
-	swap(d_H_i_const_pred,d_H_i_const_next);
-
-	swap(d_HS_j_const_pred,d_HS_j_const_next);
-	swap(d_HI_j_const_pred,d_HI_j_const_next);
-	swap(d_HD_j_const_pred,d_HD_j_const_next);
-	swap(d_H_j_const_pred,d_H_j_const_next);
-
-	d_HS_ij_pred=d_HS_ij_next;
-	d_HI_ij_pred=d_HI_ij_next;
-	d_HD_ij_pred=d_HD_ij_next;
-	d_H_ij_pred=d_H_ij_next;
-
-	long int d_H_matr_len_1=d_H_matr_len-1;
-	long int d_H_matr_len_2=d_H_matr_len-2;
-
-	//boundary conditions
-	//long int gap_tmp=-d_alp_data->d_open-d_H_matr_len_1*d_alp_data->d_epen;
-	long int gap_tmp1=-d_alp_data->d_open1-d_H_matr_len_1*d_alp_data->d_epen1;
-	long int gap_tmp2=-d_alp_data->d_open2-d_H_matr_len_1*d_alp_data->d_epen2;
-
-
-	d_HS_i_const_next[d_H_matr_len_1]=small_long;
-	d_HS_j_const_next[d_H_matr_len_1]=small_long;
-
-	d_HI_i_const_next[d_H_matr_len_1]=small_long;
-	d_HD_j_const_next[d_H_matr_len_1]=small_long;
-
-
-	d_HD_i_const_next[d_H_matr_len_1]=gap_tmp1;
-	d_HI_j_const_next[d_H_matr_len_1]=gap_tmp2;
-
-	d_H_i_const_next[d_H_matr_len_1]=gap_tmp1;
-	d_H_j_const_next[d_H_matr_len_1]=gap_tmp2;
-
-	long int i;
-	for(i=d_H_matr_len_2;i>=1;i--)
-	{
-		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
-		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2,d_HD_i_const_next[i+1]-d_alp_data->d_open2);
-		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_i_const_pred[i-1]-d_alp_data->d_open1,d_HD_i_const_pred[i-1]-d_alp_data->d_epen1);
-		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
-
-
-		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
-		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_j_const_pred[i-1]-d_alp_data->d_open2,d_HI_j_const_pred[i-1]-d_alp_data->d_epen2,d_HD_j_const_pred[i-1]-d_alp_data->d_open2);
-		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
-		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
-
-
-	};
-
-	if(d_H_matr_len>1)
-	{
-		//copy of the previous lines with a modification for i-1
-		i=0;
-		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
-		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2,d_HD_i_const_next[i+1]-d_alp_data->d_open2);
-		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open1,d_HD_ij_pred-d_alp_data->d_epen1);
-		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
-	
-
-
-		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
-		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open2,d_HI_ij_pred-d_alp_data->d_epen2,d_HD_ij_pred-d_alp_data->d_open2);
-		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
-		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
-
-
-	};
-
-	d_HS_ij_next=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_1]]+d_H_ij_pred;
-	d_HI_ij_next=alp_data::Tmax(d_HS_i_const_next[0]-d_alp_data->d_open2,d_HI_i_const_next[0]-d_alp_data->d_epen2,d_HD_i_const_next[0]-d_alp_data->d_open2);
-	d_HD_ij_next=alp_data::Tmax(d_HS_j_const_next[0]-d_alp_data->d_open1,d_HD_j_const_next[0]-d_alp_data->d_epen1);
-	d_H_ij_next=alp_data::Tmax(d_HS_ij_next,d_HI_ij_next,d_HD_ij_next);
-
-
-
-	d_cells_counts->increase_elem_by_1(d_H_ij_next);
-	for(i=0;i<=d_H_matr_len_1;i++)
-	{
-		d_cells_counts->increase_elem_by_1(d_H_i_const_next[i]);
-		d_cells_counts->increase_elem_by_1(d_H_j_const_next[i]);
-	};
-
-
-	long int tmp=d_H_ij_next;
-	for(i=0;i<=d_H_matr_len_1;i++)
-	{
-		tmp=alp_data::Tmax(tmp,d_H_i_const_next[i]);
-		tmp=alp_data::Tmax(tmp,d_H_j_const_next[i]);
-	};
-
-	d_H_edge_max[d_H_matr_len]=tmp;
-	d_M=alp_data::Tmax(tmp,d_M);
-
-	d_sentinel_i_next=d_H_matr_len_1;
-	d_sentinel_j_next=d_H_matr_len_1;
-
-
-	if(d_is_now)
-	{
-		long int i;
-		if(tmp>d_alp->d_elem[d_nalp])
-		{
-			d_nalp++;
-			d_alp->set_elem(d_nalp,tmp);
-			d_alp_pos->set_elem(d_nalp,d_H_matr_len);
-
-			d_alp_states->set_elem(d_nalp,NULL);
-			save_state(d_alp_states->d_elem[d_nalp]);
-
-		
-			long int I=-1;
-			long int J=-1;
-
-			for(i=0;i<=d_H_matr_len_1;i++)
-			{
-				if(tmp==d_H_i_const_next[i])
-				{
-					I=i;
-				};
-
-				if(tmp==d_H_j_const_next[i])
-				{
-					J=i;
-				};
-			};
-
-			d_H_I->set_elem(d_nalp,d_H_matr_len-I-1);
-			d_H_J->set_elem(d_nalp,d_H_matr_len-J-1);
-
-
-		};
-	};
-
-
-	check_time_function();
-
-
-}
-
-void alp::check_time_function()
-{
-	if(d_check_time_flag)
-	{
-		double time_after3;
-		alp_data::get_current_time(time_after3);
-
-		if((time_after3-d_alp_data->d_time_before1)>d_alp_data->d_max_time)
-		{
-			if(d_time_error_flag)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			}
-			else
-			{
-				d_time_limit_flag=true;
-				if(d_single_realiztion_calculation_flag)
-				{
-					throw error_for_single_realization();
-				};
-				return;
-			};
-		};
-
-	};
-
-	if(d_alp_data->d_max_time<=0&&d_alp_data->d_max_time_with_computation_parameters>0)
-	{
-		double time_after3;
-		alp_data::get_current_time(time_after3);
-
-		if((time_after3-d_alp_data->d_time_before1)>d_alp_data->d_max_time_with_computation_parameters)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-	};
-}
-
-void alp::increment_H_weights_with_sentinels(
-	long int diff_opt_)
-//the function calculates alignment scores for d_H_matr_len increased by 1
-//assumes that letters are defined for d_H_matr_len
-//uses sentinels
-{
-	if(d_alp_data->d_insertions_after_deletions)
-	{
-		increment_H_weights_with_sentinels_with_insertions_after_deletions(diff_opt_);
-	}
-	else
-	{
-		increment_H_weights_with_sentinels_without_insertions_after_deletions(diff_opt_);
-	};
-
-}
-
-void alp::increment_H_weights_with_sentinels_without_insertions_after_deletions(
-	long int diff_opt_)
-//the function calculates alignment scores for d_H_matr_len increased by 1
-//assumes that letters are defined for d_H_matr_len
-//uses sentinels
-{
-	if(d_H_matr_len==-1)
-	{
-		d_HS_ij_next=0;
-		d_HI_ij_next=0;
-		d_HD_ij_next=0;
-		d_H_ij_next=0;
-		d_M=0;
-
-		d_nalp=0;
-		d_alp->set_elem(0,0);
-		d_H_I->set_elem(0,0);
-		d_H_J->set_elem(0,0);
-		d_alp_pos->set_elem(0,0);
-
-		d_cells_counts->increase_elem_by_1(0);
-
-		d_H_matr_len++;
-
-		d_alp_states->set_elem(d_nalp,NULL);
-		
-
-		d_sentinel_i_next=0;
-		d_sentinel_j_next=0;
-
-
-		save_state(d_alp_states->d_elem[d_nalp]);
-
-		
-
-		return;
-	};
-
-	if(d_seqi_len<d_H_matr_len+1||d_seqj_len<d_H_matr_len+1)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-
-	if(d_H_matr_len+1>d_H_matr_a_len)
-	{
-		increment_H_matrix();
-	};
-
-	d_H_matr_len++;
-	
-
-	swap(d_HS_i_const_pred,d_HS_i_const_next);
-	swap(d_HI_i_const_pred,d_HI_i_const_next);
-	swap(d_HD_i_const_pred,d_HD_i_const_next);
-	swap(d_H_i_const_pred,d_H_i_const_next);
-
-	swap(d_HS_j_const_pred,d_HS_j_const_next);
-	swap(d_HI_j_const_pred,d_HI_j_const_next);
-	swap(d_HD_j_const_pred,d_HD_j_const_next);
-	swap(d_H_j_const_pred,d_H_j_const_next);
-
-	
-
-	d_HS_ij_pred=d_HS_ij_next;
-	d_HI_ij_pred=d_HI_ij_next;
-	d_HD_ij_pred=d_HD_ij_next;
-	d_H_ij_pred=d_H_ij_next;
-
-	d_sentinel_i_pred=d_sentinel_i_next;
-	d_sentinel_j_pred=d_sentinel_j_next;
-
-
-	long int d_H_matr_len_1=d_H_matr_len-1;
-	long int d_H_matr_len_2=d_H_matr_len-2;
-
-	//boundary conditions
-	long int sentinel_i_boundary=alp_data::Tmin(d_sentinel_i_pred+(long int)2,d_H_matr_len_1);
-	long int sentinel_j_boundary=alp_data::Tmin(d_sentinel_j_pred+(long int)2,d_H_matr_len_1);
-
-
-
-	d_HS_i_const_next[sentinel_i_boundary]=small_long;
-	d_HS_j_const_next[sentinel_j_boundary]=small_long;
-
-	d_HI_i_const_next[sentinel_i_boundary]=small_long;
-	d_HD_j_const_next[sentinel_j_boundary]=small_long;
-
-
-	d_HD_i_const_next[sentinel_i_boundary]=small_long;
-	d_HI_j_const_next[sentinel_j_boundary]=small_long;
-
-	d_H_i_const_next[sentinel_i_boundary]=small_long;
-	d_H_j_const_next[sentinel_j_boundary]=small_long;
-
-	long int i;
-	for(i=sentinel_i_boundary-1;i>=1;i--)
-	{
-		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
-		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2);
-		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_i_const_pred[i-1]-d_alp_data->d_open1,d_HD_i_const_pred[i-1]-d_alp_data->d_epen1);
-		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
-	};
-
-	for(i=sentinel_j_boundary-1;i>=1;i--)
-	{
-		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
-		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_j_const_pred[i-1]-d_alp_data->d_open2,d_HI_j_const_pred[i-1]-d_alp_data->d_epen2);
-		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
-		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
-	};
-
-
-	if(d_H_matr_len>1)
-	{
-		//copy of the previous lines with a modification for i-1
-		i=0;
-		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
-		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2);
-		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open1,d_HD_ij_pred-d_alp_data->d_epen1);
-		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
-	
-
-		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
-		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open2,d_HI_ij_pred-d_alp_data->d_epen2);
-		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
-		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
-	};
-
-	d_HS_ij_next=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_1]]+d_H_ij_pred;
-	d_HI_ij_next=alp_data::Tmax(d_HS_i_const_next[0]-d_alp_data->d_open2,d_HI_i_const_next[0]-d_alp_data->d_epen2);
-	d_HD_ij_next=alp_data::Tmax(d_HS_j_const_next[0]-d_alp_data->d_open1,d_HD_j_const_next[0]-d_alp_data->d_epen1);
-	d_H_ij_next=alp_data::Tmax(d_HS_ij_next,d_HI_ij_next,d_HD_ij_next);
-
-	d_cells_counts->increase_elem_by_1(d_H_ij_next);
-	for(i=0;i<=sentinel_i_boundary-1;i++)
-	{
-		d_cells_counts->increase_elem_by_1(d_H_i_const_next[i]);
-	};
-
-	for(i=0;i<=sentinel_j_boundary-1;i++)
-	{
-		d_cells_counts->increase_elem_by_1(d_H_j_const_next[i]);
-	};
-
-	long int tmp=d_H_ij_next;
-	for(i=0;i<=sentinel_i_boundary-1;i++)
-	{
-		tmp=alp_data::Tmax(tmp,d_H_i_const_next[i]);
-	};
-
-	for(i=0;i<=sentinel_j_boundary-1;i++)
-	{
-		tmp=alp_data::Tmax(tmp,d_H_j_const_next[i]);
-	};
-
-
-	d_H_edge_max[d_H_matr_len]=tmp;
-	d_M=alp_data::Tmax(tmp,d_M);
-
-
-	{
-		long int level=tmp-diff_opt_;
-		long int i;
-		d_sentinel_i_next=1;
-		d_sentinel_j_next=1;
-		for(i=sentinel_i_boundary-1;i>=1;i--)
-		{
-			if(d_H_i_const_next[i]>=level)
-			{
-				d_sentinel_i_next=i;
-				break;
-			};
-		};
-
-		for(i=sentinel_j_boundary-1;i>=1;i--)
-		{
-			if(d_H_j_const_next[i]>=level)
-			{
-				d_sentinel_j_next=i;
-				break;
-			};
-		};
-	};
-
-
-	if(d_is_now)
-	{
-		long int i;
-		if(tmp>d_alp->d_elem[d_nalp])
-		{
-			d_nalp++;
-			d_alp->set_elem(d_nalp,tmp);
-			d_alp_pos->set_elem(d_nalp,d_H_matr_len);
-
-			d_alp_states->set_elem(d_nalp,NULL);
-			save_state(d_alp_states->d_elem[d_nalp]);
-
-		
-			long int I=-1;
-			long int J=-1;
-
-			for(i=0;i<=sentinel_i_boundary-1;i++)
-			{
-				if(tmp==d_H_i_const_next[i])
-				{
-					I=i;
-				};
-			};
-
-			for(i=0;i<=sentinel_j_boundary-1;i++)
-			{
-				if(tmp==d_H_j_const_next[i])
-				{
-					J=i;
-				};
-			};
-
-
-
-			d_H_I->set_elem(d_nalp,d_H_matr_len-I-1);
-			d_H_J->set_elem(d_nalp,d_H_matr_len-J-1);
-
-
-		};
-	};
-
-	check_time_function();
-
-}
-
-
-
-void alp::increment_H_weights_with_sentinels_with_insertions_after_deletions(
-	long int diff_opt_)
-//the function calculates alignment scores for d_H_matr_len increased by 1
-//assumes that letters are defined for d_H_matr_len
-//uses sentinels
-{
-	if(d_H_matr_len==-1)
-	{
-		d_HS_ij_next=0;
-		d_HI_ij_next=0;
-		d_HD_ij_next=0;
-		d_H_ij_next=0;
-		d_M=0;
-
-		d_nalp=0;
-		d_alp->set_elem(0,0);
-		d_H_I->set_elem(0,0);
-		d_H_J->set_elem(0,0);
-		d_alp_pos->set_elem(0,0);
-
-		d_cells_counts->increase_elem_by_1(0);
-
-		d_H_matr_len++;
-
-		d_alp_states->set_elem(d_nalp,NULL);
-		
-
-		d_sentinel_i_next=0;
-		d_sentinel_j_next=0;
-
-
-		save_state(d_alp_states->d_elem[d_nalp]);
-
-		
-
-		return;
-	};
-
-	if(d_seqi_len<d_H_matr_len+1||d_seqj_len<d_H_matr_len+1)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-
-	if(d_H_matr_len+1>d_H_matr_a_len)
-	{
-		increment_H_matrix();
-	};
-
-	d_H_matr_len++;
-	
-
-	swap(d_HS_i_const_pred,d_HS_i_const_next);
-	swap(d_HI_i_const_pred,d_HI_i_const_next);
-	swap(d_HD_i_const_pred,d_HD_i_const_next);
-	swap(d_H_i_const_pred,d_H_i_const_next);
-
-	swap(d_HS_j_const_pred,d_HS_j_const_next);
-	swap(d_HI_j_const_pred,d_HI_j_const_next);
-	swap(d_HD_j_const_pred,d_HD_j_const_next);
-	swap(d_H_j_const_pred,d_H_j_const_next);
-
-	
-
-	d_HS_ij_pred=d_HS_ij_next;
-	d_HI_ij_pred=d_HI_ij_next;
-	d_HD_ij_pred=d_HD_ij_next;
-	d_H_ij_pred=d_H_ij_next;
-
-	d_sentinel_i_pred=d_sentinel_i_next;
-	d_sentinel_j_pred=d_sentinel_j_next;
-
-
-	long int d_H_matr_len_1=d_H_matr_len-1;
-	long int d_H_matr_len_2=d_H_matr_len-2;
-
-	//boundary conditions
-	long int sentinel_i_boundary=alp_data::Tmin(d_sentinel_i_pred+(long int)2,d_H_matr_len_1);
-	long int sentinel_j_boundary=alp_data::Tmin(d_sentinel_j_pred+(long int)2,d_H_matr_len_1);
-
-
-
-	d_HS_i_const_next[sentinel_i_boundary]=small_long;
-	d_HS_j_const_next[sentinel_j_boundary]=small_long;
-
-	d_HI_i_const_next[sentinel_i_boundary]=small_long;
-	d_HD_j_const_next[sentinel_j_boundary]=small_long;
-
-
-	d_HD_i_const_next[sentinel_i_boundary]=small_long;
-	d_HI_j_const_next[sentinel_j_boundary]=small_long;
-
-	d_H_i_const_next[sentinel_i_boundary]=small_long;
-	d_H_j_const_next[sentinel_j_boundary]=small_long;
-
-	long int i;
-	for(i=sentinel_i_boundary-1;i>=1;i--)
-	{
-		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
-		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2,d_HD_i_const_next[i+1]-d_alp_data->d_open2);
-		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_i_const_pred[i-1]-d_alp_data->d_open1,d_HD_i_const_pred[i-1]-d_alp_data->d_epen1);
-		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
-	};
-
-	for(i=sentinel_j_boundary-1;i>=1;i--)
-	{
-		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
-		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_j_const_pred[i-1]-d_alp_data->d_open2,d_HI_j_const_pred[i-1]-d_alp_data->d_epen2,d_HD_j_const_pred[i-1]-d_alp_data->d_open2);
-		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
-		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
-	};
-
-
-	if(d_H_matr_len>1)
-	{
-		//copy of the previous lines with a modification for i-1
-		i=0;
-		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
-		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2,d_HD_i_const_next[i+1]-d_alp_data->d_open2);
-		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open1,d_HD_ij_pred-d_alp_data->d_epen1);
-		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
-	
-
-		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
-		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open2,d_HI_ij_pred-d_alp_data->d_epen2,d_HD_ij_pred-d_alp_data->d_open2);
-		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
-		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
-	};
-
-	d_HS_ij_next=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_1]]+d_H_ij_pred;
-	d_HI_ij_next=alp_data::Tmax(d_HS_i_const_next[0]-d_alp_data->d_open2,d_HI_i_const_next[0]-d_alp_data->d_epen2,d_HD_i_const_next[0]-d_alp_data->d_open2);
-	d_HD_ij_next=alp_data::Tmax(d_HS_j_const_next[0]-d_alp_data->d_open1,d_HD_j_const_next[0]-d_alp_data->d_epen1);
-	d_H_ij_next=alp_data::Tmax(d_HS_ij_next,d_HI_ij_next,d_HD_ij_next);
-
-	d_cells_counts->increase_elem_by_1(d_H_ij_next);
-	for(i=0;i<=sentinel_i_boundary-1;i++)
-	{
-		d_cells_counts->increase_elem_by_1(d_H_i_const_next[i]);
-	};
-
-	for(i=0;i<=sentinel_j_boundary-1;i++)
-	{
-		d_cells_counts->increase_elem_by_1(d_H_j_const_next[i]);
-	};
-
-	long int tmp=d_H_ij_next;
-	for(i=0;i<=sentinel_i_boundary-1;i++)
-	{
-		tmp=alp_data::Tmax(tmp,d_H_i_const_next[i]);
-	};
-
-	for(i=0;i<=sentinel_j_boundary-1;i++)
-	{
-		tmp=alp_data::Tmax(tmp,d_H_j_const_next[i]);
-	};
-
-
-	d_H_edge_max[d_H_matr_len]=tmp;
-	d_M=alp_data::Tmax(tmp,d_M);
-
-
-	{
-		long int level=tmp-diff_opt_;
-		long int i;
-		d_sentinel_i_next=1;
-		d_sentinel_j_next=1;
-		for(i=sentinel_i_boundary-1;i>=1;i--)
-		{
-			if(d_H_i_const_next[i]>=level)
-			{
-				d_sentinel_i_next=i;
-				break;
-			};
-		};
-
-		for(i=sentinel_j_boundary-1;i>=1;i--)
-		{
-			if(d_H_j_const_next[i]>=level)
-			{
-				d_sentinel_j_next=i;
-				break;
-			};
-		};
-	};
-
-
-	if(d_is_now)
-	{
-		long int i;
-		if(tmp>d_alp->d_elem[d_nalp])
-		{
-			d_nalp++;
-			d_alp->set_elem(d_nalp,tmp);
-			d_alp_pos->set_elem(d_nalp,d_H_matr_len);
-
-			d_alp_states->set_elem(d_nalp,NULL);
-			save_state(d_alp_states->d_elem[d_nalp]);
-
-		
-			long int I=-1;
-			long int J=-1;
-
-			for(i=0;i<=sentinel_i_boundary-1;i++)
-			{
-				if(tmp==d_H_i_const_next[i])
-				{
-					I=i;
-				};
-			};
-
-			for(i=0;i<=sentinel_j_boundary-1;i++)
-			{
-				if(tmp==d_H_j_const_next[i])
-				{
-					J=i;
-				};
-			};
-
-
-
-			d_H_I->set_elem(d_nalp,d_H_matr_len-I-1);
-			d_H_J->set_elem(d_nalp,d_H_matr_len-J-1);
-
-
-		};
-	};
-
-	check_time_function();
-
-}
-
-
-
-void alp::restore_state(
-state * &state_)
-{
-	d_M=state_->d_M;
-	d_H_matr_len=state_->d_H_matr_len;
-
-	if(d_H_matr_len<0)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-
-	d_is_now=false;
-
-	delete d_cells_counts;d_cells_counts=NULL;
-
-	d_cells_counts=new array<long int>(d_alp_data);
-	alp_data::assert_mem(d_cells_counts);
-
-
-	d_cells_counts->set_elems(state_->d_cells_counts);
-
-
-	d_HS_ij_next=state_->d_HS_ij_next;
-	d_HI_ij_next=state_->d_HI_ij_next;
-	d_HD_ij_next=state_->d_HD_ij_next;
-	d_H_ij_next=state_->d_H_ij_next;
-
-	long int i;
-	for(i=0;i<d_H_matr_len;i++)
-	{
-		d_HS_i_const_next[i]=state_->d_HS_i_const_next[i];
-		d_HI_i_const_next[i]=state_->d_HI_i_const_next[i];
-		d_HD_i_const_next[i]=state_->d_HD_i_const_next[i];
-		d_H_i_const_next[i]=state_->d_H_i_const_next[i];
-		d_HS_j_const_next[i]=state_->d_HS_j_const_next[i];
-		d_HI_j_const_next[i]=state_->d_HI_j_const_next[i];
-		d_HD_j_const_next[i]=state_->d_HD_j_const_next[i];
-		d_H_j_const_next[i]=state_->d_H_j_const_next[i];
-	};
-
-	d_sentinel_i_next=state_->d_sentinel_i_next;
-	d_sentinel_j_next=state_->d_sentinel_j_next;
-
-
-}
-
-state::state()
-{
-	d_cells_counts=NULL;
-
-	d_HS_i_const_next=NULL;
-	d_HI_i_const_next=NULL;
-	d_HD_i_const_next=NULL;
-	d_H_i_const_next=NULL;
-
-	d_HS_j_const_next=NULL;
-	d_HI_j_const_next=NULL;
-	d_HD_j_const_next=NULL;
-	d_H_j_const_next=NULL;
-
-}
-
-void alp::save_state(
-state * &state_)
-{
-	if(d_H_matr_len<0)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-	state_=new state;
-	alp_data::assert_mem(state_);
-
-	d_alp_data->d_memory_size_in_MB+=(double)(sizeof(state))/mb_bytes;
-
-
-	state_->d_M=d_M;
-
-	state_->d_cells_counts=new array<long int>(d_alp_data);
-	alp_data::assert_mem(state_->d_cells_counts);
-
-	d_alp_data->d_memory_size_in_MB+=(double)(sizeof(array<long int>))/mb_bytes;
-
-	state_->d_cells_counts->set_elems(d_cells_counts);
-
-	state_->d_H_matr_len=d_H_matr_len;
-
-	state_->d_HS_ij_next=d_HS_ij_next;
-	state_->d_HI_ij_next=d_HI_ij_next;
-	state_->d_HD_ij_next=d_HD_ij_next;
-	state_->d_H_ij_next=d_H_ij_next;
-
-	if(d_H_matr_len==0)
-	{
-		state_->d_HS_i_const_next=NULL;;
-		state_->d_HI_i_const_next=NULL;;
-		state_->d_HD_i_const_next=NULL;;
-		state_->d_H_i_const_next=NULL;;
-		state_->d_HS_j_const_next=NULL;;
-		state_->d_HI_j_const_next=NULL;;
-		state_->d_HD_j_const_next=NULL;;
-		state_->d_H_j_const_next=NULL;
-
-
-	}
-	else
-	{
-		state_->d_HS_i_const_next=new long int[d_H_matr_len];
-		alp_data::assert_mem(state_->d_HS_i_const_next);
-
-		state_->d_HI_i_const_next=new long int[d_H_matr_len];
-		alp_data::assert_mem(state_->d_HI_i_const_next);
-
-		state_->d_HD_i_const_next=new long int[d_H_matr_len];
-		alp_data::assert_mem(state_->d_HD_i_const_next);
-
-		state_->d_H_i_const_next=new long int[d_H_matr_len];
-		alp_data::assert_mem(state_->d_H_i_const_next);
-
-		state_->d_HS_j_const_next=new long int[d_H_matr_len];
-		alp_data::assert_mem(state_->d_HS_j_const_next);
-
-		state_->d_HI_j_const_next=new long int[d_H_matr_len];
-		alp_data::assert_mem(state_->d_HI_j_const_next);
-
-		state_->d_HD_j_const_next=new long int[d_H_matr_len];
-		alp_data::assert_mem(state_->d_HD_j_const_next);
-
-		state_->d_H_j_const_next=new long int[d_H_matr_len];
-		alp_data::assert_mem(state_->d_H_j_const_next);
-
-		d_alp_data->d_memory_size_in_MB+=8.0*(double)(d_H_matr_len*sizeof(long int))/mb_bytes;
-
-		long int i;
-		for(i=0;i<d_H_matr_len;i++)
-		{
-			state_->d_HS_i_const_next[i]=d_HS_i_const_next[i];
-			state_->d_HI_i_const_next[i]=d_HI_i_const_next[i];
-			state_->d_HD_i_const_next[i]=d_HD_i_const_next[i];
-			state_->d_H_i_const_next[i]=d_H_i_const_next[i];
-			state_->d_HS_j_const_next[i]=d_HS_j_const_next[i];
-			state_->d_HI_j_const_next[i]=d_HI_j_const_next[i];
-			state_->d_HD_j_const_next[i]=d_HD_j_const_next[i];
-			state_->d_H_j_const_next[i]=d_H_j_const_next[i];
-		};
-
-	};
-
-	state_->d_sentinel_i_next=d_sentinel_i_next;
-	state_->d_sentinel_j_next=d_sentinel_j_next;
-
-}
-
-void alp::kill_upto_level(
-long int M_min_,
-long int M_level_,
-long int *M_upper_level_)
-{
-	if(d_is_now)
-	{
-		while(d_alp->d_elem[d_nalp]<M_min_)
-		{
-			simulate_next_alp();
-			if(!d_success)
-			{
-				return;
-			};
-		};
-		d_is_now=false;
-
-		long int i;
-		d_nalp_killing=-1;
-		for(i=0;i<=d_nalp;i++)
-		{
-			if(d_alp->d_elem[i]>=M_min_)
-			{
-				d_nalp_killing=i;
-				break;
-			};
-		};
-
-		if(d_nalp_killing==-1)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-		restore_state(d_alp_states->d_elem[d_nalp_killing]);
-
-	};
-
-	while(d_H_edge_max[d_H_matr_len]>=M_level_)
-	{
-		if(d_H_matr_len+1>=d_alp_data->d_dim1_tmp)
-		{
-			d_success=false;
-			return;
-		};
-
-		if(M_upper_level_)
-		{
-			if(d_H_edge_max[d_H_matr_len]>(*M_upper_level_))
-			{
-				d_success=false;
-				return;
-			};
-		};
-		
-
-		if(d_H_matr_len+1>d_seq_a_len)
-		{
-			increment_sequences();
-		};
-
-
-		d_seqi_len=d_seqj_len=d_H_matr_len+1;
-		d_seqi[d_seqi_len-1]=random_AA1();
-		d_seqj[d_seqj_len-1]=random_AA2();
-
-		if(d_sentinels_flag)
-		{
-			increment_H_weights_with_sentinels(d_diff_opt);
-		}
-		else
-		{
-			increment_H_weights();
-		};
-
-		if(d_time_limit_flag)
-		{
-			d_success=false;
-			return;
-		};
-
-	};
-
-	d_success=true;
-}
-
-double alp::John2_weight_calculation(
-long int length_)//calculation of weigths for the importance sampling
-{
-	if(length_==0)
-	{
-		return 1.0;
-	};
-
-	if(d_W_matr_len>length_)
-	{
-		throw error("Error - unexpected parameter in alp::John2_weight_calculation\n",4);
-	};
-
-	while(d_W_matr_len<length_)
-	{
-		increment_W_weights();
-	};
-
-	importance_sampling *&d_is_tmp=d_alp_data->d_is;
-
-	long int d_W_matr_len_1=d_W_matr_len-1;
-
-	double US=0;
-	double UD=0;
-	double UI=d_WI_j_const_next[d_W_matr_len_1]/(1-(d_is_tmp->d_nu));
-
-	double VS=0;
-	double VI=0;
-	double VD=d_WD_i_const_next[d_W_matr_len_1]/(1-(d_is_tmp->d_nu));
-
-	long int j;
-	for(j=1;j<=length_-1;j++)
-	{
-		double US_next=d_alp_data->d_r_i_dot[d_seqi[j-1]]*((d_is_tmp->d_eta)*US+(d_is_tmp->d_mu_SI)*UI+(d_is_tmp->d_mu_SD)*UD)+d_WS_j_const_next[d_W_matr_len_1-j];
-		double UD_next=((d_is_tmp->d_mu_DS)*US+(d_is_tmp->d_nu)*UD);
-		double UI_next=((d_is_tmp->d_mu_IS)*US_next+(d_is_tmp->d_mu_ID)*UD_next+d_WI_j_const_next[d_W_matr_len_1-j])/(1-(d_is_tmp->d_nu));
-
-		double VS_next=d_alp_data->d_r_dot_j[d_seqj[j-1]]*((d_is_tmp->d_eta)*VS+(d_is_tmp->d_mu_SI)*VI+(d_is_tmp->d_mu_SD)*VD)+d_WS_i_const_next[d_W_matr_len_1-j];
-		double VI_next=((d_is_tmp->d_mu_IS)*VS+(d_is_tmp->d_mu_ID)*VD+(d_is_tmp->d_nu)*VI);
-		double VD_next=((d_is_tmp->d_mu_DS)*VS_next+d_WD_i_const_next[d_W_matr_len_1-j])/(1-(d_is_tmp->d_nu));
-
-		US=US_next;
-		UD=UD_next;
-		UI=UI_next;
-
-		VS=VS_next;
-		VD=VD_next;
-		VI=VI_next;
-	};
-
-	//copy
-	j=length_;
-	double US_next=d_alp_data->d_r_i_dot[d_seqi[j-1]]*((d_is_tmp->d_eta)*US+(d_is_tmp->d_mu_SI)*UI+(d_is_tmp->d_mu_SD)*UD)+d_WS_ij_next;
-	double UD_next=((d_is_tmp->d_mu_DS)*US+(d_is_tmp->d_nu)*UD);
-	double UI_next=((d_is_tmp->d_mu_IS)*US_next+(d_is_tmp->d_mu_ID)*UD_next+d_WI_ij_next)/(1-(d_is_tmp->d_nu));
-
-	double VS_next=d_alp_data->d_r_dot_j[d_seqj[j-1]]*((d_is_tmp->d_eta)*VS+(d_is_tmp->d_mu_SI)*VI+(d_is_tmp->d_mu_SD)*VD)+d_WS_ij_next;
-	double VI_next=((d_is_tmp->d_mu_IS)*VS+(d_is_tmp->d_mu_ID)*VD+(d_is_tmp->d_nu)*VI);
-	double VD_next=((d_is_tmp->d_mu_DS)*VS_next+d_WD_ij_next)/(1-(d_is_tmp->d_nu));
-
-	US=US_next;
-	UD=UD_next;
-	UI=UI_next;
-
-	VS=VS_next;
-	VD=VD_next;
-	VI=VI_next;
-
-
-	double weight=-d_WS_ij_next+US+UD+VS+VI;
-
-
-
-
-	if(weight==0)
-	{
-		throw error("Unexpected error\n",4);
-	};
-	weight=1.0/weight;
-
-	return weight;
-
-}
-
-void alp::simulate_next_alp()//simulates next ALP
-{
-	if(!d_success)
-	{
-		return;
-	};
-
-	if(!d_is_now)
-	{
-		throw error("Unexpected error - ALP can be generated only in the importance sampling mode\n",4);
-	};
-
-	long int target_nalp=d_nalp+1;
-
-	while(d_nalp<target_nalp)
-	{
-		long int k=alp_data::Tmin(d_seqi_len,d_seqj_len);
-		//std::cout<<k<<"\t"<<this->d_H_edge_max[k]<<std::endl;
-
-		while(alp_data::Tmin(d_seqi_len,d_seqj_len)!=k+1)
-		{
-			bool success=one_step_of_importance_sampling_without_weight_calculation(
-			d_alp_data->d_dim1_tmp,
-			d_alp_data->d_dim2_tmp);
-
-
-			check_time_function();
-
-			if(!success)
-			{
-				d_success=false;
-				return;
-			};
-		};
-
-		if(d_sentinels_flag)
-		{
-			increment_H_weights_with_sentinels(d_diff_opt);
-		}
-		else
-		{
-			increment_H_weights();
-		};
-
-		if(d_time_limit_flag)
-		{
-			d_success=false;
-			return;
-		};
-
-
-		increment_W_weights();
-	};
-
-	double weight=John2_weight_calculation(alp_data::Tmin(d_seqi_len,d_seqj_len));
-	if(weight<=0)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-	d_alp_weights->set_elem(d_nalp,weight);
-
-}
-
-void alp::simulate_alp_upto_the_given_number(//simulates ALP upto the given number nalp_ including
-long int nalp_)
-{
-	d_sentinels_flag=false;
-	while(d_nalp<nalp_)
-	{
-		simulate_next_alp();
-		if(!d_success)
-		{
-			return;
-		};
-	};
-}
-
-void alp::simulate_alp_upto_the_given_level(//simulates ALP upto the given level M_min_ including
-long int M_min_)
-{
-	d_sentinels_flag=false;
-	while(d_alp->d_elem[d_nalp]<M_min_)
-	{
-		simulate_next_alp();
-		if(!d_success)
-		{
-			return;
-		};
-	};
-	d_nalp_killing=d_nalp;
-}
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_alp.cpp
+
+Author: Sergey Sheetlin, Martin Frith
+
+Contents: Ascending ladder points simulation
+
+******************************************************************************/
+
+
+#include "sls_alp.hpp"
+
+using namespace Sls;
+
+static long int small_long=(long int)((double)LONG_MIN/2.0);
+
+
+alp::alp(//constructor
+alp_data *alp_data_
+)
+{
+	d_seqi=NULL;
+	d_seqj=NULL;
+
+	d_WS_i_const_pred=NULL;
+	d_WI_i_const_pred=NULL;
+	d_WD_i_const_pred=NULL;
+
+	d_WS_i_const_next=NULL;
+	d_WI_i_const_next=NULL;
+	d_WD_i_const_next=NULL;
+
+	d_WS_j_const_pred=NULL;
+	d_WI_j_const_pred=NULL;
+	d_WD_j_const_pred=NULL;
+
+	d_WS_j_const_next=NULL;
+	d_WI_j_const_next=NULL;
+	d_WD_j_const_next=NULL;
+
+
+	//alignment matrix 
+	d_HS_i_const_pred=NULL;
+	d_HI_i_const_pred=NULL;
+	d_HD_i_const_pred=NULL;
+	d_H_i_const_pred=NULL;
+
+	d_HS_i_const_next=NULL;
+	d_HI_i_const_next=NULL;
+	d_HD_i_const_next=NULL;
+	d_H_i_const_next=NULL;
+
+	d_HS_j_const_pred=NULL;
+	d_HI_j_const_pred=NULL;
+	d_HD_j_const_pred=NULL;
+	d_H_j_const_pred=NULL;
+
+	d_HS_j_const_next=NULL;
+	d_HI_j_const_next=NULL;
+	d_HD_j_const_next=NULL;
+	d_H_j_const_next=NULL;
+
+	d_H_edge_max=NULL;
+	d_H_I=NULL;
+	d_H_J=NULL;
+
+	d_alp=NULL;
+	d_alp_pos=NULL;
+	d_cells_counts=NULL;
+	d_alp_weights=NULL;
+	d_alp_states=NULL;
+
+	d_success=true;
+
+	d_check_time_flag=false;
+	d_time_error_flag=false;
+	d_time_limit_flag=false;
+	d_single_realiztion_calculation_flag=false;
+
+	d_alp_data=alp_data_;
+	if(!d_alp_data)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+	d_a_step=30;
+
+	try
+	{
+
+		d_is_now=true;
+		d_seqi_len=0;
+		d_seqj_len=0;
+		d_seq_a_len=0;
+		d_H_matr_a_len=0;
+		d_W_matr_a_len=0;
+		d_H_matr_len=-1;
+		d_W_matr_len=-1;
+		d_nalp=-1;
+
+		d_H_edge_max=new long int[1];
+		alp_data::assert_mem(d_H_edge_max);
+		d_H_edge_max[0]=0;
+
+		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(long int))/mb_bytes;
+
+
+		d_alp=new array_positive<long int>(d_alp_data);
+		alp_data::assert_mem(d_alp);
+
+		d_H_I=new array_positive<long int>(d_alp_data);
+		alp_data::assert_mem(d_H_I);
+
+		d_H_J=new array_positive<long int>(d_alp_data);
+		alp_data::assert_mem(d_H_J);
+
+
+		d_alp_pos=new array_positive<long int>(d_alp_data);
+		alp_data::assert_mem(d_alp_pos);
+
+		d_alp_data->d_memory_size_in_MB+=4*(double)(sizeof(array_positive<long int>))/mb_bytes;
+
+		d_alp_states=new array_positive<state*>(d_alp_data);
+		alp_data::assert_mem(d_alp_states);
+
+		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(array_positive<state*>))/mb_bytes;
+
+
+		d_alp_weights=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(d_alp_weights);
+
+		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(array_positive<double>))/mb_bytes;
+
+
+		d_cells_counts=new array<long int>(d_alp_data);
+		alp_data::assert_mem(d_cells_counts);
+
+		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(array<long int>))/mb_bytes;
+
+
+		increment_W_weights();
+		increment_H_weights_with_sentinels(0);
+	}
+	catch (...)
+	{
+		this->~alp();
+		throw;
+	};
+
+}
+
+alp::~alp()//destructor
+{
+
+	release_and_calculate_memory(d_seqi,d_seq_a_len);
+	release_and_calculate_memory(d_seqj,d_seq_a_len);
+
+
+
+	release_and_calculate_memory(d_WS_i_const_pred,d_W_matr_a_len);
+
+	release_and_calculate_memory(d_WI_i_const_pred,d_W_matr_a_len);
+
+	release_and_calculate_memory(d_WD_i_const_pred,d_W_matr_a_len);
+
+
+	release_and_calculate_memory(d_WS_i_const_next,d_W_matr_a_len);
+
+	release_and_calculate_memory(d_WI_i_const_next,d_W_matr_a_len);
+
+	release_and_calculate_memory(d_WD_i_const_next,d_W_matr_a_len);
+
+
+
+	release_and_calculate_memory(d_WS_j_const_pred,d_W_matr_a_len);
+
+	release_and_calculate_memory(d_WI_j_const_pred,d_W_matr_a_len);
+
+	release_and_calculate_memory(d_WD_j_const_pred,d_W_matr_a_len);
+
+
+	release_and_calculate_memory(d_WS_j_const_next,d_W_matr_a_len);
+
+	release_and_calculate_memory(d_WI_j_const_next,d_W_matr_a_len);
+
+	release_and_calculate_memory(d_WD_j_const_next,d_W_matr_a_len);
+
+
+
+	release_and_calculate_memory(d_HS_i_const_pred,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_HI_i_const_pred,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_HD_i_const_pred,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_H_i_const_pred,d_H_matr_a_len);
+
+
+	release_and_calculate_memory(d_HS_i_const_next,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_HI_i_const_next,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_HD_i_const_next,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_H_i_const_next,d_H_matr_a_len);
+
+
+	release_and_calculate_memory(d_HS_j_const_pred,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_HI_j_const_pred,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_HD_j_const_pred,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_H_j_const_pred,d_H_matr_a_len);
+
+
+	release_and_calculate_memory(d_HS_j_const_next,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_HI_j_const_next,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_HD_j_const_next,d_H_matr_a_len);
+
+	release_and_calculate_memory(d_H_j_const_next,d_H_matr_a_len);
+
+
+	release_and_calculate_memory(d_H_edge_max,d_H_matr_a_len+1);
+
+
+
+	
+	release_and_calculate_memory(d_alp);
+
+	release_and_calculate_memory(d_H_I);
+
+	release_and_calculate_memory(d_H_J);
+
+	release_and_calculate_memory(d_alp_pos);
+
+
+
+
+
+	long int i;
+
+	if(d_alp_states)
+	{
+		for(i=0;i<=d_nalp;i++)
+		{
+			if(i<=d_alp_states->d_dim)
+			{
+				if(d_alp_states->d_elem[i])
+				{
+
+					for(i=0;i<=d_nalp;i++)
+					{
+
+
+						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HS_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+
+						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HI_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+
+						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HD_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+
+						release_and_calculate_memory(d_alp_states->d_elem[i]->d_H_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+
+
+						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HS_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+
+						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HI_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+
+						release_and_calculate_memory(d_alp_states->d_elem[i]->d_HD_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+
+						release_and_calculate_memory(d_alp_states->d_elem[i]->d_H_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+
+
+
+
+
+						release_and_calculate_memory(d_alp_states->d_elem[i]->d_cells_counts);
+
+						release_and_calculate_memory(d_alp_states->d_elem[i]);
+
+						
+					};
+				};
+			};
+		};
+	};
+
+	
+	release_and_calculate_memory(d_alp_states);
+
+	release_and_calculate_memory(d_alp_weights);
+
+	
+	release_and_calculate_memory(d_cells_counts);
+
+
+}
+
+void alp::partially_release_memory()
+{
+
+	
+	release_and_calculate_memory(d_seqi,d_seq_a_len);
+	release_and_calculate_memory(d_seqj,d_seq_a_len);
+
+
+	release_and_calculate_memory(d_WS_i_const_pred,d_W_matr_a_len);
+	release_and_calculate_memory(d_WI_i_const_pred,d_W_matr_a_len);
+	release_and_calculate_memory(d_WD_i_const_pred,d_W_matr_a_len);
+
+	release_and_calculate_memory(d_WS_i_const_next,d_W_matr_a_len);
+	release_and_calculate_memory(d_WI_i_const_next,d_W_matr_a_len);
+	release_and_calculate_memory(d_WD_i_const_next,d_W_matr_a_len);
+
+
+	release_and_calculate_memory(d_WS_j_const_pred,d_W_matr_a_len);
+	release_and_calculate_memory(d_WI_j_const_pred,d_W_matr_a_len);
+	release_and_calculate_memory(d_WD_j_const_pred,d_W_matr_a_len);
+
+
+	release_and_calculate_memory(d_WS_j_const_next,d_W_matr_a_len);
+	release_and_calculate_memory(d_WI_j_const_next,d_W_matr_a_len);
+	release_and_calculate_memory(d_WD_j_const_next,d_W_matr_a_len);
+
+
+
+	release_and_calculate_memory(d_HS_i_const_pred,d_H_matr_a_len);
+	release_and_calculate_memory(d_HI_i_const_pred,d_H_matr_a_len);
+	release_and_calculate_memory(d_HD_i_const_pred,d_H_matr_a_len);
+	release_and_calculate_memory(d_H_i_const_pred,d_H_matr_a_len);
+
+
+	release_and_calculate_memory(d_HS_i_const_next,d_H_matr_a_len);
+	release_and_calculate_memory(d_HI_i_const_next,d_H_matr_a_len);
+	release_and_calculate_memory(d_HD_i_const_next,d_H_matr_a_len);
+	release_and_calculate_memory(d_H_i_const_next,d_H_matr_a_len);
+
+
+
+	release_and_calculate_memory(d_HS_j_const_pred,d_H_matr_a_len);
+	release_and_calculate_memory(d_HI_j_const_pred,d_H_matr_a_len);
+	release_and_calculate_memory(d_HD_j_const_pred,d_H_matr_a_len);
+	release_and_calculate_memory(d_H_j_const_pred,d_H_matr_a_len);
+
+
+	release_and_calculate_memory(d_HS_j_const_next,d_H_matr_a_len);
+	release_and_calculate_memory(d_HI_j_const_next,d_H_matr_a_len);
+	release_and_calculate_memory(d_HD_j_const_next,d_H_matr_a_len);
+	release_and_calculate_memory(d_H_j_const_next,d_H_matr_a_len);
+
+
+
+	release_and_calculate_memory(d_H_edge_max,d_H_matr_a_len+1);
+
+
+	
+
+	long int i;
+
+	if(d_alp_states)
+	{
+		for(i=0;i<=d_nalp;i++)
+		{
+			if(i<=d_alp_states->d_dim)
+			{
+				if(d_alp_states->d_elem[i])
+				{
+
+					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HS_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HI_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HD_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+					release_and_calculate_memory(d_alp_states->d_elem[i]->d_H_i_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+
+					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HS_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HI_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+					release_and_calculate_memory(d_alp_states->d_elem[i]->d_HD_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+					release_and_calculate_memory(d_alp_states->d_elem[i]->d_H_j_const_next,d_alp_states->d_elem[i]->d_H_matr_len);
+
+
+
+					release_and_calculate_memory(d_alp_states->d_elem[i]->d_cells_counts);
+				};
+			};
+
+			
+		};
+	};
+
+}
+
+
+long int alp::random_AA1()
+{
+	return d_alp_data->random_long(
+		d_alp_data->ran2(),
+		d_alp_data->d_number_of_AA,
+		d_alp_data->d_RR1_sum,
+		d_alp_data->d_RR1_sum_elements);
+}
+
+long int alp::random_AA2()
+{
+	return d_alp_data->random_long(
+		d_alp_data->ran2(),
+		d_alp_data->d_number_of_AA,
+		d_alp_data->d_RR2_sum,
+		d_alp_data->d_RR2_sum_elements);
+}
+
+bool alp::one_step_of_importance_sampling_without_weight_calculation(
+	long int d_dim1_,
+	long int d_dim2_)
+{
+	char &state_=d_IS_state;
+
+	alp_data *&las_object_=d_alp_data;
+
+	importance_sampling *&d_is_=d_alp_data->d_is;
+	long int &length1_=d_seqi_len;
+	long int &length2_=d_seqj_len;
+
+	long int *&d_seqi_rglobal_=d_seqi;
+	long int *&d_seqj_rglobal_=d_seqj;
+
+
+	bool res=true;
+
+	if(length1_==0&&length2_==0)
+	{
+		state_=alp_data::random_long(
+			las_object_->ran2(),
+			3,
+			d_is_->d_for_S,
+			d_is_->d_for_S_states);
+	};
+
+
+	if(state_=='D')
+	{
+		if(length1_==d_dim1_)
+		{
+			res=false;
+			return res;
+		};
+
+		if(length1_>d_seq_a_len-1)
+		{
+			increment_sequences();
+		};
+
+		d_seqi_rglobal_[length1_]=random_AA1();
+		length1_++;
+
+		state_=alp_data::random_long(
+			las_object_->ran2(),
+			3,
+			d_is_->d_for_D,
+			d_is_->d_for_D_states);
+		goto weight_calculation;
+	};
+
+	if(state_=='I')
+	{
+		if(length2_==d_dim2_)
+		{
+			res=false;
+			return res;
+		};
+
+		if(length2_>d_seq_a_len-1)
+		{
+			increment_sequences();
+		};
+
+
+		d_seqj_rglobal_[length2_]=random_AA2();
+		length2_++;
+
+		state_=alp_data::random_long(
+			las_object_->ran2(),
+			2,
+			d_is_->d_for_I,
+			d_is_->d_for_I_states);
+		goto weight_calculation;
+	};
+
+	if(state_=='S')
+	{
+		if(length1_==d_dim1_||length2_==d_dim2_)
+		{
+			res=false;
+			return res;
+		};
+		q_elem pair=alp_data::random_long(
+			las_object_->ran2(),
+			d_is_->d_is_number_of_AA*d_is_->d_is_number_of_AA,
+			d_is_->d_elements_values,
+			d_is_->d_elements);
+
+		if(length1_>d_seq_a_len-1||length2_>d_seq_a_len-1)
+		{
+			increment_sequences();
+		};
+
+		d_seqi_rglobal_[length1_]=pair.d_a;
+		d_seqj_rglobal_[length2_]=pair.d_b;
+
+		
+
+		length1_++;
+		length2_++;
+
+		state_=alp_data::random_long(
+			las_object_->ran2(),
+			3,
+			d_is_->d_for_S,
+			d_is_->d_for_S_states);
+		goto weight_calculation;
+	};
+
+weight_calculation:
+//----deleted-------
+return res;
+
+}
+
+void alp::increment_sequences()
+{
+	long int *d_seqi_new=NULL;
+	long int *d_seqj_new=NULL;
+
+	try
+	{
+
+		d_seq_a_len+=d_a_step;
+
+		d_seqi_new=new long int[d_seq_a_len];
+		alp_data::assert_mem(d_seqi_new);
+
+		d_seqj_new=new long int[d_seq_a_len];
+		alp_data::assert_mem(d_seqj_new);
+
+		long int i;
+		for(i=0;i<d_seqi_len;i++)
+		{
+			d_seqi_new[i]=d_seqi[i];
+		};
+
+		for(i=0;i<d_seqj_len;i++)
+		{
+			d_seqj_new[i]=d_seqj[i];
+		};
+
+		
+		delete[]d_seqi;d_seqi=NULL;
+		delete[]d_seqj;d_seqj=NULL;
+
+
+		d_seqi=d_seqi_new;
+		d_seqj=d_seqj_new;
+
+		d_seqi_new=NULL;
+		d_seqj_new=NULL;
+
+		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(long int)*d_a_step*2)/mb_bytes;
+
+	}
+	catch (...)
+	{ 
+		delete[]d_seqi_new;d_seqi_new=NULL;
+		delete[]d_seqj_new;d_seqj_new=NULL;
+		throw;
+	};
+
+}
+
+void alp::increment_W_matrix()
+{
+	double *d_WS_i_const_pred_new=NULL;
+	double *d_WI_i_const_pred_new=NULL;
+	double *d_WD_i_const_pred_new=NULL;
+
+	double *d_WS_i_const_next_new=NULL;
+	double *d_WI_i_const_next_new=NULL;
+	double *d_WD_i_const_next_new=NULL;
+
+	double *d_WS_j_const_pred_new=NULL;
+	double *d_WI_j_const_pred_new=NULL;
+	double *d_WD_j_const_pred_new=NULL;
+
+	double *d_WS_j_const_next_new=NULL;
+	double *d_WI_j_const_next_new=NULL;
+	double *d_WD_j_const_next_new=NULL;
+
+	try
+	{
+
+		d_W_matr_a_len+=d_a_step;
+
+		//the importance sampling weights
+		d_WS_i_const_pred_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WS_i_const_pred_new);
+		d_WI_i_const_pred_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WI_i_const_pred_new);
+		d_WD_i_const_pred_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WD_i_const_pred_new);
+
+		d_WS_i_const_next_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WS_i_const_next_new);
+		d_WI_i_const_next_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WI_i_const_next_new);
+		d_WD_i_const_next_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WD_i_const_next_new);
+
+		d_WS_j_const_pred_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WS_j_const_pred_new);
+		d_WI_j_const_pred_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WI_j_const_pred_new);
+		d_WD_j_const_pred_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WD_j_const_pred_new);
+
+		d_WS_j_const_next_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WS_j_const_next_new);
+		d_WI_j_const_next_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WI_j_const_next_new);
+		d_WD_j_const_next_new=new double[d_W_matr_a_len];
+		alp_data::assert_mem(d_WD_j_const_next_new);
+
+
+
+		long int i;
+		for(i=0;i<d_W_matr_len;i++)
+		{
+			d_WS_i_const_next_new[i]=d_WS_i_const_next[i];
+			d_WI_i_const_next_new[i]=d_WI_i_const_next[i];
+			d_WD_i_const_next_new[i]=d_WD_i_const_next[i];
+
+			d_WS_j_const_next_new[i]=d_WS_j_const_next[i];
+			d_WI_j_const_next_new[i]=d_WI_j_const_next[i];
+			d_WD_j_const_next_new[i]=d_WD_j_const_next[i];
+
+		};
+
+		
+
+		for(i=0;i<d_W_matr_len-1;i++)
+		{
+			d_WS_i_const_pred_new[i]=d_WS_i_const_pred[i];
+			d_WI_i_const_pred_new[i]=d_WI_i_const_pred[i];
+			d_WD_i_const_pred_new[i]=d_WD_i_const_pred[i];
+
+			d_WS_j_const_pred_new[i]=d_WS_j_const_pred[i];
+			d_WI_j_const_pred_new[i]=d_WI_j_const_pred[i];
+			d_WD_j_const_pred_new[i]=d_WD_j_const_pred[i];
+
+		};
+
+
+		delete[]d_WS_i_const_pred;d_WS_i_const_pred=NULL;
+		delete[]d_WI_i_const_pred;d_WI_i_const_pred=NULL;
+		delete[]d_WD_i_const_pred;d_WD_i_const_pred=NULL;
+
+		delete[]d_WS_i_const_next;d_WS_i_const_next=NULL;
+		delete[]d_WI_i_const_next;d_WI_i_const_next=NULL;
+		delete[]d_WD_i_const_next;d_WD_i_const_next=NULL;
+
+		delete[]d_WS_j_const_pred;d_WS_j_const_pred=NULL;
+		delete[]d_WI_j_const_pred;d_WI_j_const_pred=NULL;
+		delete[]d_WD_j_const_pred;d_WD_j_const_pred=NULL;
+
+		delete[]d_WS_j_const_next;d_WS_j_const_next=NULL;
+		delete[]d_WI_j_const_next;d_WI_j_const_next=NULL;
+		delete[]d_WD_j_const_next;d_WD_j_const_next=NULL;
+
+		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(double)*d_a_step*12)/mb_bytes;
+
+
+		d_WS_i_const_pred=d_WS_i_const_pred_new;d_WS_i_const_pred_new=NULL;
+		d_WI_i_const_pred=d_WI_i_const_pred_new;d_WI_i_const_pred_new=NULL;
+		d_WD_i_const_pred=d_WD_i_const_pred_new;d_WD_i_const_pred_new=NULL;
+
+		d_WS_i_const_next=d_WS_i_const_next_new;d_WS_i_const_next_new=NULL;
+		d_WI_i_const_next=d_WI_i_const_next_new;d_WI_i_const_next_new=NULL;
+		d_WD_i_const_next=d_WD_i_const_next_new;d_WD_i_const_next_new=NULL;
+
+		d_WS_j_const_pred=d_WS_j_const_pred_new;d_WS_j_const_pred_new=NULL;
+		d_WI_j_const_pred=d_WI_j_const_pred_new;d_WI_j_const_pred_new=NULL;
+		d_WD_j_const_pred=d_WD_j_const_pred_new;d_WD_j_const_pred_new=NULL;
+
+
+		d_WS_j_const_next=d_WS_j_const_next_new;d_WS_j_const_next_new=NULL;
+		d_WI_j_const_next=d_WI_j_const_next_new;d_WI_j_const_next_new=NULL;
+		d_WD_j_const_next=d_WD_j_const_next_new;d_WD_j_const_next_new=NULL;
+
+		
+
+	}
+	catch (...)
+	{ 
+		delete[]d_WS_i_const_pred_new;d_WS_i_const_pred_new=NULL;
+		delete[]d_WI_i_const_pred_new;d_WI_i_const_pred_new=NULL;
+		delete[]d_WD_i_const_pred_new;d_WD_i_const_pred_new=NULL;
+
+		delete[]d_WS_i_const_next_new;d_WS_i_const_next_new=NULL;
+		delete[]d_WI_i_const_next_new;d_WI_i_const_next_new=NULL;
+		delete[]d_WD_i_const_next_new;d_WD_i_const_next_new=NULL;
+
+		delete[]d_WS_j_const_pred_new;d_WS_j_const_pred_new=NULL;
+		delete[]d_WI_j_const_pred_new;d_WI_j_const_pred_new=NULL;
+		delete[]d_WD_j_const_pred_new;d_WD_j_const_pred_new=NULL;
+
+		delete[]d_WS_j_const_next_new;d_WS_j_const_next_new=NULL;
+		delete[]d_WI_j_const_next_new;d_WI_j_const_next_new=NULL;
+		delete[]d_WD_j_const_next_new;d_WD_j_const_next_new=NULL;
+		throw;
+	};
+
+}
+
+void alp::increment_H_matrix()
+{
+
+	long int *d_HS_i_const_pred_new=NULL;
+	long int *d_HI_i_const_pred_new=NULL;
+	long int *d_HD_i_const_pred_new=NULL;
+	long int *d_H_i_const_pred_new=NULL;
+
+	long int *d_HS_i_const_next_new=NULL;
+	long int *d_HI_i_const_next_new=NULL;
+	long int *d_HD_i_const_next_new=NULL;
+	long int *d_H_i_const_next_new=NULL;
+
+	long int *d_HS_j_const_pred_new=NULL;
+	long int *d_HI_j_const_pred_new=NULL;
+	long int *d_HD_j_const_pred_new=NULL;
+	long int *d_H_j_const_pred_new=NULL;
+
+	long int *d_HS_j_const_next_new=NULL;
+	long int *d_HI_j_const_next_new=NULL;
+	long int *d_HD_j_const_next_new=NULL;
+	long int *d_H_j_const_next_new=NULL;
+
+	long int *d_H_edge_max_new=NULL;
+
+	try
+	{
+
+		d_H_matr_a_len+=d_a_step;
+
+
+		//alignment matrix 
+		d_HS_i_const_pred_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HS_i_const_pred_new);
+		d_HI_i_const_pred_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HI_i_const_pred_new);
+		d_HD_i_const_pred_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HD_i_const_pred_new);
+		d_H_i_const_pred_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_H_i_const_pred_new);
+
+		d_HS_i_const_next_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HS_i_const_next_new);
+		d_HI_i_const_next_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HI_i_const_next_new);
+		d_HD_i_const_next_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HD_i_const_next_new);
+		d_H_i_const_next_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_H_i_const_next_new);
+
+		d_HS_j_const_pred_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HS_j_const_pred_new);
+		d_HI_j_const_pred_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HI_j_const_pred_new);
+		d_HD_j_const_pred_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HD_j_const_pred_new);
+		d_H_j_const_pred_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_H_j_const_pred_new);
+
+		d_HS_j_const_next_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HS_j_const_next_new);
+		d_HI_j_const_next_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HI_j_const_next_new);
+		d_HD_j_const_next_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_HD_j_const_next_new);
+		d_H_j_const_next_new=new long int[d_H_matr_a_len];
+		alp_data::assert_mem(d_H_j_const_next_new);
+
+
+		d_H_edge_max_new=new long int[d_H_matr_a_len+1];
+		alp_data::assert_mem(d_H_edge_max_new);
+
+
+		long int i;
+		for(i=0;i<d_H_matr_len;i++)
+		{
+			d_HS_i_const_next_new[i]=d_HS_i_const_next[i];
+			d_HI_i_const_next_new[i]=d_HI_i_const_next[i];
+			d_HD_i_const_next_new[i]=d_HD_i_const_next[i];
+			d_H_i_const_next_new[i]=d_H_i_const_next[i];
+
+			d_HS_j_const_next_new[i]=d_HS_j_const_next[i];
+			d_HI_j_const_next_new[i]=d_HI_j_const_next[i];
+			d_HD_j_const_next_new[i]=d_HD_j_const_next[i];
+			d_H_j_const_next_new[i]=d_H_j_const_next[i];
+		};
+
+		for(i=0;i<d_H_matr_len-1;i++)
+		{
+			d_HS_i_const_pred_new[i]=d_HS_i_const_pred[i];
+			d_HI_i_const_pred_new[i]=d_HI_i_const_pred[i];
+			d_HD_i_const_pred_new[i]=d_HD_i_const_pred[i];
+			d_H_i_const_pred_new[i]=d_H_i_const_pred[i];
+
+			d_HS_j_const_pred_new[i]=d_HS_j_const_pred[i];
+			d_HI_j_const_pred_new[i]=d_HI_j_const_pred[i];
+			d_HD_j_const_pred_new[i]=d_HD_j_const_pred[i];
+			d_H_j_const_pred_new[i]=d_H_j_const_pred[i];
+		};
+
+
+		for(i=0;i<=d_H_matr_len;i++)
+		{
+			d_H_edge_max_new[i]=d_H_edge_max[i];
+		};
+
+		
+
+		delete[]d_HS_i_const_pred;d_HS_i_const_pred=NULL;
+		delete[]d_HI_i_const_pred;d_HI_i_const_pred=NULL;
+		delete[]d_HD_i_const_pred;d_HD_i_const_pred=NULL;
+		delete[]d_H_i_const_pred;d_H_i_const_pred=NULL;
+
+		delete[]d_HS_i_const_next;d_HS_i_const_next=NULL;
+		delete[]d_HI_i_const_next;d_HI_i_const_next=NULL;
+		delete[]d_HD_i_const_next;d_HD_i_const_next=NULL;
+		delete[]d_H_i_const_next;d_H_i_const_next=NULL;
+
+		delete[]d_HS_j_const_pred;d_HS_j_const_pred=NULL;
+		delete[]d_HI_j_const_pred;d_HI_j_const_pred=NULL;
+		delete[]d_HD_j_const_pred;d_HD_j_const_pred=NULL;
+		delete[]d_H_j_const_pred;d_H_j_const_pred=NULL;
+
+		delete[]d_HS_j_const_next;d_HS_j_const_next=NULL;
+		delete[]d_HI_j_const_next;d_HI_j_const_next=NULL;
+		delete[]d_HD_j_const_next;d_HD_j_const_next=NULL;
+		delete[]d_H_j_const_next;d_H_j_const_next=NULL;
+
+		delete[]d_H_edge_max;d_H_edge_max=NULL;
+
+		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(long int)*d_a_step*17)/mb_bytes;
+
+		d_HS_i_const_pred=d_HS_i_const_pred_new;d_HS_i_const_pred_new=NULL;
+		d_HI_i_const_pred=d_HI_i_const_pred_new;d_HI_i_const_pred_new=NULL;
+		d_HD_i_const_pred=d_HD_i_const_pred_new;d_HD_i_const_pred_new=NULL;
+		d_H_i_const_pred=d_H_i_const_pred_new;d_H_i_const_pred_new=NULL;
+
+		d_HS_i_const_next=d_HS_i_const_next_new;d_HS_i_const_next_new=NULL;
+		d_HI_i_const_next=d_HI_i_const_next_new;d_HI_i_const_next_new=NULL;
+		d_HD_i_const_next=d_HD_i_const_next_new;d_HD_i_const_next_new=NULL;
+		d_H_i_const_next=d_H_i_const_next_new;d_H_i_const_next_new=NULL;
+
+		d_HS_j_const_pred=d_HS_j_const_pred_new;d_HS_j_const_pred_new=NULL;
+		d_HI_j_const_pred=d_HI_j_const_pred_new;d_HI_j_const_pred_new=NULL;
+		d_HD_j_const_pred=d_HD_j_const_pred_new;d_HD_j_const_pred_new=NULL;
+		d_H_j_const_pred=d_H_j_const_pred_new;d_H_j_const_pred_new=NULL;
+
+		d_HS_j_const_next=d_HS_j_const_next_new;d_HS_j_const_next_new=NULL;
+		d_HI_j_const_next=d_HI_j_const_next_new;d_HI_j_const_next_new=NULL;
+		d_HD_j_const_next=d_HD_j_const_next_new;d_HD_j_const_next_new=NULL;
+		d_H_j_const_next=d_H_j_const_next_new;d_H_j_const_next_new=NULL;
+
+		d_H_edge_max=d_H_edge_max_new;d_H_edge_max_new=NULL;
+
+		
+	}
+	catch (...)
+	{ 
+		delete[]d_HS_i_const_pred_new;d_HS_i_const_pred_new=NULL;
+		delete[]d_HI_i_const_pred_new;d_HI_i_const_pred_new=NULL;
+		delete[]d_HD_i_const_pred_new;d_HD_i_const_pred_new=NULL;
+		delete[]d_H_i_const_pred_new;d_H_i_const_pred_new=NULL;
+
+		delete[]d_HS_i_const_next_new;d_HS_i_const_next_new=NULL;
+		delete[]d_HI_i_const_next_new;d_HI_i_const_next_new=NULL;
+		delete[]d_HD_i_const_next_new;d_HD_i_const_next_new=NULL;
+		delete[]d_H_i_const_next_new;d_H_i_const_next_new=NULL;
+
+		delete[]d_HS_j_const_pred_new;d_HS_j_const_pred_new=NULL;
+		delete[]d_HI_j_const_pred_new;d_HI_j_const_pred_new=NULL;
+		delete[]d_HD_j_const_pred_new;d_HD_j_const_pred_new=NULL;
+		delete[]d_H_j_const_pred_new;d_H_j_const_pred_new=NULL;
+
+		delete[]d_HS_j_const_next_new;d_HS_j_const_next_new=NULL;
+		delete[]d_HI_j_const_next_new;d_HI_j_const_next_new=NULL;
+		delete[]d_HD_j_const_next_new;d_HD_j_const_next_new=NULL;
+		delete[]d_H_j_const_next_new;d_H_j_const_next_new=NULL;
+
+		delete[]d_H_edge_max_new;d_H_edge_max_new=NULL;
+		throw;
+	};
+
+
+}
+
+void alp::increment_W_weights()
+//the function calculates weigths for d_W_matr_len increased by 1
+//assumes that letters are defined for d_W_matr_len
+{
+	if(d_W_matr_len==-1)
+	{
+		d_WS_ij_next=1.0;
+		d_WI_ij_next=0.0;
+		d_WD_ij_next=0.0;
+
+		d_W_matr_len++;
+
+		d_alp_weights->set_elem(0,1.0);
+
+		return;
+	};
+
+	if(d_seqi_len<d_W_matr_len+1||d_seqj_len<d_W_matr_len+1)
+	{
+		throw error("Unexpected error in increment_W_weights\n",4);
+	};
+
+	if(d_W_matr_len+1>d_W_matr_a_len)
+	{
+		increment_W_matrix();
+	};
+
+	d_W_matr_len++;
+	
+
+	swap(d_WS_i_const_pred,d_WS_i_const_next);
+	swap(d_WI_i_const_pred,d_WI_i_const_next);
+	swap(d_WD_i_const_pred,d_WD_i_const_next);
+
+	swap(d_WS_j_const_pred,d_WS_j_const_next);
+	swap(d_WI_j_const_pred,d_WI_j_const_next);
+	swap(d_WD_j_const_pred,d_WD_j_const_next);
+
+	d_WS_ij_pred=d_WS_ij_next;
+	d_WI_ij_pred=d_WI_ij_next;
+	d_WD_ij_pred=d_WD_ij_next;
+
+	long int d_W_matr_len_1=d_W_matr_len-1;
+	long int d_W_matr_len_2=d_W_matr_len-2;
+
+	//boundary conditions
+	importance_sampling *&d_is_tmp=d_alp_data->d_is;
+
+	d_WS_i_const_next[d_W_matr_len_1]=0;
+	d_WS_j_const_next[d_W_matr_len_1]=0;
+
+	d_WI_i_const_next[d_W_matr_len_1]=0;
+	d_WD_j_const_next[d_W_matr_len_1]=0;
+
+	double deg_tmp=degree(d_is_tmp->d_nu,d_W_matr_len_1);
+
+	d_WD_i_const_next[d_W_matr_len_1]=d_is_tmp->d_mu_DS*deg_tmp;
+	d_WI_j_const_next[d_W_matr_len_1]=d_is_tmp->d_mu_IS*deg_tmp;
+
+
+
+	long int i;
+	for(i=d_W_matr_len_2;i>=1;i--)
+	{
+		d_WS_i_const_next[i]=d_is_tmp->d_exp_s[d_seqi[d_W_matr_len_1]][d_seqj[d_W_matr_len_2-i]]*(d_is_tmp->d_eta*d_WS_i_const_pred[i]+d_is_tmp->d_mu_SI*d_WI_i_const_pred[i]+d_is_tmp->d_mu_SD*d_WD_i_const_pred[i]);
+		d_WI_i_const_next[i]=d_is_tmp->d_mu_IS*d_WS_i_const_next[i+1]+d_is_tmp->d_nu*d_WI_i_const_next[i+1]+d_is_tmp->d_mu_ID*d_WD_i_const_next[i+1];
+		d_WD_i_const_next[i]=d_is_tmp->d_mu_DS*d_WS_i_const_pred[i-1]+d_is_tmp->d_nu*d_WD_i_const_pred[i-1];
+
+		d_WS_j_const_next[i]=d_is_tmp->d_exp_s[d_seqi[d_W_matr_len_2-i]][d_seqj[d_W_matr_len_1]]*(d_is_tmp->d_eta*d_WS_j_const_pred[i]+d_is_tmp->d_mu_SI*d_WI_j_const_pred[i]+d_is_tmp->d_mu_SD*d_WD_j_const_pred[i]);
+		d_WI_j_const_next[i]=d_is_tmp->d_mu_IS*d_WS_j_const_pred[i-1]+d_is_tmp->d_nu*d_WI_j_const_pred[i-1]+d_is_tmp->d_mu_ID*d_WD_j_const_pred[i-1];
+		d_WD_j_const_next[i]=d_is_tmp->d_mu_DS*d_WS_j_const_next[i+1]+d_is_tmp->d_nu*d_WD_j_const_next[i+1];
+	};
+
+	if(d_W_matr_len>1)
+	{
+		//copy of the previous lines with a modification for i-1
+		i=0;
+		d_WS_i_const_next[i]=d_is_tmp->d_exp_s[d_seqi[d_W_matr_len_1]][d_seqj[d_W_matr_len_2-i]]*(d_is_tmp->d_eta*d_WS_i_const_pred[i]+d_is_tmp->d_mu_SI*d_WI_i_const_pred[i]+d_is_tmp->d_mu_SD*d_WD_i_const_pred[i]);
+		d_WI_i_const_next[i]=d_is_tmp->d_mu_IS*d_WS_i_const_next[i+1]+d_is_tmp->d_nu*d_WI_i_const_next[i+1]+d_is_tmp->d_mu_ID*d_WD_i_const_next[i+1];
+		d_WD_i_const_next[i]=d_is_tmp->d_mu_DS*d_WS_ij_pred+d_is_tmp->d_nu*d_WD_ij_pred;
+
+		d_WS_j_const_next[i]=d_is_tmp->d_exp_s[d_seqi[d_W_matr_len_2-i]][d_seqj[d_W_matr_len_1]]*(d_is_tmp->d_eta*d_WS_j_const_pred[i]+d_is_tmp->d_mu_SI*d_WI_j_const_pred[i]+d_is_tmp->d_mu_SD*d_WD_j_const_pred[i]);
+		d_WI_j_const_next[i]=d_is_tmp->d_mu_IS*d_WS_ij_pred+d_is_tmp->d_nu*d_WI_ij_pred+d_is_tmp->d_mu_ID*d_WD_ij_pred;
+		d_WD_j_const_next[i]=d_is_tmp->d_mu_DS*d_WS_j_const_next[i+1]+d_is_tmp->d_nu*d_WD_j_const_next[i+1];
+	};
+
+
+	d_WS_ij_next=d_is_tmp->d_exp_s[d_seqi[d_W_matr_len_1]][d_seqj[d_W_matr_len_1]]*(d_is_tmp->d_eta*d_WS_ij_pred+d_is_tmp->d_mu_SI*d_WI_ij_pred+d_is_tmp->d_mu_SD*d_WD_ij_pred);
+	d_WI_ij_next=d_is_tmp->d_mu_IS*d_WS_i_const_next[0]+d_is_tmp->d_nu*d_WI_i_const_next[0]+d_is_tmp->d_mu_ID*d_WD_i_const_next[0];
+	d_WD_ij_next=d_is_tmp->d_mu_DS*d_WS_j_const_next[0]+d_is_tmp->d_nu*d_WD_j_const_next[0];
+
+	
+
+}
+
+double alp::degree(//returns x_^n_
+double x_,
+double n_)
+{
+	if(x_<0||n_<0)
+	{
+		throw error("Error - unexpected parameter in alp::degree\n",4);
+	};
+
+	if(x_==0)
+	{
+		if(n_==0)
+		{
+			return 1.0;
+		}
+		else
+		{
+			return 0.0;
+		};
+	};
+
+	return exp(n_*log(x_));
+
+}
+
+void alp::increment_H_weights()
+{
+	if(d_alp_data->d_insertions_after_deletions)
+	{
+		increment_H_weights_with_insertions_after_deletions();
+	}
+	else
+	{
+		increment_H_weights_without_insertions_after_deletions();
+	};
+}
+
+void alp::increment_H_weights_without_insertions_after_deletions()
+//the function calculates alignment scores for d_H_matr_len increased by 1
+//assumes that letters are defined for d_H_matr_len
+{
+	if(d_H_matr_len==-1)
+	{
+		d_HS_ij_next=0;
+		d_HI_ij_next=0;
+		d_HD_ij_next=0;
+		d_H_ij_next=0;
+		d_M=0;
+
+		d_nalp=0;
+		d_alp->set_elem(0,0);
+		d_H_I->set_elem(0,0);
+		d_H_J->set_elem(0,0);
+		d_alp_pos->set_elem(0,0);
+
+		d_cells_counts->increase_elem_by_1(0);
+
+		d_H_matr_len++;
+
+		d_alp_states->set_elem(d_nalp,NULL);
+		save_state(d_alp_states->d_elem[d_nalp]);
+
+		return;
+	};
+
+	if(d_seqi_len<d_H_matr_len+1||d_seqj_len<d_H_matr_len+1)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+	if(d_H_matr_len+1>d_H_matr_a_len)
+	{
+		increment_H_matrix();
+	};
+
+	d_H_matr_len++;
+	
+
+	swap(d_HS_i_const_pred,d_HS_i_const_next);
+	swap(d_HI_i_const_pred,d_HI_i_const_next);
+	swap(d_HD_i_const_pred,d_HD_i_const_next);
+	swap(d_H_i_const_pred,d_H_i_const_next);
+
+	swap(d_HS_j_const_pred,d_HS_j_const_next);
+	swap(d_HI_j_const_pred,d_HI_j_const_next);
+	swap(d_HD_j_const_pred,d_HD_j_const_next);
+	swap(d_H_j_const_pred,d_H_j_const_next);
+
+	d_HS_ij_pred=d_HS_ij_next;
+	d_HI_ij_pred=d_HI_ij_next;
+	d_HD_ij_pred=d_HD_ij_next;
+	d_H_ij_pred=d_H_ij_next;
+
+	long int d_H_matr_len_1=d_H_matr_len-1;
+	long int d_H_matr_len_2=d_H_matr_len-2;
+
+	//boundary conditions
+	//long int gap_tmp=-d_alp_data->d_open-d_H_matr_len_1*d_alp_data->d_epen;
+		long int gap_tmp1=-d_alp_data->d_open1-d_H_matr_len_1*d_alp_data->d_epen1;
+		long int gap_tmp2=-d_alp_data->d_open2-d_H_matr_len_1*d_alp_data->d_epen2;
+
+
+	d_HS_i_const_next[d_H_matr_len_1]=small_long;
+	d_HS_j_const_next[d_H_matr_len_1]=small_long;
+
+	d_HI_i_const_next[d_H_matr_len_1]=small_long;
+	d_HD_j_const_next[d_H_matr_len_1]=small_long;
+
+
+	d_HD_i_const_next[d_H_matr_len_1]=gap_tmp1;
+	d_HI_j_const_next[d_H_matr_len_1]=gap_tmp2;
+
+	d_H_i_const_next[d_H_matr_len_1]=gap_tmp1;
+	d_H_j_const_next[d_H_matr_len_1]=gap_tmp2;
+
+	long int i;
+	for(i=d_H_matr_len_2;i>=1;i--)
+	{
+		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
+		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2);
+		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_i_const_pred[i-1]-d_alp_data->d_open1,d_HD_i_const_pred[i-1]-d_alp_data->d_epen1);
+		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
+	
+
+		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
+		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_j_const_pred[i-1]-d_alp_data->d_open2,d_HI_j_const_pred[i-1]-d_alp_data->d_epen2);
+		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
+		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
+	};
+
+	if(d_H_matr_len>1)
+	{
+		//copy of the previous lines with a modification for i-1
+		i=0;
+		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
+		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2);
+		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open1,d_HD_ij_pred-d_alp_data->d_epen1);
+		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
+	
+
+		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
+		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open2,d_HI_ij_pred-d_alp_data->d_epen2);
+		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
+		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
+	};
+
+	d_HS_ij_next=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_1]]+d_H_ij_pred;
+	d_HI_ij_next=alp_data::Tmax(d_HS_i_const_next[0]-d_alp_data->d_open2,d_HI_i_const_next[0]-d_alp_data->d_epen2);
+	d_HD_ij_next=alp_data::Tmax(d_HS_j_const_next[0]-d_alp_data->d_open1,d_HD_j_const_next[0]-d_alp_data->d_epen1);
+	d_H_ij_next=alp_data::Tmax(d_HS_ij_next,d_HI_ij_next,d_HD_ij_next);
+
+	d_cells_counts->increase_elem_by_1(d_H_ij_next);
+	for(i=0;i<=d_H_matr_len_1;i++)
+	{
+		d_cells_counts->increase_elem_by_1(d_H_i_const_next[i]);
+		d_cells_counts->increase_elem_by_1(d_H_j_const_next[i]);
+	};
+
+
+	long int tmp=d_H_ij_next;
+	for(i=0;i<=d_H_matr_len_1;i++)
+	{
+		tmp=alp_data::Tmax(tmp,d_H_i_const_next[i]);
+		tmp=alp_data::Tmax(tmp,d_H_j_const_next[i]);
+	};
+
+	d_H_edge_max[d_H_matr_len]=tmp;
+	d_M=alp_data::Tmax(tmp,d_M);
+
+	d_sentinel_i_next=d_H_matr_len_1;
+	d_sentinel_j_next=d_H_matr_len_1;
+
+
+	if(d_is_now)
+	{
+		long int i;
+		if(tmp>d_alp->d_elem[d_nalp])
+		{
+			d_nalp++;
+			d_alp->set_elem(d_nalp,tmp);
+			d_alp_pos->set_elem(d_nalp,d_H_matr_len);
+
+			d_alp_states->set_elem(d_nalp,NULL);
+			save_state(d_alp_states->d_elem[d_nalp]);
+
+		
+			long int I=-1;
+			long int J=-1;
+
+			for(i=0;i<=d_H_matr_len_1;i++)
+			{
+				if(tmp==d_H_i_const_next[i])
+				{
+					I=i;
+				};
+
+				if(tmp==d_H_j_const_next[i])
+				{
+					J=i;
+				};
+			};
+
+			d_H_I->set_elem(d_nalp,d_H_matr_len-I-1);
+			d_H_J->set_elem(d_nalp,d_H_matr_len-J-1);
+
+
+		};
+	};
+
+
+	check_time_function();
+
+
+}
+
+
+void alp::increment_H_weights_with_insertions_after_deletions()
+//the function calculates alignment scores for d_H_matr_len increased by 1
+//assumes that letters are defined for d_H_matr_len
+{
+	if(d_H_matr_len==-1)
+	{
+		d_HS_ij_next=0;
+		d_HI_ij_next=0;
+		d_HD_ij_next=0;
+		d_H_ij_next=0;
+		d_M=0;
+
+		d_nalp=0;
+		d_alp->set_elem(0,0);
+		d_H_I->set_elem(0,0);
+		d_H_J->set_elem(0,0);
+		d_alp_pos->set_elem(0,0);
+
+		d_cells_counts->increase_elem_by_1(0);
+
+		d_H_matr_len++;
+
+		d_alp_states->set_elem(d_nalp,NULL);
+		save_state(d_alp_states->d_elem[d_nalp]);
+
+		return;
+	};
+
+	if(d_seqi_len<d_H_matr_len+1||d_seqj_len<d_H_matr_len+1)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+	if(d_H_matr_len+1>d_H_matr_a_len)
+	{
+		increment_H_matrix();
+	};
+
+	d_H_matr_len++;
+	
+
+	swap(d_HS_i_const_pred,d_HS_i_const_next);
+	swap(d_HI_i_const_pred,d_HI_i_const_next);
+	swap(d_HD_i_const_pred,d_HD_i_const_next);
+	swap(d_H_i_const_pred,d_H_i_const_next);
+
+	swap(d_HS_j_const_pred,d_HS_j_const_next);
+	swap(d_HI_j_const_pred,d_HI_j_const_next);
+	swap(d_HD_j_const_pred,d_HD_j_const_next);
+	swap(d_H_j_const_pred,d_H_j_const_next);
+
+	d_HS_ij_pred=d_HS_ij_next;
+	d_HI_ij_pred=d_HI_ij_next;
+	d_HD_ij_pred=d_HD_ij_next;
+	d_H_ij_pred=d_H_ij_next;
+
+	long int d_H_matr_len_1=d_H_matr_len-1;
+	long int d_H_matr_len_2=d_H_matr_len-2;
+
+	//boundary conditions
+	//long int gap_tmp=-d_alp_data->d_open-d_H_matr_len_1*d_alp_data->d_epen;
+	long int gap_tmp1=-d_alp_data->d_open1-d_H_matr_len_1*d_alp_data->d_epen1;
+	long int gap_tmp2=-d_alp_data->d_open2-d_H_matr_len_1*d_alp_data->d_epen2;
+
+
+	d_HS_i_const_next[d_H_matr_len_1]=small_long;
+	d_HS_j_const_next[d_H_matr_len_1]=small_long;
+
+	d_HI_i_const_next[d_H_matr_len_1]=small_long;
+	d_HD_j_const_next[d_H_matr_len_1]=small_long;
+
+
+	d_HD_i_const_next[d_H_matr_len_1]=gap_tmp1;
+	d_HI_j_const_next[d_H_matr_len_1]=gap_tmp2;
+
+	d_H_i_const_next[d_H_matr_len_1]=gap_tmp1;
+	d_H_j_const_next[d_H_matr_len_1]=gap_tmp2;
+
+	long int i;
+	for(i=d_H_matr_len_2;i>=1;i--)
+	{
+		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
+		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2,d_HD_i_const_next[i+1]-d_alp_data->d_open2);
+		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_i_const_pred[i-1]-d_alp_data->d_open1,d_HD_i_const_pred[i-1]-d_alp_data->d_epen1);
+		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
+
+
+		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
+		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_j_const_pred[i-1]-d_alp_data->d_open2,d_HI_j_const_pred[i-1]-d_alp_data->d_epen2,d_HD_j_const_pred[i-1]-d_alp_data->d_open2);
+		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
+		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
+
+
+	};
+
+	if(d_H_matr_len>1)
+	{
+		//copy of the previous lines with a modification for i-1
+		i=0;
+		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
+		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2,d_HD_i_const_next[i+1]-d_alp_data->d_open2);
+		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open1,d_HD_ij_pred-d_alp_data->d_epen1);
+		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
+	
+
+
+		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
+		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open2,d_HI_ij_pred-d_alp_data->d_epen2,d_HD_ij_pred-d_alp_data->d_open2);
+		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
+		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
+
+
+	};
+
+	d_HS_ij_next=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_1]]+d_H_ij_pred;
+	d_HI_ij_next=alp_data::Tmax(d_HS_i_const_next[0]-d_alp_data->d_open2,d_HI_i_const_next[0]-d_alp_data->d_epen2,d_HD_i_const_next[0]-d_alp_data->d_open2);
+	d_HD_ij_next=alp_data::Tmax(d_HS_j_const_next[0]-d_alp_data->d_open1,d_HD_j_const_next[0]-d_alp_data->d_epen1);
+	d_H_ij_next=alp_data::Tmax(d_HS_ij_next,d_HI_ij_next,d_HD_ij_next);
+
+
+
+	d_cells_counts->increase_elem_by_1(d_H_ij_next);
+	for(i=0;i<=d_H_matr_len_1;i++)
+	{
+		d_cells_counts->increase_elem_by_1(d_H_i_const_next[i]);
+		d_cells_counts->increase_elem_by_1(d_H_j_const_next[i]);
+	};
+
+
+	long int tmp=d_H_ij_next;
+	for(i=0;i<=d_H_matr_len_1;i++)
+	{
+		tmp=alp_data::Tmax(tmp,d_H_i_const_next[i]);
+		tmp=alp_data::Tmax(tmp,d_H_j_const_next[i]);
+	};
+
+	d_H_edge_max[d_H_matr_len]=tmp;
+	d_M=alp_data::Tmax(tmp,d_M);
+
+	d_sentinel_i_next=d_H_matr_len_1;
+	d_sentinel_j_next=d_H_matr_len_1;
+
+
+	if(d_is_now)
+	{
+		long int i;
+		if(tmp>d_alp->d_elem[d_nalp])
+		{
+			d_nalp++;
+			d_alp->set_elem(d_nalp,tmp);
+			d_alp_pos->set_elem(d_nalp,d_H_matr_len);
+
+			d_alp_states->set_elem(d_nalp,NULL);
+			save_state(d_alp_states->d_elem[d_nalp]);
+
+		
+			long int I=-1;
+			long int J=-1;
+
+			for(i=0;i<=d_H_matr_len_1;i++)
+			{
+				if(tmp==d_H_i_const_next[i])
+				{
+					I=i;
+				};
+
+				if(tmp==d_H_j_const_next[i])
+				{
+					J=i;
+				};
+			};
+
+			d_H_I->set_elem(d_nalp,d_H_matr_len-I-1);
+			d_H_J->set_elem(d_nalp,d_H_matr_len-J-1);
+
+
+		};
+	};
+
+
+	check_time_function();
+
+
+}
+
+void alp::check_time_function()
+{
+	if(d_check_time_flag)
+	{
+		double time_after3;
+		alp_data::get_current_time(time_after3);
+
+		if((time_after3-d_alp_data->d_time_before1)>d_alp_data->d_max_time)
+		{
+			if(d_time_error_flag)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			}
+			else
+			{
+				d_time_limit_flag=true;
+				if(d_single_realiztion_calculation_flag)
+				{
+					throw error_for_single_realization();
+				};
+				return;
+			};
+		};
+
+	};
+
+	if(d_alp_data->d_max_time<=0&&d_alp_data->d_max_time_with_computation_parameters>0)
+	{
+		double time_after3;
+		alp_data::get_current_time(time_after3);
+
+		if((time_after3-d_alp_data->d_time_before1)>d_alp_data->d_max_time_with_computation_parameters)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+	};
+}
+
+void alp::increment_H_weights_with_sentinels(
+	long int diff_opt_)
+//the function calculates alignment scores for d_H_matr_len increased by 1
+//assumes that letters are defined for d_H_matr_len
+//uses sentinels
+{
+	if(d_alp_data->d_insertions_after_deletions)
+	{
+		increment_H_weights_with_sentinels_with_insertions_after_deletions(diff_opt_);
+	}
+	else
+	{
+		increment_H_weights_with_sentinels_without_insertions_after_deletions(diff_opt_);
+	};
+
+}
+
+void alp::increment_H_weights_with_sentinels_without_insertions_after_deletions(
+	long int diff_opt_)
+//the function calculates alignment scores for d_H_matr_len increased by 1
+//assumes that letters are defined for d_H_matr_len
+//uses sentinels
+{
+	if(d_H_matr_len==-1)
+	{
+		d_HS_ij_next=0;
+		d_HI_ij_next=0;
+		d_HD_ij_next=0;
+		d_H_ij_next=0;
+		d_M=0;
+
+		d_nalp=0;
+		d_alp->set_elem(0,0);
+		d_H_I->set_elem(0,0);
+		d_H_J->set_elem(0,0);
+		d_alp_pos->set_elem(0,0);
+
+		d_cells_counts->increase_elem_by_1(0);
+
+		d_H_matr_len++;
+
+		d_alp_states->set_elem(d_nalp,NULL);
+		
+
+		d_sentinel_i_next=0;
+		d_sentinel_j_next=0;
+
+
+		save_state(d_alp_states->d_elem[d_nalp]);
+
+		
+
+		return;
+	};
+
+	if(d_seqi_len<d_H_matr_len+1||d_seqj_len<d_H_matr_len+1)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+
+	if(d_H_matr_len+1>d_H_matr_a_len)
+	{
+		increment_H_matrix();
+	};
+
+	d_H_matr_len++;
+	
+
+	swap(d_HS_i_const_pred,d_HS_i_const_next);
+	swap(d_HI_i_const_pred,d_HI_i_const_next);
+	swap(d_HD_i_const_pred,d_HD_i_const_next);
+	swap(d_H_i_const_pred,d_H_i_const_next);
+
+	swap(d_HS_j_const_pred,d_HS_j_const_next);
+	swap(d_HI_j_const_pred,d_HI_j_const_next);
+	swap(d_HD_j_const_pred,d_HD_j_const_next);
+	swap(d_H_j_const_pred,d_H_j_const_next);
+
+	
+
+	d_HS_ij_pred=d_HS_ij_next;
+	d_HI_ij_pred=d_HI_ij_next;
+	d_HD_ij_pred=d_HD_ij_next;
+	d_H_ij_pred=d_H_ij_next;
+
+	d_sentinel_i_pred=d_sentinel_i_next;
+	d_sentinel_j_pred=d_sentinel_j_next;
+
+
+	long int d_H_matr_len_1=d_H_matr_len-1;
+	long int d_H_matr_len_2=d_H_matr_len-2;
+
+	//boundary conditions
+	long int sentinel_i_boundary=alp_data::Tmin(d_sentinel_i_pred+(long int)2,d_H_matr_len_1);
+	long int sentinel_j_boundary=alp_data::Tmin(d_sentinel_j_pred+(long int)2,d_H_matr_len_1);
+
+
+
+	d_HS_i_const_next[sentinel_i_boundary]=small_long;
+	d_HS_j_const_next[sentinel_j_boundary]=small_long;
+
+	d_HI_i_const_next[sentinel_i_boundary]=small_long;
+	d_HD_j_const_next[sentinel_j_boundary]=small_long;
+
+
+	d_HD_i_const_next[sentinel_i_boundary]=small_long;
+	d_HI_j_const_next[sentinel_j_boundary]=small_long;
+
+	d_H_i_const_next[sentinel_i_boundary]=small_long;
+	d_H_j_const_next[sentinel_j_boundary]=small_long;
+
+	long int i;
+	for(i=sentinel_i_boundary-1;i>=1;i--)
+	{
+		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
+		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2);
+		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_i_const_pred[i-1]-d_alp_data->d_open1,d_HD_i_const_pred[i-1]-d_alp_data->d_epen1);
+		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
+	};
+
+	for(i=sentinel_j_boundary-1;i>=1;i--)
+	{
+		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
+		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_j_const_pred[i-1]-d_alp_data->d_open2,d_HI_j_const_pred[i-1]-d_alp_data->d_epen2);
+		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
+		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
+	};
+
+
+	if(d_H_matr_len>1)
+	{
+		//copy of the previous lines with a modification for i-1
+		i=0;
+		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
+		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2);
+		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open1,d_HD_ij_pred-d_alp_data->d_epen1);
+		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
+	
+
+		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
+		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open2,d_HI_ij_pred-d_alp_data->d_epen2);
+		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
+		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
+	};
+
+	d_HS_ij_next=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_1]]+d_H_ij_pred;
+	d_HI_ij_next=alp_data::Tmax(d_HS_i_const_next[0]-d_alp_data->d_open2,d_HI_i_const_next[0]-d_alp_data->d_epen2);
+	d_HD_ij_next=alp_data::Tmax(d_HS_j_const_next[0]-d_alp_data->d_open1,d_HD_j_const_next[0]-d_alp_data->d_epen1);
+	d_H_ij_next=alp_data::Tmax(d_HS_ij_next,d_HI_ij_next,d_HD_ij_next);
+
+	d_cells_counts->increase_elem_by_1(d_H_ij_next);
+	for(i=0;i<=sentinel_i_boundary-1;i++)
+	{
+		d_cells_counts->increase_elem_by_1(d_H_i_const_next[i]);
+	};
+
+	for(i=0;i<=sentinel_j_boundary-1;i++)
+	{
+		d_cells_counts->increase_elem_by_1(d_H_j_const_next[i]);
+	};
+
+	long int tmp=d_H_ij_next;
+	for(i=0;i<=sentinel_i_boundary-1;i++)
+	{
+		tmp=alp_data::Tmax(tmp,d_H_i_const_next[i]);
+	};
+
+	for(i=0;i<=sentinel_j_boundary-1;i++)
+	{
+		tmp=alp_data::Tmax(tmp,d_H_j_const_next[i]);
+	};
+
+
+	d_H_edge_max[d_H_matr_len]=tmp;
+	d_M=alp_data::Tmax(tmp,d_M);
+
+
+	{
+		long int level=tmp-diff_opt_;
+		long int i;
+		d_sentinel_i_next=1;
+		d_sentinel_j_next=1;
+		for(i=sentinel_i_boundary-1;i>=1;i--)
+		{
+			if(d_H_i_const_next[i]>=level)
+			{
+				d_sentinel_i_next=i;
+				break;
+			};
+		};
+
+		for(i=sentinel_j_boundary-1;i>=1;i--)
+		{
+			if(d_H_j_const_next[i]>=level)
+			{
+				d_sentinel_j_next=i;
+				break;
+			};
+		};
+	};
+
+
+	if(d_is_now)
+	{
+		long int i;
+		if(tmp>d_alp->d_elem[d_nalp])
+		{
+			d_nalp++;
+			d_alp->set_elem(d_nalp,tmp);
+			d_alp_pos->set_elem(d_nalp,d_H_matr_len);
+
+			d_alp_states->set_elem(d_nalp,NULL);
+			save_state(d_alp_states->d_elem[d_nalp]);
+
+		
+			long int I=-1;
+			long int J=-1;
+
+			for(i=0;i<=sentinel_i_boundary-1;i++)
+			{
+				if(tmp==d_H_i_const_next[i])
+				{
+					I=i;
+				};
+			};
+
+			for(i=0;i<=sentinel_j_boundary-1;i++)
+			{
+				if(tmp==d_H_j_const_next[i])
+				{
+					J=i;
+				};
+			};
+
+
+
+			d_H_I->set_elem(d_nalp,d_H_matr_len-I-1);
+			d_H_J->set_elem(d_nalp,d_H_matr_len-J-1);
+
+
+		};
+	};
+
+	check_time_function();
+
+}
+
+
+
+void alp::increment_H_weights_with_sentinels_with_insertions_after_deletions(
+	long int diff_opt_)
+//the function calculates alignment scores for d_H_matr_len increased by 1
+//assumes that letters are defined for d_H_matr_len
+//uses sentinels
+{
+	if(d_H_matr_len==-1)
+	{
+		d_HS_ij_next=0;
+		d_HI_ij_next=0;
+		d_HD_ij_next=0;
+		d_H_ij_next=0;
+		d_M=0;
+
+		d_nalp=0;
+		d_alp->set_elem(0,0);
+		d_H_I->set_elem(0,0);
+		d_H_J->set_elem(0,0);
+		d_alp_pos->set_elem(0,0);
+
+		d_cells_counts->increase_elem_by_1(0);
+
+		d_H_matr_len++;
+
+		d_alp_states->set_elem(d_nalp,NULL);
+		
+
+		d_sentinel_i_next=0;
+		d_sentinel_j_next=0;
+
+
+		save_state(d_alp_states->d_elem[d_nalp]);
+
+		
+
+		return;
+	};
+
+	if(d_seqi_len<d_H_matr_len+1||d_seqj_len<d_H_matr_len+1)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+
+	if(d_H_matr_len+1>d_H_matr_a_len)
+	{
+		increment_H_matrix();
+	};
+
+	d_H_matr_len++;
+	
+
+	swap(d_HS_i_const_pred,d_HS_i_const_next);
+	swap(d_HI_i_const_pred,d_HI_i_const_next);
+	swap(d_HD_i_const_pred,d_HD_i_const_next);
+	swap(d_H_i_const_pred,d_H_i_const_next);
+
+	swap(d_HS_j_const_pred,d_HS_j_const_next);
+	swap(d_HI_j_const_pred,d_HI_j_const_next);
+	swap(d_HD_j_const_pred,d_HD_j_const_next);
+	swap(d_H_j_const_pred,d_H_j_const_next);
+
+	
+
+	d_HS_ij_pred=d_HS_ij_next;
+	d_HI_ij_pred=d_HI_ij_next;
+	d_HD_ij_pred=d_HD_ij_next;
+	d_H_ij_pred=d_H_ij_next;
+
+	d_sentinel_i_pred=d_sentinel_i_next;
+	d_sentinel_j_pred=d_sentinel_j_next;
+
+
+	long int d_H_matr_len_1=d_H_matr_len-1;
+	long int d_H_matr_len_2=d_H_matr_len-2;
+
+	//boundary conditions
+	long int sentinel_i_boundary=alp_data::Tmin(d_sentinel_i_pred+(long int)2,d_H_matr_len_1);
+	long int sentinel_j_boundary=alp_data::Tmin(d_sentinel_j_pred+(long int)2,d_H_matr_len_1);
+
+
+
+	d_HS_i_const_next[sentinel_i_boundary]=small_long;
+	d_HS_j_const_next[sentinel_j_boundary]=small_long;
+
+	d_HI_i_const_next[sentinel_i_boundary]=small_long;
+	d_HD_j_const_next[sentinel_j_boundary]=small_long;
+
+
+	d_HD_i_const_next[sentinel_i_boundary]=small_long;
+	d_HI_j_const_next[sentinel_j_boundary]=small_long;
+
+	d_H_i_const_next[sentinel_i_boundary]=small_long;
+	d_H_j_const_next[sentinel_j_boundary]=small_long;
+
+	long int i;
+	for(i=sentinel_i_boundary-1;i>=1;i--)
+	{
+		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
+		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2,d_HD_i_const_next[i+1]-d_alp_data->d_open2);
+		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_i_const_pred[i-1]-d_alp_data->d_open1,d_HD_i_const_pred[i-1]-d_alp_data->d_epen1);
+		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
+	};
+
+	for(i=sentinel_j_boundary-1;i>=1;i--)
+	{
+		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
+		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_j_const_pred[i-1]-d_alp_data->d_open2,d_HI_j_const_pred[i-1]-d_alp_data->d_epen2,d_HD_j_const_pred[i-1]-d_alp_data->d_open2);
+		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
+		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
+	};
+
+
+	if(d_H_matr_len>1)
+	{
+		//copy of the previous lines with a modification for i-1
+		i=0;
+		d_HS_i_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_2-i]]+d_H_i_const_pred[i];
+		d_HI_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i+1]-d_alp_data->d_open2,d_HI_i_const_next[i+1]-d_alp_data->d_epen2,d_HD_i_const_next[i+1]-d_alp_data->d_open2);
+		d_HD_i_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open1,d_HD_ij_pred-d_alp_data->d_epen1);
+		d_H_i_const_next[i]=alp_data::Tmax(d_HS_i_const_next[i],d_HI_i_const_next[i],d_HD_i_const_next[i]);
+	
+
+		d_HS_j_const_next[i]=d_alp_data->d_smatr[d_seqi[d_H_matr_len_2-i]][d_seqj[d_H_matr_len_1]]+d_H_j_const_pred[i];
+		d_HI_j_const_next[i]=alp_data::Tmax(d_HS_ij_pred-d_alp_data->d_open2,d_HI_ij_pred-d_alp_data->d_epen2,d_HD_ij_pred-d_alp_data->d_open2);
+		d_HD_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i+1]-d_alp_data->d_open1,d_HD_j_const_next[i+1]-d_alp_data->d_epen1);
+		d_H_j_const_next[i]=alp_data::Tmax(d_HS_j_const_next[i],d_HI_j_const_next[i],d_HD_j_const_next[i]);
+	};
+
+	d_HS_ij_next=d_alp_data->d_smatr[d_seqi[d_H_matr_len_1]][d_seqj[d_H_matr_len_1]]+d_H_ij_pred;
+	d_HI_ij_next=alp_data::Tmax(d_HS_i_const_next[0]-d_alp_data->d_open2,d_HI_i_const_next[0]-d_alp_data->d_epen2,d_HD_i_const_next[0]-d_alp_data->d_open2);
+	d_HD_ij_next=alp_data::Tmax(d_HS_j_const_next[0]-d_alp_data->d_open1,d_HD_j_const_next[0]-d_alp_data->d_epen1);
+	d_H_ij_next=alp_data::Tmax(d_HS_ij_next,d_HI_ij_next,d_HD_ij_next);
+
+	d_cells_counts->increase_elem_by_1(d_H_ij_next);
+	for(i=0;i<=sentinel_i_boundary-1;i++)
+	{
+		d_cells_counts->increase_elem_by_1(d_H_i_const_next[i]);
+	};
+
+	for(i=0;i<=sentinel_j_boundary-1;i++)
+	{
+		d_cells_counts->increase_elem_by_1(d_H_j_const_next[i]);
+	};
+
+	long int tmp=d_H_ij_next;
+	for(i=0;i<=sentinel_i_boundary-1;i++)
+	{
+		tmp=alp_data::Tmax(tmp,d_H_i_const_next[i]);
+	};
+
+	for(i=0;i<=sentinel_j_boundary-1;i++)
+	{
+		tmp=alp_data::Tmax(tmp,d_H_j_const_next[i]);
+	};
+
+
+	d_H_edge_max[d_H_matr_len]=tmp;
+	d_M=alp_data::Tmax(tmp,d_M);
+
+
+	{
+		long int level=tmp-diff_opt_;
+		long int i;
+		d_sentinel_i_next=1;
+		d_sentinel_j_next=1;
+		for(i=sentinel_i_boundary-1;i>=1;i--)
+		{
+			if(d_H_i_const_next[i]>=level)
+			{
+				d_sentinel_i_next=i;
+				break;
+			};
+		};
+
+		for(i=sentinel_j_boundary-1;i>=1;i--)
+		{
+			if(d_H_j_const_next[i]>=level)
+			{
+				d_sentinel_j_next=i;
+				break;
+			};
+		};
+	};
+
+
+	if(d_is_now)
+	{
+		long int i;
+		if(tmp>d_alp->d_elem[d_nalp])
+		{
+			d_nalp++;
+			d_alp->set_elem(d_nalp,tmp);
+			d_alp_pos->set_elem(d_nalp,d_H_matr_len);
+
+			d_alp_states->set_elem(d_nalp,NULL);
+			save_state(d_alp_states->d_elem[d_nalp]);
+
+		
+			long int I=-1;
+			long int J=-1;
+
+			for(i=0;i<=sentinel_i_boundary-1;i++)
+			{
+				if(tmp==d_H_i_const_next[i])
+				{
+					I=i;
+				};
+			};
+
+			for(i=0;i<=sentinel_j_boundary-1;i++)
+			{
+				if(tmp==d_H_j_const_next[i])
+				{
+					J=i;
+				};
+			};
+
+
+
+			d_H_I->set_elem(d_nalp,d_H_matr_len-I-1);
+			d_H_J->set_elem(d_nalp,d_H_matr_len-J-1);
+
+
+		};
+	};
+
+	check_time_function();
+
+}
+
+
+
+void alp::restore_state(
+state * &state_)
+{
+	d_M=state_->d_M;
+	d_H_matr_len=state_->d_H_matr_len;
+
+	if(d_H_matr_len<0)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+
+	d_is_now=false;
+
+	delete d_cells_counts;d_cells_counts=NULL;
+
+	d_cells_counts=new array<long int>(d_alp_data);
+	alp_data::assert_mem(d_cells_counts);
+
+
+	d_cells_counts->set_elems(state_->d_cells_counts);
+
+
+	d_HS_ij_next=state_->d_HS_ij_next;
+	d_HI_ij_next=state_->d_HI_ij_next;
+	d_HD_ij_next=state_->d_HD_ij_next;
+	d_H_ij_next=state_->d_H_ij_next;
+
+	long int i;
+	for(i=0;i<d_H_matr_len;i++)
+	{
+		d_HS_i_const_next[i]=state_->d_HS_i_const_next[i];
+		d_HI_i_const_next[i]=state_->d_HI_i_const_next[i];
+		d_HD_i_const_next[i]=state_->d_HD_i_const_next[i];
+		d_H_i_const_next[i]=state_->d_H_i_const_next[i];
+		d_HS_j_const_next[i]=state_->d_HS_j_const_next[i];
+		d_HI_j_const_next[i]=state_->d_HI_j_const_next[i];
+		d_HD_j_const_next[i]=state_->d_HD_j_const_next[i];
+		d_H_j_const_next[i]=state_->d_H_j_const_next[i];
+	};
+
+	d_sentinel_i_next=state_->d_sentinel_i_next;
+	d_sentinel_j_next=state_->d_sentinel_j_next;
+
+
+}
+
+state::state()
+{
+	d_cells_counts=NULL;
+
+	d_HS_i_const_next=NULL;
+	d_HI_i_const_next=NULL;
+	d_HD_i_const_next=NULL;
+	d_H_i_const_next=NULL;
+
+	d_HS_j_const_next=NULL;
+	d_HI_j_const_next=NULL;
+	d_HD_j_const_next=NULL;
+	d_H_j_const_next=NULL;
+
+}
+
+void alp::save_state(
+state * &state_)
+{
+	if(d_H_matr_len<0)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+	state_=new state;
+	alp_data::assert_mem(state_);
+
+	d_alp_data->d_memory_size_in_MB+=(double)(sizeof(state))/mb_bytes;
+
+
+	state_->d_M=d_M;
+
+	state_->d_cells_counts=new array<long int>(d_alp_data);
+	alp_data::assert_mem(state_->d_cells_counts);
+
+	d_alp_data->d_memory_size_in_MB+=(double)(sizeof(array<long int>))/mb_bytes;
+
+	state_->d_cells_counts->set_elems(d_cells_counts);
+
+	state_->d_H_matr_len=d_H_matr_len;
+
+	state_->d_HS_ij_next=d_HS_ij_next;
+	state_->d_HI_ij_next=d_HI_ij_next;
+	state_->d_HD_ij_next=d_HD_ij_next;
+	state_->d_H_ij_next=d_H_ij_next;
+
+	if(d_H_matr_len==0)
+	{
+		state_->d_HS_i_const_next=NULL;;
+		state_->d_HI_i_const_next=NULL;;
+		state_->d_HD_i_const_next=NULL;;
+		state_->d_H_i_const_next=NULL;;
+		state_->d_HS_j_const_next=NULL;;
+		state_->d_HI_j_const_next=NULL;;
+		state_->d_HD_j_const_next=NULL;;
+		state_->d_H_j_const_next=NULL;
+
+
+	}
+	else
+	{
+		state_->d_HS_i_const_next=new long int[d_H_matr_len];
+		alp_data::assert_mem(state_->d_HS_i_const_next);
+
+		state_->d_HI_i_const_next=new long int[d_H_matr_len];
+		alp_data::assert_mem(state_->d_HI_i_const_next);
+
+		state_->d_HD_i_const_next=new long int[d_H_matr_len];
+		alp_data::assert_mem(state_->d_HD_i_const_next);
+
+		state_->d_H_i_const_next=new long int[d_H_matr_len];
+		alp_data::assert_mem(state_->d_H_i_const_next);
+
+		state_->d_HS_j_const_next=new long int[d_H_matr_len];
+		alp_data::assert_mem(state_->d_HS_j_const_next);
+
+		state_->d_HI_j_const_next=new long int[d_H_matr_len];
+		alp_data::assert_mem(state_->d_HI_j_const_next);
+
+		state_->d_HD_j_const_next=new long int[d_H_matr_len];
+		alp_data::assert_mem(state_->d_HD_j_const_next);
+
+		state_->d_H_j_const_next=new long int[d_H_matr_len];
+		alp_data::assert_mem(state_->d_H_j_const_next);
+
+		d_alp_data->d_memory_size_in_MB+=8.0*(double)(d_H_matr_len*sizeof(long int))/mb_bytes;
+
+		long int i;
+		for(i=0;i<d_H_matr_len;i++)
+		{
+			state_->d_HS_i_const_next[i]=d_HS_i_const_next[i];
+			state_->d_HI_i_const_next[i]=d_HI_i_const_next[i];
+			state_->d_HD_i_const_next[i]=d_HD_i_const_next[i];
+			state_->d_H_i_const_next[i]=d_H_i_const_next[i];
+			state_->d_HS_j_const_next[i]=d_HS_j_const_next[i];
+			state_->d_HI_j_const_next[i]=d_HI_j_const_next[i];
+			state_->d_HD_j_const_next[i]=d_HD_j_const_next[i];
+			state_->d_H_j_const_next[i]=d_H_j_const_next[i];
+		};
+
+	};
+
+	state_->d_sentinel_i_next=d_sentinel_i_next;
+	state_->d_sentinel_j_next=d_sentinel_j_next;
+
+}
+
+void alp::kill_upto_level(
+long int M_min_,
+long int M_level_,
+long int *M_upper_level_)
+{
+	if(d_is_now)
+	{
+		while(d_alp->d_elem[d_nalp]<M_min_)
+		{
+			simulate_next_alp();
+			if(!d_success)
+			{
+				return;
+			};
+		};
+		d_is_now=false;
+
+		long int i;
+		d_nalp_killing=-1;
+		for(i=0;i<=d_nalp;i++)
+		{
+			if(d_alp->d_elem[i]>=M_min_)
+			{
+				d_nalp_killing=i;
+				break;
+			};
+		};
+
+		if(d_nalp_killing==-1)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+		restore_state(d_alp_states->d_elem[d_nalp_killing]);
+
+	};
+
+	while(d_H_edge_max[d_H_matr_len]>=M_level_)
+	{
+		if(d_H_matr_len+1>=d_alp_data->d_dim1_tmp)
+		{
+			d_success=false;
+			return;
+		};
+
+		if(M_upper_level_)
+		{
+			if(d_H_edge_max[d_H_matr_len]>(*M_upper_level_))
+			{
+				d_success=false;
+				return;
+			};
+		};
+		
+
+		if(d_H_matr_len+1>d_seq_a_len)
+		{
+			increment_sequences();
+		};
+
+
+		d_seqi_len=d_seqj_len=d_H_matr_len+1;
+		d_seqi[d_seqi_len-1]=random_AA1();
+		d_seqj[d_seqj_len-1]=random_AA2();
+
+		if(d_sentinels_flag)
+		{
+			increment_H_weights_with_sentinels(d_diff_opt);
+		}
+		else
+		{
+			increment_H_weights();
+		};
+
+		if(d_time_limit_flag)
+		{
+			d_success=false;
+			return;
+		};
+
+	};
+
+	d_success=true;
+}
+
+double alp::John2_weight_calculation(
+long int length_)//calculation of weigths for the importance sampling
+{
+	if(length_==0)
+	{
+		return 1.0;
+	};
+
+	if(d_W_matr_len>length_)
+	{
+		throw error("Error - unexpected parameter in alp::John2_weight_calculation\n",4);
+	};
+
+	while(d_W_matr_len<length_)
+	{
+		increment_W_weights();
+	};
+
+	importance_sampling *&d_is_tmp=d_alp_data->d_is;
+
+	long int d_W_matr_len_1=d_W_matr_len-1;
+
+	double US=0;
+	double UD=0;
+	double UI=d_WI_j_const_next[d_W_matr_len_1]/(1-(d_is_tmp->d_nu));
+
+	double VS=0;
+	double VI=0;
+	double VD=d_WD_i_const_next[d_W_matr_len_1]/(1-(d_is_tmp->d_nu));
+
+	long int j;
+	for(j=1;j<=length_-1;j++)
+	{
+		double US_next=d_alp_data->d_r_i_dot[d_seqi[j-1]]*((d_is_tmp->d_eta)*US+(d_is_tmp->d_mu_SI)*UI+(d_is_tmp->d_mu_SD)*UD)+d_WS_j_const_next[d_W_matr_len_1-j];
+		double UD_next=((d_is_tmp->d_mu_DS)*US+(d_is_tmp->d_nu)*UD);
+		double UI_next=((d_is_tmp->d_mu_IS)*US_next+(d_is_tmp->d_mu_ID)*UD_next+d_WI_j_const_next[d_W_matr_len_1-j])/(1-(d_is_tmp->d_nu));
+
+		double VS_next=d_alp_data->d_r_dot_j[d_seqj[j-1]]*((d_is_tmp->d_eta)*VS+(d_is_tmp->d_mu_SI)*VI+(d_is_tmp->d_mu_SD)*VD)+d_WS_i_const_next[d_W_matr_len_1-j];
+		double VI_next=((d_is_tmp->d_mu_IS)*VS+(d_is_tmp->d_mu_ID)*VD+(d_is_tmp->d_nu)*VI);
+		double VD_next=((d_is_tmp->d_mu_DS)*VS_next+d_WD_i_const_next[d_W_matr_len_1-j])/(1-(d_is_tmp->d_nu));
+
+		US=US_next;
+		UD=UD_next;
+		UI=UI_next;
+
+		VS=VS_next;
+		VD=VD_next;
+		VI=VI_next;
+	};
+
+	//copy
+	j=length_;
+	double US_next=d_alp_data->d_r_i_dot[d_seqi[j-1]]*((d_is_tmp->d_eta)*US+(d_is_tmp->d_mu_SI)*UI+(d_is_tmp->d_mu_SD)*UD)+d_WS_ij_next;
+	double UD_next=((d_is_tmp->d_mu_DS)*US+(d_is_tmp->d_nu)*UD);
+	double UI_next=((d_is_tmp->d_mu_IS)*US_next+(d_is_tmp->d_mu_ID)*UD_next+d_WI_ij_next)/(1-(d_is_tmp->d_nu));
+
+	double VS_next=d_alp_data->d_r_dot_j[d_seqj[j-1]]*((d_is_tmp->d_eta)*VS+(d_is_tmp->d_mu_SI)*VI+(d_is_tmp->d_mu_SD)*VD)+d_WS_ij_next;
+	double VI_next=((d_is_tmp->d_mu_IS)*VS+(d_is_tmp->d_mu_ID)*VD+(d_is_tmp->d_nu)*VI);
+	double VD_next=((d_is_tmp->d_mu_DS)*VS_next+d_WD_ij_next)/(1-(d_is_tmp->d_nu));
+
+	US=US_next;
+	UD=UD_next;
+	UI=UI_next;
+
+	VS=VS_next;
+	VD=VD_next;
+	VI=VI_next;
+
+
+	double weight=-d_WS_ij_next+US+UD+VS+VI;
+
+
+
+
+	if(weight==0)
+	{
+		throw error("Unexpected error\n",4);
+	};
+	weight=1.0/weight;
+
+	return weight;
+
+}
+
+void alp::simulate_next_alp()//simulates next ALP
+{
+	if(!d_success)
+	{
+		return;
+	};
+
+	if(!d_is_now)
+	{
+		throw error("Unexpected error - ALP can be generated only in the importance sampling mode\n",4);
+	};
+
+	long int target_nalp=d_nalp+1;
+
+	while(d_nalp<target_nalp)
+	{
+		long int k=alp_data::Tmin(d_seqi_len,d_seqj_len);
+		//std::cout<<k<<"\t"<<this->d_H_edge_max[k]<<std::endl;
+
+		while(alp_data::Tmin(d_seqi_len,d_seqj_len)!=k+1)
+		{
+			bool success=one_step_of_importance_sampling_without_weight_calculation(
+			d_alp_data->d_dim1_tmp,
+			d_alp_data->d_dim2_tmp);
+
+
+			check_time_function();
+
+			if(!success)
+			{
+				d_success=false;
+				return;
+			};
+		};
+
+		if(d_sentinels_flag)
+		{
+			increment_H_weights_with_sentinels(d_diff_opt);
+		}
+		else
+		{
+			increment_H_weights();
+		};
+
+		if(d_time_limit_flag)
+		{
+			d_success=false;
+			return;
+		};
+
+
+		increment_W_weights();
+	};
+
+	double weight=John2_weight_calculation(alp_data::Tmin(d_seqi_len,d_seqj_len));
+	if(weight<=0)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+	d_alp_weights->set_elem(d_nalp,weight);
+
+}
+
+void alp::simulate_alp_upto_the_given_number(//simulates ALP upto the given number nalp_ including
+long int nalp_)
+{
+	d_sentinels_flag=false;
+	while(d_nalp<nalp_)
+	{
+		simulate_next_alp();
+		if(!d_success)
+		{
+			return;
+		};
+	};
+}
+
+void alp::simulate_alp_upto_the_given_level(//simulates ALP upto the given level M_min_ including
+long int M_min_)
+{
+	d_sentinels_flag=false;
+	while(d_alp->d_elem[d_nalp]<M_min_)
+	{
+		simulate_next_alp();
+		if(!d_success)
+		{
+			return;
+		};
+	};
+	d_nalp_killing=d_nalp;
+}
+
diff --git a/src/alp/sls_alp.hpp b/src/alp/sls_alp.hpp
index 7d3f6c4..0ce4e7d 100644
--- a/src/alp/sls_alp.hpp
+++ b/src/alp/sls_alp.hpp
@@ -1,364 +1,364 @@
-#ifndef INCLUDED_SLS_ALP
-#define INCLUDED_SLS_ALP
-
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_alp.hpp
-
-Author: Sergey Sheetlin
-
-Contents: Ascending ladder points simulation
-
-******************************************************************************/
-
-#include <complex>
-#include <iostream>
-#include <map>
-#include <vector>
-#include <fstream>
-#include <float.h>
-
-
-#include "sls_alp_data.hpp"
-#include "sls_alp_regression.hpp"
-
-
-namespace Sls {
-
-
-	class state//struct to save a state of calculation
-	{
-	public:
-		state();
-
-	public:
-		array<long int> *d_cells_counts;
-
-		long int *d_HS_i_const_next;
-		long int *d_HI_i_const_next;
-		long int *d_HD_i_const_next;
-		long int *d_H_i_const_next;
-
-		long int *d_HS_j_const_next;
-		long int *d_HI_j_const_next;
-		long int *d_HD_j_const_next;
-		long int *d_H_j_const_next;
-
-		long int d_HS_ij_next;
-		long int d_HI_ij_next;
-		long int d_HD_ij_next;
-		long int d_H_ij_next;
-
-		long int d_H_matr_len;
-
-		long int d_M;
-
-		long int d_sentinel_i_next;
-		long int d_sentinel_j_next;
-
-	};
-
-
-	class alp{
-
-	
-
-	public:
-
-
-	alp(//constructor
-		alp_data *alp_data_
-		);
-
-
-	~alp();//destructor
-
-	long int random_AA1();//generates random AA for the sequence 1
-	long int random_AA2();//generates random AA for the sequence 2
-
-	bool one_step_of_importance_sampling_without_weight_calculation(
-		long int d_dim1_,
-		long int d_dim2_);
-
-	void increment_sequences();
-
-	void increment_W_matrix();
-	void increment_H_matrix();
-
-	void increment_W_weights();
-	//the function calculates weigths for d_W_matr_len increased by 1
-	//assumes that letters are defined for d_W_matr_len
-
-	void increment_H_weights();
-	//the function calculates alignment scores for d_H_matr_len increased by 1
-	//assumes that letters are defined for d_H_matr_len
-
-	void increment_H_weights_without_insertions_after_deletions();
-
-	void increment_H_weights_with_insertions_after_deletions();
-
-
-	void increment_H_weights_with_sentinels(
-		long int diff_opt_);
-	//the function calculates alignment scores for d_H_matr_len increased by 1
-	//assumes that letters are defined for d_H_matr_len
-	//uses sentinels
-
-	void increment_H_weights_with_sentinels_without_insertions_after_deletions(
-	long int diff_opt_);
-
-	void increment_H_weights_with_sentinels_with_insertions_after_deletions(
-	long int diff_opt_);
-
-
-
-	void simulate_next_alp();//simulates next ALP
-
-	void simulate_alp_upto_the_given_number(//simulates ALP upto the given number nalp_ including
-	long int nalp_);
-
-	void simulate_alp_upto_the_given_level(//simulates ALP upto the given level M_min_ including
-	long int M_min_);
-
-
-
-
-
-	template<typename T>
-	inline void swap(
-	T& a1_,
-	T& a2_)
-	{
-		T tmp=a1_;
-		a1_=a2_;
-		a2_=tmp;
-	}
-
-	static double degree(//returns x_^n_
-		double x_,
-		double n_);
-
-
-	double John2_weight_calculation(
-		long int length_);//calculation of weigths for the importance sampling
-
-	void save_state(
-		state * &state_);
-
-	void restore_state(
-		state * &state_);
-
-	void kill_upto_level(
-		long int M_min_,
-		long int M_level_,
-		long int *M_upper_level_=NULL);
-
-	void check_time_function();
-
-	template<typename T>
-	void release_and_calculate_memory(
-	T *&pointer_,
-	long int dim_)
-	{
-		if(pointer_==NULL)
-		{
-			return;
-		};
-		delete[]pointer_;pointer_=NULL;
-		if(d_alp_data)
-		{
-			d_alp_data->d_memory_size_in_MB-=(double)(sizeof(T)*dim_)/mb_bytes;
-		};
-		
-	}
-
-
-	template<typename T>
-	void release_and_calculate_memory(
-	T *&pointer_)
-	{
-		if(pointer_==NULL)
-		{
-			return;
-		};
-		delete pointer_;pointer_=NULL;
-		if(d_alp_data)
-		{
-			d_alp_data->d_memory_size_in_MB-=(double)(sizeof(T))/mb_bytes;
-		};
-		
-	}
-
-	void partially_release_memory();
-
-
-
-
-
-
-
-	public:
-
-
-				
-	alp_data *d_alp_data;//initial data
-	long int d_a_step;//increment for sequence length during memory allocation
-
-
-	bool d_is_now;//true if the importance sampling is being used 
-
-	
-
-
-
-	//alignment data
-
-	long int d_seqi_len;//current length of sequence 1
-	long int d_seqj_len;//current length of sequence 2
-
-
-	long int d_seq_a_len;//current length for memory allocation for the sequences
-	long int d_H_matr_a_len;//current length for memory allocation for the matrices H
-	long int d_W_matr_a_len;//current length for memory allocation for the matrices W
-
-	long int *d_seqi;//AA from sequence 1 for the next step
-	long int *d_seqj;//AA from sequence 2 for the next step
-
-	long int d_H_matr_len;//length of the matrices H currently calculated
-	long int d_W_matr_len;//length of the matrices W currently calculated
-
-	//the importance sampling weights
-	double *d_WS_i_const_pred;
-	double *d_WI_i_const_pred;
-	double *d_WD_i_const_pred;
-
-	double *d_WS_i_const_next;
-	double *d_WI_i_const_next;
-	double *d_WD_i_const_next;
-
-	double *d_WS_j_const_pred;
-	double *d_WI_j_const_pred;
-	double *d_WD_j_const_pred;
-
-	double *d_WS_j_const_next;
-	double *d_WI_j_const_next;
-	double *d_WD_j_const_next;
-
-	double d_WS_ij_pred;
-	double d_WI_ij_pred;
-	double d_WD_ij_pred;
-
-	double d_WS_ij_next;
-	double d_WI_ij_next;
-	double d_WD_ij_next;
-
-
-	//alignment matrix 
-	long int *d_HS_i_const_pred;
-	long int *d_HI_i_const_pred;
-	long int *d_HD_i_const_pred;
-	long int *d_H_i_const_pred;
-
-	long int *d_HS_i_const_next;
-	long int *d_HI_i_const_next;
-	long int *d_HD_i_const_next;
-	long int *d_H_i_const_next;
-
-	long int *d_HS_j_const_pred;
-	long int *d_HI_j_const_pred;
-	long int *d_HD_j_const_pred;
-	long int *d_H_j_const_pred;
-
-	long int *d_HS_j_const_next;
-	long int *d_HI_j_const_next;
-	long int *d_HD_j_const_next;
-	long int *d_H_j_const_next;
-
-	long int d_HS_ij_pred;
-	long int d_HI_ij_pred;
-	long int d_HD_ij_pred;
-	long int d_H_ij_pred;
-
-	long int d_HS_ij_next;
-	long int d_HI_ij_next;
-	long int d_HD_ij_next;
-	long int d_H_ij_next;
-
-	bool d_success;
-
-	//statistics
-	long int *d_H_edge_max;
-	long int d_M;
-
-	long int d_nalp;
-	long int d_nalp_killing;
-	array_positive<long int> *d_alp;
-
-	array_positive<long int> *d_H_I;
-	array_positive<long int> *d_H_J;
-
-	array_positive<long int> *d_alp_pos;
-	array_positive<double> *d_alp_weights;
-
-	array<long int> *d_cells_counts;
-
-	array_positive<state*> *d_alp_states;
-
-	long int d_sentinel_i_next;
-	long int d_sentinel_j_next;
-
-	long int d_sentinel_i_pred;
-	long int d_sentinel_j_pred;
-
-	long int d_diff_opt;
-	bool d_sentinels_flag;
-
-	bool d_check_time_flag;
-	bool d_time_error_flag;
-	bool d_time_limit_flag;
-
-	bool d_single_realiztion_calculation_flag;
-
-
-
-	//for the importance sampling
-	char d_IS_state;
-
-
-
-
-				
-
-
-	};
-
-}
-
-
-#endif
-
+#ifndef INCLUDED_SLS_ALP
+#define INCLUDED_SLS_ALP
+
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_alp.hpp
+
+Author: Sergey Sheetlin
+
+Contents: Ascending ladder points simulation
+
+******************************************************************************/
+
+#include <complex>
+#include <iostream>
+#include <map>
+#include <vector>
+#include <fstream>
+#include <float.h>
+
+
+#include "sls_alp_data.hpp"
+#include "sls_alp_regression.hpp"
+
+
+namespace Sls {
+
+
+	class state//struct to save a state of calculation
+	{
+	public:
+		state();
+
+	public:
+		array<long int> *d_cells_counts;
+
+		long int *d_HS_i_const_next;
+		long int *d_HI_i_const_next;
+		long int *d_HD_i_const_next;
+		long int *d_H_i_const_next;
+
+		long int *d_HS_j_const_next;
+		long int *d_HI_j_const_next;
+		long int *d_HD_j_const_next;
+		long int *d_H_j_const_next;
+
+		long int d_HS_ij_next;
+		long int d_HI_ij_next;
+		long int d_HD_ij_next;
+		long int d_H_ij_next;
+
+		long int d_H_matr_len;
+
+		long int d_M;
+
+		long int d_sentinel_i_next;
+		long int d_sentinel_j_next;
+
+	};
+
+
+	class alp{
+
+	
+
+	public:
+
+
+	alp(//constructor
+		alp_data *alp_data_
+		);
+
+
+	~alp();//destructor
+
+	long int random_AA1();//generates random AA for the sequence 1
+	long int random_AA2();//generates random AA for the sequence 2
+
+	bool one_step_of_importance_sampling_without_weight_calculation(
+		long int d_dim1_,
+		long int d_dim2_);
+
+	void increment_sequences();
+
+	void increment_W_matrix();
+	void increment_H_matrix();
+
+	void increment_W_weights();
+	//the function calculates weigths for d_W_matr_len increased by 1
+	//assumes that letters are defined for d_W_matr_len
+
+	void increment_H_weights();
+	//the function calculates alignment scores for d_H_matr_len increased by 1
+	//assumes that letters are defined for d_H_matr_len
+
+	void increment_H_weights_without_insertions_after_deletions();
+
+	void increment_H_weights_with_insertions_after_deletions();
+
+
+	void increment_H_weights_with_sentinels(
+		long int diff_opt_);
+	//the function calculates alignment scores for d_H_matr_len increased by 1
+	//assumes that letters are defined for d_H_matr_len
+	//uses sentinels
+
+	void increment_H_weights_with_sentinels_without_insertions_after_deletions(
+	long int diff_opt_);
+
+	void increment_H_weights_with_sentinels_with_insertions_after_deletions(
+	long int diff_opt_);
+
+
+
+	void simulate_next_alp();//simulates next ALP
+
+	void simulate_alp_upto_the_given_number(//simulates ALP upto the given number nalp_ including
+	long int nalp_);
+
+	void simulate_alp_upto_the_given_level(//simulates ALP upto the given level M_min_ including
+	long int M_min_);
+
+
+
+
+
+	template<typename T>
+	inline void swap(
+	T& a1_,
+	T& a2_)
+	{
+		T tmp=a1_;
+		a1_=a2_;
+		a2_=tmp;
+	}
+
+	static double degree(//returns x_^n_
+		double x_,
+		double n_);
+
+
+	double John2_weight_calculation(
+		long int length_);//calculation of weigths for the importance sampling
+
+	void save_state(
+		state * &state_);
+
+	void restore_state(
+		state * &state_);
+
+	void kill_upto_level(
+		long int M_min_,
+		long int M_level_,
+		long int *M_upper_level_=NULL);
+
+	void check_time_function();
+
+	template<typename T>
+	void release_and_calculate_memory(
+	T *&pointer_,
+	long int dim_)
+	{
+		if(pointer_==NULL)
+		{
+			return;
+		};
+		delete[]pointer_;pointer_=NULL;
+		if(d_alp_data)
+		{
+			d_alp_data->d_memory_size_in_MB-=(double)(sizeof(T)*dim_)/mb_bytes;
+		};
+		
+	}
+
+
+	template<typename T>
+	void release_and_calculate_memory(
+	T *&pointer_)
+	{
+		if(pointer_==NULL)
+		{
+			return;
+		};
+		delete pointer_;pointer_=NULL;
+		if(d_alp_data)
+		{
+			d_alp_data->d_memory_size_in_MB-=(double)(sizeof(T))/mb_bytes;
+		};
+		
+	}
+
+	void partially_release_memory();
+
+
+
+
+
+
+
+	public:
+
+
+				
+	alp_data *d_alp_data;//initial data
+	long int d_a_step;//increment for sequence length during memory allocation
+
+
+	bool d_is_now;//true if the importance sampling is being used 
+
+	
+
+
+
+	//alignment data
+
+	long int d_seqi_len;//current length of sequence 1
+	long int d_seqj_len;//current length of sequence 2
+
+
+	long int d_seq_a_len;//current length for memory allocation for the sequences
+	long int d_H_matr_a_len;//current length for memory allocation for the matrices H
+	long int d_W_matr_a_len;//current length for memory allocation for the matrices W
+
+	long int *d_seqi;//AA from sequence 1 for the next step
+	long int *d_seqj;//AA from sequence 2 for the next step
+
+	long int d_H_matr_len;//length of the matrices H currently calculated
+	long int d_W_matr_len;//length of the matrices W currently calculated
+
+	//the importance sampling weights
+	double *d_WS_i_const_pred;
+	double *d_WI_i_const_pred;
+	double *d_WD_i_const_pred;
+
+	double *d_WS_i_const_next;
+	double *d_WI_i_const_next;
+	double *d_WD_i_const_next;
+
+	double *d_WS_j_const_pred;
+	double *d_WI_j_const_pred;
+	double *d_WD_j_const_pred;
+
+	double *d_WS_j_const_next;
+	double *d_WI_j_const_next;
+	double *d_WD_j_const_next;
+
+	double d_WS_ij_pred;
+	double d_WI_ij_pred;
+	double d_WD_ij_pred;
+
+	double d_WS_ij_next;
+	double d_WI_ij_next;
+	double d_WD_ij_next;
+
+
+	//alignment matrix 
+	long int *d_HS_i_const_pred;
+	long int *d_HI_i_const_pred;
+	long int *d_HD_i_const_pred;
+	long int *d_H_i_const_pred;
+
+	long int *d_HS_i_const_next;
+	long int *d_HI_i_const_next;
+	long int *d_HD_i_const_next;
+	long int *d_H_i_const_next;
+
+	long int *d_HS_j_const_pred;
+	long int *d_HI_j_const_pred;
+	long int *d_HD_j_const_pred;
+	long int *d_H_j_const_pred;
+
+	long int *d_HS_j_const_next;
+	long int *d_HI_j_const_next;
+	long int *d_HD_j_const_next;
+	long int *d_H_j_const_next;
+
+	long int d_HS_ij_pred;
+	long int d_HI_ij_pred;
+	long int d_HD_ij_pred;
+	long int d_H_ij_pred;
+
+	long int d_HS_ij_next;
+	long int d_HI_ij_next;
+	long int d_HD_ij_next;
+	long int d_H_ij_next;
+
+	bool d_success;
+
+	//statistics
+	long int *d_H_edge_max;
+	long int d_M;
+
+	long int d_nalp;
+	long int d_nalp_killing;
+	array_positive<long int> *d_alp;
+
+	array_positive<long int> *d_H_I;
+	array_positive<long int> *d_H_J;
+
+	array_positive<long int> *d_alp_pos;
+	array_positive<double> *d_alp_weights;
+
+	array<long int> *d_cells_counts;
+
+	array_positive<state*> *d_alp_states;
+
+	long int d_sentinel_i_next;
+	long int d_sentinel_j_next;
+
+	long int d_sentinel_i_pred;
+	long int d_sentinel_j_pred;
+
+	long int d_diff_opt;
+	bool d_sentinels_flag;
+
+	bool d_check_time_flag;
+	bool d_time_error_flag;
+	bool d_time_limit_flag;
+
+	bool d_single_realiztion_calculation_flag;
+
+
+
+	//for the importance sampling
+	char d_IS_state;
+
+
+
+
+				
+
+
+	};
+
+}
+
+
+#endif
+
diff --git a/src/alp/sls_alp_data.cpp b/src/alp/sls_alp_data.cpp
index 399da72..c752f07 100644
--- a/src/alp/sls_alp_data.cpp
+++ b/src/alp/sls_alp_data.cpp
@@ -1,1663 +1,1663 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_alp_data.cpp
-
-Author: Sergey Sheetlin
-
-Contents: Input data for the ascending ladder points simulation
-
-******************************************************************************/
-
-#include "sls_alp_data.hpp"
-
-using namespace Sls;
-using namespace std;
-
-void alp_data::input_data_for_the_constructor(
-string randout_,//if defined, then the program outputs complete randomization information into a file
-string smatr_file_name_,//scoring matrix file name
-string RR1_file_name_,//probabilities1 file name
-string RR2_file_name_,//probabilities2 file name
-
-struct_for_randomization &rand_all_,
-bool &rand_flag_,
-long int &rand_,
-
-long int &alphabetSize_,
-long int **&substitutionScoreMatrix_,
-double *&letterFreqs1_,
-double *&letterFreqs2_)
-{
-	ifstream frand;
-
-	try
-	{
-
-		long int number_of_AA_RR1;
-		long int number_of_AA_RR2;
-		long int number_of_AA_smatr;
-
-		read_smatr(
-		smatr_file_name_,
-		d_smatr,
-		number_of_AA_smatr);
-
-		d_number_of_AA_smatr=number_of_AA_smatr;
-		
-		read_RR(
-		RR1_file_name_,
-		d_RR1,
-		d_RR1_sum,
-		d_RR1_sum_elements,
-		number_of_AA_RR1);
-
-
-		read_RR(
-		RR2_file_name_,
-		d_RR2,
-		d_RR2_sum,
-		d_RR2_sum_elements,
-		number_of_AA_RR2);
-
-
-		if(number_of_AA_RR1==number_of_AA_smatr)
-		{
-			alphabetSize_=number_of_AA_smatr;
-		}
-		else
-		{
-			throw error("Number of letters is different in the files "+smatr_file_name_+" and "+RR1_file_name_+"\n",3);
-		};
-
-		if(number_of_AA_RR2!=number_of_AA_smatr)
-		{
-			throw error("Number of letters is different in the files "+smatr_file_name_+" and "+RR2_file_name_+"\n",3);
-		};
-
-
-		if(randout_!="")
-		{
-			rand_flag_=true;
-
-			string rand_st=randout_;
-			frand.open(rand_st.data(),ios::in);
-			if(!frand)
-			{
-				rand_flag_=false;
-			}
-			else
-			{
-
-				long int i,size;
-				frand>>rand_all_.d_random_seed;
-
-
-				if(rand_all_.d_random_seed<0)
-				{
-					throw error("File "+rand_st+" is not correct\n",3);
-				};
-
-				rand_=rand_all_.d_random_seed;
-
-
-
-				frand>>size;
-				for(i=0;i<size;i++)
-				{
-					long int tmp;
-					frand>>tmp;
-					rand_all_.d_first_stage_preliminary_realizations_numbers_ALP.push_back(tmp);
-					if(tmp<0)
-					{
-						throw error("File "+rand_st+" is not correct\n",3);
-					};
-
-				};
-
-				frand>>size;
-				for(i=0;i<size;i++)
-				{
-					long int tmp;
-					frand>>tmp;
-					rand_all_.d_preliminary_realizations_numbers_ALP.push_back(tmp);
-					if(tmp<0)
-					{
-						throw error("File "+rand_st+" is not correct\n",3);
-					};
-
-				};
-
-				frand>>size;
-				for(i=0;i<size;i++)
-				{
-					long int tmp;
-					frand>>tmp;
-					rand_all_.d_preliminary_realizations_numbers_killing.push_back(tmp);
-					if(tmp<0)
-					{
-						throw error("File "+rand_st+" is not correct\n",3);
-					};
-
-				};
-
-
-				frand>>rand_all_.d_total_realizations_number_with_ALP;
-				if(rand_all_.d_total_realizations_number_with_ALP<0)
-				{
-					throw error("File "+rand_st+" is not correct\n",3);
-				};
-
-				frand>>rand_all_.d_total_realizations_number_with_killing;
-				if(rand_all_.d_total_realizations_number_with_killing<0)
-				{
-					throw error("File "+rand_st+" is not correct\n",3);
-				};
-
-				frand.close();
-			};
-		}
-		else
-		{
-			rand_flag_=false;
-		};
-
-
-		if(!(alphabetSize_>0&&substitutionScoreMatrix_&&letterFreqs1_&&letterFreqs2_))
-		{
-			throw error("Incorrect input parameters\n",1);
-		};
-
-	}
-	catch (...)
-	{ 
-		if(frand.is_open())
-		{
-			frand.close();
-		};
-		throw;
-	};
-
-}
-
-void alp_data::init_main_class_members(
-long int rand_,//randomization number
-string randout_,//if defined, then the program outputs complete randomization information into a file
-
-long int open_,//gap opening penalty
-long int open1_,//gap opening penalty for a gap in the sequence #1
-long int open2_,//gap opening penalty for a gap in the sequence #2
-
-long int epen_,//gap extension penalty
-long int epen1_,//gap extension penalty for a gap in the sequence #1
-long int epen2_,//gap extension penalty for a gap in the sequence #2
-
-double max_time_,//maximum allowed calculation time in seconds
-double max_mem_,//maximum allowed memory usage in MB
-double eps_lambda_,//relative error for lambda calculation
-double eps_K_,//relative error for K calculation
-bool insertions_after_deletions_)//if true, then insertions after deletions are allowed
-{
-	try
-	{
-		d_randout=randout_;
-
-		if(!d_rand_flag&&rand_<0)
-		{
-			
-			rand_=(long int)time(NULL);
-			#ifndef _MSC_VER //UNIX program
-				struct timeval tv;
-				struct timezone tz;
-				gettimeofday(&tv, &tz);
-				rand_+=tv.tv_usec*10000000;
-			#else
-				struct _timeb timebuffer;
-				char *timeline;
-				_ftime( &timebuffer );
-				timeline = ctime( & ( timebuffer.time ) );
-				rand_+=timebuffer.millitm*10000000;
-			#endif
-
-			rand_=abs(rand_);
-
-			d_rand_flag=false;
-			
-		};
-
-
-		d_random_seed=rand_;
-		//cout<<"Random seed "<<d_random_seed<<endl;
-
-		//srand(d_random_seed);
-
-		Njn::Random::seed(d_random_seed);
-
-		d_number_of_AA_smatr=d_number_of_AA;
-
-		d_sentinels_flag=false;
-
-		d_memory_size_in_MB=0;
-
-		#ifndef _MSDOS_ //UNIX program
-
-		#else
-			_CrtMemCheckpoint( &d_s1 );
-		#endif
-
-		d_smatr_symmetric_flag=false;
-		
-		long int t;
-		for(t=0;t<d_number_of_AA;t++)
-		{
-			if(d_RR1[t]!=d_RR2[t])
-			{
-				d_smatr_symmetric_flag=false;
-				break;
-			};
-		};
-
-		d_insertions_after_deletions=insertions_after_deletions_;
-
-
-
-		d_open=open_+epen_;
-		d_open1=open1_+epen1_;
-		d_open2=open2_+epen2_;
-
-		d_epen=epen_;
-		d_epen1=epen1_;
-		d_epen2=epen2_;
-
-		d_max_time=max_time_;
-		d_max_mem=max_mem_;
-		d_eps_lambda=eps_lambda_;
-		d_eps_K=eps_K_;
-		d_minimum_realizations_number=40;
-
-
-
-		
-
-
-		d_is=new importance_sampling(
-			this,
-			d_open,
-
-			d_epen,
-
-			d_number_of_AA,
-			d_smatr,
-			d_RR1,
-			d_RR2);
-
-		alp_data::assert_mem(d_is);
-
-		d_memory_size_in_MB+=sizeof(d_is)/mb_bytes;
-
-		d_r_i_dot=new double[d_number_of_AA];
-		alp_data::assert_mem(d_r_i_dot);
-		d_r_dot_j=new double[d_number_of_AA];
-		alp_data::assert_mem(d_r_dot_j);
-		long int k;
-		for(k=0;k<d_number_of_AA;k++)
-		{
-			d_r_i_dot[k]=0;
-			if(d_RR1[k]!=0)
-			{
-				long int i;
-				for(i=0;i<d_number_of_AA;i++)
-				{
-					if(d_RR2[i]!=0)
-					{
-						d_r_i_dot[k]+=d_is->d_exp_s[k][i]*d_RR2[i];
-					};
-				};
-			};
-		};
-
-		for(k=0;k<d_number_of_AA;k++)
-		{
-			d_r_dot_j[k]=0;
-			if(d_RR2[k]!=0)
-			{
-				long int i;
-				for(i=0;i<d_number_of_AA;i++)
-				{
-					if(d_RR1[i]!=0)
-					{
-						d_r_dot_j[k]+=d_is->d_exp_s[i][k]*d_RR1[i];
-					};
-				};
-			};
-		};
-
-
-		d_memory_size_in_MB+=(double)(sizeof(double)*d_number_of_AA*2.0)/mb_bytes;
-
-		double tmp_size1=LONG_MAX;
-
-		double tmp_size=Tmin((double)(tmp_size1),
-			(
-
-			(double)mb_bytes*d_max_mem/(double)d_minimum_realizations_number
-			)
-			/(
-			(double)(sizeof(double)*12)+(double)(sizeof(long int)*17)
-			)
-			);
-
-		d_dim1_tmp=(long int)tmp_size;
-		d_dim2_tmp=(long int)tmp_size;
-
-	}
-	catch (...)
-	{ 
-		release_memory();
-		throw;
-	};
-}
-
-
-alp_data::alp_data(//constructor
-long int rand_,//randomization number
-string randout_,//if defined, then the program outputs complete randomization information into a file
-
-long int open_,//gap opening penalty
-long int open1_,//gap opening penalty for a gap in the sequence #1
-long int open2_,//gap opening penalty for a gap in the sequence #2
-
-long int epen_,//gap extension penalty
-long int epen1_,//gap extension penalty for a gap in the sequence #1
-long int epen2_,//gap extension penalty for a gap in the sequence #2
-
-string smatr_file_name_,//scoring matrix file name
-string RR1_file_name_,//probabilities1 file name
-string RR2_file_name_,//probabilities2 file name
-double max_time_,//maximum allowed calculation time in seconds
-double max_mem_,//maximum allowed memory usage in MB
-double eps_lambda_,//relative error for lambda calculation
-double eps_K_,//relative error for K calculation
-bool insertions_after_deletions_)//if true, then insertions after deletions are allowed
-{
-
-
-	d_smatr=NULL;
-	d_RR1=NULL;
-	d_RR1_sum=NULL;
-	d_RR1_sum_elements=NULL;
-
-	d_RR2=NULL;
-	d_RR2_sum=NULL;
-	d_RR2_sum_elements=NULL;
-
-	d_is=NULL;
-	d_r_i_dot=NULL;
-	d_r_dot_j=NULL;
-
-	d_rand_all=NULL;
-
-	try
-	{
-
-		d_rand_flag=true;
-
-		d_rand_all=new struct_for_randomization;
-		alp_data::assert_mem(d_rand_all);
-		d_memory_size_in_MB+=sizeof(struct_for_randomization)/mb_bytes;
-
-
-		input_data_for_the_constructor(
-		randout_,//if defined, then the program outputs complete randomization information into a file
-		smatr_file_name_,//scoring matrix file name
-		RR1_file_name_,//probabilities1 file name
-		RR2_file_name_,//probabilities2 file name
-
-		*d_rand_all,
-		d_rand_flag,
-		rand_,
-
-
-		d_number_of_AA,
-		d_smatr,
-		d_RR1,
-		d_RR2);
-
-		init_main_class_members(
-		rand_,//randomization number
-		randout_,//if defined, then the program outputs complete randomization information into a file
-
-		open_,//gap opening penalty
-		open1_,//gap opening penalty for a gap in the sequence #1
-		open2_,//gap opening penalty for a gap in the sequence #2
-
-		epen_,//gap extension penalty
-		epen1_,//gap extension penalty for a gap in the sequence #1
-		epen2_,//gap extension penalty for a gap in the sequence #2
-
-		max_time_,//maximum allowed calculation time in seconds
-		max_mem_,//maximum allowed memory usage in MB
-		eps_lambda_,//relative error for lambda calculation
-		eps_K_,//relative error for K calculation
-		insertions_after_deletions_);//if true, then insertions after deletions are allowed
-
-		d_max_time_with_computation_parameters=-1;
-
-		if(max_time_>0)
-		{
-			d_max_time_for_quick_tests=0.25*max_time_;
-		}
-		else
-		{
-			d_max_time_for_quick_tests=1e99;
-		};
-
-
-
-	}
-	catch (...)
-	{
-		release_memory();
-		throw;
-	};
-}
-
-
-alp_data::alp_data(//constructor
-long int rand_,//randomization number
-struct_for_randomization *randomization_parameters_,//if not NULL, sets d_rand_flag to true and initializes d_rand_all
-
-long int open_,//gap opening penalty
-long int open1_,//gap opening penalty for a gap in the sequence #1
-long int open2_,//gap opening penalty for a gap in the sequence #2
-
-long int epen_,//gap extension penalty
-long int epen1_,//gap extension penalty for a gap in the sequence #1
-long int epen2_,//gap extension penalty for a gap in the sequence #2
-
-long alphabetSize_,
-const long *const *substitutionScoreMatrix_,
-const double *letterFreqs1_,
-const double *letterFreqs2_,
-
-double max_time_,//maximum allowed calculation time in seconds
-double max_mem_,//maximum allowed memory usage in MB
-double eps_lambda_,//relative error for lambda calculation
-double eps_K_,//relative error for K calculation
-bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
-double max_time_for_quick_tests_,//maximum allowed calculation time in seconds for quick tests
-double max_time_with_computation_parameters_)//maximum allowed time in seconds for the whole computation
-{
-
-
-	d_smatr=NULL;
-	d_RR1=NULL;
-	d_RR1_sum=NULL;
-	d_RR1_sum_elements=NULL;
-
-	d_RR2=NULL;
-	d_RR2_sum=NULL;
-	d_RR2_sum_elements=NULL;
-
-	d_is=NULL;
-	d_r_i_dot=NULL;
-	d_r_dot_j=NULL;
-
-	d_rand_all=NULL;
-
-	try
-	{
-
-		d_rand_flag=false;
-
-		d_number_of_AA=alphabetSize_;
-		string randout="";
-
-
-		get_memory_for_matrix(alphabetSize_,d_smatr);
-		alp_data::assert_mem(d_smatr);
-		d_RR1=new double[alphabetSize_];
-		alp_data::assert_mem(d_RR1);
-		d_RR2=new double[alphabetSize_];
-		alp_data::assert_mem(d_RR2);
-
-		long int i,j;
-		for(i=0;i<alphabetSize_;i++)
-		{
-			d_RR1[i]=letterFreqs1_[i];
-			d_RR2[i]=letterFreqs2_[i];
-			for(j=0;j<alphabetSize_;j++)
-			{
-				d_smatr[i][j]=substitutionScoreMatrix_[i][j];
-			};
-
-		};
-
-		d_rand_all=new struct_for_randomization;
-
-		if(randomization_parameters_)
-		{
-			d_rand_flag=true;
-
-			d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP=
-				randomization_parameters_->d_first_stage_preliminary_realizations_numbers_ALP;
-
-			d_rand_all->d_preliminary_realizations_numbers_ALP=
-				randomization_parameters_->d_preliminary_realizations_numbers_ALP;
-
-			d_rand_all->d_preliminary_realizations_numbers_killing=
-				randomization_parameters_->d_preliminary_realizations_numbers_killing;
-
-			d_rand_all->d_random_seed=
-				randomization_parameters_->d_random_seed;
-
-			d_rand_all->d_total_realizations_number_with_ALP=
-				randomization_parameters_->d_total_realizations_number_with_ALP;
-
-			d_rand_all->d_total_realizations_number_with_killing=
-				randomization_parameters_->d_total_realizations_number_with_killing;
-		};
-
-		alp_data::assert_mem(d_rand_all);
-		d_memory_size_in_MB+=sizeof(struct_for_randomization)/mb_bytes;
-
-		init_main_class_members(
-		rand_,//randomization number
-		randout,//if defined, then the program outputs complete randomization information into a file
-
-		open_,//gap opening penalty
-		open1_,//gap opening penalty for a gap in the sequence #1
-		open2_,//gap opening penalty for a gap in the sequence #2
-
-		epen_,//gap extension penalty
-		epen1_,//gap extension penalty for a gap in the sequence #1
-		epen2_,//gap extension penalty for a gap in the sequence #2
-
-		max_time_,//maximum allowed calculation time in seconds
-		max_mem_,//maximum allowed memory usage in MB
-		eps_lambda_,//relative error for lambda calculation
-		eps_K_,//relative error for K calculation
-		insertions_after_deletions_);//if true, then insertions after deletions are allowed
-
-		if(max_time_for_quick_tests_>0)
-		{
-			d_max_time_for_quick_tests=max_time_for_quick_tests_;
-		}
-		else
-		{
-			if(max_time_>0)
-			{
-				d_max_time_for_quick_tests=0.25*max_time_;
-			}
-			else
-			{
-				d_max_time_for_quick_tests=1e99;
-			};
-		};
-
-		if((max_time_with_computation_parameters_>0)&&(!(max_time_>0)))
-		{
-			d_max_time_with_computation_parameters=max_time_with_computation_parameters_;
-		}
-		else
-		{
-			d_max_time_with_computation_parameters=1e99;
-		};
-
-		calculate_RR_sum(
-		d_RR1,
-		alphabetSize_,
-		d_RR1_sum,
-		d_RR1_sum_elements);
-
-		calculate_RR_sum(
-		d_RR2,
-		alphabetSize_,
-		d_RR2_sum,
-		d_RR2_sum_elements);
-
-
-	}
-	catch (...)
-	{ 
-		release_memory();
-		throw;
-	};
-}
-
-long int alp_data::random_long(
-double value_,
-long int dim_)
-{
-	if(value_<0||value_>1.0||dim_<=0)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-	if(dim_==1)
-	{
-		return 0;
-	};
-
-	long int tmp=(long int)floor(value_*(double)dim_);
-	tmp=Tmin(tmp,dim_-1);
-	return tmp;
-}
-
-void alp_data::release_memory()
-{
-	delete[]d_RR1;d_RR1=NULL;
-	delete[]d_RR1_sum;d_RR1_sum=NULL;
-	delete[]d_RR1_sum_elements;d_RR1_sum_elements=NULL;
-
-	delete[]d_RR2;d_RR2=NULL;
-	delete[]d_RR2_sum;d_RR2_sum=NULL;
-	delete[]d_RR2_sum_elements;d_RR2_sum_elements=NULL;
-
-	
-	
-
-	d_memory_size_in_MB-=2.0*(double)(2.0*sizeof(double)+sizeof(long int))*(double)d_number_of_AA/mb_bytes;
-
-
-
-	if(d_smatr)
-	{
-		delete_memory_for_matrix(d_number_of_AA_smatr,d_smatr);
-	};
-
-
-	delete d_is;d_is=NULL;
-
-	d_memory_size_in_MB-=sizeof(d_is)/mb_bytes;
-
-	delete[]d_r_i_dot;d_r_i_dot=NULL;
-	delete[]d_r_dot_j;d_r_dot_j=NULL;
-	d_memory_size_in_MB-=(double)(sizeof(double)*d_number_of_AA*2.0)/mb_bytes;
-
-	delete d_rand_all;d_rand_all=NULL;
-	d_memory_size_in_MB-=sizeof(struct_for_randomization)/mb_bytes;
-
-}
-
-alp_data::~alp_data()//destructor
-{
-	release_memory();
-}
-
-void alp_data::check_out_file(
-	string out_file_name_)
-{
-	ifstream f;
-	char *str_ch=NULL;
-
-	try
-	{
-		f.open(out_file_name_.data(),ios::in);
-		if(!f)
-		{
-			return;
-		};
-
-		bool symmetric_case_flag;
-		
-		string str;
-		getline(f,str);
-		str_ch=new char[str.length()+1];
-		alp_data::assert_mem(str_ch);
-
-		long int k;
-		for(k=0;k<(long int)str.length();k++)
-		{
-			str_ch[k]=str[k];
-		};
-		str_ch[str.length()]='\0';
-
-
-		char str_for_test0[]="number of realizations with killing";
-		char *test_flag0= strstr(str_ch,str_for_test0);
-
-		if(!test_flag0)
-		{
-			throw error("The output file "+out_file_name_+" exists and does not have the correct format;\nplease delete the file and rerun the program\n",3);
-		};
-
-		char str_for_test[]="0.5*";
-
-		char*test_flag= strstr(str_ch,str_for_test);
-		if(test_flag)
-		{
-			symmetric_case_flag=true;
-		}
-		else
-		{
-			symmetric_case_flag=false;
-		};
-
-
-		
-
-		if(symmetric_case_flag)
-		{
-			if(!d_smatr_symmetric_flag)
-			{
-				throw error("The output file "+out_file_name_+" exists and corresponds to symmetric case; \nthe current calculation uses non-symmetric parameters;\nplease define another output file name\n",3);
-			};
-		};
-
-		if(!symmetric_case_flag)
-		{
-			if(d_smatr_symmetric_flag)
-			{
-				throw error("The output file "+out_file_name_+" exists and corresponds to non-symmetric case; \nthe current calculation uses symmetric parameters;\nplease define another output file name\n",3);
-			};
-		};
-
-		f.close();
-		delete[]str_ch;str_ch=NULL;
-	}
-	catch (...)
-	{ 
-		delete[]str_ch;str_ch=NULL;
-
-		if(f.is_open())
-		{
-			f.close();
-		};
-
-		throw;
-	};
-
-}
-
-double importance_sampling::lambda_equation(double x_,void* func_number_)
-{
-	data_for_lambda_equation *data=(data_for_lambda_equation*)func_number_;
-	long int d_number_of_AA=data->d_number_of_AA;
-	long int** d_smatr=data->d_smatr;
-	double *d_RR1=data->d_RR1;
-	double *d_RR2=data->d_RR2;
-
-	double res=0;
-	long int i,j;
-
-	for(i=0;i<d_number_of_AA;i++)
-	{
-		for(j=0;j<d_number_of_AA;j++)
-		{
-			res+=d_RR1[i]*d_RR2[j]*exp(x_*d_smatr[i][j]);
-		};
-	};
-
-	return res-1.0;
-}
-
-void alp_data::read_smatr(
-string smatr_file_name_,
-long int **&smatr_,
-long int &number_of_AA_smatr_)
-{
-	ifstream f;
-
-	try
-	{
-
-		long int i,j;
-		f.open(smatr_file_name_.data(),ios::in);
-		if(!f)
-		{
-			throw error("Error - file "+smatr_file_name_+" is not found\n",3);
-		};
-
-		f>>number_of_AA_smatr_;
-
-		if(number_of_AA_smatr_<=0)
-		{
-			throw error("Error - number of letters in the scoring matrix file must be greater than 0\n",3);
-		};
-
-		get_memory_for_matrix(number_of_AA_smatr_,smatr_);
-
-
-		for(i=0;i<number_of_AA_smatr_;i++)
-		{
-			for(j=0;j<number_of_AA_smatr_;j++)
-			{
-				f>>smatr_[i][j];
-			};
-		};
-
-		f.close();
-
-	}
-	catch (...)
-	{ 
-		if(f.is_open())
-		{
-			f.close();
-		};
-		throw;
-	};
-
-
-}
-
-void alp_data::read_RR(
-string RR_file_name_,
-double *&RR_,
-double *&RR_sum_,
-long int *&RR_sum_elements_,
-long int &number_of_AA_RR_)
-{
-
-	read_RR(
-	RR_file_name_,
-	RR_,
-	number_of_AA_RR_);
-
-	calculate_RR_sum(
-	RR_,
-	number_of_AA_RR_,
-	RR_sum_,
-	RR_sum_elements_);
-}
-
-void alp_data::check_RR_sum(
-double sum_tmp_,
-long int number_of_AA_RR_,
-string RR_file_name_)
-{
-
-	if(number_of_AA_RR_<=0)
-	{
-		throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
-	};
-
-	double diff_tmp=fabs(sum_tmp_-1.0);
-	if(diff_tmp>0)
-	{
-		double lg_diff=-(log(diff_tmp)-log((double)number_of_AA_RR_))/log(10.0);
-		double lg_eps=-log(DBL_EPSILON)/log(10.0)-1;
-		if(lg_diff<lg_eps)
-		{
-
-			if(sum_tmp_<=0)
-			{
-				if(RR_file_name_!="")
-				{
-					throw error("Error: the sum of the probabilities from the file "+RR_file_name_+" is non-positive\n",3);
-				}
-				else
-				{
-					throw error("Error: the sum of the probabilities is non-positive\n",3);
-				};
-
-			};
-
-			if(RR_file_name_!="")
-			{
-				static map<string, bool> flag_RR;
-
-				if(!flag_RR[RR_file_name_])
-				{
-					cout<<"\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
-					cout<<"Warning: the sum of the probabilities from the file "<<RR_file_name_<<" is not equal to 1\n";
-					cout<<"The probabilities will be normalized for the computation\n";
-					cout<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n";
-
-					flag_RR[RR_file_name_]=true;
-				};
-			}
-			else
-			{
-				//no messages if called from the library functions
-			};
-
-		};
-
-	};
-
-
-
-}
-
-void alp_data::calculate_RR_sum(
-double *RR_,
-long int number_of_AA_RR_,
-double *&RR_sum_,
-long int *&RR_sum_elements_)
-{
-	RR_sum_=NULL;
-	RR_sum_elements_=NULL;
-
-	try
-	{
-
-		long int i;
-		if(number_of_AA_RR_<=0)
-		{
-			throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
-		};
-		
-		RR_sum_=new double[number_of_AA_RR_];
-		assert_mem(RR_sum_);
-
-		RR_sum_elements_=new long int [number_of_AA_RR_];
-		assert_mem(RR_sum_elements_);
-
-
-		for(i=0;i<number_of_AA_RR_;i++)
-		{
-			if(RR_[i]<0)
-			{
-				throw error("Error - the frequencies must be non-negative\n",3);
-			};
-
-			if(i!=0)
-			{
-				RR_sum_[i]=RR_sum_[i-1]+RR_[i];
-			}
-			else
-			{
-				RR_sum_[i]=RR_[i];
-			};
-			RR_sum_elements_[i]=i;
-		};
-
-		double sum_tmp=RR_sum_[number_of_AA_RR_-1];
-
-		check_RR_sum(
-		sum_tmp,
-		number_of_AA_RR_,
-		"");
-
-		if(sum_tmp>0)
-		{
-			long int i;
-			for(i=0;i<number_of_AA_RR_;i++)
-			{
-				RR_[i]/=sum_tmp;
-				RR_sum_[i]/=sum_tmp;
-			};
-		};
-
-	}
-	catch (...)
-	{ 
-		delete[]RR_sum_;RR_sum_=NULL;
-		delete[]RR_sum_elements_;RR_sum_elements_=NULL;
-		throw;
-	};
-
-
-}
-
-
-void alp_data::read_RR(
-string RR_file_name_,
-double *&RR_,
-long int &number_of_AA_RR_)
-{
-
-	ifstream f;
-	RR_=NULL;
-
-	try
-	{
-
-		long int i;
-		f.open(RR_file_name_.data(),ios::in);
-		if(!f)
-		{
-			throw error("Error - file "+RR_file_name_+" is not found\n",3);
-		};
-
-		f>>number_of_AA_RR_;
-
-		if(number_of_AA_RR_<=0)
-		{
-			throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
-		};
-		
-		RR_=new double[number_of_AA_RR_];
-		assert_mem(RR_);
-
-
-		double sum_tmp=0;
-		for(i=0;i<number_of_AA_RR_;i++)
-		{
-			f>>RR_[i];
-
-			if(RR_[i]<0)
-			{
-				throw error("Error - the frequencies defined in the file "+RR_file_name_+" must be non-negative\n",3);
-			};
-
-			sum_tmp+=RR_[i];
-
-		};
-
-		check_RR_sum(
-		sum_tmp,
-		number_of_AA_RR_,
-		RR_file_name_);
-
-		f.close();
-	}
-
-	catch (...)
-	{ 
-		delete[]RR_;RR_=NULL;
-		if(f.is_open())
-		{
-			f.close();
-		};
-		throw;
-	};
-
-}
-
-
-
-string alp_data::long_to_string(//convert interer ot string
-long int number_)
-{
-	string res_="";
-	string tmp_string;
-	if(number_>0)
-	{
-		tmp_string="";
-	}
-	else
-	{
-		if(number_==0)
-		{
-			tmp_string="";
-		}
-		else
-		{
-			tmp_string="-";
-		};
-	};
-	number_=abs(number_);
-
-	for( ; ; )
-	{
-		long int reminder=number_%10;
-		number_=(number_-reminder)/10;
-		res_=digit_to_string(reminder)+res_;
-		if (number_==0)
-		{
-			break;
-		};
-	};
-
-	return tmp_string+res_;
-}
-
-char alp_data::digit_to_string(//convert interer ot string
-long int digit_)
-{
-	switch(digit_)
-	{
-	case 0:return '0';
-	case 1:return '1';
-	case 2:return '2';
-	case 3:return '3';
-	case 4:return '4';
-	case 5:return '5';
-	case 6:return '6';
-	case 7:return '7';
-	case 8:return '8';
-	case 9:return '9';
-	default:return '?';
-	};
-}
-
-importance_sampling::importance_sampling(
-alp_data *alp_data_,
-long int open_,
-
-long int epen_,
-
-long int number_of_AA_,
-long int **smatr_,
-double *RR1_,
-double *RR2_)
-{
-	d_elements=NULL;
-	d_elements_values=NULL;
-
-	d_exp_s=NULL;
-
-	d_alp_data=alp_data_;
-	if(!d_alp_data)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-	try
-	{
-
-
-
-		{
-
-			//calculation of the importance sampling theta
-
-			data_for_lambda_equation tmp_ptr;
-			tmp_ptr.d_number_of_AA=number_of_AA_;
-			tmp_ptr.d_RR1=RR1_;
-			tmp_ptr.d_RR2=RR2_;
-			tmp_ptr.d_smatr=smatr_;
-
-			//calculate maximum of smatr_ elements
-			long int smatr_max=smatr_[0][0];
-			long int smatr_max_i=0;
-			long int smatr_max_j=0;
-			long int smatr_min=smatr_[0][0];
-
-			long int smatr_pos_max=LONG_MIN;
-			long int smatr_neg_min=LONG_MAX;
-
-			double eps=0.00001;
-			double threshold=DBL_MIN*10.0;
-
-			double aver_score=0;
-			long int i,j;
-			for(i=0;i<number_of_AA_;i++)
-			{
-				for(j=0;j<number_of_AA_;j++)
-				{
-					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-					//if(RR1_[j]*RR2_[i]<=threshold)
-					if(RR1_[i]*RR2_[j]<=threshold)
-					{
-						continue;
-					};
-										
-
-
-					aver_score+=RR1_[i]*RR2_[j]*smatr_[i][j];
-
-					if(smatr_max<smatr_[i][j])
-					{
-						smatr_max=smatr_[i][j];
-						smatr_max_i=i;
-						smatr_max_j=j;
-					};
-					smatr_min=alp_data::Tmin(smatr_min,smatr_[i][j]);
-					
-
-					if(smatr_[i][j]>0)
-					{
-						smatr_pos_max=alp_data::Tmax(smatr_pos_max,smatr_[i][j]);
-					};
-
-					if(smatr_[i][j]<0)
-					{
-						smatr_neg_min=alp_data::Tmin(smatr_neg_min,smatr_[i][j]);
-					};
-
-				};
-			};
-
-			if(aver_score>=-threshold)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-
-			if(smatr_max<=0)
-			{
-				throw error("Error - at least one element of the scoring matrix must be positive\n",3);
-			};
-
-			
-
-			double a=eps;
-
-			while(importance_sampling::lambda_equation(a,(void*)(&tmp_ptr))>0)
-			{
-				a/=2.0;
-
-				if(a<threshold*100.0)
-				{
-					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-				};
-			};
-
-			if(a<threshold*100.0)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-
-			eps=a/10.0;
-
-
-			double tmp_pr=RR1_[smatr_max_i]*RR2_[smatr_max_j];
-			double b=(log(1+10*eps)-log(tmp_pr))/(double)smatr_max;
-
-			
-			long int n_partition=2;
-			vector<double> res_lambda;
-			
-			
-			alp_reg::find_tetta_general(
-			importance_sampling::lambda_equation,
-			(void*)(&tmp_ptr),
-			a,
-			b,
-			n_partition,
-			eps,
-			res_lambda);
-
-			sort(res_lambda.begin(),res_lambda.end());
-
-			if(res_lambda.size()==0)
-			{
-				//throw error("Error - the program is not able to find the ungapped lambda. The program does not work with the input scoring scheme. \n",3);
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-
-			d_lambda=res_lambda[res_lambda.size()-1];
-			d_ungap_lambda=d_lambda;
-
-			//cout<<"\nUngapped lambda is "<<d_ungap_lambda<<endl;
-
-			d_lambda*=1.07;
-		};
-
-
-		
-		d_is_number_of_AA=number_of_AA_;
-
-		d_elements=new q_elem[number_of_AA_*number_of_AA_];
-		alp_data::assert_mem(d_elements);
-
-		d_elements_values=new double[number_of_AA_*number_of_AA_];
-		alp_data::assert_mem(d_elements_values);
-
-
-
-		d_alp_data->get_memory_for_matrix(d_is_number_of_AA,d_exp_s);
-
-		long int ind=0;
-		double sum=0;
-		long int a,b;
-		for(a=0;a<number_of_AA_;a++)
-		{
-			for(b=0;b<number_of_AA_;b++)
-			{
-				d_exp_s[a][b]=exp(d_lambda*smatr_[a][b]);
-				d_elements_values[ind]=RR1_[a]*RR2_[b]*d_exp_s[a][b];
-				sum+=d_elements_values[ind];
-				ind++;
-			};
-		};
-
-
-		for(a=0;a<number_of_AA_;a++)
-		{
-			for(b=0;b<number_of_AA_;b++)
-			{
-				d_exp_s[a][b]/=sum;
-			};
-
-		};
-
-
-		for(ind=0;ind<number_of_AA_*number_of_AA_;ind++)
-		{
-			d_elements_values[ind]/=sum;
-		};
-
-		
-		for(ind=1;ind<number_of_AA_*number_of_AA_;ind++)
-		{
-			d_elements_values[ind]=d_elements_values[ind-1]+d_elements_values[ind];
-		};
-
-		
-		ind=0;
-		for(a=0;a<number_of_AA_;a++)
-		{
-			for(b=0;b<number_of_AA_;b++)
-			{
-				q_elem elem_tmp;
-
-				elem_tmp.d_a=a;
-				elem_tmp.d_b=b;
-
-				d_elements[ind]=elem_tmp;
-				d_elements_values[ind]=d_elements_values[ind];
-
-				ind++;
-
-			};
-		};
-
-
-
-		d_mu=exp(-fabs(d_lambda)*open_);
-		d_nu=exp(-fabs(d_lambda)*epen_);
-
-		double tmp=1+d_mu-d_nu;
-
-		d_eta=(1-d_nu)*(1-d_nu)/(tmp*tmp);
-		d_mu_SI=1-d_nu;
-		d_mu_IS=d_mu*(1-d_nu)/(tmp*tmp);
-		d_mu_DS=d_mu/tmp;
-		d_mu_SD=(1-d_nu)*(1-d_nu)/tmp;
-		d_mu_ID=d_mu*(1-d_nu)/tmp;
-
-
-		d_for_D[0]=d_nu;				d_for_D_states[0]='D';
-		d_for_D[1]=d_for_D[0]+d_mu_SD;	d_for_D_states[1]='S';
-		d_for_D[2]=d_for_D[1]+d_mu_ID;	d_for_D_states[2]='I';
-
-		d_for_I[0]=d_nu;				d_for_I_states[0]='I';
-		d_for_I[1]=d_for_I[0]+d_mu_SI;	d_for_I_states[1]='S';
-
-		d_for_S[0]=d_eta;				d_for_S_states[0]='S';
-		d_for_S[1]=d_for_S[0]+d_mu_DS;	d_for_S_states[1]='D';
-		d_for_S[2]=d_for_S[1]+d_mu_IS;	d_for_S_states[2]='I';
-
-		d_alp_data->d_memory_size_in_MB+=sizeof(double)*number_of_AA_/mb_bytes;
-		d_alp_data->d_memory_size_in_MB+=sizeof(q_elem)*number_of_AA_/mb_bytes;
-	}
-	catch (...)
-	{
-		this->~importance_sampling();
-		throw;
-	};
-
-}
-
-importance_sampling::~importance_sampling()
-{
-	delete []d_elements;d_elements=NULL;
-	delete []d_elements_values;d_elements_values=NULL;
-
-	if(d_alp_data)
-	{
-		d_alp_data->delete_memory_for_matrix(d_is_number_of_AA,d_exp_s);
-		d_alp_data->d_memory_size_in_MB-=sizeof(double)*d_is_number_of_AA/mb_bytes;
-		d_alp_data->d_memory_size_in_MB-=sizeof(q_elem)*d_is_number_of_AA/mb_bytes;
-	};
-
-}
-
-double alp_data::error_of_the_sum(//v1_+v2_
-double v1_error_,
-double v2_error_)
-{
-	if(v1_error_>=1e100||v2_error_>=1e100)
-	{
-		return 1e100;
-	};
-
-	return sqrt(v1_error_*v1_error_+v2_error_*v2_error_);
-}
-
-double alp_data::error_of_the_product(//v1_*v2_
-double v1_,
-double v1_error_,
-double v2_,
-double v2_error_)
-{
-	if(v1_error_>=1e100||v2_error_>=1e100)
-	{
-		return 1e100;
-	};
-
-	double a1=(v1_+v1_error_)*(v2_+v2_error_);
-	double a2=(v1_-v1_error_)*(v2_+v2_error_);
-	double a3=(v1_+v1_error_)*(v2_-v2_error_);
-	double a4=(v1_-v1_error_)*(v2_-v2_error_);
-
-	double a=v1_*v2_;
-
-	return Tmax(fabs(a1-a),fabs(a2-a),fabs(a3-a),fabs(a4-a));
-
-}
-
-double alp_data::error_of_the_sqrt(//sqrt(v1_)
-double v1_,
-double v1_error_)
-{
-	if(v1_error_>=1e100||v1_<0)
-	{
-		return 1e100;
-	};
-
-	double s=sqrt(v1_);
-	double s1=sqrt(alp_data::Tmax(0.0,v1_-v1_error_));
-	double s2=sqrt(alp_data::Tmax(0.0,v1_+v1_error_));
-
-	return alp_data::Tmax(fabs(s-s1),fabs(s-s2));
-}
-
-double alp_data::error_of_the_ratio(//v1_/v2_
-double v1_,
-double v1_error_,
-double v2_,
-double v2_error_)
-{
-	if(v1_error_>=1e100||v2_error_>=1e100)
-	{
-		return 1e100;
-	};
-
-	if(v2_==0)
-	{
-		return 1e100;
-	};
-
-	if(v1_==0&&v1_error_==0)
-	{
-		return 0.0;
-	};
-
-	double a=v1_/v2_;
-
-	if(((v2_+v2_error_)*v2_<=0))
-	{
-		double a3=(v1_+v1_error_)/(v2_-v2_error_);
-		double a4=(v1_-v1_error_)/(v2_-v2_error_);
-		return alp_data::Tmax(fabs(a-a3),fabs(a-a4));
-	};
-
-	if(((v2_-v2_error_)*v2_<=0))
-	{
-		double a1=(v1_+v1_error_)/(v2_+v2_error_);
-		double a2=(v1_-v1_error_)/(v2_+v2_error_);
-		return alp_data::Tmax(fabs(a-a1),fabs(a-a2));
-	};
-
-
-	double a1=(v1_+v1_error_)/(v2_+v2_error_);
-	double a2=(v1_-v1_error_)/(v2_+v2_error_);
-	double a3=(v1_+v1_error_)/(v2_-v2_error_);
-	double a4=(v1_-v1_error_)/(v2_-v2_error_);
-
-	return Tmax(fabs(a-a1),fabs(a-a2),fabs(a-a3),fabs(a-a4));
-}
-
-double alp_data::error_of_the_lg(//lg(v1_)
-double v1_,
-double v1_error_)
-{
-	if(v1_error_>=1e100||v1_<=0)
-	{
-		return 1e100;
-	};
-
-	return alp_data::Tmin(fabs(log(v1_)/log(10.0)),v1_error_/v1_/log(10.0));
-}
-
-bool alp_data::the_value_is_double(
-string str_,
-double &val_)
-{
-	if(str_=="")
-	{
-		return false;
-	};
-
-	bool res=false;
-	errno=0;
-	char *p;
-	val_=strtod(str_.c_str(),&p);
-	if(errno!=0)
-	{
-		res=false;
-	}
-	else
-	{
-		res=(*p==0);
-	};
-	return res;
-}
-
-bool alp_data::the_value_is_long(
-string str_,
-long int &val_)
-{
-
-	if(str_.length()==0)
-	{
-		return false;
-	};
-	if(!(str_[0]=='+'||str_[0]=='-'||isdigit(str_[0])))
-	{
-		return false;
-	};
-
-	long int start_digit=0;
-
-	if(str_[0]=='+'||str_[0]=='-')
-	{
-		start_digit=1;
-	};
-
-
-	long int i;
-	for(i=start_digit;i<(long int)str_.size();i++)
-	{
-		if(!isdigit(str_[i]))
-		{
-			return false;
-		};
-	};
-
-	if(((long int)str_.size()-start_digit)<=0)
-	{
-		return false;
-	};
-
-	if(((long int)str_.size()-start_digit)>1)
-	{
-		/*
-		if(str_[start_digit]=='0')
-		{
-			return false;
-		};
-		*/
-
-		while(str_[start_digit]=='0')
-		{
-			string::iterator it=str_.begin()+start_digit;
-
-
-			str_.erase(it);
-			if((long int)str_.size()<=start_digit+1)
-			{
-				break;
-			};
-		};
-	};
-
-	if(((long int)str_.size()-start_digit>10)||((long int)str_.size()-start_digit)<=0)
-	{
-		return false;
-	};
-
-
-	if((long int)str_.size()-start_digit==10)
-	{
-		if(!(str_[start_digit]=='1'||str_[start_digit]=='2'))
-		{
-			return false;
-		};
-
-		if(str_[start_digit]=='2')
-		{
-
-			long int val2;
-			string str2=str_.substr(start_digit+1,9);
-			int flag=sscanf(str2.c_str(),"%ld",&val2);
-			if(flag!=1)
-			{
-				return false;
-			};
-
-			bool positive=true;
-			if(start_digit>0)
-			{
-				if(str_[0]=='-')
-				{
-					positive=false;
-				};
-			};
-
-			if(positive)
-			{
-				if(val2>147483647)
-				{
-					return false;
-				};
-			}
-			else
-			{
-				if(val2>147483648)
-				{
-					return false;
-				};
-			};
-
-		};
-	};
-
-	int flag=sscanf(str_.c_str(),"%ld",&val_);
-	if(flag!=1)
-	{
-		return false;
-	};
-
-	return true;
-}
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_alp_data.cpp
+
+Author: Sergey Sheetlin
+
+Contents: Input data for the ascending ladder points simulation
+
+******************************************************************************/
+
+#include "sls_alp_data.hpp"
+
+using namespace Sls;
+using namespace std;
+
+void alp_data::input_data_for_the_constructor(
+string randout_,//if defined, then the program outputs complete randomization information into a file
+string smatr_file_name_,//scoring matrix file name
+string RR1_file_name_,//probabilities1 file name
+string RR2_file_name_,//probabilities2 file name
+
+struct_for_randomization &rand_all_,
+bool &rand_flag_,
+long int &rand_,
+
+long int &alphabetSize_,
+long int **&substitutionScoreMatrix_,
+double *&letterFreqs1_,
+double *&letterFreqs2_)
+{
+	ifstream frand;
+
+	try
+	{
+
+		long int number_of_AA_RR1;
+		long int number_of_AA_RR2;
+		long int number_of_AA_smatr;
+
+		read_smatr(
+		smatr_file_name_,
+		d_smatr,
+		number_of_AA_smatr);
+
+		d_number_of_AA_smatr=number_of_AA_smatr;
+		
+		read_RR(
+		RR1_file_name_,
+		d_RR1,
+		d_RR1_sum,
+		d_RR1_sum_elements,
+		number_of_AA_RR1);
+
+
+		read_RR(
+		RR2_file_name_,
+		d_RR2,
+		d_RR2_sum,
+		d_RR2_sum_elements,
+		number_of_AA_RR2);
+
+
+		if(number_of_AA_RR1==number_of_AA_smatr)
+		{
+			alphabetSize_=number_of_AA_smatr;
+		}
+		else
+		{
+			throw error("Number of letters is different in the files "+smatr_file_name_+" and "+RR1_file_name_+"\n",3);
+		};
+
+		if(number_of_AA_RR2!=number_of_AA_smatr)
+		{
+			throw error("Number of letters is different in the files "+smatr_file_name_+" and "+RR2_file_name_+"\n",3);
+		};
+
+
+		if(randout_!="")
+		{
+			rand_flag_=true;
+
+			string rand_st=randout_;
+			frand.open(rand_st.data(),ios::in);
+			if(!frand)
+			{
+				rand_flag_=false;
+			}
+			else
+			{
+
+				long int i,size;
+				frand>>rand_all_.d_random_seed;
+
+
+				if(rand_all_.d_random_seed<0)
+				{
+					throw error("File "+rand_st+" is not correct\n",3);
+				};
+
+				rand_=rand_all_.d_random_seed;
+
+
+
+				frand>>size;
+				for(i=0;i<size;i++)
+				{
+					long int tmp;
+					frand>>tmp;
+					rand_all_.d_first_stage_preliminary_realizations_numbers_ALP.push_back(tmp);
+					if(tmp<0)
+					{
+						throw error("File "+rand_st+" is not correct\n",3);
+					};
+
+				};
+
+				frand>>size;
+				for(i=0;i<size;i++)
+				{
+					long int tmp;
+					frand>>tmp;
+					rand_all_.d_preliminary_realizations_numbers_ALP.push_back(tmp);
+					if(tmp<0)
+					{
+						throw error("File "+rand_st+" is not correct\n",3);
+					};
+
+				};
+
+				frand>>size;
+				for(i=0;i<size;i++)
+				{
+					long int tmp;
+					frand>>tmp;
+					rand_all_.d_preliminary_realizations_numbers_killing.push_back(tmp);
+					if(tmp<0)
+					{
+						throw error("File "+rand_st+" is not correct\n",3);
+					};
+
+				};
+
+
+				frand>>rand_all_.d_total_realizations_number_with_ALP;
+				if(rand_all_.d_total_realizations_number_with_ALP<0)
+				{
+					throw error("File "+rand_st+" is not correct\n",3);
+				};
+
+				frand>>rand_all_.d_total_realizations_number_with_killing;
+				if(rand_all_.d_total_realizations_number_with_killing<0)
+				{
+					throw error("File "+rand_st+" is not correct\n",3);
+				};
+
+				frand.close();
+			};
+		}
+		else
+		{
+			rand_flag_=false;
+		};
+
+
+		if(!(alphabetSize_>0&&substitutionScoreMatrix_&&letterFreqs1_&&letterFreqs2_))
+		{
+			throw error("Incorrect input parameters\n",1);
+		};
+
+	}
+	catch (...)
+	{ 
+		if(frand.is_open())
+		{
+			frand.close();
+		};
+		throw;
+	};
+
+}
+
+void alp_data::init_main_class_members(
+long int rand_,//randomization number
+string randout_,//if defined, then the program outputs complete randomization information into a file
+
+long int open_,//gap opening penalty
+long int open1_,//gap opening penalty for a gap in the sequence #1
+long int open2_,//gap opening penalty for a gap in the sequence #2
+
+long int epen_,//gap extension penalty
+long int epen1_,//gap extension penalty for a gap in the sequence #1
+long int epen2_,//gap extension penalty for a gap in the sequence #2
+
+double max_time_,//maximum allowed calculation time in seconds
+double max_mem_,//maximum allowed memory usage in MB
+double eps_lambda_,//relative error for lambda calculation
+double eps_K_,//relative error for K calculation
+bool insertions_after_deletions_)//if true, then insertions after deletions are allowed
+{
+	try
+	{
+		d_randout=randout_;
+
+		if(!d_rand_flag&&rand_<0)
+		{
+			
+			rand_=(long int)time(NULL);
+			#ifndef _MSC_VER //UNIX program
+				struct timeval tv;
+				struct timezone tz;
+				gettimeofday(&tv, &tz);
+				rand_+=tv.tv_usec*10000000;
+			#else
+				struct _timeb timebuffer;
+				char *timeline;
+				_ftime( &timebuffer );
+				timeline = ctime( & ( timebuffer.time ) );
+				rand_+=timebuffer.millitm*10000000;
+			#endif
+
+			rand_=abs(rand_);
+
+			d_rand_flag=false;
+			
+		};
+
+
+		d_random_seed=rand_;
+		//cout<<"Random seed "<<d_random_seed<<endl;
+
+		//srand(d_random_seed);
+
+		Njn::Random::seed(d_random_seed);
+
+		d_number_of_AA_smatr=d_number_of_AA;
+
+		d_sentinels_flag=false;
+
+		d_memory_size_in_MB=0;
+
+		#ifndef _MSDOS_ //UNIX program
+
+		#else
+			_CrtMemCheckpoint( &d_s1 );
+		#endif
+
+		d_smatr_symmetric_flag=false;
+		
+		long int t;
+		for(t=0;t<d_number_of_AA;t++)
+		{
+			if(d_RR1[t]!=d_RR2[t])
+			{
+				d_smatr_symmetric_flag=false;
+				break;
+			};
+		};
+
+		d_insertions_after_deletions=insertions_after_deletions_;
+
+
+
+		d_open=open_+epen_;
+		d_open1=open1_+epen1_;
+		d_open2=open2_+epen2_;
+
+		d_epen=epen_;
+		d_epen1=epen1_;
+		d_epen2=epen2_;
+
+		d_max_time=max_time_;
+		d_max_mem=max_mem_;
+		d_eps_lambda=eps_lambda_;
+		d_eps_K=eps_K_;
+		d_minimum_realizations_number=40;
+
+
+
+		
+
+
+		d_is=new importance_sampling(
+			this,
+			d_open,
+
+			d_epen,
+
+			d_number_of_AA,
+			d_smatr,
+			d_RR1,
+			d_RR2);
+
+		alp_data::assert_mem(d_is);
+
+		d_memory_size_in_MB+=sizeof(d_is)/mb_bytes;
+
+		d_r_i_dot=new double[d_number_of_AA];
+		alp_data::assert_mem(d_r_i_dot);
+		d_r_dot_j=new double[d_number_of_AA];
+		alp_data::assert_mem(d_r_dot_j);
+		long int k;
+		for(k=0;k<d_number_of_AA;k++)
+		{
+			d_r_i_dot[k]=0;
+			if(d_RR1[k]!=0)
+			{
+				long int i;
+				for(i=0;i<d_number_of_AA;i++)
+				{
+					if(d_RR2[i]!=0)
+					{
+						d_r_i_dot[k]+=d_is->d_exp_s[k][i]*d_RR2[i];
+					};
+				};
+			};
+		};
+
+		for(k=0;k<d_number_of_AA;k++)
+		{
+			d_r_dot_j[k]=0;
+			if(d_RR2[k]!=0)
+			{
+				long int i;
+				for(i=0;i<d_number_of_AA;i++)
+				{
+					if(d_RR1[i]!=0)
+					{
+						d_r_dot_j[k]+=d_is->d_exp_s[i][k]*d_RR1[i];
+					};
+				};
+			};
+		};
+
+
+		d_memory_size_in_MB+=(double)(sizeof(double)*d_number_of_AA*2.0)/mb_bytes;
+
+		double tmp_size1=LONG_MAX;
+
+		double tmp_size=Tmin((double)(tmp_size1),
+			(
+
+			(double)mb_bytes*d_max_mem/(double)d_minimum_realizations_number
+			)
+			/(
+			(double)(sizeof(double)*12)+(double)(sizeof(long int)*17)
+			)
+			);
+
+		d_dim1_tmp=(long int)tmp_size;
+		d_dim2_tmp=(long int)tmp_size;
+
+	}
+	catch (...)
+	{ 
+		release_memory();
+		throw;
+	};
+}
+
+
+alp_data::alp_data(//constructor
+long int rand_,//randomization number
+string randout_,//if defined, then the program outputs complete randomization information into a file
+
+long int open_,//gap opening penalty
+long int open1_,//gap opening penalty for a gap in the sequence #1
+long int open2_,//gap opening penalty for a gap in the sequence #2
+
+long int epen_,//gap extension penalty
+long int epen1_,//gap extension penalty for a gap in the sequence #1
+long int epen2_,//gap extension penalty for a gap in the sequence #2
+
+string smatr_file_name_,//scoring matrix file name
+string RR1_file_name_,//probabilities1 file name
+string RR2_file_name_,//probabilities2 file name
+double max_time_,//maximum allowed calculation time in seconds
+double max_mem_,//maximum allowed memory usage in MB
+double eps_lambda_,//relative error for lambda calculation
+double eps_K_,//relative error for K calculation
+bool insertions_after_deletions_)//if true, then insertions after deletions are allowed
+{
+
+
+	d_smatr=NULL;
+	d_RR1=NULL;
+	d_RR1_sum=NULL;
+	d_RR1_sum_elements=NULL;
+
+	d_RR2=NULL;
+	d_RR2_sum=NULL;
+	d_RR2_sum_elements=NULL;
+
+	d_is=NULL;
+	d_r_i_dot=NULL;
+	d_r_dot_j=NULL;
+
+	d_rand_all=NULL;
+
+	try
+	{
+
+		d_rand_flag=true;
+
+		d_rand_all=new struct_for_randomization;
+		alp_data::assert_mem(d_rand_all);
+		d_memory_size_in_MB+=sizeof(struct_for_randomization)/mb_bytes;
+
+
+		input_data_for_the_constructor(
+		randout_,//if defined, then the program outputs complete randomization information into a file
+		smatr_file_name_,//scoring matrix file name
+		RR1_file_name_,//probabilities1 file name
+		RR2_file_name_,//probabilities2 file name
+
+		*d_rand_all,
+		d_rand_flag,
+		rand_,
+
+
+		d_number_of_AA,
+		d_smatr,
+		d_RR1,
+		d_RR2);
+
+		init_main_class_members(
+		rand_,//randomization number
+		randout_,//if defined, then the program outputs complete randomization information into a file
+
+		open_,//gap opening penalty
+		open1_,//gap opening penalty for a gap in the sequence #1
+		open2_,//gap opening penalty for a gap in the sequence #2
+
+		epen_,//gap extension penalty
+		epen1_,//gap extension penalty for a gap in the sequence #1
+		epen2_,//gap extension penalty for a gap in the sequence #2
+
+		max_time_,//maximum allowed calculation time in seconds
+		max_mem_,//maximum allowed memory usage in MB
+		eps_lambda_,//relative error for lambda calculation
+		eps_K_,//relative error for K calculation
+		insertions_after_deletions_);//if true, then insertions after deletions are allowed
+
+		d_max_time_with_computation_parameters=-1;
+
+		if(max_time_>0)
+		{
+			d_max_time_for_quick_tests=0.25*max_time_;
+		}
+		else
+		{
+			d_max_time_for_quick_tests=1e99;
+		};
+
+
+
+	}
+	catch (...)
+	{
+		release_memory();
+		throw;
+	};
+}
+
+
+alp_data::alp_data(//constructor
+long int rand_,//randomization number
+struct_for_randomization *randomization_parameters_,//if not NULL, sets d_rand_flag to true and initializes d_rand_all
+
+long int open_,//gap opening penalty
+long int open1_,//gap opening penalty for a gap in the sequence #1
+long int open2_,//gap opening penalty for a gap in the sequence #2
+
+long int epen_,//gap extension penalty
+long int epen1_,//gap extension penalty for a gap in the sequence #1
+long int epen2_,//gap extension penalty for a gap in the sequence #2
+
+long alphabetSize_,
+const long *const *substitutionScoreMatrix_,
+const double *letterFreqs1_,
+const double *letterFreqs2_,
+
+double max_time_,//maximum allowed calculation time in seconds
+double max_mem_,//maximum allowed memory usage in MB
+double eps_lambda_,//relative error for lambda calculation
+double eps_K_,//relative error for K calculation
+bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
+double max_time_for_quick_tests_,//maximum allowed calculation time in seconds for quick tests
+double max_time_with_computation_parameters_)//maximum allowed time in seconds for the whole computation
+{
+
+
+	d_smatr=NULL;
+	d_RR1=NULL;
+	d_RR1_sum=NULL;
+	d_RR1_sum_elements=NULL;
+
+	d_RR2=NULL;
+	d_RR2_sum=NULL;
+	d_RR2_sum_elements=NULL;
+
+	d_is=NULL;
+	d_r_i_dot=NULL;
+	d_r_dot_j=NULL;
+
+	d_rand_all=NULL;
+
+	try
+	{
+
+		d_rand_flag=false;
+
+		d_number_of_AA=alphabetSize_;
+		string randout="";
+
+
+		get_memory_for_matrix(alphabetSize_,d_smatr);
+		alp_data::assert_mem(d_smatr);
+		d_RR1=new double[alphabetSize_];
+		alp_data::assert_mem(d_RR1);
+		d_RR2=new double[alphabetSize_];
+		alp_data::assert_mem(d_RR2);
+
+		long int i,j;
+		for(i=0;i<alphabetSize_;i++)
+		{
+			d_RR1[i]=letterFreqs1_[i];
+			d_RR2[i]=letterFreqs2_[i];
+			for(j=0;j<alphabetSize_;j++)
+			{
+				d_smatr[i][j]=substitutionScoreMatrix_[i][j];
+			};
+
+		};
+
+		d_rand_all=new struct_for_randomization;
+
+		if(randomization_parameters_)
+		{
+			d_rand_flag=true;
+
+			d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP=
+				randomization_parameters_->d_first_stage_preliminary_realizations_numbers_ALP;
+
+			d_rand_all->d_preliminary_realizations_numbers_ALP=
+				randomization_parameters_->d_preliminary_realizations_numbers_ALP;
+
+			d_rand_all->d_preliminary_realizations_numbers_killing=
+				randomization_parameters_->d_preliminary_realizations_numbers_killing;
+
+			d_rand_all->d_random_seed=
+				randomization_parameters_->d_random_seed;
+
+			d_rand_all->d_total_realizations_number_with_ALP=
+				randomization_parameters_->d_total_realizations_number_with_ALP;
+
+			d_rand_all->d_total_realizations_number_with_killing=
+				randomization_parameters_->d_total_realizations_number_with_killing;
+		};
+
+		alp_data::assert_mem(d_rand_all);
+		d_memory_size_in_MB+=sizeof(struct_for_randomization)/mb_bytes;
+
+		init_main_class_members(
+		rand_,//randomization number
+		randout,//if defined, then the program outputs complete randomization information into a file
+
+		open_,//gap opening penalty
+		open1_,//gap opening penalty for a gap in the sequence #1
+		open2_,//gap opening penalty for a gap in the sequence #2
+
+		epen_,//gap extension penalty
+		epen1_,//gap extension penalty for a gap in the sequence #1
+		epen2_,//gap extension penalty for a gap in the sequence #2
+
+		max_time_,//maximum allowed calculation time in seconds
+		max_mem_,//maximum allowed memory usage in MB
+		eps_lambda_,//relative error for lambda calculation
+		eps_K_,//relative error for K calculation
+		insertions_after_deletions_);//if true, then insertions after deletions are allowed
+
+		if(max_time_for_quick_tests_>0)
+		{
+			d_max_time_for_quick_tests=max_time_for_quick_tests_;
+		}
+		else
+		{
+			if(max_time_>0)
+			{
+				d_max_time_for_quick_tests=0.25*max_time_;
+			}
+			else
+			{
+				d_max_time_for_quick_tests=1e99;
+			};
+		};
+
+		if((max_time_with_computation_parameters_>0)&&(!(max_time_>0)))
+		{
+			d_max_time_with_computation_parameters=max_time_with_computation_parameters_;
+		}
+		else
+		{
+			d_max_time_with_computation_parameters=1e99;
+		};
+
+		calculate_RR_sum(
+		d_RR1,
+		alphabetSize_,
+		d_RR1_sum,
+		d_RR1_sum_elements);
+
+		calculate_RR_sum(
+		d_RR2,
+		alphabetSize_,
+		d_RR2_sum,
+		d_RR2_sum_elements);
+
+
+	}
+	catch (...)
+	{ 
+		release_memory();
+		throw;
+	};
+}
+
+long int alp_data::random_long(
+double value_,
+long int dim_)
+{
+	if(value_<0||value_>1.0||dim_<=0)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+	if(dim_==1)
+	{
+		return 0;
+	};
+
+	long int tmp=(long int)floor(value_*(double)dim_);
+	tmp=Tmin(tmp,dim_-1);
+	return tmp;
+}
+
+void alp_data::release_memory()
+{
+	delete[]d_RR1;d_RR1=NULL;
+	delete[]d_RR1_sum;d_RR1_sum=NULL;
+	delete[]d_RR1_sum_elements;d_RR1_sum_elements=NULL;
+
+	delete[]d_RR2;d_RR2=NULL;
+	delete[]d_RR2_sum;d_RR2_sum=NULL;
+	delete[]d_RR2_sum_elements;d_RR2_sum_elements=NULL;
+
+	
+	
+
+	d_memory_size_in_MB-=2.0*(double)(2.0*sizeof(double)+sizeof(long int))*(double)d_number_of_AA/mb_bytes;
+
+
+
+	if(d_smatr)
+	{
+		delete_memory_for_matrix(d_number_of_AA_smatr,d_smatr);
+	};
+
+
+	delete d_is;d_is=NULL;
+
+	d_memory_size_in_MB-=sizeof(d_is)/mb_bytes;
+
+	delete[]d_r_i_dot;d_r_i_dot=NULL;
+	delete[]d_r_dot_j;d_r_dot_j=NULL;
+	d_memory_size_in_MB-=(double)(sizeof(double)*d_number_of_AA*2.0)/mb_bytes;
+
+	delete d_rand_all;d_rand_all=NULL;
+	d_memory_size_in_MB-=sizeof(struct_for_randomization)/mb_bytes;
+
+}
+
+alp_data::~alp_data()//destructor
+{
+	release_memory();
+}
+
+void alp_data::check_out_file(
+	string out_file_name_)
+{
+	ifstream f;
+	char *str_ch=NULL;
+
+	try
+	{
+		f.open(out_file_name_.data(),ios::in);
+		if(!f)
+		{
+			return;
+		};
+
+		bool symmetric_case_flag;
+		
+		string str;
+		getline(f,str);
+		str_ch=new char[str.length()+1];
+		alp_data::assert_mem(str_ch);
+
+		long int k;
+		for(k=0;k<(long int)str.length();k++)
+		{
+			str_ch[k]=str[k];
+		};
+		str_ch[str.length()]='\0';
+
+
+		char str_for_test0[]="number of realizations with killing";
+		char *test_flag0= strstr(str_ch,str_for_test0);
+
+		if(!test_flag0)
+		{
+			throw error("The output file "+out_file_name_+" exists and does not have the correct format;\nplease delete the file and rerun the program\n",3);
+		};
+
+		char str_for_test[]="0.5*";
+
+		char*test_flag= strstr(str_ch,str_for_test);
+		if(test_flag)
+		{
+			symmetric_case_flag=true;
+		}
+		else
+		{
+			symmetric_case_flag=false;
+		};
+
+
+		
+
+		if(symmetric_case_flag)
+		{
+			if(!d_smatr_symmetric_flag)
+			{
+				throw error("The output file "+out_file_name_+" exists and corresponds to symmetric case; \nthe current calculation uses non-symmetric parameters;\nplease define another output file name\n",3);
+			};
+		};
+
+		if(!symmetric_case_flag)
+		{
+			if(d_smatr_symmetric_flag)
+			{
+				throw error("The output file "+out_file_name_+" exists and corresponds to non-symmetric case; \nthe current calculation uses symmetric parameters;\nplease define another output file name\n",3);
+			};
+		};
+
+		f.close();
+		delete[]str_ch;str_ch=NULL;
+	}
+	catch (...)
+	{ 
+		delete[]str_ch;str_ch=NULL;
+
+		if(f.is_open())
+		{
+			f.close();
+		};
+
+		throw;
+	};
+
+}
+
+double importance_sampling::lambda_equation(double x_,void* func_number_)
+{
+	data_for_lambda_equation *data=(data_for_lambda_equation*)func_number_;
+	long int d_number_of_AA=data->d_number_of_AA;
+	long int** d_smatr=data->d_smatr;
+	double *d_RR1=data->d_RR1;
+	double *d_RR2=data->d_RR2;
+
+	double res=0;
+	long int i,j;
+
+	for(i=0;i<d_number_of_AA;i++)
+	{
+		for(j=0;j<d_number_of_AA;j++)
+		{
+			res+=d_RR1[i]*d_RR2[j]*exp(x_*d_smatr[i][j]);
+		};
+	};
+
+	return res-1.0;
+}
+
+void alp_data::read_smatr(
+string smatr_file_name_,
+long int **&smatr_,
+long int &number_of_AA_smatr_)
+{
+	ifstream f;
+
+	try
+	{
+
+		long int i,j;
+		f.open(smatr_file_name_.data(),ios::in);
+		if(!f)
+		{
+			throw error("Error - file "+smatr_file_name_+" is not found\n",3);
+		};
+
+		f>>number_of_AA_smatr_;
+
+		if(number_of_AA_smatr_<=0)
+		{
+			throw error("Error - number of letters in the scoring matrix file must be greater than 0\n",3);
+		};
+
+		get_memory_for_matrix(number_of_AA_smatr_,smatr_);
+
+
+		for(i=0;i<number_of_AA_smatr_;i++)
+		{
+			for(j=0;j<number_of_AA_smatr_;j++)
+			{
+				f>>smatr_[i][j];
+			};
+		};
+
+		f.close();
+
+	}
+	catch (...)
+	{ 
+		if(f.is_open())
+		{
+			f.close();
+		};
+		throw;
+	};
+
+
+}
+
+void alp_data::read_RR(
+string RR_file_name_,
+double *&RR_,
+double *&RR_sum_,
+long int *&RR_sum_elements_,
+long int &number_of_AA_RR_)
+{
+
+	read_RR(
+	RR_file_name_,
+	RR_,
+	number_of_AA_RR_);
+
+	calculate_RR_sum(
+	RR_,
+	number_of_AA_RR_,
+	RR_sum_,
+	RR_sum_elements_);
+}
+
+void alp_data::check_RR_sum(
+double sum_tmp_,
+long int number_of_AA_RR_,
+string RR_file_name_)
+{
+
+	if(number_of_AA_RR_<=0)
+	{
+		throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
+	};
+
+	double diff_tmp=fabs(sum_tmp_-1.0);
+	if(diff_tmp>0)
+	{
+		double lg_diff=-(log(diff_tmp)-log((double)number_of_AA_RR_))/log(10.0);
+		double lg_eps=-log(DBL_EPSILON)/log(10.0)-1;
+		if(lg_diff<lg_eps)
+		{
+
+			if(sum_tmp_<=0)
+			{
+				if(RR_file_name_!="")
+				{
+					throw error("Error: the sum of the probabilities from the file "+RR_file_name_+" is non-positive\n",3);
+				}
+				else
+				{
+					throw error("Error: the sum of the probabilities is non-positive\n",3);
+				};
+
+			};
+
+			if(RR_file_name_!="")
+			{
+				static map<string, bool> flag_RR;
+
+				if(!flag_RR[RR_file_name_])
+				{
+					cout<<"\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
+					cout<<"Warning: the sum of the probabilities from the file "<<RR_file_name_<<" is not equal to 1\n";
+					cout<<"The probabilities will be normalized for the computation\n";
+					cout<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n";
+
+					flag_RR[RR_file_name_]=true;
+				};
+			}
+			else
+			{
+				//no messages if called from the library functions
+			};
+
+		};
+
+	};
+
+
+
+}
+
+void alp_data::calculate_RR_sum(
+double *RR_,
+long int number_of_AA_RR_,
+double *&RR_sum_,
+long int *&RR_sum_elements_)
+{
+	RR_sum_=NULL;
+	RR_sum_elements_=NULL;
+
+	try
+	{
+
+		long int i;
+		if(number_of_AA_RR_<=0)
+		{
+			throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
+		};
+		
+		RR_sum_=new double[number_of_AA_RR_];
+		assert_mem(RR_sum_);
+
+		RR_sum_elements_=new long int [number_of_AA_RR_];
+		assert_mem(RR_sum_elements_);
+
+
+		for(i=0;i<number_of_AA_RR_;i++)
+		{
+			if(RR_[i]<0)
+			{
+				throw error("Error - the frequencies must be non-negative\n",3);
+			};
+
+			if(i!=0)
+			{
+				RR_sum_[i]=RR_sum_[i-1]+RR_[i];
+			}
+			else
+			{
+				RR_sum_[i]=RR_[i];
+			};
+			RR_sum_elements_[i]=i;
+		};
+
+		double sum_tmp=RR_sum_[number_of_AA_RR_-1];
+
+		check_RR_sum(
+		sum_tmp,
+		number_of_AA_RR_,
+		"");
+
+		if(sum_tmp>0)
+		{
+			long int i;
+			for(i=0;i<number_of_AA_RR_;i++)
+			{
+				RR_[i]/=sum_tmp;
+				RR_sum_[i]/=sum_tmp;
+			};
+		};
+
+	}
+	catch (...)
+	{ 
+		delete[]RR_sum_;RR_sum_=NULL;
+		delete[]RR_sum_elements_;RR_sum_elements_=NULL;
+		throw;
+	};
+
+
+}
+
+
+void alp_data::read_RR(
+string RR_file_name_,
+double *&RR_,
+long int &number_of_AA_RR_)
+{
+
+	ifstream f;
+	RR_=NULL;
+
+	try
+	{
+
+		long int i;
+		f.open(RR_file_name_.data(),ios::in);
+		if(!f)
+		{
+			throw error("Error - file "+RR_file_name_+" is not found\n",3);
+		};
+
+		f>>number_of_AA_RR_;
+
+		if(number_of_AA_RR_<=0)
+		{
+			throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
+		};
+		
+		RR_=new double[number_of_AA_RR_];
+		assert_mem(RR_);
+
+
+		double sum_tmp=0;
+		for(i=0;i<number_of_AA_RR_;i++)
+		{
+			f>>RR_[i];
+
+			if(RR_[i]<0)
+			{
+				throw error("Error - the frequencies defined in the file "+RR_file_name_+" must be non-negative\n",3);
+			};
+
+			sum_tmp+=RR_[i];
+
+		};
+
+		check_RR_sum(
+		sum_tmp,
+		number_of_AA_RR_,
+		RR_file_name_);
+
+		f.close();
+	}
+
+	catch (...)
+	{ 
+		delete[]RR_;RR_=NULL;
+		if(f.is_open())
+		{
+			f.close();
+		};
+		throw;
+	};
+
+}
+
+
+
+string alp_data::long_to_string(//convert interer ot string
+long int number_)
+{
+	string res_="";
+	string tmp_string;
+	if(number_>0)
+	{
+		tmp_string="";
+	}
+	else
+	{
+		if(number_==0)
+		{
+			tmp_string="";
+		}
+		else
+		{
+			tmp_string="-";
+		};
+	};
+	number_=abs(number_);
+
+	for( ; ; )
+	{
+		long int reminder=number_%10;
+		number_=(number_-reminder)/10;
+		res_=digit_to_string(reminder)+res_;
+		if (number_==0)
+		{
+			break;
+		};
+	};
+
+	return tmp_string+res_;
+}
+
+char alp_data::digit_to_string(//convert interer ot string
+long int digit_)
+{
+	switch(digit_)
+	{
+	case 0:return '0';
+	case 1:return '1';
+	case 2:return '2';
+	case 3:return '3';
+	case 4:return '4';
+	case 5:return '5';
+	case 6:return '6';
+	case 7:return '7';
+	case 8:return '8';
+	case 9:return '9';
+	default:return '?';
+	};
+}
+
+importance_sampling::importance_sampling(
+alp_data *alp_data_,
+long int open_,
+
+long int epen_,
+
+long int number_of_AA_,
+long int **smatr_,
+double *RR1_,
+double *RR2_)
+{
+	d_elements=NULL;
+	d_elements_values=NULL;
+
+	d_exp_s=NULL;
+
+	d_alp_data=alp_data_;
+	if(!d_alp_data)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+	try
+	{
+
+
+
+		{
+
+			//calculation of the importance sampling theta
+
+			data_for_lambda_equation tmp_ptr;
+			tmp_ptr.d_number_of_AA=number_of_AA_;
+			tmp_ptr.d_RR1=RR1_;
+			tmp_ptr.d_RR2=RR2_;
+			tmp_ptr.d_smatr=smatr_;
+
+			//calculate maximum of smatr_ elements
+			long int smatr_max=smatr_[0][0];
+			long int smatr_max_i=0;
+			long int smatr_max_j=0;
+			long int smatr_min=smatr_[0][0];
+
+			long int smatr_pos_max=LONG_MIN;
+			long int smatr_neg_min=LONG_MAX;
+
+			double eps=0.00001;
+			double threshold=DBL_MIN*10.0;
+
+			double aver_score=0;
+			long int i,j;
+			for(i=0;i<number_of_AA_;i++)
+			{
+				for(j=0;j<number_of_AA_;j++)
+				{
+					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+					//if(RR1_[j]*RR2_[i]<=threshold)
+					if(RR1_[i]*RR2_[j]<=threshold)
+					{
+						continue;
+					};
+										
+
+
+					aver_score+=RR1_[i]*RR2_[j]*smatr_[i][j];
+
+					if(smatr_max<smatr_[i][j])
+					{
+						smatr_max=smatr_[i][j];
+						smatr_max_i=i;
+						smatr_max_j=j;
+					};
+					smatr_min=alp_data::Tmin(smatr_min,smatr_[i][j]);
+					
+
+					if(smatr_[i][j]>0)
+					{
+						smatr_pos_max=alp_data::Tmax(smatr_pos_max,smatr_[i][j]);
+					};
+
+					if(smatr_[i][j]<0)
+					{
+						smatr_neg_min=alp_data::Tmin(smatr_neg_min,smatr_[i][j]);
+					};
+
+				};
+			};
+
+			if(aver_score>=-threshold)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+
+			if(smatr_max<=0)
+			{
+				throw error("Error - at least one element of the scoring matrix must be positive\n",3);
+			};
+
+			
+
+			double a=eps;
+
+			while(importance_sampling::lambda_equation(a,(void*)(&tmp_ptr))>0)
+			{
+				a/=2.0;
+
+				if(a<threshold*100.0)
+				{
+					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+				};
+			};
+
+			if(a<threshold*100.0)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+
+			eps=a/10.0;
+
+
+			double tmp_pr=RR1_[smatr_max_i]*RR2_[smatr_max_j];
+			double b=(log(1+10*eps)-log(tmp_pr))/(double)smatr_max;
+
+			
+			long int n_partition=2;
+			vector<double> res_lambda;
+			
+			
+			alp_reg::find_tetta_general(
+			importance_sampling::lambda_equation,
+			(void*)(&tmp_ptr),
+			a,
+			b,
+			n_partition,
+			eps,
+			res_lambda);
+
+			sort(res_lambda.begin(),res_lambda.end());
+
+			if(res_lambda.size()==0)
+			{
+				//throw error("Error - the program is not able to find the ungapped lambda. The program does not work with the input scoring scheme. \n",3);
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+
+			d_lambda=res_lambda[res_lambda.size()-1];
+			d_ungap_lambda=d_lambda;
+
+			//cout<<"\nUngapped lambda is "<<d_ungap_lambda<<endl;
+
+			d_lambda*=1.07;
+		};
+
+
+		
+		d_is_number_of_AA=number_of_AA_;
+
+		d_elements=new q_elem[number_of_AA_*number_of_AA_];
+		alp_data::assert_mem(d_elements);
+
+		d_elements_values=new double[number_of_AA_*number_of_AA_];
+		alp_data::assert_mem(d_elements_values);
+
+
+
+		d_alp_data->get_memory_for_matrix(d_is_number_of_AA,d_exp_s);
+
+		long int ind=0;
+		double sum=0;
+		long int a,b;
+		for(a=0;a<number_of_AA_;a++)
+		{
+			for(b=0;b<number_of_AA_;b++)
+			{
+				d_exp_s[a][b]=exp(d_lambda*smatr_[a][b]);
+				d_elements_values[ind]=RR1_[a]*RR2_[b]*d_exp_s[a][b];
+				sum+=d_elements_values[ind];
+				ind++;
+			};
+		};
+
+
+		for(a=0;a<number_of_AA_;a++)
+		{
+			for(b=0;b<number_of_AA_;b++)
+			{
+				d_exp_s[a][b]/=sum;
+			};
+
+		};
+
+
+		for(ind=0;ind<number_of_AA_*number_of_AA_;ind++)
+		{
+			d_elements_values[ind]/=sum;
+		};
+
+		
+		for(ind=1;ind<number_of_AA_*number_of_AA_;ind++)
+		{
+			d_elements_values[ind]=d_elements_values[ind-1]+d_elements_values[ind];
+		};
+
+		
+		ind=0;
+		for(a=0;a<number_of_AA_;a++)
+		{
+			for(b=0;b<number_of_AA_;b++)
+			{
+				q_elem elem_tmp;
+
+				elem_tmp.d_a=a;
+				elem_tmp.d_b=b;
+
+				d_elements[ind]=elem_tmp;
+				d_elements_values[ind]=d_elements_values[ind];
+
+				ind++;
+
+			};
+		};
+
+
+
+		d_mu=exp(-fabs(d_lambda)*open_);
+		d_nu=exp(-fabs(d_lambda)*epen_);
+
+		double tmp=1+d_mu-d_nu;
+
+		d_eta=(1-d_nu)*(1-d_nu)/(tmp*tmp);
+		d_mu_SI=1-d_nu;
+		d_mu_IS=d_mu*(1-d_nu)/(tmp*tmp);
+		d_mu_DS=d_mu/tmp;
+		d_mu_SD=(1-d_nu)*(1-d_nu)/tmp;
+		d_mu_ID=d_mu*(1-d_nu)/tmp;
+
+
+		d_for_D[0]=d_nu;				d_for_D_states[0]='D';
+		d_for_D[1]=d_for_D[0]+d_mu_SD;	d_for_D_states[1]='S';
+		d_for_D[2]=d_for_D[1]+d_mu_ID;	d_for_D_states[2]='I';
+
+		d_for_I[0]=d_nu;				d_for_I_states[0]='I';
+		d_for_I[1]=d_for_I[0]+d_mu_SI;	d_for_I_states[1]='S';
+
+		d_for_S[0]=d_eta;				d_for_S_states[0]='S';
+		d_for_S[1]=d_for_S[0]+d_mu_DS;	d_for_S_states[1]='D';
+		d_for_S[2]=d_for_S[1]+d_mu_IS;	d_for_S_states[2]='I';
+
+		d_alp_data->d_memory_size_in_MB+=sizeof(double)*number_of_AA_/mb_bytes;
+		d_alp_data->d_memory_size_in_MB+=sizeof(q_elem)*number_of_AA_/mb_bytes;
+	}
+	catch (...)
+	{
+		this->~importance_sampling();
+		throw;
+	};
+
+}
+
+importance_sampling::~importance_sampling()
+{
+	delete []d_elements;d_elements=NULL;
+	delete []d_elements_values;d_elements_values=NULL;
+
+	if(d_alp_data)
+	{
+		d_alp_data->delete_memory_for_matrix(d_is_number_of_AA,d_exp_s);
+		d_alp_data->d_memory_size_in_MB-=sizeof(double)*d_is_number_of_AA/mb_bytes;
+		d_alp_data->d_memory_size_in_MB-=sizeof(q_elem)*d_is_number_of_AA/mb_bytes;
+	};
+
+}
+
+double alp_data::error_of_the_sum(//v1_+v2_
+double v1_error_,
+double v2_error_)
+{
+	if(v1_error_>=1e100||v2_error_>=1e100)
+	{
+		return 1e100;
+	};
+
+	return sqrt(v1_error_*v1_error_+v2_error_*v2_error_);
+}
+
+double alp_data::error_of_the_product(//v1_*v2_
+double v1_,
+double v1_error_,
+double v2_,
+double v2_error_)
+{
+	if(v1_error_>=1e100||v2_error_>=1e100)
+	{
+		return 1e100;
+	};
+
+	double a1=(v1_+v1_error_)*(v2_+v2_error_);
+	double a2=(v1_-v1_error_)*(v2_+v2_error_);
+	double a3=(v1_+v1_error_)*(v2_-v2_error_);
+	double a4=(v1_-v1_error_)*(v2_-v2_error_);
+
+	double a=v1_*v2_;
+
+	return Tmax(fabs(a1-a),fabs(a2-a),fabs(a3-a),fabs(a4-a));
+
+}
+
+double alp_data::error_of_the_sqrt(//sqrt(v1_)
+double v1_,
+double v1_error_)
+{
+	if(v1_error_>=1e100||v1_<0)
+	{
+		return 1e100;
+	};
+
+	double s=sqrt(v1_);
+	double s1=sqrt(alp_data::Tmax(0.0,v1_-v1_error_));
+	double s2=sqrt(alp_data::Tmax(0.0,v1_+v1_error_));
+
+	return alp_data::Tmax(fabs(s-s1),fabs(s-s2));
+}
+
+double alp_data::error_of_the_ratio(//v1_/v2_
+double v1_,
+double v1_error_,
+double v2_,
+double v2_error_)
+{
+	if(v1_error_>=1e100||v2_error_>=1e100)
+	{
+		return 1e100;
+	};
+
+	if(v2_==0)
+	{
+		return 1e100;
+	};
+
+	if(v1_==0&&v1_error_==0)
+	{
+		return 0.0;
+	};
+
+	double a=v1_/v2_;
+
+	if(((v2_+v2_error_)*v2_<=0))
+	{
+		double a3=(v1_+v1_error_)/(v2_-v2_error_);
+		double a4=(v1_-v1_error_)/(v2_-v2_error_);
+		return alp_data::Tmax(fabs(a-a3),fabs(a-a4));
+	};
+
+	if(((v2_-v2_error_)*v2_<=0))
+	{
+		double a1=(v1_+v1_error_)/(v2_+v2_error_);
+		double a2=(v1_-v1_error_)/(v2_+v2_error_);
+		return alp_data::Tmax(fabs(a-a1),fabs(a-a2));
+	};
+
+
+	double a1=(v1_+v1_error_)/(v2_+v2_error_);
+	double a2=(v1_-v1_error_)/(v2_+v2_error_);
+	double a3=(v1_+v1_error_)/(v2_-v2_error_);
+	double a4=(v1_-v1_error_)/(v2_-v2_error_);
+
+	return Tmax(fabs(a-a1),fabs(a-a2),fabs(a-a3),fabs(a-a4));
+}
+
+double alp_data::error_of_the_lg(//lg(v1_)
+double v1_,
+double v1_error_)
+{
+	if(v1_error_>=1e100||v1_<=0)
+	{
+		return 1e100;
+	};
+
+	return alp_data::Tmin(fabs(log(v1_)/log(10.0)),v1_error_/v1_/log(10.0));
+}
+
+bool alp_data::the_value_is_double(
+string str_,
+double &val_)
+{
+	if(str_=="")
+	{
+		return false;
+	};
+
+	bool res=false;
+	errno=0;
+	char *p;
+	val_=strtod(str_.c_str(),&p);
+	if(errno!=0)
+	{
+		res=false;
+	}
+	else
+	{
+		res=(*p==0);
+	};
+	return res;
+}
+
+bool alp_data::the_value_is_long(
+string str_,
+long int &val_)
+{
+
+	if(str_.length()==0)
+	{
+		return false;
+	};
+	if(!(str_[0]=='+'||str_[0]=='-'||isdigit(str_[0])))
+	{
+		return false;
+	};
+
+	long int start_digit=0;
+
+	if(str_[0]=='+'||str_[0]=='-')
+	{
+		start_digit=1;
+	};
+
+
+	long int i;
+	for(i=start_digit;i<(long int)str_.size();i++)
+	{
+		if(!isdigit(str_[i]))
+		{
+			return false;
+		};
+	};
+
+	if(((long int)str_.size()-start_digit)<=0)
+	{
+		return false;
+	};
+
+	if(((long int)str_.size()-start_digit)>1)
+	{
+		/*
+		if(str_[start_digit]=='0')
+		{
+			return false;
+		};
+		*/
+
+		while(str_[start_digit]=='0')
+		{
+			string::iterator it=str_.begin()+start_digit;
+
+
+			str_.erase(it);
+			if((long int)str_.size()<=start_digit+1)
+			{
+				break;
+			};
+		};
+	};
+
+	if(((long int)str_.size()-start_digit>10)||((long int)str_.size()-start_digit)<=0)
+	{
+		return false;
+	};
+
+
+	if((long int)str_.size()-start_digit==10)
+	{
+		if(!(str_[start_digit]=='1'||str_[start_digit]=='2'))
+		{
+			return false;
+		};
+
+		if(str_[start_digit]=='2')
+		{
+
+			long int val2;
+			string str2=str_.substr(start_digit+1,9);
+			int flag=sscanf(str2.c_str(),"%ld",&val2);
+			if(flag!=1)
+			{
+				return false;
+			};
+
+			bool positive=true;
+			if(start_digit>0)
+			{
+				if(str_[0]=='-')
+				{
+					positive=false;
+				};
+			};
+
+			if(positive)
+			{
+				if(val2>147483647)
+				{
+					return false;
+				};
+			}
+			else
+			{
+				if(val2>147483648)
+				{
+					return false;
+				};
+			};
+
+		};
+	};
+
+	int flag=sscanf(str_.c_str(),"%ld",&val_);
+	if(flag!=1)
+	{
+		return false;
+	};
+
+	return true;
+}
+
diff --git a/src/alp/sls_alp_data.hpp b/src/alp/sls_alp_data.hpp
index d3d5372..24e6150 100644
--- a/src/alp/sls_alp_data.hpp
+++ b/src/alp/sls_alp_data.hpp
@@ -1,937 +1,937 @@
-#ifndef INCLUDED_SLS_ALP_DATA
-#define INCLUDED_SLS_ALP_DATA
-
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_alp_data.hpp
-
-Author: Sergey Sheetlin, Martin Frith
-
-Contents: Contains input data
-
-******************************************************************************/
-#include "sls_basic.hpp"
-
-#include <complex>
-#include <iostream>
-#include <map>
-#include <vector>
-#include <fstream>
-#include <float.h>
-#include <ctime>
-#include <stdlib.h>
-#include <limits>
-#include <climits>
-#include <cstring>
-#include <cstdlib>
-#include <errno.h>
-
-
-#ifndef _MSC_VER //UNIX program
-#include <sys/time.h>
-#else
-#include <sys/timeb.h>
-
-#define _CRTDBG_MAP_ALLOC
-#include <crtdbg.h>
-
-#endif
-
-
-#include "sls_alp_regression.hpp"
-#include "njn_random.hpp"
-#include "njn_uniform.hpp"
-
-
-const double mb_bytes=1048576.0;
-
-namespace Sls {
-
-
-	struct struct_for_randomization
-	{
-		long int d_random_seed;
-		std::vector<long int> d_first_stage_preliminary_realizations_numbers_ALP;
-		std::vector<long int> d_preliminary_realizations_numbers_ALP;
-		std::vector<long int> d_preliminary_realizations_numbers_killing;
-		long int d_total_realizations_number_with_ALP;
-		long int d_total_realizations_number_with_killing;
-	};
-
-
-
-	struct error_for_single_realization//struct to handle exceptions during calclation of single realization
-	{
-		std::string st;
-		error_for_single_realization(){};
-	};
-
-	struct data_for_lambda_equation//struct for lambda_equation
-	{
-		long int d_number_of_AA;//number of AA
-		long int** d_smatr;//scoring matrix
-		double *d_RR1;//AA probabilities
-		double *d_RR2;//AA probabilities
-	};
-
-
-	class alp_data;
-
-	template<typename T> class array_positive{
-	public:
-		array_positive(alp_data *alp_data_)// constructor
-		{ 
-			d_elem=NULL;
-			d_alp_data=alp_data_; 
-			if(!d_alp_data)
-			{
-				throw error("Unexpected error\n",4);
-			};
-			d_dim=-1;
-			d_step=10;
-		}
-
-		~array_positive();
-
-
-		void increment_array(long int ind_);
-		
-
-		inline void set_elem(
-			long int ind_,
-			T elem_)
-		{
-			if(ind_>d_dim)
-			{
-				increment_array(ind_);
-			};
-
-			d_elem[ind_]=elem_;
-		}
-
-		inline void increase_elem_by_1(
-			long int ind_)
-		{
-			if(ind_>d_dim)
-			{
-				increment_array(ind_);
-			};
-
-			d_elem[ind_]++;
-		}
-
-		inline void increase_elem_by_x(
-			long int ind_,
-			T x_)
-		{
-			if(ind_>d_dim)
-			{
-				increment_array(ind_);
-			};
-
-			d_elem[ind_]+=x_;
-		}
-
-
-
-	public:
-		
-		long int d_step;
-		long int d_dim;//dimension of the array is d_dim+1
-		T * d_elem;
-		alp_data *d_alp_data;//initial data
-	};
-
-
-	template<typename T> class array{
-	public:
-		array(alp_data *alp_data_)// constructor
-		{ 
-			d_elem=NULL;
-			d_alp_data=alp_data_; 
-			d_dim=-1;
-			d_ind0=0;
-			d_step=10;
-			d_dim_plus_d_ind0=d_dim+d_ind0;
-		}
-
-		~array();
-
-		void increment_array_on_the_right(long int ind_);
-
-		void increment_array_on_the_left(long int ind_);
-
-
-		void set_elems(const array<T> *a_);
-
-		inline void set_elem(
-			long int ind_,
-			T elem_)
-		{
-			if(ind_>d_dim_plus_d_ind0)
-			{
-				increment_array_on_the_right(ind_);
-			};
-
-			if(ind_<d_ind0)
-			{
-				increment_array_on_the_left(ind_);
-			};
-
-			d_elem[ind_-d_ind0]=elem_;
-		}
-
-		inline void increase_elem_by_1(
-			long int ind_)
-		{
-			if(ind_>d_dim_plus_d_ind0)
-			{
-				increment_array_on_the_right(ind_);
-			};
-
-			if(ind_<d_ind0)
-			{
-				increment_array_on_the_left(ind_);
-			};
-
-			d_elem[ind_-d_ind0]++;
-		}
-
-		
-	public:
-		
-		long int d_step;
-		long int d_dim;//dimension of the array is d_dim+1
-		long int d_ind0;//the leftmost index of the array
-		long int d_dim_plus_d_ind0;
-		T * d_elem;
-		alp_data *d_alp_data;//initial data
-	};
-
-
-	struct q_elem
-	{
-		long int d_a;
-		long int d_b;
-	};
-
-	class importance_sampling{
-
-	public:
-		importance_sampling(
-		alp_data *alp_data_,
-		long int open_,
-
-		long int epen_,
-
-		long int number_of_AA_,
-		long int **smatr_,
-		double *RR1_,
-		double *RR2_);
-
-		double d_mu;
-		double d_nu;
-		double d_eta;
-		double d_mu_SI;
-		double d_mu_DS;
-		double d_mu_ID;
-		double d_mu_IS;
-		double d_mu_SD;
-		q_elem * d_elements;
-		double * d_elements_values;
-
-
-		double d_for_D[3];
-		double d_for_I[2];
-		double d_for_S[3];
-
-		char d_for_D_states[3];
-		char d_for_I_states[2];
-		char d_for_S_states[3];
-
-		double **d_exp_s;
-		double d_lambda;
-		double d_ungap_lambda;
-
-
-
-		~importance_sampling();
-
-		static double lambda_equation(double x_,void* func_number_);
-
-
-		long int d_is_number_of_AA;
-		alp_data *d_alp_data;//initial data
-
-	};
-
-
-
-	class alp_data: public sls_basic{
-
-	
-
-	public:
-
-		alp_data(//constructor
-			long int rand_,//randomization number
-			std::string randout_,//if defined, then the program outputs complete randomization information into a file
-
-			long int open_,//gap opening penalty
-			long int open1_,//gap opening penalty for a gap in the sequence #1
-			long int open2_,//gap opening penalty for a gap in the sequence #2
-
-			long int epen_,//gap extension penalty
-			long int epen1_,//gap extension penalty for a gap in the sequence #1
-			long int epen2_,//gap extension penalty for a gap in the sequence #2
-
-			std::string smatr_file_name_,//scoring matrix file name
-			std::string RR1_file_name_,//probabilities1 file name
-			std::string RR2_file_name_,//probabilities2 file name
-			double max_time_,//maximum allowed calculation time in seconds
-			double max_mem_,//maximum allowed memory usage in MB
-			double eps_lambda_,//relative error for lambda calculation
-			double eps_K_,//relative error for K calculation
-			bool insertions_after_deletions_);//if true, then insertions after deletions are allowed
-
-			alp_data(//constructor
-			long int rand_,//randomization number
-			struct_for_randomization *randomization_parameters_,//if not NULL, sets d_rand_flag to true and initializes d_rand_all
-
-			long int open_,//gap opening penalty
-			long int open1_,//gap opening penalty for a gap in the sequence #1
-			long int open2_,//gap opening penalty for a gap in the sequence #2
-
-			long int epen_,//gap extension penalty
-			long int epen1_,//gap extension penalty for a gap in the sequence #1
-			long int epen2_,//gap extension penalty for a gap in the sequence #2
-
-			long alphabetSize_,
-			const long *const *substitutionScoreMatrix_,
-			const double *letterFreqs1_,
-			const double *letterFreqs2_,
-
-			double max_time_,//maximum allowed calculation time in seconds
-			double max_mem_,//maximum allowed memory usage in MB
-			double eps_lambda_,//relative error for lambda calculation
-			double eps_K_,//relative error for K calculation
-			bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
-			double max_time_for_quick_tests_,//maximum allowed calculation time in seconds for quick tests
-			double max_time_with_computation_parameters_);//maximum allowed time in seconds for the whole computation
-
-
-			void input_data_for_the_constructor(
-			std::string randout_,//if defined, then the program outputs complete randomization information into a file
-			std::string smatr_file_name_,//scoring matrix file name
-			std::string RR1_file_name_,//probabilities1 file name
-			std::string RR2_file_name_,//probabilities2 file name
-
-			struct_for_randomization &rand_all_,
-			bool &rand_flag_,
-			long int &rand_,
-
-			long int &alphabetSize_,
-			long int **&substitutionScoreMatrix_,
-			double *&letterFreqs1_,
-			double *&letterFreqs2_);
-
-			void init_main_class_members(
-			long int rand_,//randomization number
-			std::string randout_,//if defined, then the program outputs complete randomization information into a file
-
-			long int open_,//gap opening penalty
-			long int open1_,//gap opening penalty for a gap in the sequence #1
-			long int open2_,//gap opening penalty for a gap in the sequence #2
-
-			long int epen_,//gap extension penalty
-			long int epen1_,//gap extension penalty for a gap in the sequence #1
-			long int epen2_,//gap extension penalty for a gap in the sequence #2
-
-			double max_time_,//maximum allowed calculation time in seconds
-			double max_mem_,//maximum allowed memory usage in MB
-			double eps_lambda_,//relative error for lambda calculation
-			double eps_K_,//relative error for K calculation
-			bool insertions_after_deletions_);//if true, then insertions after deletions are allowed
-
-
-		~alp_data();//destructor
-
-		void release_memory();
-
-		inline double ran2()//generates the next random value
-		{
-			return Njn::Uniform::variate <double> (0,1);
-		}
-
-		static void read_smatr(
-			std::string smatr_file_name_,
-			long int **&smatr_,
-			long int &number_of_AA_smatr_);
-
-		void check_out_file(
-			std::string out_file_name_);
-
-
-
-		static std::string long_to_string(//convert interer ot string
-			long int number_);
-
-		static char digit_to_string(//convert interer ot string
-			long int digit_);
-
-				static bool the_value_is_double(
-				std::string str_,
-				double &val_);
-
-				static bool the_value_is_long(
-				std::string str_,
-				long int &val_);
-
-
-
-
-
-		static void read_RR(
-			std::string RR_file_name_,
-			double *&RR_,
-			double *&RR_sum_,
-			long int *&RR_sum_elements_,
-			long int &number_of_AA_RR_);
-
-		static void read_RR(
-			std::string RR_file_name_,
-			double *&RR_,
-			long int &number_of_AA_RR_);
-
-		static void calculate_RR_sum(
-			double *RR_,
-			long int number_of_AA_RR_,
-			double *&RR_sum_,
-			long int *&RR_sum_elements_);
-
-		static void check_RR_sum(
-			double sum_tmp_,
-			long int number_of_AA_RR_,
-			std::string RR_file_name_);
-
-
-
-
-		template<typename T>
-		static void get_memory_for_matrix(
-		long int dim_,
-		T ** &matr_,
-		alp_data *alp_data_=NULL)
-		{
-			matr_=NULL;
-
-			try
-			{
-
-				long int i;
-				matr_=new T *[dim_];
-				assert_mem(matr_);
-
-				for(i=0;i<dim_;i++)
-				{
-					matr_[i]=NULL;
-				};
-
-				for(i=0;i<dim_;i++)
-				{
-					matr_[i]=new T [dim_];
-					assert_mem(matr_[i]);
-				};
-
-				if(alp_data_)
-				{
-					alp_data_->d_memory_size_in_MB+=(double)sizeof(T)*(double)dim_*(double)dim_/mb_bytes;
-				};
-
-			}
-			catch (...)
-			{ 
-				if(matr_)
-				{
-					long int i;
-					for(i=0;i<dim_;i++)
-					{
-						delete[]matr_[i];matr_[i]=NULL;
-					};
-
-					delete[]matr_;matr_=NULL;
-				};
-				throw;
-			};
-
-
-		}
-
-		template<typename T>
-		static void delete_memory_for_matrix(
-		long int dim_,
-		T ** &matr_,
-		alp_data *alp_data_=NULL)
-		{
-			long int i;
-			if(matr_)
-			{
-				for(i=0;i<dim_;i++)
-				{
-					delete []matr_[i];matr_[i]=NULL;
-				};
-				delete []matr_;matr_=NULL;
-			};
-
-			if(alp_data_)
-			{
-				alp_data_->d_memory_size_in_MB-=(double)sizeof(T)*(double)dim_*(double)dim_/mb_bytes;
-			};
-		}
-
-	static long int random_long(
-	double value_,
-	long int dim_);
-
-	template<typename T>
-	static T random_long(
-	double value_,
-	long int dim_,
-	double *sum_distr_,
-	T* elements_)//sum_distr_[dim_-1] must be equal to 1
-	{
-		if(value_<0||value_>1)	
-		{
-			throw error("Unexpected error in alp_data::random_long\n",4);
-		};
-
-		long int v1=0;
-		long int v2=dim_;
-
-		while(v2-v1>1)
-		{
-			long int v3=(long int)(Sls::alp_data::round(double(v2+v1)/2.0));
-			if(sum_distr_[v3-1]==value_)
-			{
-				v1=v3-1;
-				v2=v3;
-				break;
-			};
-
-			if(sum_distr_[v3-1]>value_)
-			{
-				v2=v3;
-			}
-			else
-			{
-				v1=v3;
-			};
-		};
-
-		if(elements_)
-		{
-			long int v2_1=v2-1;
-
-
-			long int v2_minus=-1;
-
-			long int j;
-			for(j=v2_1;j>=1;j--)
-			{
-				if(sum_distr_[j]!=sum_distr_[j-1])
-				{
-					v2_minus=j;
-					break;
-				};
-			};
-
-			if(v2_minus<0)
-			{
-				if(sum_distr_[0]>0)
-				{
-					v2_minus=0;
-				};
-			};
-
-			if(v2_minus>=0)
-			{
-				return elements_[v2_minus];
-			};
-
-			long int v2_plus=-1;
-			for(j=v2;j<dim_;j++)
-			{
-				if(sum_distr_[j]!=sum_distr_[j-1])
-				{
-					v2_plus=j;
-					break;
-				};
-			};
-
-			if(v2_minus<0)
-			{
-				throw error("Unexpected error in alp_data::random_long\n",1);
-			}
-			else
-			{
-				return elements_[v2_plus];
-			};
-
-		}
-		else
-		{
-			throw error("Unexpected error in alp_data::random_long: the parameter elements_ must be defined\n",4);
-		};
-
-	}
-
-	static double error_of_the_sum(//v1_+v2_
-	double v1_error_,
-	double v2_error_);
-	
-	static double error_of_the_product(//v1_*v2_
-	double v1_,
-	double v1_error_,
-	double v2_,
-	double v2_error_);
-
-	static double error_of_the_sqrt(//sqrt(v1_)
-	double v1_,
-	double v1_error_);
-
-	static double error_of_the_ratio(//v1_/v2_
-	double v1_,
-	double v1_error_,
-	double v2_,
-	double v2_error_);
-
-	static double error_of_the_lg(//lg(v1_)
-	double v1_,
-	double v1_error_);
-
-
-
-	public:
-
-
-	
-	//input parameters
-	long int d_open;//gap opening penalty
-	long int d_open1;//gap opening penalty for a gap in the sequence #1
-	long int d_open2;//gap opening penalty for a gap in the sequence #2
-
-
-	long int d_epen;//gap extension penalty
-	long int d_epen1;//gap extension penalty for a gap in the sequence #1
-	long int d_epen2;//gap extension penalty for a gap in the sequence #2
-
-
-	double d_max_time;//maximum allowed calculation time in seconds
-	double d_max_time_for_quick_tests;//maximum allowed calculation time in seconds for quick tests
-	double d_max_time_with_computation_parameters;//maximum allowed time in seconds for the whole computation
-	double d_max_mem;//maximum allowed memory usage in MB
-	double d_eps_lambda;//relative error for lambda calculation
-	double d_eps_K;//relative error for K calculation
-
-	bool d_insertions_after_deletions;//if true, then insertions after deletions are allowed
-
-	
-	//additional parameters
-
-	bool d_smatr_symmetric_flag;//true if the scoring matrix is symmetric
-
-	long int d_number_of_AA;//number of AA
-	long int d_number_of_AA_smatr;
-
-	long int** d_smatr;//scoring matrix
-
-	double *d_RR1;//AA probabilities
-	double *d_RR1_sum;//probability distribution function for d_RR
-	long int *d_RR1_sum_elements;//numbers of AA corresponded to d_RR
-
-	double *d_RR2;//AA probabilities
-	double *d_RR2_sum;//probability distribution function for d_RR
-	long int *d_RR2_sum_elements;//numbers of AA corresponded to d_RR
-
-	long int d_random_seed;
-	std::string d_randout;//if defined, then the program outputs complete randomization information into a file
-
-
-	double d_memory_size_in_MB;//approximate current allocated memory size
-
-	importance_sampling *d_is;//data for the importance sampling
-
-	double *d_r_i_dot;
-	double *d_r_dot_j;
-
-	long int d_minimum_realizations_number;
-
-	bool d_sentinels_flag;
-
-	
-
-	//for debugging
-	long int d_dim1_tmp;
-	long int d_dim2_tmp;
-
-	long int d_realizations_number2;
-
-	double d_time_before1;
-
-	struct_for_randomization *d_rand_all;
-	bool d_rand_flag;
-	
-
-
-	};
-
-	//array_positive functions
-	template<class T>
-	array_positive<T>::~array_positive()
-	{
-		delete[]d_elem;d_elem=NULL;
-		if(d_alp_data)
-		{
-			d_alp_data->d_memory_size_in_MB-=(double)sizeof(T)*(double)(d_dim+1)/mb_bytes;
-		};
-
-	}
-
-
-	template<class T>
-	void array_positive<T>::increment_array(long int ind_)
-	{
-		T *d_elem_new=NULL;
-
-		try
-		{
-			long int o_dim=d_dim;
-			do{
-			  d_dim+=d_step;
-			}while(ind_>d_dim);
-			long int jump=d_dim-o_dim;
-
-			d_elem_new=new T[d_dim+1];
-			alp_data::assert_mem(d_elem_new);
-
-			long int i;
-			for(i=0;i<o_dim+1;i++)
-			{
-				d_elem_new[i]=d_elem[i];
-			};
-
-			for(i=o_dim+1;i<d_dim+1;i++)
-			{
-				d_elem_new[i]=0;
-			};
-
-
-			delete[]d_elem;d_elem=NULL;
-			if(d_alp_data)
-			{
-				d_alp_data->d_memory_size_in_MB+=(double)sizeof(T)*(double)jump/mb_bytes;
-			};
-
-			d_elem=d_elem_new;d_elem_new=NULL;
-		}
-		catch (...)
-		{ 
-			delete[]d_elem_new;d_elem_new=NULL;
-			throw;
-		};
-		
-	}
-
-	//array functions
-
-	template<class T>
-	array<T>::~array()
-	{
-		delete[]d_elem;d_elem=NULL;
-		if(d_alp_data)
-		{
-			d_alp_data->d_memory_size_in_MB-=(double)sizeof(T)*(double)(d_dim+1)/mb_bytes;
-		};
-
-	}
-
-	template<class T>
-	void array<T>::set_elems(const array<T> *a_)
-	{
-		long int a0=a_->d_ind0;
-		long int a1=a_->d_dim_plus_d_ind0;
-
-		if(a0>a1)return;
-
-		while(a1>d_dim_plus_d_ind0)
-		{
-			d_dim_plus_d_ind0+=d_step;
-		};
-
-		while(a0<d_ind0)
-		{
-			d_ind0-=d_step;
-		};
-
-		d_dim=d_dim_plus_d_ind0-d_ind0;
-		d_elem=new T[d_dim+1];
-		sls_basic::assert_mem(d_elem);
-
-		if(d_alp_data)
-		{
-			d_alp_data->d_memory_size_in_MB+=(double)sizeof(T)*(double)(d_dim+1)/mb_bytes;
-		};
-
-		long int i;
-		for(i=a0;i<=a1;i++)
-		{
-			d_elem[i-d_ind0]=a_->d_elem[i-a0];
-		}
-	}
-
-
-	template<class T>
-	void array<T>::increment_array_on_the_right(long int ind_)
-	{
-		bool ee_error_flag=false;
-		error ee_error("",0);
-		T *d_elem_new=NULL;
-
-		try
-		{
-		try
-		{
-
-
-			long int o_dim=d_dim;
-			do{
-			  d_dim+=d_step;
-			  d_dim_plus_d_ind0+=d_step;
-			}while(ind_>d_dim_plus_d_ind0);
-			long int jump=d_dim-o_dim;
-
-			d_elem_new=new T[d_dim+1];
-			alp_data::assert_mem(d_elem_new);
-
-			long int i;
-			for(i=0;i<o_dim+1;i++)
-			{
-				d_elem_new[i]=d_elem[i];
-			};
-
-			for(i=o_dim+1;i<d_dim+1;i++)
-			{
-				d_elem_new[i]=0;
-			};
-
-			if(d_alp_data)
-			{
-				d_alp_data->d_memory_size_in_MB+=(double)sizeof(T)*(double)jump/mb_bytes;
-			};
-
-
-			delete[]d_elem;d_elem=NULL;
-			d_elem=d_elem_new;d_elem_new=NULL;
-
-
-		}
-		catch (error er)
-		{
-			ee_error_flag=true;
-			ee_error=er;		
-		};
-		}
-		catch (...)
-		{ 
-			ee_error_flag=true;
-			ee_error=error("Internal error in the program\n",4);
-		};
-
-		//memory release
-
-		if(ee_error_flag)
-		{
-			delete[]d_elem_new;d_elem_new=NULL;
-			throw error(ee_error.st,ee_error.error_code);
-		};
-
-	}
-
-	template<class T>
-		void array<T>::increment_array_on_the_left(long int ind_)
-	{
-		T *d_elem_new=NULL;
-
-		try
-		{
-			long int o_dim=d_dim;
-			do{
-			  d_dim+=d_step;
-			  d_ind0-=d_step;
-			}while(ind_<d_ind0);
-			long int jump=d_dim-o_dim;
-
-			d_elem_new=new T[d_dim+1];
-			alp_data::assert_mem(d_elem_new);
-
-			long int i;
-
-			for(i=0;i<jump;i++)
-			{
-				d_elem_new[i]=0;
-			};
-
-			for(i=0;i<o_dim+1;i++)
-			{
-				d_elem_new[i+jump]=d_elem[i];
-			};
-
-			if(d_alp_data)
-			{
-				d_alp_data->d_memory_size_in_MB+=(double)sizeof(T)*(double)jump/mb_bytes;
-			};
-
-			delete[]d_elem;d_elem=NULL;
-			d_elem=d_elem_new;d_elem_new=NULL;
-
-		}
-		catch (...)
-		{
-			delete[]d_elem_new;d_elem_new=NULL;
-			throw;
-		};
-
-
-	}
-
-
-	}
-
-
-#endif
-
+#ifndef INCLUDED_SLS_ALP_DATA
+#define INCLUDED_SLS_ALP_DATA
+
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_alp_data.hpp
+
+Author: Sergey Sheetlin, Martin Frith
+
+Contents: Contains input data
+
+******************************************************************************/
+#include "sls_basic.hpp"
+
+#include <complex>
+#include <iostream>
+#include <map>
+#include <vector>
+#include <fstream>
+#include <float.h>
+#include <ctime>
+#include <stdlib.h>
+#include <limits>
+#include <climits>
+#include <cstring>
+#include <cstdlib>
+#include <errno.h>
+
+
+#ifndef _MSC_VER //UNIX program
+#include <sys/time.h>
+#else
+#include <sys/timeb.h>
+
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+
+#endif
+
+
+#include "sls_alp_regression.hpp"
+#include "njn_random.hpp"
+#include "njn_uniform.hpp"
+
+
+const double mb_bytes=1048576.0;
+
+namespace Sls {
+
+
+	struct struct_for_randomization
+	{
+		long int d_random_seed;
+		std::vector<long int> d_first_stage_preliminary_realizations_numbers_ALP;
+		std::vector<long int> d_preliminary_realizations_numbers_ALP;
+		std::vector<long int> d_preliminary_realizations_numbers_killing;
+		long int d_total_realizations_number_with_ALP;
+		long int d_total_realizations_number_with_killing;
+	};
+
+
+
+	struct error_for_single_realization//struct to handle exceptions during calclation of single realization
+	{
+		std::string st;
+		error_for_single_realization(){};
+	};
+
+	struct data_for_lambda_equation//struct for lambda_equation
+	{
+		long int d_number_of_AA;//number of AA
+		long int** d_smatr;//scoring matrix
+		double *d_RR1;//AA probabilities
+		double *d_RR2;//AA probabilities
+	};
+
+
+	class alp_data;
+
+	template<typename T> class array_positive{
+	public:
+		array_positive(alp_data *alp_data_)// constructor
+		{ 
+			d_elem=NULL;
+			d_alp_data=alp_data_; 
+			if(!d_alp_data)
+			{
+				throw error("Unexpected error\n",4);
+			};
+			d_dim=-1;
+			d_step=10;
+		}
+
+		~array_positive();
+
+
+		void increment_array(long int ind_);
+		
+
+		inline void set_elem(
+			long int ind_,
+			T elem_)
+		{
+			if(ind_>d_dim)
+			{
+				increment_array(ind_);
+			};
+
+			d_elem[ind_]=elem_;
+		}
+
+		inline void increase_elem_by_1(
+			long int ind_)
+		{
+			if(ind_>d_dim)
+			{
+				increment_array(ind_);
+			};
+
+			d_elem[ind_]++;
+		}
+
+		inline void increase_elem_by_x(
+			long int ind_,
+			T x_)
+		{
+			if(ind_>d_dim)
+			{
+				increment_array(ind_);
+			};
+
+			d_elem[ind_]+=x_;
+		}
+
+
+
+	public:
+		
+		long int d_step;
+		long int d_dim;//dimension of the array is d_dim+1
+		T * d_elem;
+		alp_data *d_alp_data;//initial data
+	};
+
+
+	template<typename T> class array{
+	public:
+		array(alp_data *alp_data_)// constructor
+		{ 
+			d_elem=NULL;
+			d_alp_data=alp_data_; 
+			d_dim=-1;
+			d_ind0=0;
+			d_step=10;
+			d_dim_plus_d_ind0=d_dim+d_ind0;
+		}
+
+		~array();
+
+		void increment_array_on_the_right(long int ind_);
+
+		void increment_array_on_the_left(long int ind_);
+
+
+		void set_elems(const array<T> *a_);
+
+		inline void set_elem(
+			long int ind_,
+			T elem_)
+		{
+			if(ind_>d_dim_plus_d_ind0)
+			{
+				increment_array_on_the_right(ind_);
+			};
+
+			if(ind_<d_ind0)
+			{
+				increment_array_on_the_left(ind_);
+			};
+
+			d_elem[ind_-d_ind0]=elem_;
+		}
+
+		inline void increase_elem_by_1(
+			long int ind_)
+		{
+			if(ind_>d_dim_plus_d_ind0)
+			{
+				increment_array_on_the_right(ind_);
+			};
+
+			if(ind_<d_ind0)
+			{
+				increment_array_on_the_left(ind_);
+			};
+
+			d_elem[ind_-d_ind0]++;
+		}
+
+		
+	public:
+		
+		long int d_step;
+		long int d_dim;//dimension of the array is d_dim+1
+		long int d_ind0;//the leftmost index of the array
+		long int d_dim_plus_d_ind0;
+		T * d_elem;
+		alp_data *d_alp_data;//initial data
+	};
+
+
+	struct q_elem
+	{
+		long int d_a;
+		long int d_b;
+	};
+
+	class importance_sampling{
+
+	public:
+		importance_sampling(
+		alp_data *alp_data_,
+		long int open_,
+
+		long int epen_,
+
+		long int number_of_AA_,
+		long int **smatr_,
+		double *RR1_,
+		double *RR2_);
+
+		double d_mu;
+		double d_nu;
+		double d_eta;
+		double d_mu_SI;
+		double d_mu_DS;
+		double d_mu_ID;
+		double d_mu_IS;
+		double d_mu_SD;
+		q_elem * d_elements;
+		double * d_elements_values;
+
+
+		double d_for_D[3];
+		double d_for_I[2];
+		double d_for_S[3];
+
+		char d_for_D_states[3];
+		char d_for_I_states[2];
+		char d_for_S_states[3];
+
+		double **d_exp_s;
+		double d_lambda;
+		double d_ungap_lambda;
+
+
+
+		~importance_sampling();
+
+		static double lambda_equation(double x_,void* func_number_);
+
+
+		long int d_is_number_of_AA;
+		alp_data *d_alp_data;//initial data
+
+	};
+
+
+
+	class alp_data: public sls_basic{
+
+	
+
+	public:
+
+		alp_data(//constructor
+			long int rand_,//randomization number
+			std::string randout_,//if defined, then the program outputs complete randomization information into a file
+
+			long int open_,//gap opening penalty
+			long int open1_,//gap opening penalty for a gap in the sequence #1
+			long int open2_,//gap opening penalty for a gap in the sequence #2
+
+			long int epen_,//gap extension penalty
+			long int epen1_,//gap extension penalty for a gap in the sequence #1
+			long int epen2_,//gap extension penalty for a gap in the sequence #2
+
+			std::string smatr_file_name_,//scoring matrix file name
+			std::string RR1_file_name_,//probabilities1 file name
+			std::string RR2_file_name_,//probabilities2 file name
+			double max_time_,//maximum allowed calculation time in seconds
+			double max_mem_,//maximum allowed memory usage in MB
+			double eps_lambda_,//relative error for lambda calculation
+			double eps_K_,//relative error for K calculation
+			bool insertions_after_deletions_);//if true, then insertions after deletions are allowed
+
+			alp_data(//constructor
+			long int rand_,//randomization number
+			struct_for_randomization *randomization_parameters_,//if not NULL, sets d_rand_flag to true and initializes d_rand_all
+
+			long int open_,//gap opening penalty
+			long int open1_,//gap opening penalty for a gap in the sequence #1
+			long int open2_,//gap opening penalty for a gap in the sequence #2
+
+			long int epen_,//gap extension penalty
+			long int epen1_,//gap extension penalty for a gap in the sequence #1
+			long int epen2_,//gap extension penalty for a gap in the sequence #2
+
+			long alphabetSize_,
+			const long *const *substitutionScoreMatrix_,
+			const double *letterFreqs1_,
+			const double *letterFreqs2_,
+
+			double max_time_,//maximum allowed calculation time in seconds
+			double max_mem_,//maximum allowed memory usage in MB
+			double eps_lambda_,//relative error for lambda calculation
+			double eps_K_,//relative error for K calculation
+			bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
+			double max_time_for_quick_tests_,//maximum allowed calculation time in seconds for quick tests
+			double max_time_with_computation_parameters_);//maximum allowed time in seconds for the whole computation
+
+
+			void input_data_for_the_constructor(
+			std::string randout_,//if defined, then the program outputs complete randomization information into a file
+			std::string smatr_file_name_,//scoring matrix file name
+			std::string RR1_file_name_,//probabilities1 file name
+			std::string RR2_file_name_,//probabilities2 file name
+
+			struct_for_randomization &rand_all_,
+			bool &rand_flag_,
+			long int &rand_,
+
+			long int &alphabetSize_,
+			long int **&substitutionScoreMatrix_,
+			double *&letterFreqs1_,
+			double *&letterFreqs2_);
+
+			void init_main_class_members(
+			long int rand_,//randomization number
+			std::string randout_,//if defined, then the program outputs complete randomization information into a file
+
+			long int open_,//gap opening penalty
+			long int open1_,//gap opening penalty for a gap in the sequence #1
+			long int open2_,//gap opening penalty for a gap in the sequence #2
+
+			long int epen_,//gap extension penalty
+			long int epen1_,//gap extension penalty for a gap in the sequence #1
+			long int epen2_,//gap extension penalty for a gap in the sequence #2
+
+			double max_time_,//maximum allowed calculation time in seconds
+			double max_mem_,//maximum allowed memory usage in MB
+			double eps_lambda_,//relative error for lambda calculation
+			double eps_K_,//relative error for K calculation
+			bool insertions_after_deletions_);//if true, then insertions after deletions are allowed
+
+
+		~alp_data();//destructor
+
+		void release_memory();
+
+		inline double ran2()//generates the next random value
+		{
+			return Njn::Uniform::variate <double> (0,1);
+		}
+
+		static void read_smatr(
+			std::string smatr_file_name_,
+			long int **&smatr_,
+			long int &number_of_AA_smatr_);
+
+		void check_out_file(
+			std::string out_file_name_);
+
+
+
+		static std::string long_to_string(//convert interer ot string
+			long int number_);
+
+		static char digit_to_string(//convert interer ot string
+			long int digit_);
+
+				static bool the_value_is_double(
+				std::string str_,
+				double &val_);
+
+				static bool the_value_is_long(
+				std::string str_,
+				long int &val_);
+
+
+
+
+
+		static void read_RR(
+			std::string RR_file_name_,
+			double *&RR_,
+			double *&RR_sum_,
+			long int *&RR_sum_elements_,
+			long int &number_of_AA_RR_);
+
+		static void read_RR(
+			std::string RR_file_name_,
+			double *&RR_,
+			long int &number_of_AA_RR_);
+
+		static void calculate_RR_sum(
+			double *RR_,
+			long int number_of_AA_RR_,
+			double *&RR_sum_,
+			long int *&RR_sum_elements_);
+
+		static void check_RR_sum(
+			double sum_tmp_,
+			long int number_of_AA_RR_,
+			std::string RR_file_name_);
+
+
+
+
+		template<typename T>
+		static void get_memory_for_matrix(
+		long int dim_,
+		T ** &matr_,
+		alp_data *alp_data_=NULL)
+		{
+			matr_=NULL;
+
+			try
+			{
+
+				long int i;
+				matr_=new T *[dim_];
+				assert_mem(matr_);
+
+				for(i=0;i<dim_;i++)
+				{
+					matr_[i]=NULL;
+				};
+
+				for(i=0;i<dim_;i++)
+				{
+					matr_[i]=new T [dim_];
+					assert_mem(matr_[i]);
+				};
+
+				if(alp_data_)
+				{
+					alp_data_->d_memory_size_in_MB+=(double)sizeof(T)*(double)dim_*(double)dim_/mb_bytes;
+				};
+
+			}
+			catch (...)
+			{ 
+				if(matr_)
+				{
+					long int i;
+					for(i=0;i<dim_;i++)
+					{
+						delete[]matr_[i];matr_[i]=NULL;
+					};
+
+					delete[]matr_;matr_=NULL;
+				};
+				throw;
+			};
+
+
+		}
+
+		template<typename T>
+		static void delete_memory_for_matrix(
+		long int dim_,
+		T ** &matr_,
+		alp_data *alp_data_=NULL)
+		{
+			long int i;
+			if(matr_)
+			{
+				for(i=0;i<dim_;i++)
+				{
+					delete []matr_[i];matr_[i]=NULL;
+				};
+				delete []matr_;matr_=NULL;
+			};
+
+			if(alp_data_)
+			{
+				alp_data_->d_memory_size_in_MB-=(double)sizeof(T)*(double)dim_*(double)dim_/mb_bytes;
+			};
+		}
+
+	static long int random_long(
+	double value_,
+	long int dim_);
+
+	template<typename T>
+	static T random_long(
+	double value_,
+	long int dim_,
+	double *sum_distr_,
+	T* elements_)//sum_distr_[dim_-1] must be equal to 1
+	{
+		if(value_<0||value_>1)	
+		{
+			throw error("Unexpected error in alp_data::random_long\n",4);
+		};
+
+		long int v1=0;
+		long int v2=dim_;
+
+		while(v2-v1>1)
+		{
+			long int v3=(long int)(Sls::alp_data::round(double(v2+v1)/2.0));
+			if(sum_distr_[v3-1]==value_)
+			{
+				v1=v3-1;
+				v2=v3;
+				break;
+			};
+
+			if(sum_distr_[v3-1]>value_)
+			{
+				v2=v3;
+			}
+			else
+			{
+				v1=v3;
+			};
+		};
+
+		if(elements_)
+		{
+			long int v2_1=v2-1;
+
+
+			long int v2_minus=-1;
+
+			long int j;
+			for(j=v2_1;j>=1;j--)
+			{
+				if(sum_distr_[j]!=sum_distr_[j-1])
+				{
+					v2_minus=j;
+					break;
+				};
+			};
+
+			if(v2_minus<0)
+			{
+				if(sum_distr_[0]>0)
+				{
+					v2_minus=0;
+				};
+			};
+
+			if(v2_minus>=0)
+			{
+				return elements_[v2_minus];
+			};
+
+			long int v2_plus=-1;
+			for(j=v2;j<dim_;j++)
+			{
+				if(sum_distr_[j]!=sum_distr_[j-1])
+				{
+					v2_plus=j;
+					break;
+				};
+			};
+
+			if(v2_minus<0)
+			{
+				throw error("Unexpected error in alp_data::random_long\n",1);
+			}
+			else
+			{
+				return elements_[v2_plus];
+			};
+
+		}
+		else
+		{
+			throw error("Unexpected error in alp_data::random_long: the parameter elements_ must be defined\n",4);
+		};
+
+	}
+
+	static double error_of_the_sum(//v1_+v2_
+	double v1_error_,
+	double v2_error_);
+	
+	static double error_of_the_product(//v1_*v2_
+	double v1_,
+	double v1_error_,
+	double v2_,
+	double v2_error_);
+
+	static double error_of_the_sqrt(//sqrt(v1_)
+	double v1_,
+	double v1_error_);
+
+	static double error_of_the_ratio(//v1_/v2_
+	double v1_,
+	double v1_error_,
+	double v2_,
+	double v2_error_);
+
+	static double error_of_the_lg(//lg(v1_)
+	double v1_,
+	double v1_error_);
+
+
+
+	public:
+
+
+	
+	//input parameters
+	long int d_open;//gap opening penalty
+	long int d_open1;//gap opening penalty for a gap in the sequence #1
+	long int d_open2;//gap opening penalty for a gap in the sequence #2
+
+
+	long int d_epen;//gap extension penalty
+	long int d_epen1;//gap extension penalty for a gap in the sequence #1
+	long int d_epen2;//gap extension penalty for a gap in the sequence #2
+
+
+	double d_max_time;//maximum allowed calculation time in seconds
+	double d_max_time_for_quick_tests;//maximum allowed calculation time in seconds for quick tests
+	double d_max_time_with_computation_parameters;//maximum allowed time in seconds for the whole computation
+	double d_max_mem;//maximum allowed memory usage in MB
+	double d_eps_lambda;//relative error for lambda calculation
+	double d_eps_K;//relative error for K calculation
+
+	bool d_insertions_after_deletions;//if true, then insertions after deletions are allowed
+
+	
+	//additional parameters
+
+	bool d_smatr_symmetric_flag;//true if the scoring matrix is symmetric
+
+	long int d_number_of_AA;//number of AA
+	long int d_number_of_AA_smatr;
+
+	long int** d_smatr;//scoring matrix
+
+	double *d_RR1;//AA probabilities
+	double *d_RR1_sum;//probability distribution function for d_RR
+	long int *d_RR1_sum_elements;//numbers of AA corresponded to d_RR
+
+	double *d_RR2;//AA probabilities
+	double *d_RR2_sum;//probability distribution function for d_RR
+	long int *d_RR2_sum_elements;//numbers of AA corresponded to d_RR
+
+	long int d_random_seed;
+	std::string d_randout;//if defined, then the program outputs complete randomization information into a file
+
+
+	double d_memory_size_in_MB;//approximate current allocated memory size
+
+	importance_sampling *d_is;//data for the importance sampling
+
+	double *d_r_i_dot;
+	double *d_r_dot_j;
+
+	long int d_minimum_realizations_number;
+
+	bool d_sentinels_flag;
+
+	
+
+	//for debugging
+	long int d_dim1_tmp;
+	long int d_dim2_tmp;
+
+	long int d_realizations_number2;
+
+	double d_time_before1;
+
+	struct_for_randomization *d_rand_all;
+	bool d_rand_flag;
+	
+
+
+	};
+
+	//array_positive functions
+	template<class T>
+	array_positive<T>::~array_positive()
+	{
+		delete[]d_elem;d_elem=NULL;
+		if(d_alp_data)
+		{
+			d_alp_data->d_memory_size_in_MB-=(double)sizeof(T)*(double)(d_dim+1)/mb_bytes;
+		};
+
+	}
+
+
+	template<class T>
+	void array_positive<T>::increment_array(long int ind_)
+	{
+		T *d_elem_new=NULL;
+
+		try
+		{
+			long int o_dim=d_dim;
+			do{
+			  d_dim+=d_step;
+			}while(ind_>d_dim);
+			long int jump=d_dim-o_dim;
+
+			d_elem_new=new T[d_dim+1];
+			alp_data::assert_mem(d_elem_new);
+
+			long int i;
+			for(i=0;i<o_dim+1;i++)
+			{
+				d_elem_new[i]=d_elem[i];
+			};
+
+			for(i=o_dim+1;i<d_dim+1;i++)
+			{
+				d_elem_new[i]=0;
+			};
+
+
+			delete[]d_elem;d_elem=NULL;
+			if(d_alp_data)
+			{
+				d_alp_data->d_memory_size_in_MB+=(double)sizeof(T)*(double)jump/mb_bytes;
+			};
+
+			d_elem=d_elem_new;d_elem_new=NULL;
+		}
+		catch (...)
+		{ 
+			delete[]d_elem_new;d_elem_new=NULL;
+			throw;
+		};
+		
+	}
+
+	//array functions
+
+	template<class T>
+	array<T>::~array()
+	{
+		delete[]d_elem;d_elem=NULL;
+		if(d_alp_data)
+		{
+			d_alp_data->d_memory_size_in_MB-=(double)sizeof(T)*(double)(d_dim+1)/mb_bytes;
+		};
+
+	}
+
+	template<class T>
+	void array<T>::set_elems(const array<T> *a_)
+	{
+		long int a0=a_->d_ind0;
+		long int a1=a_->d_dim_plus_d_ind0;
+
+		if(a0>a1)return;
+
+		while(a1>d_dim_plus_d_ind0)
+		{
+			d_dim_plus_d_ind0+=d_step;
+		};
+
+		while(a0<d_ind0)
+		{
+			d_ind0-=d_step;
+		};
+
+		d_dim=d_dim_plus_d_ind0-d_ind0;
+		d_elem=new T[d_dim+1];
+		sls_basic::assert_mem(d_elem);
+
+		if(d_alp_data)
+		{
+			d_alp_data->d_memory_size_in_MB+=(double)sizeof(T)*(double)(d_dim+1)/mb_bytes;
+		};
+
+		long int i;
+		for(i=a0;i<=a1;i++)
+		{
+			d_elem[i-d_ind0]=a_->d_elem[i-a0];
+		}
+	}
+
+
+	template<class T>
+	void array<T>::increment_array_on_the_right(long int ind_)
+	{
+		bool ee_error_flag=false;
+		error ee_error("",0);
+		T *d_elem_new=NULL;
+
+		try
+		{
+		try
+		{
+
+
+			long int o_dim=d_dim;
+			do{
+			  d_dim+=d_step;
+			  d_dim_plus_d_ind0+=d_step;
+			}while(ind_>d_dim_plus_d_ind0);
+			long int jump=d_dim-o_dim;
+
+			d_elem_new=new T[d_dim+1];
+			alp_data::assert_mem(d_elem_new);
+
+			long int i;
+			for(i=0;i<o_dim+1;i++)
+			{
+				d_elem_new[i]=d_elem[i];
+			};
+
+			for(i=o_dim+1;i<d_dim+1;i++)
+			{
+				d_elem_new[i]=0;
+			};
+
+			if(d_alp_data)
+			{
+				d_alp_data->d_memory_size_in_MB+=(double)sizeof(T)*(double)jump/mb_bytes;
+			};
+
+
+			delete[]d_elem;d_elem=NULL;
+			d_elem=d_elem_new;d_elem_new=NULL;
+
+
+		}
+		catch (error er)
+		{
+			ee_error_flag=true;
+			ee_error=er;		
+		};
+		}
+		catch (...)
+		{ 
+			ee_error_flag=true;
+			ee_error=error("Internal error in the program\n",4);
+		};
+
+		//memory release
+
+		if(ee_error_flag)
+		{
+			delete[]d_elem_new;d_elem_new=NULL;
+			throw error(ee_error.st,ee_error.error_code);
+		};
+
+	}
+
+	template<class T>
+		void array<T>::increment_array_on_the_left(long int ind_)
+	{
+		T *d_elem_new=NULL;
+
+		try
+		{
+			long int o_dim=d_dim;
+			do{
+			  d_dim+=d_step;
+			  d_ind0-=d_step;
+			}while(ind_<d_ind0);
+			long int jump=d_dim-o_dim;
+
+			d_elem_new=new T[d_dim+1];
+			alp_data::assert_mem(d_elem_new);
+
+			long int i;
+
+			for(i=0;i<jump;i++)
+			{
+				d_elem_new[i]=0;
+			};
+
+			for(i=0;i<o_dim+1;i++)
+			{
+				d_elem_new[i+jump]=d_elem[i];
+			};
+
+			if(d_alp_data)
+			{
+				d_alp_data->d_memory_size_in_MB+=(double)sizeof(T)*(double)jump/mb_bytes;
+			};
+
+			delete[]d_elem;d_elem=NULL;
+			d_elem=d_elem_new;d_elem_new=NULL;
+
+		}
+		catch (...)
+		{
+			delete[]d_elem_new;d_elem_new=NULL;
+			throw;
+		};
+
+
+	}
+
+
+	}
+
+
+#endif
+
diff --git a/src/alp/sls_alp_sim.cpp b/src/alp/sls_alp_sim.cpp
index 8e7ada5..78cd918 100644
--- a/src/alp/sls_alp_sim.cpp
+++ b/src/alp/sls_alp_sim.cpp
@@ -1,4549 +1,4549 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_alp_sim.cpp
-
-Author: Sergey Sheetlin
-
-Contents: Calculation of Gumbel parameters
-
-******************************************************************************/
-
-
-#include "sls_alp_sim.hpp"
-
-using namespace Sls;
-using namespace std;
-
-static bool calculate_C_S_constant_flag=true;
-static double dbl_max_log=log(DBL_MAX);
-
-alp_sim::alp_sim(//constructor
-alp_data *alp_data_)
-{
-
-	
-	d_alp_obj=NULL;
-
-
-	d_lambda_tmp=NULL;
-	d_lambda_tmp_errors=NULL;
-
-	d_C_tmp=NULL;
-	d_C_tmp_errors=NULL;
-
-
-	d_alp_data=alp_data_;
-
-	ofstream frand;
-
-	try
-	{
-
-		if(!d_alp_data)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-		d_alp_obj=new array_positive<alp*> (d_alp_data);
-		alp_data::assert_mem(d_alp_obj);
-		d_n_alp_obj=0;
-
-		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(array_positive<alp*>))/mb_bytes;
-
-
-		double memory_before1=d_alp_data->d_memory_size_in_MB;
-		double time_before1;
-		alp_data::get_current_time(time_before1);
-
-
-		d_alp_data->d_time_before1=time_before1;
-
-		if(!d_alp_data->d_rand_flag)
-		{
-			d_alp_data->d_rand_all->d_random_seed=d_alp_data->d_random_seed;
-		};
-
-
-		//trial simulation for estimation time and memory 
-		long int M_min;
-		long int nalp;
-
-		double time_after_tmp;
-
-		d_lambda_tmp=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(d_lambda_tmp);
-
-		d_lambda_tmp_errors=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(d_lambda_tmp_errors);
-
-		d_C_tmp=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(d_C_tmp);
-
-		d_C_tmp_errors=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(d_C_tmp_errors);
-
-
-		//quick tests
-		
-		quick_test(
-		quick_tests_trials_number,
-		d_alp_data->d_max_time_for_quick_tests);
-
-		long int maximum_number_of_realizations_for_preliminary_simulation=1000;
-
-		bool loop_break_flag;
-		long int rand_i=-1;
-
-		bool lambda_accuracy_flag=true;
-		long int sim_number=1;
-		do{
-
-			long int nalp_lambda;
-			bool C_calculation=false;
-			
-			long int number_tmp;
-
-			bool check_time_flag=true;
-
-			if(d_alp_data->d_rand_flag)
-			{
-				check_time_flag=false;
-				rand_i++;
-				number_tmp=d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP[rand_i];
-			}
-			else
-			{
-				number_tmp=alp_data::Tmin(maximum_number_of_realizations_for_preliminary_simulation-1,d_n_alp_obj+sim_number*d_alp_data->d_minimum_realizations_number-1);
-			};
-
-
-		get_minimal_simulation(
-			0,
-			number_tmp,
-			M_min,
-			nalp,
-			nalp_lambda,
-			C_calculation,
-			check_time_flag);
-
-		if(!d_alp_data->d_rand_flag)
-		{
-			d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP.push_back(number_tmp);
-		};
-
-		
-
-		sim_number*=2;
-
-		if(d_lambda_tmp->d_elem[nalp]>=0)
-		{
-			if(d_lambda_tmp_errors->d_elem[nalp]/d_lambda_tmp->d_elem[nalp]<alp_data_->d_eps_lambda)
-			{
-				lambda_accuracy_flag=false;
-			};
-		};
-
-		alp_data::get_current_time(time_after_tmp);
-
-		
-		if(number_tmp>=maximum_number_of_realizations_for_preliminary_simulation-1)
-		{
-			if(!d_alp_data->d_rand_flag)
-			{
-				break;
-			};
-		};
-		
-		if(d_alp_data->d_rand_flag)
-		{
-			loop_break_flag=(rand_i>=(long int)(d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP.size()-1));
-		}
-		else
-		{
-		loop_break_flag=!(maximum_number_of_realizations_for_preliminary_simulation>d_n_alp_obj-1&&
-			lambda_accuracy_flag&&((time_after_tmp-time_before1)<=0||((time_after_tmp-time_before1)<0.01*d_alp_data->d_max_time&&d_alp_data->d_memory_size_in_MB<d_alp_data->d_max_mem)));
-		};
-
-		}
-		while(!loop_break_flag);
-
-
-		
-
-		double memory_after1=d_alp_data->d_memory_size_in_MB;
-		double time_after1;
-		alp_data::get_current_time(time_after1);
-
-		if(memory_after1<=memory_before1)
-		{
-			delete d_alp_obj;d_alp_obj=NULL;
-			throw error("Unexpected error\n",4);
-		};
-
-		long int limit_by_memory=(long int)alp_data::Tmin((double)LONG_MAX-1,alp_data::round(d_alp_data->d_max_mem/2.0/(memory_after1-memory_before1)*d_n_alp_obj));
-
-		if(d_alp_data->d_memory_size_in_MB>d_alp_data->d_max_mem)
-		{
-			//cout<<"\nWarning: memory limit is reached.\nTo get the requested accuracy please\nincrease maximum allowed amount of memory if possible\n\n";
-		};
-
-
-		long int limit_by_time;
-		if(time_after1<=time_before1)
-		{
-			limit_by_time=LONG_MAX;
-		}
-		else
-		{
-			limit_by_time=(long int)alp_data::Tmin((double)LONG_MAX-1,alp_data::round(d_alp_data->d_max_time/3.0/4.0/(time_after1-time_before1)*d_n_alp_obj));
-		};
-
-
-		long int realizations_number2=alp_data::Tmin((long int)alp_data::round(limit_by_time)-1,limit_by_memory-1);
-		
-		realizations_number2=alp_data::Tmin(maximum_number_of_realizations_for_preliminary_simulation-(long int)1,realizations_number2);
-
-		realizations_number2=alp_data::Tmax(d_n_alp_obj-(long int)1,realizations_number2);
-		
-
-
-		delete d_lambda_tmp;d_lambda_tmp=NULL;
-		delete d_lambda_tmp_errors;d_lambda_tmp_errors=NULL;
-
-		delete d_C_tmp;d_C_tmp=NULL;
-		delete d_C_tmp_errors;d_C_tmp_errors=NULL;
-
-
-		//trial simulation for estimation M_min and nalp
-		d_lambda_tmp=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(d_lambda_tmp);
-
-		d_lambda_tmp_errors=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(d_lambda_tmp_errors);
-
-		d_C_tmp=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(d_C_tmp);
-
-		d_C_tmp_errors=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(d_C_tmp_errors);
-
-
-
-		long int nalp_lambda;
-		bool C_calculation=false;
-
-		
-
-
-		double lambda;
-		double eps_K=d_alp_data->d_eps_K;
-		double K_C;
-		double K_C_error;
-		long int level;
-		long int diff_opt;
-
-
-		rand_i=-1;
-		loop_break_flag=false;
-
-		double time_before_ALP;
-		double time_during_ALP;
-		long int number_of_realizations_with_ALP=alp_data::Tmin(realizations_number2,d_n_alp_obj-(long int)1+d_alp_data->d_minimum_realizations_number);
-		long int number_of_realizations_with_ALP_pred;
-
-		alp_data::get_current_time(time_before_ALP);
-		do{
-
-			bool check_time_flag=true;
-
-			if(d_alp_data->d_rand_flag)
-			{
-				check_time_flag=false;
-				rand_i++;
-				number_of_realizations_with_ALP=d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP[rand_i];
-			};
-
-		get_minimal_simulation(
-			0,
-			number_of_realizations_with_ALP,
-			M_min,
-			nalp,
-			nalp_lambda,
-			C_calculation,
-			check_time_flag);
-
-
-		if(!d_alp_data->d_rand_flag)
-		{
-			d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP.push_back(number_of_realizations_with_ALP);
-		};
-
-
-		lambda=d_lambda_tmp->d_elem[nalp];
-
-		double tmp_lambda=2.0;
-
-		if(d_lambda_tmp->d_elem[nalp]>0)
-		{
-			tmp_lambda=((d_lambda_tmp_errors->d_elem[nalp]/d_lambda_tmp->d_elem[nalp])/d_alp_data->d_eps_lambda);
-		};
-		
-
-			
-			
-
-		number_of_realizations_with_ALP_pred=number_of_realizations_with_ALP;
-
-
-
-		alp_data::get_current_time(time_during_ALP);
-
-		if(d_alp_data->d_rand_flag)
-		{
-			loop_break_flag=(rand_i>=(long int)(d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP.size()-1));
-			if(loop_break_flag)
-			{
-				break;
-			};
-		};
-
-
-		if(time_during_ALP-time_before1>=d_alp_data->d_max_time*0.25||number_of_realizations_with_ALP>=realizations_number2||tmp_lambda<=1.0)
-		{
-			if(!d_alp_data->d_rand_flag)
-			{
-				break;
-			};
-		};
-
-		if(time_during_ALP<=time_before_ALP)
-		{
-			number_of_realizations_with_ALP=alp_data::Tmin(realizations_number2,number_of_realizations_with_ALP+d_alp_data->d_minimum_realizations_number);
-		}
-		else
-		{
-
-			long int max_number_of_realizations=(long int)floor(number_of_realizations_with_ALP*(d_alp_data->d_max_time*0.35-(time_before_ALP-time_before1))/(time_during_ALP-time_before_ALP));
-			number_of_realizations_with_ALP=alp_data::Tmin(realizations_number2,(long int)floor(0.5*number_of_realizations_with_ALP+0.5*max_number_of_realizations));
-			if(number_of_realizations_with_ALP>=max_number_of_realizations)
-			{
-				number_of_realizations_with_ALP=d_alp_data->Tmin(realizations_number2,number_of_realizations_with_ALP+d_alp_data->d_minimum_realizations_number);
-			};
-
-			if((double)(number_of_realizations_with_ALP-number_of_realizations_with_ALP_pred)/(double)number_of_realizations_with_ALP_pred<0.005)
-			{
-				number_of_realizations_with_ALP=number_of_realizations_with_ALP_pred;
-				if(!d_alp_data->d_rand_flag)
-				{
-					break;
-				};
-
-			};
-		};
-
-
-
-		}
-		while(!loop_break_flag);
-
-		realizations_number2=number_of_realizations_with_ALP;
-		long int realizations_number2_lambda=number_of_realizations_with_ALP;
-
-		rand_i=-1;
-		loop_break_flag=false;
-
-		double time_before_kill;
-		double time_during_kill;
-		long int number_of_realizations_with_killing=d_alp_data->Tmin(realizations_number2,d_alp_data->d_minimum_realizations_number-(long int)1);
-		long int number_of_realizations_with_killing_pred;
-
-		alp_data::get_current_time(time_before_kill);
-		do{
-
-			bool check_time_flag=false;
-
-			if(d_alp_data->d_rand_flag)
-			{
-				check_time_flag=false;
-				rand_i++;
-				number_of_realizations_with_killing=d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing[rand_i];
-			};
-
-			
-			kill(
-				check_time_flag,
-				0,
-				number_of_realizations_with_killing,
-				M_min,
-				lambda,
-				eps_K,
-				K_C,
-				K_C_error,
-				level,
-				diff_opt);
-
-			if(!d_alp_data->d_rand_flag)
-			{
-				d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing.push_back(number_of_realizations_with_killing);
-			};
-
-	
-
-			number_of_realizations_with_killing_pred=number_of_realizations_with_killing;
-
-
-		alp_data::get_current_time(time_during_kill);
-
-		double tmp_K=2.0;
-
-		if(K_C>0)
-		{
-			tmp_K=((K_C_error/K_C)/d_alp_data->d_eps_K);
-		};
-
-		if(d_alp_data->d_rand_flag)
-		{
-			loop_break_flag=(rand_i>=(long int)(d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing.size()-1));
-			if(loop_break_flag)
-			{
-				break;
-			};
-		};
-
-
-		if(time_during_kill-time_before1>=d_alp_data->d_max_time||number_of_realizations_with_killing>=realizations_number2||tmp_K<=1.0)
-		{
-			if(!d_alp_data->d_rand_flag)
-			{
-				break;
-			};
-		};
-
-
-
-		if(time_during_kill<=time_before_kill)
-		{
-			number_of_realizations_with_killing=d_alp_data->Tmin(realizations_number2,number_of_realizations_with_killing+d_alp_data->d_minimum_realizations_number);
-		}
-		else
-		{
-
-			long int max_number_of_realizations=(long int)floor(number_of_realizations_with_killing*(d_alp_data->d_max_time-(time_before_kill-time_before1))/(time_during_kill-time_before_kill));
-			number_of_realizations_with_killing=d_alp_data->Tmin(realizations_number2,(long int)floor(0.5*number_of_realizations_with_killing+0.5*max_number_of_realizations));
-			if(number_of_realizations_with_killing>=max_number_of_realizations)
-			{
-				number_of_realizations_with_killing=d_alp_data->Tmin(realizations_number2,number_of_realizations_with_killing+d_alp_data->d_minimum_realizations_number);
-			};
-
-			if((double)(number_of_realizations_with_killing-number_of_realizations_with_killing_pred)/(double)number_of_realizations_with_killing_pred<0.005)
-			{
-				number_of_realizations_with_killing=number_of_realizations_with_killing_pred;
-				if(!d_alp_data->d_rand_flag)
-				{
-					break;
-				};
-			};
-		};
-
-
-		}
-		while(!loop_break_flag);
-
-
-		long int k;
-		for(k=0;k<=number_of_realizations_with_killing;k++)
-		{
-			d_alp_obj->d_elem[k]->partially_release_memory();		
-		};
-
-			
-		realizations_number2=number_of_realizations_with_killing;
-		long int realizations_number2_K=number_of_realizations_with_killing;
-
-
-
-		d_alp_data->d_realizations_number2=realizations_number2_lambda;
-
-
-		if(K_C<=0)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-		double tmp=((K_C_error/K_C)/d_alp_data->d_eps_K);
-		tmp=alp_data::Tmin(ceil((realizations_number2_K+1)*tmp*tmp),(double)LONG_MAX);
-		long int realizations_number_killing=(long int)tmp;
-		tmp=((d_lambda_tmp_errors->d_elem[nalp]/d_lambda_tmp->d_elem[nalp])/d_alp_data->d_eps_lambda);
-		tmp=alp_data::Tmin(ceil((realizations_number2_lambda+1)*tmp*tmp),(double)LONG_MAX);
-		long int realizations_number_lambda=(long int)tmp;
-
-		double time_after2;
-		alp_data::get_current_time(time_after2);
-		time_after2=alp_data::Tmax(time_after2,time_after_tmp);
-
-		delete d_lambda_tmp;d_lambda_tmp=NULL;
-		delete d_lambda_tmp_errors;d_lambda_tmp_errors=NULL;
-
-		delete d_C_tmp;d_C_tmp=NULL;
-		delete d_C_tmp_errors;d_C_tmp_errors=NULL;
-
-		
-
-
-		//main simulation
-
-		long int j;
-		j=1;
-		long int kill_j=0;
-
-
-
-
-		bool kill_flag=(realizations_number_killing>realizations_number2_K+1+j);
-		bool lambda_flag=(realizations_number_lambda>realizations_number2_lambda+1+j);
-		long int nalp_for_simulation=nalp;
-
-		//!!!!!!!!!!!!!!!!!!!!!!!
-		//cout<<"A number of ALPs\t"<<nalp_for_simulation<<endl;
-
-		if(d_alp_data->d_rand_flag)
-		{
-			lambda_flag=(d_alp_data->d_rand_all->d_total_realizations_number_with_ALP>realizations_number2_K+j-1);
-			kill_flag=(d_alp_data->d_rand_all->d_total_realizations_number_with_killing>realizations_number2_K+j-1);
-		};
-
-
-
-
-		if(kill_flag||lambda_flag)
-		{
-
-			
-
-			long int step_for_time=1;
-
-			//long int number_of_unsuccesful_objects=0;
-
-			//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-			//cout<<"M_min="<<M_min<<endl;
-
-			
-			
-			while(d_n_alp_obj<LONG_MAX-realizations_number2_lambda-j)
-			{
-				kill_flag=(realizations_number_killing>realizations_number2_K+j);
-				lambda_flag=(realizations_number_lambda>realizations_number2_lambda+j);
-
-				if(d_alp_data->d_rand_flag)
-				{
-					lambda_flag=(d_alp_data->d_rand_all->d_total_realizations_number_with_ALP>realizations_number2_K+j-1);
-					kill_flag=(d_alp_data->d_rand_all->d_total_realizations_number_with_killing>realizations_number2_K+j-1);
-				};
-
-				if(!(kill_flag||lambda_flag))
-				{
-					if(!d_alp_data->d_rand_flag)
-					{
-						//cout<<"\nThe parameters were calculated with the required accuracy\n\n";
-						break;
-					}
-					else
-					{
-						break;
-					};
-				};
-
-
-
-				
-
-				if(!kill_flag)
-				{
-					nalp_for_simulation=alp_data::Tmin(nalp_lambda,nalp);
-				};
-
-				bool sucess_flag=false;
-				
-
-
-				if(realizations_number2_K+j<=realizations_number2_lambda)
-				{
-			
-				}
-				else
-				{
-					d_alp_obj->set_elem(realizations_number2_K+j,NULL);
-					d_n_alp_obj++;
-				};
-
-				alp *&obj=d_alp_obj->d_elem[realizations_number2_K+j];
-
-
-
-				try
-				{
-					double eps_tmp;
-
-				while(!sucess_flag)
-				{
-
-					
-					bool check_time_flag=true;
-
-					if(d_alp_data->d_rand_flag)
-					{
-						check_time_flag=false;
-					};
-
-						get_single_realization(
-						check_time_flag,
-						M_min,
-						nalp_for_simulation,
-						kill_flag,
-						level,
-						diff_opt,
-						obj,
-						sucess_flag,
-						eps_tmp);
-
-						
-
-						
-						
-
-
-					if(!sucess_flag)
-					{
-						if(realizations_number2_K+j>realizations_number2_lambda)
-						{
-							d_n_alp_obj--;
-						};
-
-						//number_of_unsuccesful_objects++;
-//						if(number_of_unsuccesful_objects>/*5+*/0.5*alp_data::Tmin(d_alp_data->d_rand_all->d_total_realizations_number_with_killing,d_alp_data->d_rand_all->d_total_realizations_number_with_ALP)*eps_tmp)
-//						{
-							//if(realizations_number2_K+j>realizations_number2_lambda)
-							//{
-							//	d_n_alp_obj--;
-							//};
-							//throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-//						};
-					};
-				};
-
-				}
-				catch (error_for_single_realization er)
-				{
-					if(d_alp_data->d_rand_flag)
-					{
-						throw error("Unexpected error in ramdomization\n",4);
-					};
-
-					//cout<<"\nWarning: time limit is reached.\nTo get the requested accuracy please\nincrease the allowed calculation time if possible\n\n";
-					if(realizations_number2_K+j>realizations_number2_lambda)
-					{
-						delete obj;obj=NULL;
-						d_n_alp_obj--;
-					};
-					break;
-				};
-
-				
-
-				
-
-				if(realizations_number2_K+j>realizations_number2_lambda)
-				{
-
-					if(kill_flag)
-					{
-						kill_j=j;
-					};
-
-				};
-
-
-				d_alp_obj->d_elem[realizations_number2_K+j]->partially_release_memory();
-
-				j++;
-
-				
-
-				if(d_alp_data->d_memory_size_in_MB>d_alp_data->d_max_mem)
-				{
-					if(!d_alp_data->d_rand_flag)
-					{
-						//cout<<"\nWarning: memory limit is reached.\nTo get the requested accuracy please\nincrease the allowed amount of memory if possible\n\n";
-						break;
-					};
-				};
-				
-
-				if(j%step_for_time==0)
-				{
-					double time_after3;
-					alp_data::get_current_time(time_after3);
-
-					if((time_after3-time_before1)>d_alp_data->d_max_time)
-					{
-						if(!d_alp_data->d_rand_flag)
-						{
-							//cout<<"\nWarning: time limit is reached.\nTo get the requested accuracy please\nincrease the allowed calculation time if possible\n\n";
-							break;
-						};
-					};
-				};
-			};
-		}
-		else
-		{
-			//cout<<"\nThe parameters were calculated with required accuracy\n\n";
-		};
-		
-
-		long int final_realizations_number_killing=kill_j+realizations_number2_K+1;
-		long int final_realizations_number_lambda=alp_data::Tmax(realizations_number2_lambda+1,j+realizations_number2_K);
-		d_n_alp_obj=final_realizations_number_lambda;
-
-
-		double time_after100;
-		alp_data::get_current_time(time_after100);
-		//cout<<"\nActual calculation time is "<<time_after100-time_before1<<" seconds\n";
-		//cout<<"Actual memory usage is "<<d_alp_data->Tmax(memory_after2,memory_after3)<<" MBs\n\n";
-
-		if(!d_alp_data->d_rand_flag)
-		{
-			d_alp_data->d_rand_all->d_total_realizations_number_with_ALP=final_realizations_number_lambda-1;
-			d_alp_data->d_rand_all->d_total_realizations_number_with_killing=final_realizations_number_killing-1;
-		};
-
-		//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-		//output of a file with complete randomization information
-		if(!d_alp_data->d_rand_flag&&d_alp_data->d_randout!="")
-		{
-			//string rand_st="rand_"+alp_data::long_to_string(d_alp_data->d_rand_all->d_random_factor)+".out";
-			string rand_st=d_alp_data->d_randout;
-			frand.open(rand_st.data(),ios::out);
-			if(!frand)
-			{
-				throw error("Error - file "+rand_st+" cannot be created\n",3);
-			};
-
-			long int i;
-
-
-			frand<<d_alp_data->d_rand_all->d_random_seed<<endl;
-			frand<<d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP.size()<<"\t";
-			for(i=0;i<(long int)d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP.size();i++)
-			{
-				frand<<d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP[i]<<"\t";
-			};
-			frand<<endl;
-
-			frand<<d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP.size()<<"\t";
-			for(i=0;i<(long int)d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP.size();i++)
-			{
-				frand<<d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP[i]<<"\t";
-			};
-			frand<<endl;
-
-			frand<<d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing.size()<<"\t";
-			for(i=0;i<(long int)d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing.size();i++)
-			{
-				frand<<d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing[i]<<"\t";
-			};
-			frand<<endl;
-
-			frand<<d_alp_data->d_rand_all->d_total_realizations_number_with_ALP<<endl;
-			frand<<d_alp_data->d_rand_all->d_total_realizations_number_with_killing<<endl;
-
-
-
-			frand.close();
-
-		};
-
-		//cout<<"A number of realizations\t"<<d_alp_data->d_rand_all->d_total_realizations_number_with_ALP<<endl;
-
-	
-
-		bool inside_simulation_flag;
-
-		this->m_CalcTime=time_after100-time_before1;
-
-		output_main_parameters2m_new(
-		nalp_for_simulation,
-		level,
-		inside_simulation_flag,
-		final_realizations_number_lambda,
-		final_realizations_number_killing);
-
-
-	}
-	catch (...)
-	{ 
-		delete d_lambda_tmp;d_lambda_tmp=NULL;
-		delete d_lambda_tmp_errors;d_lambda_tmp_errors=NULL;
-
-		delete d_C_tmp;d_C_tmp=NULL;
-		delete d_C_tmp_errors;d_C_tmp_errors=NULL;
-
-		this->~alp_sim();
-
-		if(frand.is_open())
-		{
-			frand.close();
-		};
-
-		throw;
-
-	};
-}
-
-void alp_sim::symmetric_parameters_for_symmetric_scheme()
-{
-	//check whether the scoring scheme is symmetric
-	bool symmetric_flag=true;
-	long int i,j;
-	for(i=0;i<d_alp_data->d_number_of_AA;i++)
-	{
-		for(j=0;j<i;j++)
-		{
-			if(d_alp_data->d_smatr[i][j]!=d_alp_data->d_smatr[j][i])
-			{
-				symmetric_flag=false;
-				break;
-			};
-		};
-		if(!symmetric_flag)
-		{
-			break;
-		};
-	};
-
-	if(symmetric_flag)
-	{
-		for(i=0;i<d_alp_data->d_number_of_AA;i++)
-		{
-			if(d_alp_data->d_RR1[i]!=d_alp_data->d_RR2[i])
-			{
-				symmetric_flag=false;
-				break;
-			};
-		};
-	};
-
-	if(symmetric_flag)
-	{
-		if(d_alp_data->d_epen1!=d_alp_data->d_epen2||d_alp_data->d_open1!=d_alp_data->d_open2)
-		{
-			symmetric_flag=false;
-		};
-	};
-
-	if(symmetric_flag)
-	{
-		m_AI=0.5*(m_AI+m_AJ);
-		m_AJ=m_AI;
-		m_AIError=0.5*(m_AIError+m_AJError);
-		m_AJError=m_AIError;
-
-
-		m_AlphaI=0.5*(m_AlphaI+m_AlphaJ);
-		m_AlphaJ=m_AlphaI;
-		m_AlphaIError=0.5*(m_AlphaIError+m_AlphaJError);
-		m_AlphaJError=m_AlphaIError;
-
-	};
-
-}
-
-void alp_sim::randomize_realizations(
-long int final_realizations_number_lambda_,
-long int final_realizations_number_killing_)
-{
-	randomize_realizations_ind(0,final_realizations_number_killing_-1);
-	randomize_realizations_ind(final_realizations_number_killing_,final_realizations_number_lambda_-1);
-}
-
-void alp_sim::randomize_realizations_ind(
-long int ind1_,
-long int ind2_)
-{
-	alp**array_ind=NULL;
-	long int *perm=NULL;
-
-	try
-	{
-
-		if(ind1_>=ind2_)
-		{
-			return;
-		};
-
-		if(ind2_>d_n_alp_obj-1)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-
-		long int total_number=ind2_-ind1_+1;
-
-		array_ind=new alp*[total_number];
-		alp_data::assert_mem(array_ind);
-
-
-
-
-		
-		perm=new long int [total_number];
-		alp_data::assert_mem(perm);
-
-		generate_random_permulation(perm,total_number);
-
-		long int i;
-		for(i=0;i<total_number;i++)
-		{
-			array_ind[i]=d_alp_obj->d_elem[ind1_+perm[i]];
-		};
-
-		for(i=0;i<total_number;i++)
-		{
-			d_alp_obj->d_elem[ind1_+i]=array_ind[i];
-		};
-
-		delete[]array_ind;array_ind=NULL;
-		delete[]perm;perm=NULL;
-	}
-	catch (...)
-	{ 
-		delete[]array_ind;array_ind=NULL;
-		delete[]perm;perm=NULL;
-		throw;
-	};
-
-}
-
-void alp_sim::generate_random_permulation(
-long int *perm_,
-long int dim_)
-{
-	long int i;
-	for(i=0;i<dim_;i++)
-	{
-		perm_[i]=i;
-	};
-
-	for(i=0;i<dim_-1;i++)
-	{
-		long int ind_swap=i+alp_data::random_long(d_alp_data->ran2(),dim_-i);
-		long int tmp=perm_[ind_swap];
-		perm_[ind_swap]=perm_[i];
-		perm_[i]=tmp;
-	};
-}
-
-void alp_sim::output_main_parameters2m_new(
-long int nalp_for_lambda_simulation,
-long int level,
-bool &inside_simulation_flag,
-long int final_realizations_number_lambda_,
-long int final_realizations_number_killing_)
-{
-
-	double lambda;
-	double lambda_error;
-	double test_difference;
-	double test_difference_error;
-	double C;
-	double C_error;
-	double K_C;
-	double K_C_error;
-	double a_I;
-	double a_I_error;
-	double a_J;
-	double a_J_error;
-	double sigma;
-	double sigma_error;
-	double alpha_I;
-	double alpha_I_error;
-	double alpha_J;
-	double alpha_J_error;
-	double K;
-	double K_error;
-
-	bool flag=false;
-	long int number_of_trials=0;
-	long int number_of_trials_threshold=4;
-
-	do{
-
-	calculate_main_parameters2m(
-	final_realizations_number_lambda_,
-	final_realizations_number_killing_,
-	nalp_for_lambda_simulation,
-	level,
-	inside_simulation_flag,
-	lambda,
-	lambda_error,
-	test_difference,
-	test_difference_error,
-	C,
-	C_error,
-	K_C,
-	K_C_error,
-	a_I,
-	a_I_error,
-	a_J,
-	a_J_error,
-	sigma,
-	sigma_error,
-	alpha_I,
-	alpha_I_error,
-	alpha_J,
-	alpha_J_error,
-	K,
-	K_error,
-	flag);
-
-
-	number_of_trials++;
-
-	if(!flag)
-	{
-		randomize_realizations(
-		final_realizations_number_lambda_,
-		final_realizations_number_killing_);
-		//cout<<"Randomization attempt\t"<<number_of_trials<<endl;
-	};
-	}
-	while(!flag&&number_of_trials<=number_of_trials_threshold);
-
-	if(!flag)
-	{
-		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-	};
-}
-
-double alp_sim::round_double(
-double val_,
-long int digits_)
-{
-	long int i;
-	for(i=0;i<digits_;i++)
-	{
-		val_*=10;
-	};
-	val_=alp_data::round(val_);
-	for(i=0;i<digits_;i++)
-	{
-		val_/=10.0;
-	};
-
-	return val_;
-}
-
-double alp_sim::relative_error_in_percents(
-double val_,
-double val_error_)
-{
-	if(val_==0)
-	{
-		return DBL_MAX;
-	};
-
-	return fabs(round_double(val_error_/val_*100.0,1));
-
-}
-
-long int alp_sim::get_number_of_subsimulations(
-long int number_of_realizations_)
-{
-	long int max_number_of_subsimulations=20;
-	long int min_number_of_subsimulations=3;
-
-	long int min_number_of_realizations_for_subsimulation=2;
-
-	if(number_of_realizations_<min_number_of_realizations_for_subsimulation*min_number_of_subsimulations)
-	{
-		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-	};
-
-	long int res_subsimulations=(long int)ceil(sqrt((double)number_of_realizations_));
-	res_subsimulations=alp_data::Tmin(res_subsimulations,max_number_of_subsimulations);
-	res_subsimulations=alp_data::Tmax(res_subsimulations,min_number_of_subsimulations);
-
-	return res_subsimulations;
-}
-
-void alp_sim::memory_release_for_calculate_main_parameters2m(
-long int nalp_for_lambda_simulation,
-long int *&d_mult_realizations,
-long int *&d_mult_K_realizations,
-
-double *&lambda_mult,
-double *&lambda_mult_error,
-
-double *&C_mult,
-double *&C_mult_error,
-
-double *&a_I_mult,
-double *&a_I_mult_error,
-
-double *&a_J_mult,
-double *&a_J_mult_error,
-
-double *&sigma_mult,
-double *&sigma_mult_error,
-
-double *&alpha_I_mult,
-double *&alpha_I_mult_error,
-
-double *&alpha_J_mult,
-double *&alpha_J_mult_error,
-
-double *&K_C_mult,
-double *&K_C_mult_error,
-
-double *&K_mult,
-double *&K_mult_error,
-
-double *&Sc_mult,
-double *&Sc_mult_error,
-
-
-void **&alp_distr,
-void **&alp_distr_errors,
-
-void ***&alp_mult_distr,
-void ***&alp_mult_distr_errors)
-{
-	if(alp_distr)
-	{
-		long int j;
-		for(j=1;j<=nalp_for_lambda_simulation;j++)
-		{
-			delete (array_positive<double>*)alp_distr[j];alp_distr[j]=NULL;
-		};
-
-		delete[]alp_distr;alp_distr=NULL;
-	};
-
-
-
-	if(alp_distr_errors)
-	{
-		long int j;
-		for(j=1;j<=nalp_for_lambda_simulation;j++)
-		{
-			delete (array_positive<double>*)alp_distr_errors[j];alp_distr_errors[j]=NULL;
-		};
-
-		delete[]alp_distr_errors;alp_distr_errors=NULL;
-	};
-
-
-	if(alp_mult_distr)
-	{
-		long int k,j;
-		for(k=1;k<=d_mult_number;k++)
-		{
-			if(alp_mult_distr[k])
-			{
-				for(j=1;j<=nalp_for_lambda_simulation;j++)
-				{
-					delete (array_positive<double>*)alp_mult_distr[k][j];alp_mult_distr[k][j]=NULL;
-				};
-
-				delete[]alp_mult_distr[k];alp_mult_distr[k]=NULL;
-			};
-		};
-
-		delete[]alp_mult_distr;alp_mult_distr=NULL;
-	};
-
-
-	if(alp_mult_distr_errors)
-	{
-		long int k,j;
-		for(k=1;k<=d_mult_number;k++)
-		{
-			if(alp_mult_distr_errors[k])
-			{
-				for(j=1;j<=nalp_for_lambda_simulation;j++)
-				{
-					delete (array_positive<double>*)alp_mult_distr_errors[k][j];alp_mult_distr_errors[k][j]=NULL;
-				};
-
-				delete[]alp_mult_distr_errors[k];alp_mult_distr_errors[k]=NULL;
-			};
-		};
-
-		delete[]alp_mult_distr_errors;alp_mult_distr_errors=NULL;
-	};
-
-
-	delete[]d_mult_realizations;d_mult_realizations=NULL;
-	delete[]d_mult_K_realizations;d_mult_K_realizations=NULL;
-
-	delete[]lambda_mult;lambda_mult=NULL;
-	delete[]lambda_mult_error;lambda_mult_error=NULL;
-
-	delete[]C_mult;C_mult=NULL;
-	delete[]C_mult_error;C_mult_error=NULL;
-
-	delete[]a_I_mult;a_I_mult=NULL;
-	delete[]a_I_mult_error;a_I_mult_error=NULL;
-	delete[]a_J_mult;a_J_mult=NULL;
-	delete[]a_J_mult_error;a_J_mult_error=NULL;
-	delete[]sigma_mult;sigma_mult=NULL;
-	delete[]sigma_mult_error;sigma_mult_error=NULL;
-	delete[]alpha_I_mult;alpha_I_mult=NULL;
-	delete[]alpha_I_mult_error;alpha_I_mult_error=NULL;
-	delete[]alpha_J_mult;alpha_J_mult=NULL;
-	delete[]alpha_J_mult_error;alpha_J_mult_error=NULL;
-
-	delete[]K_C_mult;K_C_mult=NULL;
-	delete[]K_C_mult_error;K_C_mult_error=NULL;
-
-	delete[]K_mult;K_mult=NULL;
-	delete[]K_mult_error;K_mult_error=NULL;
-
-	delete[]Sc_mult;Sc_mult=NULL;
-	delete[]Sc_mult_error;Sc_mult_error=NULL;
-
-}
-
-void alp_sim::calculate_main_parameters2m(
-long int final_realizations_number_lambda_,
-long int final_realizations_number_killing_,
-long int nalp_for_lambda_simulation,
-long int level,
-bool &inside_simulation_flag,
-double &lambda,
-double &lambda_error,
-double &test_difference,
-double &test_difference_error,
-double &C,
-double &C_error,
-double &K_C,
-double &K_C_error,
-double &a_I,
-double &a_I_error,
-double &a_J,
-double &a_J_error,
-double &sigma,
-double &sigma_error,
-double &alpha_I,
-double &alpha_I_error,
-double &alpha_J,
-double &alpha_J_error,
-double &K,
-double &K_error,
-bool &flag_)
-{
-
-	long int *d_mult_realizations=NULL;
-	long int *d_mult_K_realizations=NULL;
-
-	double *lambda_mult=NULL;
-	double *lambda_mult_error=NULL;
-
-	double *C_mult=NULL;
-	double *C_mult_error=NULL;
-
-	double *a_I_mult=NULL;
-	double *a_I_mult_error=NULL;
-
-	double *a_J_mult=NULL;
-	double *a_J_mult_error=NULL;
-
-	double *sigma_mult=NULL;
-	double *sigma_mult_error=NULL;
-
-	double *alpha_I_mult=NULL;
-	double *alpha_I_mult_error=NULL;
-
-	double *alpha_J_mult=NULL;
-	double *alpha_J_mult_error=NULL;
-
-	double *K_C_mult=NULL;
-	double *K_C_mult_error=NULL;
-
-	double *K_mult=NULL;
-	double *K_mult_error=NULL;
-
-	double *Sc_mult=NULL;
-	double *Sc_mult_error=NULL;
-
-
-	void **alp_distr=NULL;
-	void **alp_distr_errors=NULL;
-
-	void ***alp_mult_distr=NULL;
- 	void ***alp_mult_distr_errors=NULL;
-
-	try
-	{
-
-		flag_=false;
-
-
-		if(final_realizations_number_killing_>final_realizations_number_lambda_)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-		long int mult_number_lambda=get_number_of_subsimulations(d_n_alp_obj);
-		long int mult_number_K=get_number_of_subsimulations(final_realizations_number_killing_);
-
-		//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-		//mult_number_lambda=mult_number_K=final_realizations_number_killing_;
-
-
-		d_mult_number=alp_data::Tmin(mult_number_lambda,mult_number_K);
-
-		double mult_number_double_lambda=mult_number_lambda;
-		double mult_number_double_K=mult_number_lambda;
-
-
-
-		long int j;
-
-
-		d_mult_realizations=new long int[d_mult_number+1];
-		alp_data::assert_mem(d_mult_realizations);
-
-
-
-		d_mult_K_realizations=new long int[d_mult_number+1];
-		alp_data::assert_mem(d_mult_K_realizations);
-
-		lambda_mult=new double[d_mult_number+1];
-		alp_data::assert_mem(lambda_mult);
-		lambda_mult_error=new double[d_mult_number+1];
-		alp_data::assert_mem(lambda_mult_error);
-
-		C_mult=new double[d_mult_number+1];
-		alp_data::assert_mem(C_mult);
-		C_mult_error=new double[d_mult_number+1];
-		alp_data::assert_mem(C_mult_error);
-
-		a_I_mult=new double[d_mult_number+1];
-		alp_data::assert_mem(a_I_mult);
-		a_I_mult_error=new double[d_mult_number+1];
-		alp_data::assert_mem(a_I_mult_error);
-
-		a_J_mult=new double[d_mult_number+1];
-		alp_data::assert_mem(a_J_mult);
-		a_J_mult_error=new double[d_mult_number+1];
-		alp_data::assert_mem(a_J_mult_error);
-
-		sigma_mult=new double[d_mult_number+1];
-		alp_data::assert_mem(sigma_mult);
-		sigma_mult_error=new double[d_mult_number+1];
-		alp_data::assert_mem(sigma_mult_error);
-
-		alpha_I_mult=new double[d_mult_number+1];
-		alp_data::assert_mem(alpha_I_mult);
-		alpha_I_mult_error=new double[d_mult_number+1];
-		alp_data::assert_mem(alpha_I_mult_error);
-
-		alpha_J_mult=new double[d_mult_number+1];
-		alp_data::assert_mem(alpha_J_mult);
-		alpha_J_mult_error=new double[d_mult_number+1];
-		alp_data::assert_mem(alpha_J_mult_error);
-
-		K_C_mult=new double[d_mult_number+1];
-		alp_data::assert_mem(K_C_mult);
-		K_C_mult_error=new double[d_mult_number+1];
-		alp_data::assert_mem(K_C_mult_error);
-
-		K_mult=new double[d_mult_number+1];
-		alp_data::assert_mem(K_mult);
-		K_mult_error=new double[d_mult_number+1];
-		alp_data::assert_mem(K_mult_error);
-
-		Sc_mult=new double[d_mult_number+1];
-		alp_data::assert_mem(Sc_mult);
-		Sc_mult_error=new double[d_mult_number+1];
-		alp_data::assert_mem(Sc_mult_error);
-
-
-
-		double lambda_mult2=0;
-		double C_mult2=0;
-		double K_C_mult2=0;
-		double a_I_mult2=0;
-		double a_J_mult2=0;
-		double sigma_mult2=0;
-		double alpha_I_mult2=0;
-		double alpha_J_mult2=0;
-		double K_mult2=0;
-		double Sc_mult2=0;
-
-		double lambda_mult2_error=0;
-		double C_mult2_error=0;
-		double K_C_mult2_error=0;
-		double a_I_mult2_error=0;
-		double a_J_mult2_error=0;
-		double sigma_mult2_error=0;
-		double alpha_I_mult2_error=0;
-		double alpha_J_mult2_error=0;
-		double K_mult2_error=0;
-		double Sc_mult2_error=0;
-
-
-
-
-		
-		for(j=0;j<=nalp_for_lambda_simulation;j++)
-		{
-			get_and_allocate_alp_distribution(
-			0,
-			d_n_alp_obj-1,
-			alp_distr,
-			alp_distr_errors,
-			j);
-		};
-
-
-		alp_mult_distr=new void **[d_mult_number+1];
-		alp_data::assert_mem(alp_mult_distr);
-
-		for(j=0;j<=d_mult_number;j++)
-		{
-			alp_mult_distr[j]=NULL;
-		};
-
-		alp_mult_distr_errors=new void **[d_mult_number+1];
-		alp_data::assert_mem(alp_mult_distr_errors);
-		for(j=0;j<=d_mult_number;j++)
-		{
-			alp_mult_distr_errors[j]=NULL;
-		};
-
-		alp_mult_distr[0]=alp_distr;
-		alp_mult_distr_errors[0]=alp_distr_errors;
-
-		long int real_number=(long int)floor((double)final_realizations_number_lambda_/(double)d_mult_number);
-
-		d_mult_realizations[0]=final_realizations_number_lambda_;
-
-		long int k;
-		for(k=1;k<=d_mult_number;k++)
-		{
-			d_mult_realizations[k]=real_number;
-		};
-
-
-		long int nr_tmp=0;
-		for(k=1;k<=d_mult_number;k++)
-		{
-			nr_tmp+=d_mult_realizations[k];
-			long int j;
-			for(j=0;j<=nalp_for_lambda_simulation;j++)
-			{
-				get_and_allocate_alp_distribution(
-				nr_tmp-d_mult_realizations[k],
-				nr_tmp-1,
-				alp_mult_distr[k],
-				alp_mult_distr_errors[k],
-				j);
-			};
-		};
-
-		nr_tmp=0;
-		for(k=1;k<=d_mult_number;k++)
-		{
-			nr_tmp+=d_mult_realizations[k];
-			long int nalp_tmp;
-
-			double test_difference;
-			double test_difference_error;
-
-
-
-			calculate_lambda(
-			false,
-			nalp_for_lambda_simulation,
-			nalp_tmp,
-			inside_simulation_flag,
-			alp_mult_distr[k],
-			alp_mult_distr_errors[k],
-			lambda_mult[k],
-			lambda_mult_error[k],
-			test_difference,
-			test_difference_error);
-
-
-			if(!inside_simulation_flag)
-			{
-				goto label1;
-			};
-
-
-			lambda_mult2+=lambda_mult[k];
-			lambda_mult2_error+=lambda_mult[k]*lambda_mult[k];
-		};
-
-
-
-		long int nalp_tmp;
-
-		calculate_lambda(
-		false,
-		nalp_for_lambda_simulation,
-		nalp_tmp,
-		inside_simulation_flag,
-		alp_distr,
-		alp_distr_errors,
-		lambda,
-		lambda_error,
-		test_difference,
-		test_difference_error);
-
-		if(!inside_simulation_flag)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-		lambda_mult[0]=lambda;
-		lambda_mult_error[0]=lambda_error;
-
-		
-
-		nr_tmp=0;
-		for(k=1;k<=d_mult_number;k++)
-		{
-			nr_tmp+=d_mult_realizations[k];
-			calculate_C(
-			0,
-			nalp_for_lambda_simulation,
-			alp_mult_distr[k],
-			alp_mult_distr_errors[k],
-			lambda_mult[k],
-			lambda_mult_error[k],
-			C_mult[k],
-			C_mult_error[k],
-			Sc_mult[k],
-			Sc_mult_error[k]);
-
-			C_mult2+=C_mult[k];
-			C_mult2_error+=C_mult[k]*C_mult[k];
-
-			Sc_mult2+=Sc_mult[k];
-			Sc_mult2_error+=Sc_mult[k]*Sc_mult[k];
-
-
-		};
-		
-		double Sc;
-		double Sc_error;
-
-
-		calculate_C(
-		0,
-		nalp_for_lambda_simulation,
-		alp_distr,
-		alp_distr_errors,
-		lambda,
-		lambda_error,
-		C,
-		C_error,
-		Sc,
-		Sc_error);
-
-
-
-		C_mult[0]=C;
-		C_mult_error[0]=C_error;
-
-		Sc_mult[0]=Sc;
-		Sc_mult_error[0]=Sc_error;
-
-
-		nr_tmp=0;
-		for(k=1;k<=d_mult_number;k++)
-		{
-
-			nr_tmp+=d_mult_realizations[k];
-			calculate_FSC(
-			nalp_for_lambda_simulation,
-			nr_tmp-d_mult_realizations[k],
-			nr_tmp-1,
-			alp_mult_distr[k],
-			lambda_mult[k],
-			Sc_mult[k],
-			//Sc_mult_error[k],
-
-			a_I_mult[k],
-			a_I_mult_error[k],
-			a_J_mult[k],
-			a_J_mult_error[k],
-			sigma_mult[k],
-			sigma_mult_error[k],
-			alpha_I_mult[k],
-			alpha_I_mult_error[k],
-			alpha_J_mult[k],
-			alpha_J_mult_error[k]);
-
-			a_I_mult2+=a_I_mult[k];
-			a_I_mult2_error+=a_I_mult[k]*a_I_mult[k];
-
-			a_J_mult2+=a_J_mult[k];
-			a_J_mult2_error+=a_J_mult[k]*a_J_mult[k];
-
-			sigma_mult2+=sigma_mult[k];
-			sigma_mult2_error+=sigma_mult[k]*sigma_mult[k];
-
-			alpha_I_mult2+=alpha_I_mult[k];
-			alpha_I_mult2_error+=alpha_I_mult[k]*alpha_I_mult[k];
-
-			alpha_J_mult2+=alpha_J_mult[k];
-			alpha_J_mult2_error+=alpha_J_mult[k]*alpha_J_mult[k];
-
-
-		};
-
-
-		calculate_FSC(
-		nalp_for_lambda_simulation,
-		0,
-		final_realizations_number_lambda_-1,
-		alp_distr,
-		lambda,
-		Sc,
-		//Sc_error,
-
-		a_I,
-		a_I_error,
-		a_J,
-		a_J_error,
-		sigma,
-		sigma_error,
-		alpha_I,
-		alpha_I_error,
-		alpha_J,
-		alpha_J_error);
-		
-
-		a_I_mult[0]=a_I;
-		a_I_mult_error[0]=a_I_error;
-		a_J_mult[0]=a_J;
-		a_J_mult_error[0]=a_J_error;
-		sigma_mult[0]=sigma;
-		sigma_mult_error[0]=sigma_error;
-		alpha_I_mult[0]=alpha_I;
-		alpha_I_mult_error[0]=alpha_I_error;
-		alpha_J_mult[0]=alpha_J;
-		alpha_J_mult_error[0]=alpha_J_error;
-		
-
-		real_number=(long int)floor((double)final_realizations_number_killing_/(double)d_mult_number);
-
-
-		d_mult_K_realizations[0]=final_realizations_number_killing_;
-
-
-		for(k=1;k<=d_mult_number;k++)
-		{
-			d_mult_K_realizations[k]=real_number;
-		};
-
-		//output2
-		nr_tmp=0;
-		for(k=1;k<=d_mult_number;k++)
-		{
-			nr_tmp+=d_mult_K_realizations[k];
-
-			long int recommended_level;
-			long int diff_opt;
-
-
-
-			check_K_criterion_during_killing(
-			nr_tmp-d_mult_K_realizations[k],
-			nr_tmp-1,
-			lambda_mult[k],
-			d_alp_data->d_eps_K,
-			level,
-			recommended_level,
-			diff_opt,
-			K_C_mult[k],
-			K_C_mult_error[k]);
-
-
-			K_mult[k]=C_mult[k]*K_C_mult[k];
-			K_mult_error[k]=alp_data::error_of_the_product(
-			C_mult[k],
-			C_mult_error[k],
-			K_C_mult[k],
-			K_C_mult_error[k]);
-
-			K_C_mult2+=K_C_mult[k];
-			K_C_mult2_error+=K_C_mult[k]*K_C_mult[k];
-
-			K_mult2+=K_mult[k];
-			K_mult2_error+=K_mult[k]*K_mult[k];
-
-		};
-
-
-		long int recommended_level;
-		long int diff_opt;
-
-
-
-		check_K_criterion_during_killing(
-		0,
-		final_realizations_number_killing_-1,
-		lambda,
-		d_alp_data->d_eps_K,
-		level,
-		recommended_level,
-		diff_opt,
-		K_C,
-		K_C_error);
-
-
-
-		
-
-		K=C*K_C;
-		K_error=alp_data::error_of_the_product(
-		C,
-		C_error,
-		K_C,
-		K_C_error);
-
-		K_C_mult[0]=K_C;
-		K_C_mult_error[0]=K_C_error;
-
-		K_mult[0]=K;
-		K_mult_error[0]=K_error;
-
-
-
-		lambda_mult2/=d_mult_number;
-		C_mult2/=d_mult_number;
-		K_C_mult2/=d_mult_number;
-		a_I_mult2/=d_mult_number;
-		a_J_mult2/=d_mult_number;
-		sigma_mult2/=d_mult_number;
-		alpha_I_mult2/=d_mult_number;
-		alpha_J_mult2/=d_mult_number;
-		K_mult2/=d_mult_number;
-
-		lambda_mult2_error/=d_mult_number;
-		C_mult2_error/=d_mult_number;
-		K_C_mult2_error/=d_mult_number;
-		a_I_mult2_error/=d_mult_number;
-		a_J_mult2_error/=d_mult_number;
-		sigma_mult2_error/=d_mult_number;
-		alpha_I_mult2_error/=d_mult_number;
-		alpha_J_mult2_error/=d_mult_number;
-		K_mult2_error/=d_mult_number;
-
-
-		mult_number_double_lambda=(double)final_realizations_number_lambda_/(double)real_number;
-		mult_number_double_K=(double)final_realizations_number_killing_/(double)real_number;
-
-
-		lambda_mult2_error=alp_reg::sqrt_for_errors(lambda_mult2_error-lambda_mult2*lambda_mult2)/sqrt((double)mult_number_double_lambda);
-		C_mult2_error=alp_reg::sqrt_for_errors(C_mult2_error-C_mult2*C_mult2)/sqrt((double)mult_number_double_lambda);
-		K_C_mult2_error=alp_reg::sqrt_for_errors(K_C_mult2_error-K_C_mult2*K_C_mult2)/sqrt((double)mult_number_double_K);
-		a_I_mult2_error=alp_reg::sqrt_for_errors(a_I_mult2_error-a_I_mult2*a_I_mult2)/sqrt((double)mult_number_double_lambda);
-		a_J_mult2_error=alp_reg::sqrt_for_errors(a_J_mult2_error-a_J_mult2*a_J_mult2)/sqrt((double)mult_number_double_lambda);
-		sigma_mult2_error=alp_reg::sqrt_for_errors(sigma_mult2_error-sigma_mult2*sigma_mult2)/sqrt((double)mult_number_double_lambda);
-		alpha_I_mult2_error=alp_reg::sqrt_for_errors(alpha_I_mult2_error-alpha_I_mult2*alpha_I_mult2)/sqrt((double)mult_number_double_lambda);
-		alpha_J_mult2_error=alp_reg::sqrt_for_errors(alpha_J_mult2_error-alpha_J_mult2*alpha_J_mult2)/sqrt((double)mult_number_double_lambda);
-		K_mult2_error=alp_reg::sqrt_for_errors(K_mult2_error-K_mult2*K_mult2)/sqrt((double)alp_data::Tmin(mult_number_double_lambda,mult_number_double_K));
-
-
-		error_in_calculate_main_parameters2m(
-		lambda,
-		lambda_error,
-		lambda_mult2,
-		lambda_mult2_error);
-
-		error_in_calculate_main_parameters2m(
-		C,
-		C_error,
-		C_mult2,
-		C_mult2_error);
-
-		error_in_calculate_main_parameters2m(
-		K_C,
-		K_C_error,
-		K_C_mult2,
-		K_C_mult2_error);
-
-		error_in_calculate_main_parameters2m(
-		a_I,
-		a_I_error,
-		a_I_mult2,
-		a_I_mult2_error);
-
-		error_in_calculate_main_parameters2m(
-		a_J,
-		a_J_error,
-		a_J_mult2,
-		a_J_mult2_error);
-
-
-		error_in_calculate_main_parameters2m(
-		sigma,
-		sigma_error,
-		sigma_mult2,
-		sigma_mult2_error);
-
-		error_in_calculate_main_parameters2m(
-		alpha_I,
-		alpha_I_error,
-		alpha_I_mult2,
-		alpha_I_mult2_error);
-
-		error_in_calculate_main_parameters2m(
-		alpha_J,
-		alpha_J_error,
-		alpha_J_mult2,
-		alpha_J_mult2_error);
-
-		error_in_calculate_main_parameters2m(
-		K,
-		K_error,
-		K_mult2,
-		K_mult2_error);
-
-		flag_=true;
-
-
-		this->m_AI=a_I;
-		this->m_AIError=a_I_error;
-		this->m_AJ=a_J;
-		this->m_AJError=a_J_error;
-		this->m_Sigma=sigma;
-		this->m_SigmaError=sigma_error;
-		this->m_C=C;
-		this->m_CError=C_error;
-		this->m_K=K;
-		this->m_KError=K_error;
-		this->m_Lambda=lambda;
-		this->m_LambdaError=lambda_error;
-
-		this->m_AlphaI=alpha_I;
-		this->m_AlphaIError=alpha_I_error;
-		this->m_AlphaJ=alpha_J;
-		this->m_AlphaJError=alpha_J_error;
-
-		this->m_AISbs.resize(d_mult_number);
-		this->m_AJSbs.resize(d_mult_number);
-		this->m_SigmaSbs.resize(d_mult_number);
-		this->m_CSbs.resize(d_mult_number);
-		this->m_KSbs.resize(d_mult_number);
-		this->m_LambdaSbs.resize(d_mult_number);
-
-		this->m_AlphaISbs.resize(d_mult_number);
-		this->m_AlphaJSbs.resize(d_mult_number);
-
-
-		for(k=1;k<=d_mult_number;k++)
-		{
-			this->m_AISbs[k-1]=a_I_mult[k];
-			this->m_AJSbs[k-1]=a_J_mult[k];
-			this->m_SigmaSbs[k-1]=sigma_mult[k];
-			this->m_CSbs[k-1]=C_mult[k];
-			this->m_KSbs[k-1]=K_mult[k];
-			this->m_LambdaSbs[k-1]=lambda_mult[k];
-
-			this->m_AlphaISbs[k-1]=alpha_I_mult[k];
-			this->m_AlphaJSbs[k-1]=alpha_J_mult[k];
-		};
-
-
-
-	label1:;
-
-	symmetric_parameters_for_symmetric_scheme();
-
-
-
-	}
-	catch (...)
-	{ 
-		memory_release_for_calculate_main_parameters2m(
-		nalp_for_lambda_simulation,
-		d_mult_realizations,
-		d_mult_K_realizations,
-
-		lambda_mult,
-		lambda_mult_error,
-
-		C_mult,
-		C_mult_error,
-
-		a_I_mult,
-		a_I_mult_error,
-
-		a_J_mult,
-		a_J_mult_error,
-
-		sigma_mult,
-		sigma_mult_error,
-
-		alpha_I_mult,
-		alpha_I_mult_error,
-
-		alpha_J_mult,
-		alpha_J_mult_error,
-
-		K_C_mult,
-		K_C_mult_error,
-
-		K_mult,
-		K_mult_error,
-
-		Sc_mult,
-		Sc_mult_error,
-
-
-		alp_distr,
-		alp_distr_errors,
-
-		alp_mult_distr,
-		alp_mult_distr_errors);
-		throw;
-	};
-
-
-	memory_release_for_calculate_main_parameters2m(
-	nalp_for_lambda_simulation,
-	d_mult_realizations,
-	d_mult_K_realizations,
-
-	lambda_mult,
-	lambda_mult_error,
-
-	C_mult,
-	C_mult_error,
-
-	a_I_mult,
-	a_I_mult_error,
-
-	a_J_mult,
-	a_J_mult_error,
-
-	sigma_mult,
-	sigma_mult_error,
-
-	alpha_I_mult,
-	alpha_I_mult_error,
-
-	alpha_J_mult,
-	alpha_J_mult_error,
-
-	K_C_mult,
-	K_C_mult_error,
-
-	K_mult,
-	K_mult_error,
-
-	Sc_mult,
-	Sc_mult_error,
-
-
-	alp_distr,
-	alp_distr_errors,
-
-	alp_mult_distr,
-	alp_mult_distr_errors);
-}
-
-void alp_sim::error_in_calculate_main_parameters2m(
-double C,
-double &C_error,
-double C_mult2,
-double C_mult2_error)
-{
-	if(C!=0&&C_mult2!=0)
-	{
-		C_error=fabs(C*C_mult2_error/C_mult2);
-	}
-	else
-	{
-		C_error=C_mult2_error;
-	};
-}
-
-alp_sim::~alp_sim()//destructor
-{
-	long int i;
-
-	if(d_alp_obj)
-	{
-		for(i=0;i<d_n_alp_obj;i++)
-		{
-			delete d_alp_obj->d_elem[i];d_alp_obj->d_elem[i]=NULL;
-		};
-
-		if(d_alp_data)
-		{
-			d_alp_data->d_memory_size_in_MB-=sizeof(alp)*d_n_alp_obj/mb_bytes;
-		};
-
-		delete d_alp_obj;d_alp_obj=NULL;
-	};
-	if(d_alp_data)
-	{
-		d_alp_data->d_memory_size_in_MB-=(double)(sizeof(array_positive<alp*>))/mb_bytes;
-	};
-
-
-}
-
-void alp_sim::kill(
-bool check_time_,
-long int ind1_,
-long int ind2_,
-long int M_min_,
-double lambda_,
-double eps_K_,
-double &K_C_,
-double &K_C_error_,
-long int &level_,
-long int &diff_opt_)
-{
-
-	bool flag=false;
-	long int current_level=(long int)floor(M_min_*0.5);
-	long int recommended_level;
-	//long int number_of_unsucesful_objects=0;
-
-	
-	long int i;
-	for(i=ind1_;i<=ind2_;i++)
-	{
-	
-		alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
-		if(i-ind1_+1>alp_obj_tmp->d_alp_data->d_minimum_realizations_number)
-		{
-			alp_obj_tmp->d_check_time_flag=check_time_;
-			alp_obj_tmp->d_time_error_flag=check_time_;
-		};
-	};
-
-	do{
-		long int i;
-		for(i=ind1_;i<=ind2_;i++)
-		{
-			alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
-			bool flag=false;
-			while(!flag)
-			{
-				alp_obj_tmp->d_sentinels_flag=false;
-				alp_obj_tmp->kill_upto_level(M_min_,current_level);
-				if(!alp_obj_tmp->d_success)
-				{
-					//number_of_unsucesful_objects++;
-					//if(number_of_unsucesful_objects>/*5+*/0.5*(ind2_-ind1_+1)*
-					//	d_alp_obj->d_alp_data->d_eps_K 
-					//	)
-					//{
-						//throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-					//};
-					delete alp_obj_tmp;alp_obj_tmp=NULL;
-					alp_obj_tmp=new alp(d_alp_data);
-					alp_data::assert_mem(alp_obj_tmp);
-
-					if(i-ind1_+1>alp_obj_tmp->d_alp_data->d_minimum_realizations_number)
-					{
-						alp_obj_tmp->d_check_time_flag=check_time_;
-						alp_obj_tmp->d_time_error_flag=check_time_;
-					};
-
-					bool flag=false;
-					while(!flag)
-					{
-						alp_obj_tmp->simulate_alp_upto_the_given_level(M_min_);
-						//if(!alp_obj_tmp->d_success)
-						//{
-						//	number_of_unsucesful_objects++;
-						//	if(number_of_unsucesful_objects>/*5+*/0.5*(ind2_-ind1_+1)*
-						//		d_alp_obj->d_alp_data->d_eps_K 
-						//		)
-						//	{
-								//throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-						//	};
-						//};
-						flag=alp_obj_tmp->d_success;
-					};
-
-				};
-				flag=alp_obj_tmp->d_success;
-			};
-		};
-
-
-		flag=check_K_criterion_during_killing(
-		ind1_,
-		ind2_,
-		lambda_,
-		eps_K_,
-		current_level,
-		recommended_level,
-		diff_opt_,
-		K_C_,
-		K_C_error_);
-
-		current_level=recommended_level;
-
-	}
-	while(!flag);
-
-	level_=current_level;
-
-}
-
-void alp_sim::get_single_realization(
-bool check_time_,
-long int M_min_,
-long int nalp_,
-bool killing_flag_,
-long int level_,
-long int diff_opt_,
-alp *&obj_,
-bool &sucess_flag_,
-double &d_eps_)
-{
-	if(!obj_)
-	{
-		obj_=new alp(d_alp_data);
-		alp_data::assert_mem(obj_);
-		d_alp_data->d_memory_size_in_MB+=sizeof(alp)/mb_bytes;
-	};
-	obj_->d_single_realiztion_calculation_flag=true;
-	obj_->d_check_time_flag=check_time_;
-
-	d_eps_=d_alp_data->Tmin(d_alp_data->d_eps_K,d_alp_data->d_eps_lambda);
-
-	
-
-	alp*&obj=obj_;
-
-	obj->d_diff_opt=diff_opt_;
-
-	obj->d_sentinels_flag=d_alp_data->d_sentinels_flag;
-
-	sucess_flag_=true;
-
-	while(obj->d_nalp<nalp_)
-	{
-		obj->simulate_next_alp();
-		if(!obj->d_success)
-		{
-			sucess_flag_=false;
-			delete obj_;obj_=NULL;
-			d_eps_=d_alp_data->d_eps_lambda;
-			d_alp_data->d_memory_size_in_MB-=sizeof(alp)/mb_bytes;
-			return;
-		};
-	};
-
-
-	if(killing_flag_)
-	{
-		obj->kill_upto_level(M_min_,level_);		
-		if(!obj->d_success)
-		{
-			sucess_flag_=false;
-			delete obj_;obj_=NULL;
-			d_eps_=d_alp_data->d_eps_K;
-			d_alp_data->d_memory_size_in_MB-=sizeof(alp)/mb_bytes;
-			return;
-		};
-	};
-
-}
-
-void alp_sim::quick_test(
-long int trials_number_,
-double max_time_)
-{
-	if(trials_number_<=0)
-	{
-		throw error("Unexpected error in alp_sim::quick_test\n",1);
-	};
-
-	bool check_time_flag=false;
-	if(max_time_>0)
-	{
-		check_time_flag=true;
-	};
-
-	long int alp_number=5;
-	double p_thres=1e-10;
-
-	double lambda_ungapped=this->d_alp_data->d_is->d_ungap_lambda;
-	if(lambda_ungapped<=0)
-	{
-		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-	};
-	long int score_diff=(long int)alp_data::round(-log(p_thres)/lambda_ungapped);
-
-	long int i;
-
-	long int max_number_of_unsuccessful_objects2=(long int)floor(/*5+*/0.5*trials_number_*(d_alp_obj->d_alp_data->d_eps_K+d_alp_obj->d_alp_data->d_eps_lambda));
-	long int number_of_unsuccessful_objects2=0;
-
-	double max_time_store=d_alp_data->d_max_time;
-	
-	if(check_time_flag)
-	{
-		d_alp_data->d_max_time=max_time_;
-	};
-
-	for(i=0;i<trials_number_;i++)
-	{
-
-		alp* alp_obj_tmp=NULL;
-		bool success3=false;
-		while(!success3)
-		{
-			alp_obj_tmp=new alp(d_alp_data);
-			alp_data::assert_mem(alp_obj_tmp);
-
-			d_alp_data->d_memory_size_in_MB+=(double)(sizeof(alp))/mb_bytes;
-
-			alp_obj_tmp->d_check_time_flag=check_time_flag;
-			alp_obj_tmp->d_time_error_flag=check_time_flag;
-
-
-			alp_obj_tmp->simulate_alp_upto_the_given_number(alp_number+1);
-
-			success3=alp_obj_tmp->d_success;
-
-			
-
-			if(!success3)
-			{
-				delete alp_obj_tmp;alp_obj_tmp=NULL;
-				d_alp_data->d_memory_size_in_MB-=(double)(sizeof(alp))/mb_bytes;
-				number_of_unsuccessful_objects2++;
-				if(number_of_unsuccessful_objects2>max_number_of_unsuccessful_objects2)
-				{
-					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-				};
-			};
-		};
-
-		long int last_alp=alp_obj_tmp->d_alp->d_elem[alp_number];
-		long int M_upper_level=last_alp+score_diff;
-		
-		alp_obj_tmp->d_sentinels_flag=false;
-		alp_obj_tmp->kill_upto_level(last_alp,last_alp-score_diff,&M_upper_level);
-		if(!alp_obj_tmp->d_success)
-		{
-			number_of_unsuccessful_objects2++;
-			if(number_of_unsuccessful_objects2>max_number_of_unsuccessful_objects2)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-		};
-
-
-		delete alp_obj_tmp;alp_obj_tmp=NULL;
-		d_alp_data->d_memory_size_in_MB-=(double)(sizeof(alp))/mb_bytes;
-
-	};
-
-	if(check_time_flag)
-	{
-		d_alp_data->d_max_time=max_time_store;
-	};
-}
-
-
-void alp_sim::get_minimal_simulation(
-long int ind1_,
-long int ind2_,
-long int &M_min_,
-long int &nalp_,
-long int &nalp_lambda_,
-bool C_calculation_,
-bool check_time_flag_)
-{
-
-	long int &alp_number=nalp_;
-
-	void **alp_distr=NULL;
-	void **alp_distr_errors=NULL;
-
-	try
-	{
-
-		long int add_alp_number=3;
-		long int add_alp_number_count=0;
-		long int max_alp_number=30;
-
-		if(d_n_alp_obj<ind1_||d_n_alp_obj-1>ind2_)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-		
-
-		alp_number=0;
-
-		//long int nalp_lambda_equilibration=-1;
-
-		//create the objects
-		long int i;
-		for(i=d_n_alp_obj;i<=ind2_;i++)
-		{
-			d_alp_obj->set_elem(i,NULL);
-
-
-			alp *&alp_obj_tmp=d_alp_obj->d_elem[i];
-
-			alp_obj_tmp=new alp(d_alp_data);
-			alp_data::assert_mem(alp_obj_tmp);
-
-			d_alp_data->d_memory_size_in_MB+=sizeof(alp)/mb_bytes;
-			
-
-			alp_obj_tmp->d_check_time_flag=check_time_flag_;
-			alp_obj_tmp->d_time_error_flag=check_time_flag_;
-
-		};
-
-		d_n_alp_obj=ind2_+1;
-	
-
-		bool M_min_flag=false;
-		bool nalp_flag=false;
-
-
-		bool criterion_flag=false;
-		long int number_of_fails=0;
-		long int number_of_fails_threshold=5;
-
-		do{
-			if(alp_number>=max_alp_number)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",1);
-			};
-
-			//long int number_of_unsuccessful_objects=0;
-			long int i;
-			for(i=ind1_;i<=ind2_;i++)
-			{
-				alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
-
-				alp_obj_tmp->d_check_time_flag=check_time_flag_;
-				alp_obj_tmp->d_time_error_flag=check_time_flag_;
-
-
-				if(alp_obj_tmp->d_nalp<alp_number+1)
-				{
-
-					alp_obj_tmp->simulate_alp_upto_the_given_number(alp_number+1);
-
-					//cout<<i<<"\t"<<alp_obj_tmp->d_success<<endl;
-
-					if(!alp_obj_tmp->d_success)
-					{
-						//number_of_unsuccessful_objects++;
-						delete alp_obj_tmp;
-						alp_obj_tmp=NULL;
-
-						//if(number_of_unsuccessful_objects>/*5+*/0.5*(ind2_-ind1_+1)*
-						//	d_alp_obj->d_alp_data->d_eps_lambda*(alp_number+1)
-						//	)
-						//{
-							
-							//throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-						//};
-
-
-						bool success2=false;
-						while(!success2)
-						{
-							alp_obj_tmp=new alp(d_alp_data);
-							alp_data::assert_mem(alp_obj_tmp);
-
-
-							long int j;
-							for(j=0;j<=alp_number;j++)
-							{
-								alp_obj_tmp->simulate_alp_upto_the_given_number(j+1);
-							};
-
-							success2=alp_obj_tmp->d_success;
-
-							
-
-							if(!success2)
-							{
-								delete alp_obj_tmp;
-								alp_obj_tmp=NULL;
-								//number_of_unsuccessful_objects++;
-								//if(number_of_unsuccessful_objects>/*5+*/0.5*(ind2_-ind1_+1)*
-								//	d_alp_obj->d_alp_data->d_eps_lambda*(alp_number+1)
-								//	)
-								//{
-									
-									//throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-								//};
-							};
-
-						};
-					};
-
-				};
-
-			};
-
-			alp_number++;
-			
-
-
-			bool inside_simulation_flag=false;
-
-			double lambda;
-
-			criterion_flag=the_criterion(
-				alp_number,
-				nalp_lambda_,
-				0,
-				ind2_,
-				alp_distr,
-				alp_distr_errors,
-				M_min_,
-				M_min_flag,
-				nalp_flag,
-				inside_simulation_flag,
-				C_calculation_,
-				&lambda);
-
-			if(inside_simulation_flag)
-			{
-				if(lambda<=0)
-				{
-					criterion_flag=false;
-					inside_simulation_flag=false;
-				};
-			}
-			else
-			{
-				criterion_flag=false;
-			};
-			
-			//if(nalp_lambda_equilibration==-1&&nalp_flag)
-			//if(nalp_flag)
-			//{
-			//	nalp_lambda_equilibration=alp_number;
-			//};
-
-			if(!inside_simulation_flag)
-			{
-				number_of_fails++;
-
-				long int i;
-				if(alp_distr)
-				{
-					for(i=1;i<=alp_number;i++)
-					{
-						delete (array_positive<double>*)alp_distr[i];alp_distr[i]=NULL;
-					};
-
-					delete[]alp_distr;alp_distr=NULL;
-				};
-
-				if(alp_distr_errors)
-				{
-					for(i=1;i<=alp_number;i++)
-					{
-						delete (array_positive<double>*)alp_distr_errors[i];alp_distr_errors[i]=NULL;
-					};
-
-					delete[]alp_distr_errors;alp_distr_errors=NULL;
-				};
-
-
-				M_min_flag=false;
-				nalp_flag=false;
-
-
-				alp_distr=NULL;
-				alp_distr_errors=NULL;
-
-				alp_number=0;
-
-				criterion_flag=false;
-				
-
-
-				for(i=ind1_;i<=ind2_;i++)
-				{
-					alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
-					delete alp_obj_tmp;alp_obj_tmp=NULL;
-
-				};
-
-				if(number_of_fails>number_of_fails_threshold)
-				{
-					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-				};
-
-				for(i=ind1_;i<=ind2_;i++)
-				{
-					alp *alp_obj_tmp;
-					alp_obj_tmp=new alp(d_alp_data);
-					alp_data::assert_mem(alp_obj_tmp);
-					d_alp_obj->set_elem(i,alp_obj_tmp);
-
-
-					alp_obj_tmp->d_check_time_flag=check_time_flag_;
-					alp_obj_tmp->d_time_error_flag=check_time_flag_;
-
-				};
-
-				continue;
-
-			};
-
-			if(criterion_flag)
-			{
-				add_alp_number_count++;
-				if(add_alp_number_count<add_alp_number)
-				{
-					criterion_flag=false;
-				};
-
-				if(criterion_flag)
-				{
-					criterion_flag=check_K_criterion(
-					alp_number,
-					ind1_,
-					ind2_,
-					lambda,
-					d_alp_data->d_eps_K,
-					M_min_);
-				};
-
-			}
-			else
-			{
-				add_alp_number_count=0;
-			};
-
-		}
-		while(!criterion_flag);
-
-		
-		//nalp_lambda_=alp_data::Tmax(nalp_lambda_equilibration,nalp_lambda_);
-		//nalp_lambda_=alp_data::Tmin(nalp_lambda_,nalp_);
-
-		nalp_lambda_=nalp_;
-
-	}
-	catch (...)
-	{ 
-		memory_release_for_get_minimal_simulation(
-		nalp_,
-		alp_distr,
-		alp_distr_errors);
-
-		throw;
-	};
-
-	memory_release_for_get_minimal_simulation(
-	nalp_,
-	alp_distr,
-	alp_distr_errors);
-
-}
-
-void alp_sim::memory_release_for_get_minimal_simulation(
-long int nalp_,
-void **&alp_distr,
-void **&alp_distr_errors)
-{
-	//memory release
-	if(alp_distr)
-	{
-		long int i;
-		for(i=1;i<=nalp_;i++)
-		{
-			delete (array_positive<double>*)alp_distr[i];alp_distr[i]=NULL;
-		};
-
-		delete[]alp_distr;alp_distr=NULL;
-	};
-
-	if(alp_distr_errors)
-	{
-		long int i;
-		for(i=1;i<=nalp_;i++)
-		{
-			delete (array_positive<double>*)alp_distr_errors[i];alp_distr_errors[i]=NULL;
-		};
-
-		delete[]alp_distr_errors;alp_distr_errors=NULL;
-	};
-
-}
-
-bool alp_sim::the_criterion(//criteria of stopping of the simulating ALP
-//if the function returns true then calculates optimal M_min and ALP number
-//sets the flags M_min_flag_ and nalp_flag_ checking the corresponding condition
-long int upto_nalp_,
-long int &nalp_for_lambda_simulation_,
-long int ind1_,
-long int ind2_,
-void **&alp_distr,
-void **&alp_distr_errors,
-long int &M_min_,
-bool &M_min_flag_,
-bool &nalp_flag_,
-bool &inside_simulation_flag_,
-bool C_calculation_,
-double *lambda_,
-double *lambda_error_)
-{
-
-	nalp_flag_=false;
-	M_min_flag_=false;
-
-	if(ind1_>ind2_)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-
-
-	double lambda=0;
-	double lambda_error=0;
-
-	double test_difference=0;
-	double test_difference_error=0;
-
-	long int nalp=upto_nalp_;
-
-	if(nalp<1)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-
-	get_and_allocate_alp_distribution(
-	ind1_,
-	ind2_,
-	alp_distr,
-	alp_distr_errors,
-	nalp);
-
-
-	calculate_lambda(
-	true,
-	upto_nalp_,
-	nalp_for_lambda_simulation_,
-	inside_simulation_flag_,
-	alp_distr,
-	alp_distr_errors,
-	lambda,
-	lambda_error,
-	test_difference,
-	test_difference_error);
-
-	if(!inside_simulation_flag_)
-	{
-		return false;
-	};
-
-
-	d_lambda_tmp->set_elem(upto_nalp_,lambda);
-	d_lambda_tmp_errors->set_elem(upto_nalp_,lambda_error);
-
-
-	if(C_calculation_)
-	{
-		double C;
-		double C_error;
-
-		double Sc;
-		double Sc_error;
-
-
-
-		calculate_C(
-		0,
-		upto_nalp_,
-		alp_distr,
-		alp_distr_errors,
-		lambda,
-		lambda_error,
-		C,
-		C_error,
-		Sc,
-		Sc_error);
-
-
-		d_C_tmp->set_elem(upto_nalp_,C);
-		d_C_tmp_errors->set_elem(upto_nalp_,C_error);
-
-	};
-
-
-	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-	if(lambda_)
-	{
-		*lambda_=lambda;
-	};
-	if(lambda_error_)
-	{
-		*lambda_error_=lambda_error;
-	};
-
-
-	if(nalp>=1)
-	{
-
-		if(test_difference<=test_difference_error)
-		{
-			nalp_flag_=true;
-			/*
-			M_min_flag_=check_K_criterion(
-			nalp,
-			ind1_,
-			ind2_,
-			lambda,
-			d_alp_data->d_eps_K,
-			M_min_);
-			*/
-			M_min_=0;
-
-			//return M_min_flag_;
-			return true;
-		};
-	};
-
-
-	return false;
-}
-
-double alp_sim::lambda_exp(
-long int &i_,
-double *&exp_array_)
-{
-	if(exp_array_[i_]==-1)
-	{
-		throw error("The program is not able to calculate the parameters; rescaling penalties and scoring matrix might help\n",3);
-	};
-
-	return exp_array_[i_];
-}
-
-void alp_sim::memory_release_for_calculate_FSC(
-double *&exp_array,
-
-double *&delta_E,
-double *&delta_E_error,
-
-double *&delta_E_E,
-double *&delta_E_E_error,
-
-
-double *&delta_I,
-double *&delta_I_error,
-
-double *&delta_J,
-double *&delta_J_error,
-
-double *&delta_I_I,
-double *&delta_I_I_error,
-
-double *&delta_I_J,
-double *&delta_I_J_error,
-
-double *&delta_J_J,
-double *&delta_J_J_error,
-
-double *&cov_J_J,
-double *&cov_J_J_error,
-
-double *&cov_I_J,
-double *&cov_I_J_error,
-
-double *&cov_I_I,
-double *&cov_I_I_error,
-
-double *&cov_E_E,
-double *&cov_E_E_error)
-{
-	//memory release
-	delete[]exp_array;exp_array=NULL;
-
-	delete[]delta_E;delta_E=NULL;
-	delete[]delta_E_error;delta_E_error=NULL;
-	delete[]delta_E_E;delta_E_E=NULL;
-	delete[]delta_E_E_error;delta_E_E_error=NULL;
-
-	delete[]delta_I;delta_I=NULL;
-	delete[]delta_I_error;delta_I_error=NULL;
-	delete[]delta_J;delta_J=NULL;
-	delete[]delta_J_error;delta_J_error=NULL;
-
-	delete[]delta_I_J;delta_I_J=NULL;
-	delete[]delta_I_J_error;delta_I_J_error=NULL;
-	delete[]delta_J_J;delta_J_J=NULL;
-	delete[]delta_J_J_error;delta_J_J_error=NULL;
-	delete[]delta_I_I;delta_I_I=NULL;
-	delete[]delta_I_I_error;delta_I_I_error=NULL;
-
-	delete[]cov_I_J;cov_I_J=NULL;
-	delete[]cov_I_J_error;cov_I_J_error=NULL;
-	delete[]cov_J_J;cov_J_J=NULL;
-	delete[]cov_J_J_error;cov_J_J_error=NULL;
-	delete[]cov_I_I;cov_I_I=NULL;
-	delete[]cov_I_I_error;cov_I_I_error=NULL;
-
-	delete[]cov_E_E;cov_E_E=NULL;
-	delete[]cov_E_E_error;cov_E_E_error=NULL;
-
-}
-
-void alp_sim::calculate_FSC(
-long int nalp_,
-long int ind1_,
-long int ind2_,
-void **alp_distr,
-double lambda_,
-double Sc_,
-//double Sc_error_,
-double &a_I_,
-double &a_I_error_,
-double &a_J_,
-double &a_J_error_,
-double &sigma_,
-double &sigma_error_,
-double &alpha_I_,
-double &alpha_I_error_,
-double &alpha_J_,
-double &alpha_J_error_)
-{
-
-	double *exp_array=NULL;
-
-	double *delta_E=NULL;
-	double *delta_E_error=NULL;
-
-	double *delta_E_E=NULL;
-	double *delta_E_E_error=NULL;
-
-
-	double *delta_I=NULL;
-	double *delta_I_error=NULL;
-
-	double *delta_J=NULL;
-	double *delta_J_error=NULL;
-
-	double *delta_I_I=NULL;
-	double *delta_I_I_error=NULL;
-
-	double *delta_I_J=NULL;
-	double *delta_I_J_error=NULL;
-
-	double *delta_J_J=NULL;
-	double *delta_J_J_error=NULL;
-
-	double *cov_J_J=NULL;
-	double *cov_J_J_error=NULL;
-
-	double *cov_I_J=NULL;
-	double *cov_I_J_error=NULL;
-
-	double *cov_I_I=NULL;
-	double *cov_I_I_error=NULL;
-
-	double *cov_E_E=NULL;
-	double *cov_E_E_error=NULL;
-
-
-	try
-	{
-
-
-		if(nalp_<1)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-		array_positive<double>* tmp=((array_positive<double>*)alp_distr[nalp_]);
-		long int dim=tmp->d_dim;
-
-		exp_array=new double[dim+1];
-		alp_data::assert_mem(exp_array);
-
-
-		long int i;
-		for(i=0;i<=dim;i++)
-		{
-			double tmp=(double)i*lambda_;
-			if(tmp<dbl_max_log)
-			{
-				exp_array[i]=exp(tmp);
-			}
-			else
-			{
-				exp_array[i]=-1;
-			};
-		};
-
-		
-
-
-		delta_E=new double[nalp_];
-		alp_data::assert_mem(delta_E);
-		delta_E_error=new double[nalp_];
-		alp_data::assert_mem(delta_E_error);
-
-		delta_E_E=new double[nalp_];
-		alp_data::assert_mem(delta_E_E);
-		delta_E_E_error=new double[nalp_];
-		alp_data::assert_mem(delta_E_E_error);
-
-		cov_E_E=new double[nalp_];
-		alp_data::assert_mem(cov_E_E);
-		cov_E_E_error=new double[nalp_];
-		alp_data::assert_mem(cov_E_E_error);
-
-
-		delta_I=new double[nalp_];
-		alp_data::assert_mem(delta_I);
-		delta_I_error=new double[nalp_];
-		alp_data::assert_mem(delta_I_error);
-
-		delta_J=new double[nalp_];
-		alp_data::assert_mem(delta_J);
-		delta_J_error=new double[nalp_];
-		alp_data::assert_mem(delta_J_error);
-
-		delta_I_I=new double[nalp_];
-		alp_data::assert_mem(delta_I_I);
-		delta_I_I_error=new double[nalp_];
-		alp_data::assert_mem(delta_I_I_error);
-
-		delta_I_J=new double[nalp_];
-		alp_data::assert_mem(delta_I_J);
-		delta_I_J_error=new double[nalp_];
-		alp_data::assert_mem(delta_I_J_error);
-
-		delta_J_J=new double[nalp_];
-		alp_data::assert_mem(delta_J_J);
-		delta_J_J_error=new double[nalp_];
-		alp_data::assert_mem(delta_J_J_error);
-
-		cov_J_J=new double[nalp_];
-		alp_data::assert_mem(cov_J_J);
-		cov_J_J_error=new double[nalp_];
-		alp_data::assert_mem(cov_J_J_error);
-
-		cov_I_J=new double[nalp_];
-		alp_data::assert_mem(cov_I_J);
-		cov_I_J_error=new double[nalp_];
-		alp_data::assert_mem(cov_I_J_error);
-
-		cov_I_I=new double[nalp_];
-		alp_data::assert_mem(cov_I_I);
-		cov_I_I_error=new double[nalp_];
-		alp_data::assert_mem(cov_I_I_error);
-
-		long int j;
-		for(j=0;j<nalp_;j++)
-		{
-			delta_E[j]=0.0;
-			delta_E_error[j]=0.0;
-
-			delta_E_E[j]=0.0;
-			delta_E_E_error[j]=0.0;
-
-			delta_I[j]=0.0;
-			delta_I_error[j]=0.0;
-			delta_J[j]=0.0;
-			delta_J_error[j]=0.0;
-
-			delta_I_I[j]=0.0;
-
-			delta_I_I_error[j]=0.0;
-			delta_I_J[j]=0.0;
-			delta_I_J_error[j]=0.0;
-			delta_J_J[j]=0.0;
-			delta_J_J_error[j]=0.0;
-		};
-
-		double C_S_constant=1.0;
-
-		if(calculate_C_S_constant_flag)
-		{
-			if(Sc_>0)
-			{
-				C_S_constant=Sc_;
-			};
-		};
-
-		double one_div_C_S_constant=1.0/C_S_constant;
-		
-		
-		for(i=ind1_;i<=ind2_;i++)
-		{
-			alp* alp_obj_tmp=d_alp_obj->d_elem[i];
-
-			long int j;
-			for(j=1;j<=nalp_;j++)
-			{
-				long int j_1=j-1;
-
-				long int &E_j_1=alp_obj_tmp->d_alp->d_elem[j_1];
-				long int &E_j=alp_obj_tmp->d_alp->d_elem[j];
-				double &weight_j=alp_obj_tmp->d_alp_weights->d_elem[j];
-
-				long int &I_j_1=alp_obj_tmp->d_H_I->d_elem[j_1];
-				long int &I_j=alp_obj_tmp->d_H_I->d_elem[j];
-
-				long int &J_j_1=alp_obj_tmp->d_H_J->d_elem[j_1];
-				long int &J_j=alp_obj_tmp->d_H_J->d_elem[j];
-
-				double exp_tmp=lambda_exp(E_j,exp_array)*one_div_C_S_constant;
-
-				double delta_I_tmp=(I_j-I_j_1)*exp_tmp*weight_j;
-				double delta_J_tmp=(J_j-J_j_1)*exp_tmp*weight_j;
-				double delta_E_tmp=(E_j-E_j_1)*exp_tmp*weight_j;
-				double delta_E_E_tmp=(E_j-E_j_1)*(E_j-E_j_1)*exp_tmp*weight_j;
-
-				
-				double delta_I_I_tmp=delta_I_tmp*(I_j-I_j_1);
-				double delta_J_J_tmp=delta_J_tmp*(J_j-J_j_1);
-				double delta_I_J_tmp=delta_I_tmp*(J_j-J_j_1);
-
-	
-
-
-				delta_E[j_1]+=delta_E_tmp;
-				delta_E_error[j_1]+=delta_E_tmp*delta_E_tmp;
-
-				delta_E_E[j_1]+=delta_E_E_tmp;
-				delta_E_E_error[j_1]+=delta_E_E_tmp*delta_E_E_tmp;
-
-				delta_I[j_1]+=delta_I_tmp;
-				delta_I_error[j_1]+=delta_I_tmp*delta_I_tmp;
-				delta_J[j_1]+=delta_J_tmp;
-				delta_J_error[j_1]+=delta_J_tmp*delta_J_tmp;
-
-				delta_I_I[j_1]+=delta_I_I_tmp;
-				delta_I_I_error[j_1]+=delta_I_I_tmp*delta_I_I_tmp;
-
-				delta_I_J[j_1]+=delta_I_J_tmp;
-				delta_I_J_error[j_1]+=delta_I_J_tmp*delta_I_J_tmp;
-
-				delta_J_J[j_1]+=delta_J_J_tmp;
-				delta_J_J_error[j_1]+=delta_J_J_tmp*delta_J_J_tmp;
-				
-			};
-		};
-
-
-		double ind_diff=(double)(ind2_-ind1_+1);
-		for(j=0;j<nalp_;j++)
-		{
-			delta_E[j]/=ind_diff;
-			delta_E_error[j]/=ind_diff;
-			delta_E_error[j]-=delta_E[j]*delta_E[j];
-			delta_E_error[j]/=ind_diff;
-			delta_E_error[j]=alp_reg::sqrt_for_errors(delta_E_error[j]);
-
-			delta_E_E[j]/=ind_diff;
-			delta_E_E_error[j]/=ind_diff;
-			delta_E_E_error[j]-=delta_E_E[j]*delta_E_E[j];
-			delta_E_E_error[j]/=ind_diff;
-
-
-			delta_I[j]/=ind_diff;
-			delta_I_error[j]/=ind_diff;
-			delta_I_error[j]-=delta_I[j]*delta_I[j];
-			delta_I_error[j]/=ind_diff;
-			delta_I_error[j]=alp_reg::sqrt_for_errors(delta_I_error[j]);
-
-			delta_J[j]/=ind_diff;
-			delta_J_error[j]/=ind_diff;
-			delta_J_error[j]-=delta_J[j]*delta_J[j];
-			delta_J_error[j]/=ind_diff;
-			delta_J_error[j]=alp_reg::sqrt_for_errors(delta_J_error[j]);
-
-			delta_I_J[j]/=ind_diff;
-			delta_I_J_error[j]/=ind_diff;
-			delta_I_J_error[j]-=delta_I_J[j]*delta_I_J[j];
-			delta_I_J_error[j]/=ind_diff;
-
-
-			delta_I_I[j]/=ind_diff;
-			delta_I_I_error[j]/=ind_diff;
-			delta_I_I_error[j]-=delta_I_I[j]*delta_I_I[j];
-			delta_I_I_error[j]/=ind_diff;
-
-
-			delta_J_J[j]/=ind_diff;
-			delta_J_J_error[j]/=ind_diff;
-			delta_J_J_error[j]-=delta_J_J[j]*delta_J_J[j];
-			delta_J_J_error[j]/=ind_diff;
-
-
-			cov_I_J[j]=delta_I_J[j]-delta_I[j]*delta_J[j];
-			cov_I_I[j]=delta_I_I[j]-delta_I[j]*delta_I[j];
-			cov_J_J[j]=delta_J_J[j]-delta_J[j]*delta_J[j];
-
-			cov_E_E[j]=delta_E_E[j]-delta_E[j]*delta_E[j];
-
-			cov_I_J_error[j]=alp_data::error_of_the_product(delta_I[j],delta_I_error[j],delta_J[j],delta_J_error[j]);
-			cov_I_J_error[j]=alp_reg::sqrt_for_errors(delta_I_J_error[j]+cov_I_J_error[j]*cov_I_J_error[j]);
-
-			cov_I_I_error[j]=alp_data::error_of_the_product(delta_I[j],delta_I_error[j],delta_I[j],delta_I_error[j]);
-			cov_I_I_error[j]=alp_reg::sqrt_for_errors(delta_I_I_error[j]+cov_I_I_error[j]*cov_I_I_error[j]);
-
-			cov_J_J_error[j]=alp_data::error_of_the_product(delta_J[j],delta_J_error[j],delta_J[j],delta_J_error[j]);
-			cov_J_J_error[j]=alp_reg::sqrt_for_errors(delta_J_J_error[j]+cov_J_J_error[j]*cov_J_J_error[j]);
-
-			cov_E_E_error[j]=alp_data::error_of_the_product(delta_E[j],delta_E_error[j],delta_E[j],delta_E_error[j]);
-			cov_E_E_error[j]=alp_reg::sqrt_for_errors(delta_E_E_error[j]+cov_E_E_error[j]*cov_E_E_error[j]);
-
-		};
-
-
-		//regression
-
-		double beta1=0;
-		double beta1_error=0;
-
-		long int number_of_elements=nalp_;
-
-		bool cut_left_tail=true;
-		bool cut_right_tail=false;
-
-		double y=2;
-
-		long int k1_opt;
-		long int k2_opt;
-
-
-		double delta_I_aver;
-		double delta_I_aver_error;
-
-
-
-		bool res_was_calculated;
-		
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		delta_I,
-		delta_I_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		delta_I_aver,
-		beta1,
-		delta_I_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-
-
-		double delta_J_aver;
-		double delta_J_aver_error;
-
-		
-		
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		delta_J,
-		delta_J_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		delta_J_aver,
-		beta1,
-		delta_J_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-
-		double delta_E_aver;
-		double delta_E_aver_error;
-		
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		delta_E,
-		delta_E_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		delta_E_aver,
-		beta1,
-		delta_E_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-		double cov_I_I_aver;
-		double cov_I_I_aver_error;
-
-		double cov_I_J_aver;
-		double cov_I_J_aver_error;
-
-		double cov_J_J_aver;
-		double cov_J_J_aver_error;
-
-		double cov_E_E_aver;
-		double cov_E_E_aver_error;
-
-
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		cov_I_J,
-		cov_I_J_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		cov_I_J_aver,
-		beta1,
-		cov_I_J_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			//error
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		cov_I_I,
-		cov_I_I_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		cov_I_I_aver,
-		beta1,
-		cov_I_I_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		cov_J_J,
-		cov_J_J_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		cov_J_J_aver,
-		beta1,
-		cov_J_J_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		cov_E_E,
-		cov_E_E_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		cov_E_E_aver,
-		beta1,
-		cov_E_E_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-
-
-		if(delta_E_aver<=0)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-
-
-		a_I_=delta_I_aver/delta_E_aver;
-		a_I_error_=alp_data::error_of_the_ratio(delta_I_aver,delta_I_aver_error,delta_E_aver,delta_E_aver_error);
-		a_J_=delta_J_aver/delta_E_aver;
-		a_J_error_=alp_data::error_of_the_ratio(delta_J_aver,delta_J_aver_error,delta_E_aver,delta_E_aver_error);
-
-
-		sigma_calculation(
-		delta_I_aver,
-		delta_I_aver_error,
-		delta_J_aver,
-		delta_J_aver_error,
-		delta_E_aver,
-		delta_E_aver_error,
-		cov_E_E_aver,
-		cov_E_E_aver_error,
-		cov_I_J_aver,
-		cov_I_J_aver_error,
-		sigma_,
-		sigma_error_);
-
-
-		sigma_calculation(
-		delta_I_aver,
-		delta_I_aver_error,
-		delta_I_aver,
-		delta_I_aver_error,
-		delta_E_aver,
-		delta_E_aver_error,
-		cov_E_E_aver,
-		cov_E_E_aver_error,
-		cov_I_I_aver,
-		cov_I_I_aver_error,
-		alpha_I_,
-		alpha_I_error_);
-
-
-
-		sigma_calculation(
-		delta_J_aver,
-		delta_J_aver_error,
-		delta_J_aver,
-		delta_J_aver_error,
-		delta_E_aver,
-		delta_E_aver_error,
-		cov_E_E_aver,
-		cov_E_E_aver_error,
-		cov_J_J_aver,
-		cov_J_J_aver_error,
-		alpha_J_,
-		alpha_J_error_);
-
-		//if the estimates are negative, replace them by 0.0
-		a_I_=alp_data::Tmax(a_I_,0.0);
-		a_J_=alp_data::Tmax(a_J_,0.0);
-		sigma_=alp_data::Tmax(sigma_,0.0);
-		alpha_I_=alp_data::Tmax(alpha_I_,0.0);
-		alpha_J_=alp_data::Tmax(alpha_J_,0.0);
-
-
-	}
-	catch (...)
-	{ 
-		memory_release_for_calculate_FSC(
-		exp_array,
-
-		delta_E,
-		delta_E_error,
-
-		delta_E_E,
-		delta_E_E_error,
-
-
-		delta_I,
-		delta_I_error,
-
-		delta_J,
-		delta_J_error,
-
-		delta_I_I,
-		delta_I_I_error,
-
-		delta_I_J,
-		delta_I_J_error,
-
-		delta_J_J,
-		delta_J_J_error,
-
-		cov_J_J,
-		cov_J_J_error,
-
-		cov_I_J,
-		cov_I_J_error,
-
-		cov_I_I,
-		cov_I_I_error,
-
-		cov_E_E,
-		cov_E_E_error);
-		throw;
-	};
-
-
-	memory_release_for_calculate_FSC(
-	exp_array,
-
-	delta_E,
-	delta_E_error,
-
-	delta_E_E,
-	delta_E_E_error,
-
-
-	delta_I,
-	delta_I_error,
-
-	delta_J,
-	delta_J_error,
-
-	delta_I_I,
-	delta_I_I_error,
-
-	delta_I_J,
-	delta_I_J_error,
-
-	delta_J_J,
-	delta_J_J_error,
-
-	cov_J_J,
-	cov_J_J_error,
-
-	cov_I_J,
-	cov_I_J_error,
-
-	cov_I_I,
-	cov_I_I_error,
-
-	cov_E_E,
-	cov_E_E_error);
-
-}
-
-void alp_sim::sigma_calculation(
-double delta_I_aver_,
-double delta_I_aver_error_,
-double delta_J_aver_,
-double delta_J_aver_error_,
-double delta_E_aver_,
-double delta_E_aver_error_,
-double cov_E_E_aver_,
-double cov_E_E_aver_error_,
-double cov_I_J_aver_,
-double cov_I_J_aver_error_,
-double &sigma_,
-double &sigma_error_)
-{
-	double nom1_1=delta_I_aver_*delta_J_aver_;
-	double nom2_2=delta_E_aver_*delta_E_aver_;
-
-	double den=nom2_2*delta_E_aver_;
-
-	double nom1=nom1_1*cov_E_E_aver_;
-	double nom2=nom2_2*cov_I_J_aver_;
-
-	sigma_=(nom1+nom2)/den;
-
-	
-	double nom1_sigma_error=alp_data::error_of_the_product(delta_I_aver_,delta_I_aver_error_,delta_J_aver_,delta_J_aver_error_);
-	nom1_sigma_error=alp_data::error_of_the_product(nom1_1,nom1_sigma_error,cov_E_E_aver_,cov_E_E_aver_error_);
-
-	
-	double nom2_sigma_error_2=alp_data::error_of_the_product(delta_E_aver_,delta_E_aver_error_,delta_E_aver_,delta_E_aver_error_);
-	double nom2_sigma_error=alp_data::error_of_the_product(nom2_2,nom2_sigma_error_2,cov_I_J_aver_,cov_I_J_aver_error_);
-
-	
-	double den_sigma_error=alp_data::error_of_the_product(nom2_2,nom2_sigma_error_2,delta_E_aver_,delta_E_aver_error_);
-
-	double nom_sigma_error=alp_data::error_of_the_sum(nom1_sigma_error,nom2_sigma_error);
-
-	sigma_error_=alp_data::error_of_the_ratio(nom1+nom2,nom_sigma_error,den,den_sigma_error);
-
-}
-
-void alp_sim::calculate_C(
-long int starting_point,
-long int nalp_,
-void **alp_distr,
-void **alp_distr_errors,
-double lambda_,
-double lambda_error_,
-double &C_,
-double &C_error_,
-double &Sc_,
-double &Sc_error_)
-{
-
-	double *P=NULL;
-	double *P_errors=NULL;
-	double *values_P_ratio=NULL;
-	double *errors_P_ratio=NULL;
-
-	double *E=NULL;
-	double *E_errors=NULL;
-
-	double *E_T_beta=NULL;
-	double *E_T_beta_errors=NULL;
-
-
-	try
-	{
-
-		long int total_number_of_ALP=nalp_;
-
-		if(total_number_of_ALP<1)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-
-		//1)P(beta=infinity)
-		long int j;
-
-
-		P=new double[total_number_of_ALP+1];
-		alp_data::assert_mem(P);
-		P_errors=new double[total_number_of_ALP+1];
-		alp_data::assert_mem(P_errors);
-
-		P[0]=1.0;
-		P_errors[0]=0.0;
-
-		
-		for(j=1;j<=total_number_of_ALP;j++)
-		{
-			array_positive<double>* tmp=((array_positive<double>*)alp_distr[j]);
-			array_positive<double>* tmp_errors=((array_positive<double>*)alp_distr_errors[j]);
-
-			P[j]=0;
-			P_errors[j]=0;
-			long int i;
-			for(i=0;i<=tmp->d_dim;i++)
-			{
-				P[j]+=tmp->d_elem[i];
-				P_errors[j]+=tmp_errors->d_elem[i];
-			};
-
-			P_errors[j]=alp_reg::sqrt_for_errors(P_errors[j]);
-		};
-
-		
-
-		values_P_ratio=new double[total_number_of_ALP];
-		alp_data::assert_mem(values_P_ratio);
-		errors_P_ratio=new double[total_number_of_ALP];
-		alp_data::assert_mem(errors_P_ratio);
-
-		
-
-		for(j=0;j<total_number_of_ALP;j++)
-		{
-			values_P_ratio[j]=P[j+1]/P[j];
-			errors_P_ratio[j]=alp_data::error_of_the_ratio(P[j+1],P_errors[j+1],P[j],P_errors[j]);
-		};
-
-
-
-		double beta1=0;
-		double beta1_error=0;
-
-		long int number_of_elements=total_number_of_ALP;
-
-		bool cut_left_tail=true;
-		bool cut_right_tail=false;
-
-		double y=2;
-
-		long int k1_opt;
-		long int k2_opt;
-
-
-		double P_beta_inf;
-		double P_beta_inf_error=0;
-
-		bool res_was_calculated;
-		
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements-starting_point,
-		values_P_ratio+starting_point,
-		errors_P_ratio+starting_point,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		P_beta_inf,
-		beta1,
-		P_beta_inf_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-
-		
-
-		if(!res_was_calculated)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-		P_beta_inf=1-P_beta_inf;
-
-		
-		//2)E(exp(lambda*T_beta)) and E(T_beta*exp(lambda*T_beta))
-		E=new double[total_number_of_ALP+1];
-		alp_data::assert_mem(E);
-		E_errors=new double[total_number_of_ALP+1];
-		alp_data::assert_mem(E_errors);
-
-		E_T_beta=new double[total_number_of_ALP+1];
-		alp_data::assert_mem(E_T_beta);
-		E_T_beta_errors=new double[total_number_of_ALP+1];
-		alp_data::assert_mem(E_T_beta);
-
-
-		E[0]=1;
-		E_T_beta[0]=0;
-
-		E_errors[0]=0;
-		E_T_beta_errors[0]=0;
-
-		
-
-
-		for(j=1;j<=total_number_of_ALP;j++)
-		{
-			array_positive<double>* tmp=((array_positive<double>*)alp_distr[j]);
-			array_positive<double>* tmp_errors=((array_positive<double>*)alp_distr_errors[j]);
-
-			E[j]=0;
-			E_T_beta[j]=0;
-
-			E_errors[j]=0;
-			E_T_beta_errors[j]=0;
-
-			long int i;
-			for(i=0;i<=tmp->d_dim;i++)
-			{
-				double tmp_double=exp(lambda_*(double)i);
-				E[j]+=tmp_double*tmp->d_elem[i];
-				E_errors[j]+=tmp_double*tmp_double*tmp_errors->d_elem[i];
-
-				tmp_double=(double)i*exp(lambda_*(double)i);
-				E_T_beta[j]+=tmp_double*tmp->d_elem[i];
-				E_T_beta_errors[j]+=tmp_double*tmp_double*tmp_errors->d_elem[i];
-			};
-
-			E_errors[j]=alp_reg::sqrt_for_errors(E_errors[j]);
-			E_T_beta_errors[j]=alp_reg::sqrt_for_errors(E_T_beta_errors[j]);
-
-		};
-
-
-		double E_aver;
-		double E_aver_error;
-
-		double E_T_beta_diff_aver;
-		double E_T_beta_diff_aver_error;
-
-
-		if(total_number_of_ALP==1)
-		{
-			E_aver=E[1];
-			E_aver_error=E_errors[1];
-
-			E_T_beta_diff_aver=E_T_beta[1]-E_T_beta[0];
-			E_T_beta_diff_aver_error=E_T_beta_errors[1];
-
-		}
-		else
-		{
-			long int number_of_elements=total_number_of_ALP;
-
-			bool cut_left_tail=true;
-			bool cut_right_tail=false;
-
-
-			double beta0;
-			double beta1=0;
-			double beta0_error;
-			double beta1_error=0;
-
-			bool res_was_calculated;
-
-			alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-			0,
-			number_of_elements-starting_point,
-			E+1+starting_point,
-			E_errors+1+starting_point,
-			cut_left_tail,
-			cut_right_tail,
-			y,
-			E_aver,
-			beta1,
-			E_aver_error,
-			beta1_error,
-			k1_opt,
-			k2_opt,
-			res_was_calculated);
-
-
-			if(!res_was_calculated)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-
-
-			number_of_elements=total_number_of_ALP;
-
-
-			alp_reg::robust_regression_sum_with_cut_LSM(
-			0,
-			number_of_elements-starting_point,
-			E_T_beta+1+starting_point,
-			E_T_beta_errors+1+starting_point,
-			cut_left_tail,
-			cut_right_tail,
-			y,
-			beta0,
-			beta1,
-			beta0_error,
-			beta1_error,
-			k1_opt,
-			k2_opt,
-			res_was_calculated);
-
-			
-
-			if(!res_was_calculated)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-
-
-			E_T_beta_diff_aver=beta1;
-			E_T_beta_diff_aver_error=beta1_error;
-
-			
-			
-		};
-
-
-
-		double exp_lambda_error=exp(-lambda_)*lambda_error_;
-		double exp_lambda=(1-exp(-lambda_));
-
-		
-		double den_error=alp_data::error_of_the_product(E_T_beta_diff_aver,E_T_beta_diff_aver_error,exp_lambda,exp_lambda_error);
-		double den=(1-exp(-lambda_))*E_T_beta_diff_aver;
-
-
-		double nom;
-		double nom_error;
-
-		if(calculate_C_S_constant_flag)
-		{
-			Sc_error_=E_aver_error;
-			Sc_=E_aver;
-
-			nom_error=alp_data::error_of_the_product(P_beta_inf,P_beta_inf_error,E_aver,E_aver_error);
-			nom=P_beta_inf*E_aver;
-		}
-		else
-		{
-			double E_aver_sqr_error=alp_data::error_of_the_product(E_aver,E_aver_error,E_aver,E_aver_error);
-			double E_aver_sqr=E_aver*E_aver;
-
-			nom_error=alp_data::error_of_the_product(P_beta_inf,P_beta_inf_error,E_aver_sqr,E_aver_sqr_error);
-			nom=P_beta_inf*E_aver_sqr;
-
-		};
-
-		C_error_=alp_data::error_of_the_ratio(nom,nom_error,den,den_error);
-		C_=nom/den;
-
-
-
-
-	}
-	catch (...)
-	{ 
-		//memory release
-
-		delete[]values_P_ratio;values_P_ratio=NULL;
-		delete[]errors_P_ratio;errors_P_ratio=NULL;
-
-
-		delete[]P;P=NULL;
-		delete[]P_errors;P_errors=NULL;
-
-		delete[]E;E=NULL;
-		delete[]E_T_beta;E_T_beta=NULL;
-		delete[]E_errors;E_errors=NULL;
-		delete[]E_T_beta_errors;E_T_beta_errors=NULL;
-		throw;
-
-	};
-
-	//memory release
-
-	delete[]values_P_ratio;values_P_ratio=NULL;
-	delete[]errors_P_ratio;errors_P_ratio=NULL;
-
-
-	delete[]P;P=NULL;
-	delete[]P_errors;P_errors=NULL;
-
-	delete[]E;E=NULL;
-	delete[]E_T_beta;E_T_beta=NULL;
-	delete[]E_errors;E_errors=NULL;
-	delete[]E_T_beta_errors;E_T_beta_errors=NULL;
-
-
-}
-
-void alp_sim::get_and_allocate_alp_distribution(
-long int ind1_,
-long int ind2_,
-void **&alp_distr,
-void **&alp_distr_errors,
-long int nalp)
-{
-	if(nalp<=0)
-	{
-		if(nalp<0)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-		alp_distr=NULL;
-		alp_distr_errors=NULL;
-
-		return;
-	};
-
-	void **alp_distr_tmp=NULL;
-	void **alp_distr_errors_tmp=NULL;
-
-	long int allocation_dim=nalp;
-	long int allocation_dim_tmp=nalp+1;
-
-	try
-	{
-
-
-		long int i;
-		alp_distr_tmp=new void*[nalp+1];
-		alp_data::assert_mem(alp_distr_tmp);
-
-		alp_distr_errors_tmp=new void*[nalp+1];
-		alp_data::assert_mem(alp_distr_errors_tmp);
-
-		for(i=0;i<=nalp;i++)
-		{
-			alp_distr_tmp[i]=NULL;
-			alp_distr_errors_tmp[i]=NULL;
-		};
-
-
-		for(i=1;i<=nalp-1;i++)
-		{
-			alp_distr_tmp[i]=alp_distr[i];
-			alp_distr_errors_tmp[i]=alp_distr_errors[i];
-		};
-
-		delete[]alp_distr;alp_distr=NULL;
-		delete[]alp_distr_errors;alp_distr_errors=NULL;
-
-		alp_distr=alp_distr_tmp;alp_distr_tmp=NULL;
-		alp_distr_errors=alp_distr_errors_tmp;alp_distr_errors_tmp=NULL;
-
-		allocation_dim=nalp+1;
-
-		
-
-		alp_distr[nalp]=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(alp_distr[nalp]);
-
-		alp_distr_errors[nalp]=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(alp_distr_errors[nalp]);
-
-
-
-		for(i=ind1_;i<=ind2_;i++)
-		{
-			alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
-			long int k=nalp;
-			long int &alp_tmp=alp_obj_tmp->d_alp->d_elem[k];
-			double &weight_tmp=alp_obj_tmp->d_alp_weights->d_elem[k];
-
-
-			((array_positive<double>*)alp_distr[k])->increase_elem_by_x(alp_tmp,weight_tmp);
-			((array_positive<double>*)alp_distr_errors[k])->increase_elem_by_x(alp_tmp,weight_tmp*weight_tmp);
-		};
-
-		double ind_diff=(double)(ind2_-ind1_+1);
-		long int k=nalp;
-		array_positive<double>* tmp=((array_positive<double>*)alp_distr[k]);
-		array_positive<double>* tmp_errors=((array_positive<double>*)alp_distr_errors[k]);
-		long int j;
-		for(j=0;j<=tmp->d_dim;j++)
-		{
-			tmp->d_elem[j]/=ind_diff;
-			tmp_errors->d_elem[j]/=ind_diff;
-			tmp_errors->d_elem[j]-=tmp->d_elem[j]*tmp->d_elem[j];
-			tmp_errors->d_elem[j]/=ind_diff;
-		};
-	}
-
-	catch (...)
-	{ 
-		long int i;
-		if(alp_distr_tmp)
-		{
-			for(i=0;i<=allocation_dim_tmp;i++)
-			{
-				delete (array_positive<double>*)alp_distr_tmp[i];alp_distr_tmp[i]=NULL;
-			};
-			delete []alp_distr_tmp;alp_distr_tmp=NULL;
-		};
-
-		if(alp_distr_errors_tmp)
-		{
-			for(i=0;i<=allocation_dim_tmp;i++)
-			{
-				delete (array_positive<double>*)alp_distr_errors_tmp[i];alp_distr_errors_tmp[i]=NULL;
-			};
-			delete []alp_distr_errors_tmp;alp_distr_errors_tmp=NULL;
-		};
-
-		if(alp_distr)
-		{
-			for(i=0;i<=allocation_dim;i++)
-			{
-				delete (array_positive<double>*)alp_distr[i];alp_distr[i]=NULL;
-			};
-			delete []alp_distr;alp_distr=NULL;
-		};
-
-		if(alp_distr_errors)
-		{
-			for(i=0;i<=allocation_dim;i++)
-			{
-				delete (array_positive<double>*)alp_distr_errors[i];alp_distr_errors[i]=NULL;
-			};
-			delete []alp_distr_errors;alp_distr_errors=NULL;
-		};
-
-		throw;
-	};
-
-
-
-}
-
-bool alp_sim::check_K_criterion(
-long int nalp_,
-long int ind1_,
-long int ind2_,
-double lambda_,
-double eps_K_,
-long int &M_min_)
-{
-	if(nalp_<=0)
-	{
-		throw error("Unexpected error\n",4);
-	};
-	array_positive<double>* diff=NULL;
-
-	try
-	{
-
-		diff=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(diff);
-
-		double sum_of_weights=0;
-		double M_aver=0;
-
-		long int i;
-		for(i=ind1_;i<=ind2_;i++)
-		{
-			alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
-			long int &alp_tmp=alp_obj_tmp->d_alp->d_elem[nalp_];
-			double &weight_tmp=alp_obj_tmp->d_alp_weights->d_elem[nalp_];
-			sum_of_weights+=weight_tmp;
-			M_aver+=alp_tmp*weight_tmp;
-
-			array<long int> *cells_counts=alp_obj_tmp->d_cells_counts;
-
-			long int k;
-			for(k=cells_counts->d_ind0;k<=alp_data::Tmin(alp_tmp,cells_counts->d_dim_plus_d_ind0);k++)
-			{
-				diff->increase_elem_by_x(alp_tmp-k,cells_counts->d_elem[k-cells_counts->d_ind0]*weight_tmp);
-			};
-		};
-
-
-
-		double den=0;
-		for(i=0;i<=diff->d_dim;i++)
-		{
-			den+=exp(-lambda_*(double)i)*diff->d_elem[i];
-		};
-
-
-		if(den<=0||sum_of_weights<=0)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-
-		M_aver/=sum_of_weights;
-
-
-		double delta_val=den*eps_K_*(1-exp(-lambda_));
-
-		long int diff_opt=1;;
-		for(i=diff->d_dim;i>=0;i--)
-		{
-			if(exp(-lambda_*(double)i)*diff->d_elem[i]>delta_val)
-			{
-				diff_opt=i+1;
-				break;
-			};
-		};
-
-		
-
-
-		M_min_=(long int)alp_data::round(M_aver);
-
-
-		delete diff;diff=NULL;
-		if(M_aver<diff_opt)
-		{
-			return false;
-		};
-		
-		return true;
-	}
-	catch (...)
-	{ 
-		delete diff;diff=NULL;
-		throw;
-	};
-
-}
-
-bool alp_sim::check_K_criterion_during_killing(
-long int ind1_,
-long int ind2_,
-double lambda_,
-double eps_K_,
-long int current_level_,
-long int &recommended_level_,
-long int &diff_opt_,
-double &K_C_,
-double &K_C_error_)
-{
-	if(ind1_>ind2_)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-	array_positive<double>* diff=NULL;
-	array_positive<double>* diff_error=NULL;
-
-	try
-	{
-
-		diff=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(diff);
-
-		diff_error=new array_positive<double>(d_alp_data);
-		alp_data::assert_mem(diff_error);
-
-
-		double sum_of_weights=0;
-		double sum_of_weights_error=0;
-
-		double M_aver=0;
-
-		long int i;
-		for(i=ind1_;i<=ind2_;i++)
-		{
-			alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
-			long int &alp_tmp=alp_obj_tmp->d_M;
-			double &weight_tmp=alp_obj_tmp->d_alp_weights->d_elem[alp_obj_tmp->d_nalp_killing];
-			sum_of_weights+=weight_tmp;
-			sum_of_weights_error+=weight_tmp*weight_tmp;
-			M_aver+=alp_tmp*weight_tmp;
-
-
-			array<long int> *cells_counts=alp_obj_tmp->d_cells_counts;
-
-			long int k;
-			for(k=cells_counts->d_ind0;k<=alp_data::Tmin(alp_tmp,cells_counts->d_dim_plus_d_ind0);k++)
-			{
-				double tmp=cells_counts->d_elem[k-cells_counts->d_ind0]*weight_tmp;
-				diff->increase_elem_by_x(alp_tmp-k,tmp);
-				diff_error->increase_elem_by_x(alp_tmp-k,tmp*tmp);
-			};
-		};
-
-
-
-		double tmp2=(double)(ind2_-ind1_+1);
-
-		sum_of_weights/=tmp2;
-		sum_of_weights_error/=tmp2;
-		sum_of_weights_error-=sum_of_weights*sum_of_weights;
-		sum_of_weights_error/=tmp2;
-		sum_of_weights_error=alp_reg::sqrt_for_errors(sum_of_weights_error);
-
-
-		
-		for(i=0;i<=diff->d_dim;i++)
-		{
-			diff->d_elem[i]/=tmp2;
-			diff_error->d_elem[i]/=tmp2;
-			diff_error->d_elem[i]-=diff->d_elem[i]*diff->d_elem[i];
-			diff_error->d_elem[i]/=tmp2;
-		};
-
-
-
-		double den=0;
-		double den_error=0;
-		for(i=0;i<=diff->d_dim;i++)
-		{
-			double tmp=exp(-lambda_*(double)i);
-			den+=tmp*diff->d_elem[i];
-			den_error+=tmp*tmp*diff_error->d_elem[i];
-
-		};
-
-
-
-		den_error=alp_reg::sqrt_for_errors(den_error);
-
-
-		if(den<=0||sum_of_weights<=0)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-		K_C_=sum_of_weights/den;
-		K_C_error_=alp_data::error_of_the_ratio(sum_of_weights,sum_of_weights_error,den,den_error);
-
-
-		M_aver/=tmp2;
-		M_aver/=sum_of_weights;
-
-
-		double delta_val=den*eps_K_*(1-exp(-lambda_));
-
-		long int diff_opt=1;;
-		for(i=diff->d_dim;i>=0;i--)
-		{
-			if(exp(-lambda_*(double)i)*diff->d_elem[i]>delta_val)
-			{
-				diff_opt=i+1;
-				break;
-			};
-		};
-
-		delete diff;diff=NULL;
-		delete diff_error;diff_error=NULL;
-
-		if(M_aver-diff_opt<current_level_)
-		{
-			recommended_level_=(long int)floor(M_aver-diff_opt*1.1);
-			diff_opt_=(long int)ceil(M_aver-recommended_level_);
-			return false;
-		};
-		recommended_level_=current_level_;
-		diff_opt_=(long int)ceil(M_aver-recommended_level_);
-		return true;
-	}
-	catch (...)
-	{ 
-		delete diff;diff=NULL;
-		delete diff_error;diff_error=NULL;
-		throw;
-	};
-
-}
-
-void alp_sim::calculate_lambda(
-bool check_the_criteria_,
-long int nalp_,
-long int &nalp_thr_,
-bool &inside_simulation_flag_,
-void **alp_distr,
-void **alp_distr_errors,
-double &lambda_,
-double &lambda_error_,
-double &test_difference_,
-double &test_difference_error_)
-{
-	long int nalp=nalp_;
-
-	if(nalp<=0)
-	{
-		throw error("Unexpected error\n",4);
-	};
-
-	
-
-	struct_for_lambda_calculation tmp_struct;
-	tmp_struct.d_alp_distr=alp_distr;
-	tmp_struct.d_alp_distr_errors=alp_distr_errors;
-	tmp_struct.d_nalp=nalp;
-	tmp_struct.d_calculate_alp_number=false;
-
-
-	function_type *func=function_for_lambda_calculation;
-	void* func_pointer=&tmp_struct;
-	double a=0;
-	//double b=d_alp_data->d_is->d_lambda*3;
-	double b=d_alp_data->d_is->d_lambda*2;
-	long int n_partition=30;
-	double eps=1e-10;
-	std::vector<double> res;
-
-
-
-	alp_reg::find_tetta_general(
-	func,
-	func_pointer,
-	a,//[a,b] is the interval for search of equation solution
-	b,
-	n_partition,
-	eps,
-	res);
-
-	
-
-
-	inside_simulation_flag_=true;
-	if(res.size()==0)
-	{
-		inside_simulation_flag_=false;
-		return;
-	};
-
-	
-
-	lambda_=get_root(res,d_alp_data->d_is->d_lambda);
-	
-
-	tmp_struct.d_calculate_alp_number=true;
-	double f1=func(lambda_,func_pointer);//cout<<ind1_<<"\t"<<ind2_<<"\t"<<tmp_struct.d_last_sum<<"\t"<<tmp_struct.d_last_sum_error<<endl;
-	nalp_thr_=tmp_struct.d_alp_number;
-	tmp_struct.d_calculate_alp_number=false;
-
-	double slope_error=tmp_struct.d_f_error;
-
-
-	double sum1=tmp_struct.d_last_sum;
-	double sum1_error=tmp_struct.d_last_sum_error;
-
-	double delta_lambda=lambda_/100.0;
-	double f2=func(lambda_+delta_lambda,func_pointer);
-	
-	
-
-	if(delta_lambda==0||f1==f2)
-	{
-		lambda_error_=0.0;
-	}
-	else
-	{
-		double derivative=(f2-f1)/delta_lambda;
-		lambda_error_=fabs(slope_error/derivative);
-	};
-	
-	if(!check_the_criteria_)
-	{
-		return;
-	};
-
-	if(nalp>1)
-	{
-		func(d_lambda_tmp->d_elem[nalp-1],func_pointer);
-	}
-	else
-	{
-		func(d_alp_data->d_is->d_ungap_lambda,func_pointer);
-	};
-
-	
-	
-	double sum2=tmp_struct.d_last_sum;
-	double sum2_error=tmp_struct.d_last_sum_error;
-
-	
-
-	double max_sum=alp_data::Tmax(fabs(sum1),fabs(sum2));
-
-	if(max_sum!=0)
-	{
-		test_difference_=fabs((sum1-sum2)/max_sum);
-		test_difference_error_=0.5*(sum1_error+sum2_error)/max_sum;
-	}
-	else
-	{
-		test_difference_=-1;
-		test_difference_error_=0;
-	};
-
-}
-
-double alp_sim::get_root(
-const std::vector<double> &res_tmp_,
-double point_)
-{
-	if(res_tmp_.size()==0)
-	{
-		//throw error("Error in alp_sim::get_root - the equation does not have roots\n",2);
-		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-	};
-
-	long int i;
-	long int p=0;
-	double d1=fabs(point_-res_tmp_[0]);
-	for(i=1;i<(long int)res_tmp_.size();i++)
-	{
-		double d2=fabs(point_-res_tmp_[i]);
-		if(d2<d1)
-		{
-			p=i;
-			d1=d2;
-		};
-	};
-
-	return res_tmp_[p];
-}
-
-double alp_sim::function_for_lambda_calculation(
-double lambda_,
-void * data_)
-{
-
-	double *expect=NULL;
-	double *expect_errors=NULL;
-
-	try
-	{
-
-		struct_for_lambda_calculation *tmp_struct=(struct_for_lambda_calculation *)data_;
-		void **alp_distr=tmp_struct->d_alp_distr;
-		void **alp_distr_errors=tmp_struct->d_alp_distr_errors;
-		long int nalp=tmp_struct->d_nalp;
-
-		expect=new double[nalp];
-		alp_data::assert_mem(expect);
-		expect_errors=new double[nalp];
-		alp_data::assert_mem(expect_errors);
-
-		if(nalp<1)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-
-
-		long int k;
-		for(k=1;k<=nalp;k++)
-		{
-			array_positive<double>* tmp=((array_positive<double>*)alp_distr[k]);
-			array_positive<double>* tmp_errors=((array_positive<double>*)alp_distr_errors[k]);
-
-			double val=0;
-			double val_error=0;
-
-			long int j;
-			for(j=0;j<=tmp->d_dim;j++)
-			{
-				if(tmp->d_elem[j]<=0)
-				{
-					continue;
-				};
-				double exp_tmp=exp(lambda_*j);
-				val+=exp_tmp*tmp->d_elem[j];
-				val_error+=exp_tmp*exp_tmp*tmp_errors->d_elem[j];
-			};
-			val_error=alp_reg::sqrt_for_errors(val_error);
-			expect[k-1]=val;
-			expect_errors[k-1]=val_error;
-
-
-		};
-
-		tmp_struct->d_last_sum=expect[nalp-1];
-		tmp_struct->d_last_sum_error=expect_errors[nalp-1];
-
-		if(tmp_struct->d_calculate_alp_number)
-		{
-			double tmp=0.0;
-			long int k;
-			for(k=0;k<nalp;k++)
-			{
-				if(expect_errors[k]!=0)
-				{
-					tmp+=1.0/(expect_errors[k]*expect_errors[k]);
-				};
-
-			};
-
-			long int tmp_alp=nalp;
-			double tmp1=0.0;
-			for(k=nalp-1;k>=0;k--)
-			{
-				if(expect_errors[k]!=0)
-				{
-					tmp1+=1.0/(expect_errors[k]*expect_errors[k]);
-				};
-				if(tmp1>0.2*tmp)
-				{
-					tmp_alp=k+1;
-					break;
-				};
-			};
-
-			tmp_struct->d_alp_number=tmp_alp;
-		};
-
-		if(nalp==1)
-		{
-			double tmp=expect[0]-1.0;
-			tmp_struct->d_f_error=expect_errors[0];
-			delete[]expect;expect=NULL;
-			delete[]expect_errors;expect_errors=NULL;
-			return tmp;
-		};
-
-
-		long int min_length=0;
-		long int number_of_elements=nalp;
-		bool cut_left_tail=true;
-		bool cut_right_tail=false;
-		double y=2;
-		double beta0;
-		double beta1;
-		double beta0_error;
-		double beta1_error;
-		long int k1_opt;
-		long int k2_opt;
-
-		bool res_was_calculated;
-
-		alp_reg::robust_regression_sum_with_cut_LSM(
-		min_length,
-		number_of_elements,
-		expect,
-		expect_errors,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		beta0,
-		beta1,
-		beta0_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-
-		delete[]expect;expect=NULL;
-		delete[]expect_errors;expect_errors=NULL;
-
-		tmp_struct->d_f_error=beta1_error;
-		return beta1;
-
-	}
-	catch (...)
-	{ 
-		delete[]expect;expect=NULL;
-		delete[]expect_errors;expect_errors=NULL;
-		throw;
-	};
-
-}
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_alp_sim.cpp
+
+Author: Sergey Sheetlin
+
+Contents: Calculation of Gumbel parameters
+
+******************************************************************************/
+
+
+#include "sls_alp_sim.hpp"
+
+using namespace Sls;
+using namespace std;
+
+static bool calculate_C_S_constant_flag=true;
+static double dbl_max_log=log(DBL_MAX);
+
+alp_sim::alp_sim(//constructor
+alp_data *alp_data_)
+{
+
+	
+	d_alp_obj=NULL;
+
+
+	d_lambda_tmp=NULL;
+	d_lambda_tmp_errors=NULL;
+
+	d_C_tmp=NULL;
+	d_C_tmp_errors=NULL;
+
+
+	d_alp_data=alp_data_;
+
+	ofstream frand;
+
+	try
+	{
+
+		if(!d_alp_data)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+		d_alp_obj=new array_positive<alp*> (d_alp_data);
+		alp_data::assert_mem(d_alp_obj);
+		d_n_alp_obj=0;
+
+		d_alp_data->d_memory_size_in_MB+=(double)(sizeof(array_positive<alp*>))/mb_bytes;
+
+
+		double memory_before1=d_alp_data->d_memory_size_in_MB;
+		double time_before1;
+		alp_data::get_current_time(time_before1);
+
+
+		d_alp_data->d_time_before1=time_before1;
+
+		if(!d_alp_data->d_rand_flag)
+		{
+			d_alp_data->d_rand_all->d_random_seed=d_alp_data->d_random_seed;
+		};
+
+
+		//trial simulation for estimation time and memory 
+		long int M_min;
+		long int nalp;
+
+		double time_after_tmp;
+
+		d_lambda_tmp=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(d_lambda_tmp);
+
+		d_lambda_tmp_errors=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(d_lambda_tmp_errors);
+
+		d_C_tmp=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(d_C_tmp);
+
+		d_C_tmp_errors=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(d_C_tmp_errors);
+
+
+		//quick tests
+		
+		quick_test(
+		quick_tests_trials_number,
+		d_alp_data->d_max_time_for_quick_tests);
+
+		long int maximum_number_of_realizations_for_preliminary_simulation=1000;
+
+		bool loop_break_flag;
+		long int rand_i=-1;
+
+		bool lambda_accuracy_flag=true;
+		long int sim_number=1;
+		do{
+
+			long int nalp_lambda;
+			bool C_calculation=false;
+			
+			long int number_tmp;
+
+			bool check_time_flag=true;
+
+			if(d_alp_data->d_rand_flag)
+			{
+				check_time_flag=false;
+				rand_i++;
+				number_tmp=d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP[rand_i];
+			}
+			else
+			{
+				number_tmp=alp_data::Tmin(maximum_number_of_realizations_for_preliminary_simulation-1,d_n_alp_obj+sim_number*d_alp_data->d_minimum_realizations_number-1);
+			};
+
+
+		get_minimal_simulation(
+			0,
+			number_tmp,
+			M_min,
+			nalp,
+			nalp_lambda,
+			C_calculation,
+			check_time_flag);
+
+		if(!d_alp_data->d_rand_flag)
+		{
+			d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP.push_back(number_tmp);
+		};
+
+		
+
+		sim_number*=2;
+
+		if(d_lambda_tmp->d_elem[nalp]>=0)
+		{
+			if(d_lambda_tmp_errors->d_elem[nalp]/d_lambda_tmp->d_elem[nalp]<alp_data_->d_eps_lambda)
+			{
+				lambda_accuracy_flag=false;
+			};
+		};
+
+		alp_data::get_current_time(time_after_tmp);
+
+		
+		if(number_tmp>=maximum_number_of_realizations_for_preliminary_simulation-1)
+		{
+			if(!d_alp_data->d_rand_flag)
+			{
+				break;
+			};
+		};
+		
+		if(d_alp_data->d_rand_flag)
+		{
+			loop_break_flag=(rand_i>=(long int)(d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP.size()-1));
+		}
+		else
+		{
+		loop_break_flag=!(maximum_number_of_realizations_for_preliminary_simulation>d_n_alp_obj-1&&
+			lambda_accuracy_flag&&((time_after_tmp-time_before1)<=0||((time_after_tmp-time_before1)<0.01*d_alp_data->d_max_time&&d_alp_data->d_memory_size_in_MB<d_alp_data->d_max_mem)));
+		};
+
+		}
+		while(!loop_break_flag);
+
+
+		
+
+		double memory_after1=d_alp_data->d_memory_size_in_MB;
+		double time_after1;
+		alp_data::get_current_time(time_after1);
+
+		if(memory_after1<=memory_before1)
+		{
+			delete d_alp_obj;d_alp_obj=NULL;
+			throw error("Unexpected error\n",4);
+		};
+
+		long int limit_by_memory=(long int)alp_data::Tmin((double)LONG_MAX-1,alp_data::round(d_alp_data->d_max_mem/2.0/(memory_after1-memory_before1)*d_n_alp_obj));
+
+		if(d_alp_data->d_memory_size_in_MB>d_alp_data->d_max_mem)
+		{
+			//cout<<"\nWarning: memory limit is reached.\nTo get the requested accuracy please\nincrease maximum allowed amount of memory if possible\n\n";
+		};
+
+
+		long int limit_by_time;
+		if(time_after1<=time_before1)
+		{
+			limit_by_time=LONG_MAX;
+		}
+		else
+		{
+			limit_by_time=(long int)alp_data::Tmin((double)LONG_MAX-1,alp_data::round(d_alp_data->d_max_time/3.0/4.0/(time_after1-time_before1)*d_n_alp_obj));
+		};
+
+
+		long int realizations_number2=alp_data::Tmin((long int)alp_data::round(limit_by_time)-1,limit_by_memory-1);
+		
+		realizations_number2=alp_data::Tmin(maximum_number_of_realizations_for_preliminary_simulation-(long int)1,realizations_number2);
+
+		realizations_number2=alp_data::Tmax(d_n_alp_obj-(long int)1,realizations_number2);
+		
+
+
+		delete d_lambda_tmp;d_lambda_tmp=NULL;
+		delete d_lambda_tmp_errors;d_lambda_tmp_errors=NULL;
+
+		delete d_C_tmp;d_C_tmp=NULL;
+		delete d_C_tmp_errors;d_C_tmp_errors=NULL;
+
+
+		//trial simulation for estimation M_min and nalp
+		d_lambda_tmp=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(d_lambda_tmp);
+
+		d_lambda_tmp_errors=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(d_lambda_tmp_errors);
+
+		d_C_tmp=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(d_C_tmp);
+
+		d_C_tmp_errors=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(d_C_tmp_errors);
+
+
+
+		long int nalp_lambda;
+		bool C_calculation=false;
+
+		
+
+
+		double lambda;
+		double eps_K=d_alp_data->d_eps_K;
+		double K_C;
+		double K_C_error;
+		long int level;
+		long int diff_opt;
+
+
+		rand_i=-1;
+		loop_break_flag=false;
+
+		double time_before_ALP;
+		double time_during_ALP;
+		long int number_of_realizations_with_ALP=alp_data::Tmin(realizations_number2,d_n_alp_obj-(long int)1+d_alp_data->d_minimum_realizations_number);
+		long int number_of_realizations_with_ALP_pred;
+
+		alp_data::get_current_time(time_before_ALP);
+		do{
+
+			bool check_time_flag=true;
+
+			if(d_alp_data->d_rand_flag)
+			{
+				check_time_flag=false;
+				rand_i++;
+				number_of_realizations_with_ALP=d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP[rand_i];
+			};
+
+		get_minimal_simulation(
+			0,
+			number_of_realizations_with_ALP,
+			M_min,
+			nalp,
+			nalp_lambda,
+			C_calculation,
+			check_time_flag);
+
+
+		if(!d_alp_data->d_rand_flag)
+		{
+			d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP.push_back(number_of_realizations_with_ALP);
+		};
+
+
+		lambda=d_lambda_tmp->d_elem[nalp];
+
+		double tmp_lambda=2.0;
+
+		if(d_lambda_tmp->d_elem[nalp]>0)
+		{
+			tmp_lambda=((d_lambda_tmp_errors->d_elem[nalp]/d_lambda_tmp->d_elem[nalp])/d_alp_data->d_eps_lambda);
+		};
+		
+
+			
+			
+
+		number_of_realizations_with_ALP_pred=number_of_realizations_with_ALP;
+
+
+
+		alp_data::get_current_time(time_during_ALP);
+
+		if(d_alp_data->d_rand_flag)
+		{
+			loop_break_flag=(rand_i>=(long int)(d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP.size()-1));
+			if(loop_break_flag)
+			{
+				break;
+			};
+		};
+
+
+		if(time_during_ALP-time_before1>=d_alp_data->d_max_time*0.25||number_of_realizations_with_ALP>=realizations_number2||tmp_lambda<=1.0)
+		{
+			if(!d_alp_data->d_rand_flag)
+			{
+				break;
+			};
+		};
+
+		if(time_during_ALP<=time_before_ALP)
+		{
+			number_of_realizations_with_ALP=alp_data::Tmin(realizations_number2,number_of_realizations_with_ALP+d_alp_data->d_minimum_realizations_number);
+		}
+		else
+		{
+
+			long int max_number_of_realizations=(long int)floor(number_of_realizations_with_ALP*(d_alp_data->d_max_time*0.35-(time_before_ALP-time_before1))/(time_during_ALP-time_before_ALP));
+			number_of_realizations_with_ALP=alp_data::Tmin(realizations_number2,(long int)floor(0.5*number_of_realizations_with_ALP+0.5*max_number_of_realizations));
+			if(number_of_realizations_with_ALP>=max_number_of_realizations)
+			{
+				number_of_realizations_with_ALP=d_alp_data->Tmin(realizations_number2,number_of_realizations_with_ALP+d_alp_data->d_minimum_realizations_number);
+			};
+
+			if((double)(number_of_realizations_with_ALP-number_of_realizations_with_ALP_pred)/(double)number_of_realizations_with_ALP_pred<0.005)
+			{
+				number_of_realizations_with_ALP=number_of_realizations_with_ALP_pred;
+				if(!d_alp_data->d_rand_flag)
+				{
+					break;
+				};
+
+			};
+		};
+
+
+
+		}
+		while(!loop_break_flag);
+
+		realizations_number2=number_of_realizations_with_ALP;
+		long int realizations_number2_lambda=number_of_realizations_with_ALP;
+
+		rand_i=-1;
+		loop_break_flag=false;
+
+		double time_before_kill;
+		double time_during_kill;
+		long int number_of_realizations_with_killing=d_alp_data->Tmin(realizations_number2,d_alp_data->d_minimum_realizations_number-(long int)1);
+		long int number_of_realizations_with_killing_pred;
+
+		alp_data::get_current_time(time_before_kill);
+		do{
+
+			bool check_time_flag=false;
+
+			if(d_alp_data->d_rand_flag)
+			{
+				check_time_flag=false;
+				rand_i++;
+				number_of_realizations_with_killing=d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing[rand_i];
+			};
+
+			
+			kill(
+				check_time_flag,
+				0,
+				number_of_realizations_with_killing,
+				M_min,
+				lambda,
+				eps_K,
+				K_C,
+				K_C_error,
+				level,
+				diff_opt);
+
+			if(!d_alp_data->d_rand_flag)
+			{
+				d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing.push_back(number_of_realizations_with_killing);
+			};
+
+	
+
+			number_of_realizations_with_killing_pred=number_of_realizations_with_killing;
+
+
+		alp_data::get_current_time(time_during_kill);
+
+		double tmp_K=2.0;
+
+		if(K_C>0)
+		{
+			tmp_K=((K_C_error/K_C)/d_alp_data->d_eps_K);
+		};
+
+		if(d_alp_data->d_rand_flag)
+		{
+			loop_break_flag=(rand_i>=(long int)(d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing.size()-1));
+			if(loop_break_flag)
+			{
+				break;
+			};
+		};
+
+
+		if(time_during_kill-time_before1>=d_alp_data->d_max_time||number_of_realizations_with_killing>=realizations_number2||tmp_K<=1.0)
+		{
+			if(!d_alp_data->d_rand_flag)
+			{
+				break;
+			};
+		};
+
+
+
+		if(time_during_kill<=time_before_kill)
+		{
+			number_of_realizations_with_killing=d_alp_data->Tmin(realizations_number2,number_of_realizations_with_killing+d_alp_data->d_minimum_realizations_number);
+		}
+		else
+		{
+
+			long int max_number_of_realizations=(long int)floor(number_of_realizations_with_killing*(d_alp_data->d_max_time-(time_before_kill-time_before1))/(time_during_kill-time_before_kill));
+			number_of_realizations_with_killing=d_alp_data->Tmin(realizations_number2,(long int)floor(0.5*number_of_realizations_with_killing+0.5*max_number_of_realizations));
+			if(number_of_realizations_with_killing>=max_number_of_realizations)
+			{
+				number_of_realizations_with_killing=d_alp_data->Tmin(realizations_number2,number_of_realizations_with_killing+d_alp_data->d_minimum_realizations_number);
+			};
+
+			if((double)(number_of_realizations_with_killing-number_of_realizations_with_killing_pred)/(double)number_of_realizations_with_killing_pred<0.005)
+			{
+				number_of_realizations_with_killing=number_of_realizations_with_killing_pred;
+				if(!d_alp_data->d_rand_flag)
+				{
+					break;
+				};
+			};
+		};
+
+
+		}
+		while(!loop_break_flag);
+
+
+		long int k;
+		for(k=0;k<=number_of_realizations_with_killing;k++)
+		{
+			d_alp_obj->d_elem[k]->partially_release_memory();		
+		};
+
+			
+		realizations_number2=number_of_realizations_with_killing;
+		long int realizations_number2_K=number_of_realizations_with_killing;
+
+
+
+		d_alp_data->d_realizations_number2=realizations_number2_lambda;
+
+
+		if(K_C<=0)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+		double tmp=((K_C_error/K_C)/d_alp_data->d_eps_K);
+		tmp=alp_data::Tmin(ceil((realizations_number2_K+1)*tmp*tmp),(double)LONG_MAX);
+		long int realizations_number_killing=(long int)tmp;
+		tmp=((d_lambda_tmp_errors->d_elem[nalp]/d_lambda_tmp->d_elem[nalp])/d_alp_data->d_eps_lambda);
+		tmp=alp_data::Tmin(ceil((realizations_number2_lambda+1)*tmp*tmp),(double)LONG_MAX);
+		long int realizations_number_lambda=(long int)tmp;
+
+		double time_after2;
+		alp_data::get_current_time(time_after2);
+		time_after2=alp_data::Tmax(time_after2,time_after_tmp);
+
+		delete d_lambda_tmp;d_lambda_tmp=NULL;
+		delete d_lambda_tmp_errors;d_lambda_tmp_errors=NULL;
+
+		delete d_C_tmp;d_C_tmp=NULL;
+		delete d_C_tmp_errors;d_C_tmp_errors=NULL;
+
+		
+
+
+		//main simulation
+
+		long int j;
+		j=1;
+		long int kill_j=0;
+
+
+
+
+		bool kill_flag=(realizations_number_killing>realizations_number2_K+1+j);
+		bool lambda_flag=(realizations_number_lambda>realizations_number2_lambda+1+j);
+		long int nalp_for_simulation=nalp;
+
+		//!!!!!!!!!!!!!!!!!!!!!!!
+		//cout<<"A number of ALPs\t"<<nalp_for_simulation<<endl;
+
+		if(d_alp_data->d_rand_flag)
+		{
+			lambda_flag=(d_alp_data->d_rand_all->d_total_realizations_number_with_ALP>realizations_number2_K+j-1);
+			kill_flag=(d_alp_data->d_rand_all->d_total_realizations_number_with_killing>realizations_number2_K+j-1);
+		};
+
+
+
+
+		if(kill_flag||lambda_flag)
+		{
+
+			
+
+			long int step_for_time=1;
+
+			//long int number_of_unsuccesful_objects=0;
+
+			//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+			//cout<<"M_min="<<M_min<<endl;
+
+			
+			
+			while(d_n_alp_obj<LONG_MAX-realizations_number2_lambda-j)
+			{
+				kill_flag=(realizations_number_killing>realizations_number2_K+j);
+				lambda_flag=(realizations_number_lambda>realizations_number2_lambda+j);
+
+				if(d_alp_data->d_rand_flag)
+				{
+					lambda_flag=(d_alp_data->d_rand_all->d_total_realizations_number_with_ALP>realizations_number2_K+j-1);
+					kill_flag=(d_alp_data->d_rand_all->d_total_realizations_number_with_killing>realizations_number2_K+j-1);
+				};
+
+				if(!(kill_flag||lambda_flag))
+				{
+					if(!d_alp_data->d_rand_flag)
+					{
+						//cout<<"\nThe parameters were calculated with the required accuracy\n\n";
+						break;
+					}
+					else
+					{
+						break;
+					};
+				};
+
+
+
+				
+
+				if(!kill_flag)
+				{
+					nalp_for_simulation=alp_data::Tmin(nalp_lambda,nalp);
+				};
+
+				bool sucess_flag=false;
+				
+
+
+				if(realizations_number2_K+j<=realizations_number2_lambda)
+				{
+			
+				}
+				else
+				{
+					d_alp_obj->set_elem(realizations_number2_K+j,NULL);
+					d_n_alp_obj++;
+				};
+
+				alp *&obj=d_alp_obj->d_elem[realizations_number2_K+j];
+
+
+
+				try
+				{
+					double eps_tmp;
+
+				while(!sucess_flag)
+				{
+
+					
+					bool check_time_flag=true;
+
+					if(d_alp_data->d_rand_flag)
+					{
+						check_time_flag=false;
+					};
+
+						get_single_realization(
+						check_time_flag,
+						M_min,
+						nalp_for_simulation,
+						kill_flag,
+						level,
+						diff_opt,
+						obj,
+						sucess_flag,
+						eps_tmp);
+
+						
+
+						
+						
+
+
+					if(!sucess_flag)
+					{
+						if(realizations_number2_K+j>realizations_number2_lambda)
+						{
+							d_n_alp_obj--;
+						};
+
+						//number_of_unsuccesful_objects++;
+//						if(number_of_unsuccesful_objects>/*5+*/0.5*alp_data::Tmin(d_alp_data->d_rand_all->d_total_realizations_number_with_killing,d_alp_data->d_rand_all->d_total_realizations_number_with_ALP)*eps_tmp)
+//						{
+							//if(realizations_number2_K+j>realizations_number2_lambda)
+							//{
+							//	d_n_alp_obj--;
+							//};
+							//throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+//						};
+					};
+				};
+
+				}
+				catch (error_for_single_realization er)
+				{
+					if(d_alp_data->d_rand_flag)
+					{
+						throw error("Unexpected error in ramdomization\n",4);
+					};
+
+					//cout<<"\nWarning: time limit is reached.\nTo get the requested accuracy please\nincrease the allowed calculation time if possible\n\n";
+					if(realizations_number2_K+j>realizations_number2_lambda)
+					{
+						delete obj;obj=NULL;
+						d_n_alp_obj--;
+					};
+					break;
+				};
+
+				
+
+				
+
+				if(realizations_number2_K+j>realizations_number2_lambda)
+				{
+
+					if(kill_flag)
+					{
+						kill_j=j;
+					};
+
+				};
+
+
+				d_alp_obj->d_elem[realizations_number2_K+j]->partially_release_memory();
+
+				j++;
+
+				
+
+				if(d_alp_data->d_memory_size_in_MB>d_alp_data->d_max_mem)
+				{
+					if(!d_alp_data->d_rand_flag)
+					{
+						//cout<<"\nWarning: memory limit is reached.\nTo get the requested accuracy please\nincrease the allowed amount of memory if possible\n\n";
+						break;
+					};
+				};
+				
+
+				if(j%step_for_time==0)
+				{
+					double time_after3;
+					alp_data::get_current_time(time_after3);
+
+					if((time_after3-time_before1)>d_alp_data->d_max_time)
+					{
+						if(!d_alp_data->d_rand_flag)
+						{
+							//cout<<"\nWarning: time limit is reached.\nTo get the requested accuracy please\nincrease the allowed calculation time if possible\n\n";
+							break;
+						};
+					};
+				};
+			};
+		}
+		else
+		{
+			//cout<<"\nThe parameters were calculated with required accuracy\n\n";
+		};
+		
+
+		long int final_realizations_number_killing=kill_j+realizations_number2_K+1;
+		long int final_realizations_number_lambda=alp_data::Tmax(realizations_number2_lambda+1,j+realizations_number2_K);
+		d_n_alp_obj=final_realizations_number_lambda;
+
+
+		double time_after100;
+		alp_data::get_current_time(time_after100);
+		//cout<<"\nActual calculation time is "<<time_after100-time_before1<<" seconds\n";
+		//cout<<"Actual memory usage is "<<d_alp_data->Tmax(memory_after2,memory_after3)<<" MBs\n\n";
+
+		if(!d_alp_data->d_rand_flag)
+		{
+			d_alp_data->d_rand_all->d_total_realizations_number_with_ALP=final_realizations_number_lambda-1;
+			d_alp_data->d_rand_all->d_total_realizations_number_with_killing=final_realizations_number_killing-1;
+		};
+
+		//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+		//output of a file with complete randomization information
+		if(!d_alp_data->d_rand_flag&&d_alp_data->d_randout!="")
+		{
+			//string rand_st="rand_"+alp_data::long_to_string(d_alp_data->d_rand_all->d_random_factor)+".out";
+			string rand_st=d_alp_data->d_randout;
+			frand.open(rand_st.data(),ios::out);
+			if(!frand)
+			{
+				throw error("Error - file "+rand_st+" cannot be created\n",3);
+			};
+
+			long int i;
+
+
+			frand<<d_alp_data->d_rand_all->d_random_seed<<endl;
+			frand<<d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP.size()<<"\t";
+			for(i=0;i<(long int)d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP.size();i++)
+			{
+				frand<<d_alp_data->d_rand_all->d_first_stage_preliminary_realizations_numbers_ALP[i]<<"\t";
+			};
+			frand<<endl;
+
+			frand<<d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP.size()<<"\t";
+			for(i=0;i<(long int)d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP.size();i++)
+			{
+				frand<<d_alp_data->d_rand_all->d_preliminary_realizations_numbers_ALP[i]<<"\t";
+			};
+			frand<<endl;
+
+			frand<<d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing.size()<<"\t";
+			for(i=0;i<(long int)d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing.size();i++)
+			{
+				frand<<d_alp_data->d_rand_all->d_preliminary_realizations_numbers_killing[i]<<"\t";
+			};
+			frand<<endl;
+
+			frand<<d_alp_data->d_rand_all->d_total_realizations_number_with_ALP<<endl;
+			frand<<d_alp_data->d_rand_all->d_total_realizations_number_with_killing<<endl;
+
+
+
+			frand.close();
+
+		};
+
+		//cout<<"A number of realizations\t"<<d_alp_data->d_rand_all->d_total_realizations_number_with_ALP<<endl;
+
+	
+
+		bool inside_simulation_flag;
+
+		this->m_CalcTime=time_after100-time_before1;
+
+		output_main_parameters2m_new(
+		nalp_for_simulation,
+		level,
+		inside_simulation_flag,
+		final_realizations_number_lambda,
+		final_realizations_number_killing);
+
+
+	}
+	catch (...)
+	{ 
+		delete d_lambda_tmp;d_lambda_tmp=NULL;
+		delete d_lambda_tmp_errors;d_lambda_tmp_errors=NULL;
+
+		delete d_C_tmp;d_C_tmp=NULL;
+		delete d_C_tmp_errors;d_C_tmp_errors=NULL;
+
+		this->~alp_sim();
+
+		if(frand.is_open())
+		{
+			frand.close();
+		};
+
+		throw;
+
+	};
+}
+
+void alp_sim::symmetric_parameters_for_symmetric_scheme()
+{
+	//check whether the scoring scheme is symmetric
+	bool symmetric_flag=true;
+	long int i,j;
+	for(i=0;i<d_alp_data->d_number_of_AA;i++)
+	{
+		for(j=0;j<i;j++)
+		{
+			if(d_alp_data->d_smatr[i][j]!=d_alp_data->d_smatr[j][i])
+			{
+				symmetric_flag=false;
+				break;
+			};
+		};
+		if(!symmetric_flag)
+		{
+			break;
+		};
+	};
+
+	if(symmetric_flag)
+	{
+		for(i=0;i<d_alp_data->d_number_of_AA;i++)
+		{
+			if(d_alp_data->d_RR1[i]!=d_alp_data->d_RR2[i])
+			{
+				symmetric_flag=false;
+				break;
+			};
+		};
+	};
+
+	if(symmetric_flag)
+	{
+		if(d_alp_data->d_epen1!=d_alp_data->d_epen2||d_alp_data->d_open1!=d_alp_data->d_open2)
+		{
+			symmetric_flag=false;
+		};
+	};
+
+	if(symmetric_flag)
+	{
+		m_AI=0.5*(m_AI+m_AJ);
+		m_AJ=m_AI;
+		m_AIError=0.5*(m_AIError+m_AJError);
+		m_AJError=m_AIError;
+
+
+		m_AlphaI=0.5*(m_AlphaI+m_AlphaJ);
+		m_AlphaJ=m_AlphaI;
+		m_AlphaIError=0.5*(m_AlphaIError+m_AlphaJError);
+		m_AlphaJError=m_AlphaIError;
+
+	};
+
+}
+
+void alp_sim::randomize_realizations(
+long int final_realizations_number_lambda_,
+long int final_realizations_number_killing_)
+{
+	randomize_realizations_ind(0,final_realizations_number_killing_-1);
+	randomize_realizations_ind(final_realizations_number_killing_,final_realizations_number_lambda_-1);
+}
+
+void alp_sim::randomize_realizations_ind(
+long int ind1_,
+long int ind2_)
+{
+	alp**array_ind=NULL;
+	long int *perm=NULL;
+
+	try
+	{
+
+		if(ind1_>=ind2_)
+		{
+			return;
+		};
+
+		if(ind2_>d_n_alp_obj-1)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+
+		long int total_number=ind2_-ind1_+1;
+
+		array_ind=new alp*[total_number];
+		alp_data::assert_mem(array_ind);
+
+
+
+
+		
+		perm=new long int [total_number];
+		alp_data::assert_mem(perm);
+
+		generate_random_permulation(perm,total_number);
+
+		long int i;
+		for(i=0;i<total_number;i++)
+		{
+			array_ind[i]=d_alp_obj->d_elem[ind1_+perm[i]];
+		};
+
+		for(i=0;i<total_number;i++)
+		{
+			d_alp_obj->d_elem[ind1_+i]=array_ind[i];
+		};
+
+		delete[]array_ind;array_ind=NULL;
+		delete[]perm;perm=NULL;
+	}
+	catch (...)
+	{ 
+		delete[]array_ind;array_ind=NULL;
+		delete[]perm;perm=NULL;
+		throw;
+	};
+
+}
+
+void alp_sim::generate_random_permulation(
+long int *perm_,
+long int dim_)
+{
+	long int i;
+	for(i=0;i<dim_;i++)
+	{
+		perm_[i]=i;
+	};
+
+	for(i=0;i<dim_-1;i++)
+	{
+		long int ind_swap=i+alp_data::random_long(d_alp_data->ran2(),dim_-i);
+		long int tmp=perm_[ind_swap];
+		perm_[ind_swap]=perm_[i];
+		perm_[i]=tmp;
+	};
+}
+
+void alp_sim::output_main_parameters2m_new(
+long int nalp_for_lambda_simulation,
+long int level,
+bool &inside_simulation_flag,
+long int final_realizations_number_lambda_,
+long int final_realizations_number_killing_)
+{
+
+	double lambda;
+	double lambda_error;
+	double test_difference;
+	double test_difference_error;
+	double C;
+	double C_error;
+	double K_C;
+	double K_C_error;
+	double a_I;
+	double a_I_error;
+	double a_J;
+	double a_J_error;
+	double sigma;
+	double sigma_error;
+	double alpha_I;
+	double alpha_I_error;
+	double alpha_J;
+	double alpha_J_error;
+	double K;
+	double K_error;
+
+	bool flag=false;
+	long int number_of_trials=0;
+	long int number_of_trials_threshold=4;
+
+	do{
+
+	calculate_main_parameters2m(
+	final_realizations_number_lambda_,
+	final_realizations_number_killing_,
+	nalp_for_lambda_simulation,
+	level,
+	inside_simulation_flag,
+	lambda,
+	lambda_error,
+	test_difference,
+	test_difference_error,
+	C,
+	C_error,
+	K_C,
+	K_C_error,
+	a_I,
+	a_I_error,
+	a_J,
+	a_J_error,
+	sigma,
+	sigma_error,
+	alpha_I,
+	alpha_I_error,
+	alpha_J,
+	alpha_J_error,
+	K,
+	K_error,
+	flag);
+
+
+	number_of_trials++;
+
+	if(!flag)
+	{
+		randomize_realizations(
+		final_realizations_number_lambda_,
+		final_realizations_number_killing_);
+		//cout<<"Randomization attempt\t"<<number_of_trials<<endl;
+	};
+	}
+	while(!flag&&number_of_trials<=number_of_trials_threshold);
+
+	if(!flag)
+	{
+		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+	};
+}
+
+double alp_sim::round_double(
+double val_,
+long int digits_)
+{
+	long int i;
+	for(i=0;i<digits_;i++)
+	{
+		val_*=10;
+	};
+	val_=alp_data::round(val_);
+	for(i=0;i<digits_;i++)
+	{
+		val_/=10.0;
+	};
+
+	return val_;
+}
+
+double alp_sim::relative_error_in_percents(
+double val_,
+double val_error_)
+{
+	if(val_==0)
+	{
+		return DBL_MAX;
+	};
+
+	return fabs(round_double(val_error_/val_*100.0,1));
+
+}
+
+long int alp_sim::get_number_of_subsimulations(
+long int number_of_realizations_)
+{
+	long int max_number_of_subsimulations=20;
+	long int min_number_of_subsimulations=3;
+
+	long int min_number_of_realizations_for_subsimulation=2;
+
+	if(number_of_realizations_<min_number_of_realizations_for_subsimulation*min_number_of_subsimulations)
+	{
+		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+	};
+
+	long int res_subsimulations=(long int)ceil(sqrt((double)number_of_realizations_));
+	res_subsimulations=alp_data::Tmin(res_subsimulations,max_number_of_subsimulations);
+	res_subsimulations=alp_data::Tmax(res_subsimulations,min_number_of_subsimulations);
+
+	return res_subsimulations;
+}
+
+void alp_sim::memory_release_for_calculate_main_parameters2m(
+long int nalp_for_lambda_simulation,
+long int *&d_mult_realizations,
+long int *&d_mult_K_realizations,
+
+double *&lambda_mult,
+double *&lambda_mult_error,
+
+double *&C_mult,
+double *&C_mult_error,
+
+double *&a_I_mult,
+double *&a_I_mult_error,
+
+double *&a_J_mult,
+double *&a_J_mult_error,
+
+double *&sigma_mult,
+double *&sigma_mult_error,
+
+double *&alpha_I_mult,
+double *&alpha_I_mult_error,
+
+double *&alpha_J_mult,
+double *&alpha_J_mult_error,
+
+double *&K_C_mult,
+double *&K_C_mult_error,
+
+double *&K_mult,
+double *&K_mult_error,
+
+double *&Sc_mult,
+double *&Sc_mult_error,
+
+
+void **&alp_distr,
+void **&alp_distr_errors,
+
+void ***&alp_mult_distr,
+void ***&alp_mult_distr_errors)
+{
+	if(alp_distr)
+	{
+		long int j;
+		for(j=1;j<=nalp_for_lambda_simulation;j++)
+		{
+			delete (array_positive<double>*)alp_distr[j];alp_distr[j]=NULL;
+		};
+
+		delete[]alp_distr;alp_distr=NULL;
+	};
+
+
+
+	if(alp_distr_errors)
+	{
+		long int j;
+		for(j=1;j<=nalp_for_lambda_simulation;j++)
+		{
+			delete (array_positive<double>*)alp_distr_errors[j];alp_distr_errors[j]=NULL;
+		};
+
+		delete[]alp_distr_errors;alp_distr_errors=NULL;
+	};
+
+
+	if(alp_mult_distr)
+	{
+		long int k,j;
+		for(k=1;k<=d_mult_number;k++)
+		{
+			if(alp_mult_distr[k])
+			{
+				for(j=1;j<=nalp_for_lambda_simulation;j++)
+				{
+					delete (array_positive<double>*)alp_mult_distr[k][j];alp_mult_distr[k][j]=NULL;
+				};
+
+				delete[]alp_mult_distr[k];alp_mult_distr[k]=NULL;
+			};
+		};
+
+		delete[]alp_mult_distr;alp_mult_distr=NULL;
+	};
+
+
+	if(alp_mult_distr_errors)
+	{
+		long int k,j;
+		for(k=1;k<=d_mult_number;k++)
+		{
+			if(alp_mult_distr_errors[k])
+			{
+				for(j=1;j<=nalp_for_lambda_simulation;j++)
+				{
+					delete (array_positive<double>*)alp_mult_distr_errors[k][j];alp_mult_distr_errors[k][j]=NULL;
+				};
+
+				delete[]alp_mult_distr_errors[k];alp_mult_distr_errors[k]=NULL;
+			};
+		};
+
+		delete[]alp_mult_distr_errors;alp_mult_distr_errors=NULL;
+	};
+
+
+	delete[]d_mult_realizations;d_mult_realizations=NULL;
+	delete[]d_mult_K_realizations;d_mult_K_realizations=NULL;
+
+	delete[]lambda_mult;lambda_mult=NULL;
+	delete[]lambda_mult_error;lambda_mult_error=NULL;
+
+	delete[]C_mult;C_mult=NULL;
+	delete[]C_mult_error;C_mult_error=NULL;
+
+	delete[]a_I_mult;a_I_mult=NULL;
+	delete[]a_I_mult_error;a_I_mult_error=NULL;
+	delete[]a_J_mult;a_J_mult=NULL;
+	delete[]a_J_mult_error;a_J_mult_error=NULL;
+	delete[]sigma_mult;sigma_mult=NULL;
+	delete[]sigma_mult_error;sigma_mult_error=NULL;
+	delete[]alpha_I_mult;alpha_I_mult=NULL;
+	delete[]alpha_I_mult_error;alpha_I_mult_error=NULL;
+	delete[]alpha_J_mult;alpha_J_mult=NULL;
+	delete[]alpha_J_mult_error;alpha_J_mult_error=NULL;
+
+	delete[]K_C_mult;K_C_mult=NULL;
+	delete[]K_C_mult_error;K_C_mult_error=NULL;
+
+	delete[]K_mult;K_mult=NULL;
+	delete[]K_mult_error;K_mult_error=NULL;
+
+	delete[]Sc_mult;Sc_mult=NULL;
+	delete[]Sc_mult_error;Sc_mult_error=NULL;
+
+}
+
+void alp_sim::calculate_main_parameters2m(
+long int final_realizations_number_lambda_,
+long int final_realizations_number_killing_,
+long int nalp_for_lambda_simulation,
+long int level,
+bool &inside_simulation_flag,
+double &lambda,
+double &lambda_error,
+double &test_difference,
+double &test_difference_error,
+double &C,
+double &C_error,
+double &K_C,
+double &K_C_error,
+double &a_I,
+double &a_I_error,
+double &a_J,
+double &a_J_error,
+double &sigma,
+double &sigma_error,
+double &alpha_I,
+double &alpha_I_error,
+double &alpha_J,
+double &alpha_J_error,
+double &K,
+double &K_error,
+bool &flag_)
+{
+
+	long int *d_mult_realizations=NULL;
+	long int *d_mult_K_realizations=NULL;
+
+	double *lambda_mult=NULL;
+	double *lambda_mult_error=NULL;
+
+	double *C_mult=NULL;
+	double *C_mult_error=NULL;
+
+	double *a_I_mult=NULL;
+	double *a_I_mult_error=NULL;
+
+	double *a_J_mult=NULL;
+	double *a_J_mult_error=NULL;
+
+	double *sigma_mult=NULL;
+	double *sigma_mult_error=NULL;
+
+	double *alpha_I_mult=NULL;
+	double *alpha_I_mult_error=NULL;
+
+	double *alpha_J_mult=NULL;
+	double *alpha_J_mult_error=NULL;
+
+	double *K_C_mult=NULL;
+	double *K_C_mult_error=NULL;
+
+	double *K_mult=NULL;
+	double *K_mult_error=NULL;
+
+	double *Sc_mult=NULL;
+	double *Sc_mult_error=NULL;
+
+
+	void **alp_distr=NULL;
+	void **alp_distr_errors=NULL;
+
+	void ***alp_mult_distr=NULL;
+ 	void ***alp_mult_distr_errors=NULL;
+
+	try
+	{
+
+		flag_=false;
+
+
+		if(final_realizations_number_killing_>final_realizations_number_lambda_)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+		long int mult_number_lambda=get_number_of_subsimulations(d_n_alp_obj);
+		long int mult_number_K=get_number_of_subsimulations(final_realizations_number_killing_);
+
+		//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+		//mult_number_lambda=mult_number_K=final_realizations_number_killing_;
+
+
+		d_mult_number=alp_data::Tmin(mult_number_lambda,mult_number_K);
+
+		double mult_number_double_lambda=mult_number_lambda;
+		double mult_number_double_K=mult_number_lambda;
+
+
+
+		long int j;
+
+
+		d_mult_realizations=new long int[d_mult_number+1];
+		alp_data::assert_mem(d_mult_realizations);
+
+
+
+		d_mult_K_realizations=new long int[d_mult_number+1];
+		alp_data::assert_mem(d_mult_K_realizations);
+
+		lambda_mult=new double[d_mult_number+1];
+		alp_data::assert_mem(lambda_mult);
+		lambda_mult_error=new double[d_mult_number+1];
+		alp_data::assert_mem(lambda_mult_error);
+
+		C_mult=new double[d_mult_number+1];
+		alp_data::assert_mem(C_mult);
+		C_mult_error=new double[d_mult_number+1];
+		alp_data::assert_mem(C_mult_error);
+
+		a_I_mult=new double[d_mult_number+1];
+		alp_data::assert_mem(a_I_mult);
+		a_I_mult_error=new double[d_mult_number+1];
+		alp_data::assert_mem(a_I_mult_error);
+
+		a_J_mult=new double[d_mult_number+1];
+		alp_data::assert_mem(a_J_mult);
+		a_J_mult_error=new double[d_mult_number+1];
+		alp_data::assert_mem(a_J_mult_error);
+
+		sigma_mult=new double[d_mult_number+1];
+		alp_data::assert_mem(sigma_mult);
+		sigma_mult_error=new double[d_mult_number+1];
+		alp_data::assert_mem(sigma_mult_error);
+
+		alpha_I_mult=new double[d_mult_number+1];
+		alp_data::assert_mem(alpha_I_mult);
+		alpha_I_mult_error=new double[d_mult_number+1];
+		alp_data::assert_mem(alpha_I_mult_error);
+
+		alpha_J_mult=new double[d_mult_number+1];
+		alp_data::assert_mem(alpha_J_mult);
+		alpha_J_mult_error=new double[d_mult_number+1];
+		alp_data::assert_mem(alpha_J_mult_error);
+
+		K_C_mult=new double[d_mult_number+1];
+		alp_data::assert_mem(K_C_mult);
+		K_C_mult_error=new double[d_mult_number+1];
+		alp_data::assert_mem(K_C_mult_error);
+
+		K_mult=new double[d_mult_number+1];
+		alp_data::assert_mem(K_mult);
+		K_mult_error=new double[d_mult_number+1];
+		alp_data::assert_mem(K_mult_error);
+
+		Sc_mult=new double[d_mult_number+1];
+		alp_data::assert_mem(Sc_mult);
+		Sc_mult_error=new double[d_mult_number+1];
+		alp_data::assert_mem(Sc_mult_error);
+
+
+
+		double lambda_mult2=0;
+		double C_mult2=0;
+		double K_C_mult2=0;
+		double a_I_mult2=0;
+		double a_J_mult2=0;
+		double sigma_mult2=0;
+		double alpha_I_mult2=0;
+		double alpha_J_mult2=0;
+		double K_mult2=0;
+		double Sc_mult2=0;
+
+		double lambda_mult2_error=0;
+		double C_mult2_error=0;
+		double K_C_mult2_error=0;
+		double a_I_mult2_error=0;
+		double a_J_mult2_error=0;
+		double sigma_mult2_error=0;
+		double alpha_I_mult2_error=0;
+		double alpha_J_mult2_error=0;
+		double K_mult2_error=0;
+		double Sc_mult2_error=0;
+
+
+
+
+		
+		for(j=0;j<=nalp_for_lambda_simulation;j++)
+		{
+			get_and_allocate_alp_distribution(
+			0,
+			d_n_alp_obj-1,
+			alp_distr,
+			alp_distr_errors,
+			j);
+		};
+
+
+		alp_mult_distr=new void **[d_mult_number+1];
+		alp_data::assert_mem(alp_mult_distr);
+
+		for(j=0;j<=d_mult_number;j++)
+		{
+			alp_mult_distr[j]=NULL;
+		};
+
+		alp_mult_distr_errors=new void **[d_mult_number+1];
+		alp_data::assert_mem(alp_mult_distr_errors);
+		for(j=0;j<=d_mult_number;j++)
+		{
+			alp_mult_distr_errors[j]=NULL;
+		};
+
+		alp_mult_distr[0]=alp_distr;
+		alp_mult_distr_errors[0]=alp_distr_errors;
+
+		long int real_number=(long int)floor((double)final_realizations_number_lambda_/(double)d_mult_number);
+
+		d_mult_realizations[0]=final_realizations_number_lambda_;
+
+		long int k;
+		for(k=1;k<=d_mult_number;k++)
+		{
+			d_mult_realizations[k]=real_number;
+		};
+
+
+		long int nr_tmp=0;
+		for(k=1;k<=d_mult_number;k++)
+		{
+			nr_tmp+=d_mult_realizations[k];
+			long int j;
+			for(j=0;j<=nalp_for_lambda_simulation;j++)
+			{
+				get_and_allocate_alp_distribution(
+				nr_tmp-d_mult_realizations[k],
+				nr_tmp-1,
+				alp_mult_distr[k],
+				alp_mult_distr_errors[k],
+				j);
+			};
+		};
+
+		nr_tmp=0;
+		for(k=1;k<=d_mult_number;k++)
+		{
+			nr_tmp+=d_mult_realizations[k];
+			long int nalp_tmp;
+
+			double test_difference;
+			double test_difference_error;
+
+
+
+			calculate_lambda(
+			false,
+			nalp_for_lambda_simulation,
+			nalp_tmp,
+			inside_simulation_flag,
+			alp_mult_distr[k],
+			alp_mult_distr_errors[k],
+			lambda_mult[k],
+			lambda_mult_error[k],
+			test_difference,
+			test_difference_error);
+
+
+			if(!inside_simulation_flag)
+			{
+				goto label1;
+			};
+
+
+			lambda_mult2+=lambda_mult[k];
+			lambda_mult2_error+=lambda_mult[k]*lambda_mult[k];
+		};
+
+
+
+		long int nalp_tmp;
+
+		calculate_lambda(
+		false,
+		nalp_for_lambda_simulation,
+		nalp_tmp,
+		inside_simulation_flag,
+		alp_distr,
+		alp_distr_errors,
+		lambda,
+		lambda_error,
+		test_difference,
+		test_difference_error);
+
+		if(!inside_simulation_flag)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+		lambda_mult[0]=lambda;
+		lambda_mult_error[0]=lambda_error;
+
+		
+
+		nr_tmp=0;
+		for(k=1;k<=d_mult_number;k++)
+		{
+			nr_tmp+=d_mult_realizations[k];
+			calculate_C(
+			0,
+			nalp_for_lambda_simulation,
+			alp_mult_distr[k],
+			alp_mult_distr_errors[k],
+			lambda_mult[k],
+			lambda_mult_error[k],
+			C_mult[k],
+			C_mult_error[k],
+			Sc_mult[k],
+			Sc_mult_error[k]);
+
+			C_mult2+=C_mult[k];
+			C_mult2_error+=C_mult[k]*C_mult[k];
+
+			Sc_mult2+=Sc_mult[k];
+			Sc_mult2_error+=Sc_mult[k]*Sc_mult[k];
+
+
+		};
+		
+		double Sc;
+		double Sc_error;
+
+
+		calculate_C(
+		0,
+		nalp_for_lambda_simulation,
+		alp_distr,
+		alp_distr_errors,
+		lambda,
+		lambda_error,
+		C,
+		C_error,
+		Sc,
+		Sc_error);
+
+
+
+		C_mult[0]=C;
+		C_mult_error[0]=C_error;
+
+		Sc_mult[0]=Sc;
+		Sc_mult_error[0]=Sc_error;
+
+
+		nr_tmp=0;
+		for(k=1;k<=d_mult_number;k++)
+		{
+
+			nr_tmp+=d_mult_realizations[k];
+			calculate_FSC(
+			nalp_for_lambda_simulation,
+			nr_tmp-d_mult_realizations[k],
+			nr_tmp-1,
+			alp_mult_distr[k],
+			lambda_mult[k],
+			Sc_mult[k],
+			//Sc_mult_error[k],
+
+			a_I_mult[k],
+			a_I_mult_error[k],
+			a_J_mult[k],
+			a_J_mult_error[k],
+			sigma_mult[k],
+			sigma_mult_error[k],
+			alpha_I_mult[k],
+			alpha_I_mult_error[k],
+			alpha_J_mult[k],
+			alpha_J_mult_error[k]);
+
+			a_I_mult2+=a_I_mult[k];
+			a_I_mult2_error+=a_I_mult[k]*a_I_mult[k];
+
+			a_J_mult2+=a_J_mult[k];
+			a_J_mult2_error+=a_J_mult[k]*a_J_mult[k];
+
+			sigma_mult2+=sigma_mult[k];
+			sigma_mult2_error+=sigma_mult[k]*sigma_mult[k];
+
+			alpha_I_mult2+=alpha_I_mult[k];
+			alpha_I_mult2_error+=alpha_I_mult[k]*alpha_I_mult[k];
+
+			alpha_J_mult2+=alpha_J_mult[k];
+			alpha_J_mult2_error+=alpha_J_mult[k]*alpha_J_mult[k];
+
+
+		};
+
+
+		calculate_FSC(
+		nalp_for_lambda_simulation,
+		0,
+		final_realizations_number_lambda_-1,
+		alp_distr,
+		lambda,
+		Sc,
+		//Sc_error,
+
+		a_I,
+		a_I_error,
+		a_J,
+		a_J_error,
+		sigma,
+		sigma_error,
+		alpha_I,
+		alpha_I_error,
+		alpha_J,
+		alpha_J_error);
+		
+
+		a_I_mult[0]=a_I;
+		a_I_mult_error[0]=a_I_error;
+		a_J_mult[0]=a_J;
+		a_J_mult_error[0]=a_J_error;
+		sigma_mult[0]=sigma;
+		sigma_mult_error[0]=sigma_error;
+		alpha_I_mult[0]=alpha_I;
+		alpha_I_mult_error[0]=alpha_I_error;
+		alpha_J_mult[0]=alpha_J;
+		alpha_J_mult_error[0]=alpha_J_error;
+		
+
+		real_number=(long int)floor((double)final_realizations_number_killing_/(double)d_mult_number);
+
+
+		d_mult_K_realizations[0]=final_realizations_number_killing_;
+
+
+		for(k=1;k<=d_mult_number;k++)
+		{
+			d_mult_K_realizations[k]=real_number;
+		};
+
+		//output2
+		nr_tmp=0;
+		for(k=1;k<=d_mult_number;k++)
+		{
+			nr_tmp+=d_mult_K_realizations[k];
+
+			long int recommended_level;
+			long int diff_opt;
+
+
+
+			check_K_criterion_during_killing(
+			nr_tmp-d_mult_K_realizations[k],
+			nr_tmp-1,
+			lambda_mult[k],
+			d_alp_data->d_eps_K,
+			level,
+			recommended_level,
+			diff_opt,
+			K_C_mult[k],
+			K_C_mult_error[k]);
+
+
+			K_mult[k]=C_mult[k]*K_C_mult[k];
+			K_mult_error[k]=alp_data::error_of_the_product(
+			C_mult[k],
+			C_mult_error[k],
+			K_C_mult[k],
+			K_C_mult_error[k]);
+
+			K_C_mult2+=K_C_mult[k];
+			K_C_mult2_error+=K_C_mult[k]*K_C_mult[k];
+
+			K_mult2+=K_mult[k];
+			K_mult2_error+=K_mult[k]*K_mult[k];
+
+		};
+
+
+		long int recommended_level;
+		long int diff_opt;
+
+
+
+		check_K_criterion_during_killing(
+		0,
+		final_realizations_number_killing_-1,
+		lambda,
+		d_alp_data->d_eps_K,
+		level,
+		recommended_level,
+		diff_opt,
+		K_C,
+		K_C_error);
+
+
+
+		
+
+		K=C*K_C;
+		K_error=alp_data::error_of_the_product(
+		C,
+		C_error,
+		K_C,
+		K_C_error);
+
+		K_C_mult[0]=K_C;
+		K_C_mult_error[0]=K_C_error;
+
+		K_mult[0]=K;
+		K_mult_error[0]=K_error;
+
+
+
+		lambda_mult2/=d_mult_number;
+		C_mult2/=d_mult_number;
+		K_C_mult2/=d_mult_number;
+		a_I_mult2/=d_mult_number;
+		a_J_mult2/=d_mult_number;
+		sigma_mult2/=d_mult_number;
+		alpha_I_mult2/=d_mult_number;
+		alpha_J_mult2/=d_mult_number;
+		K_mult2/=d_mult_number;
+
+		lambda_mult2_error/=d_mult_number;
+		C_mult2_error/=d_mult_number;
+		K_C_mult2_error/=d_mult_number;
+		a_I_mult2_error/=d_mult_number;
+		a_J_mult2_error/=d_mult_number;
+		sigma_mult2_error/=d_mult_number;
+		alpha_I_mult2_error/=d_mult_number;
+		alpha_J_mult2_error/=d_mult_number;
+		K_mult2_error/=d_mult_number;
+
+
+		mult_number_double_lambda=(double)final_realizations_number_lambda_/(double)real_number;
+		mult_number_double_K=(double)final_realizations_number_killing_/(double)real_number;
+
+
+		lambda_mult2_error=alp_reg::sqrt_for_errors(lambda_mult2_error-lambda_mult2*lambda_mult2)/sqrt((double)mult_number_double_lambda);
+		C_mult2_error=alp_reg::sqrt_for_errors(C_mult2_error-C_mult2*C_mult2)/sqrt((double)mult_number_double_lambda);
+		K_C_mult2_error=alp_reg::sqrt_for_errors(K_C_mult2_error-K_C_mult2*K_C_mult2)/sqrt((double)mult_number_double_K);
+		a_I_mult2_error=alp_reg::sqrt_for_errors(a_I_mult2_error-a_I_mult2*a_I_mult2)/sqrt((double)mult_number_double_lambda);
+		a_J_mult2_error=alp_reg::sqrt_for_errors(a_J_mult2_error-a_J_mult2*a_J_mult2)/sqrt((double)mult_number_double_lambda);
+		sigma_mult2_error=alp_reg::sqrt_for_errors(sigma_mult2_error-sigma_mult2*sigma_mult2)/sqrt((double)mult_number_double_lambda);
+		alpha_I_mult2_error=alp_reg::sqrt_for_errors(alpha_I_mult2_error-alpha_I_mult2*alpha_I_mult2)/sqrt((double)mult_number_double_lambda);
+		alpha_J_mult2_error=alp_reg::sqrt_for_errors(alpha_J_mult2_error-alpha_J_mult2*alpha_J_mult2)/sqrt((double)mult_number_double_lambda);
+		K_mult2_error=alp_reg::sqrt_for_errors(K_mult2_error-K_mult2*K_mult2)/sqrt((double)alp_data::Tmin(mult_number_double_lambda,mult_number_double_K));
+
+
+		error_in_calculate_main_parameters2m(
+		lambda,
+		lambda_error,
+		lambda_mult2,
+		lambda_mult2_error);
+
+		error_in_calculate_main_parameters2m(
+		C,
+		C_error,
+		C_mult2,
+		C_mult2_error);
+
+		error_in_calculate_main_parameters2m(
+		K_C,
+		K_C_error,
+		K_C_mult2,
+		K_C_mult2_error);
+
+		error_in_calculate_main_parameters2m(
+		a_I,
+		a_I_error,
+		a_I_mult2,
+		a_I_mult2_error);
+
+		error_in_calculate_main_parameters2m(
+		a_J,
+		a_J_error,
+		a_J_mult2,
+		a_J_mult2_error);
+
+
+		error_in_calculate_main_parameters2m(
+		sigma,
+		sigma_error,
+		sigma_mult2,
+		sigma_mult2_error);
+
+		error_in_calculate_main_parameters2m(
+		alpha_I,
+		alpha_I_error,
+		alpha_I_mult2,
+		alpha_I_mult2_error);
+
+		error_in_calculate_main_parameters2m(
+		alpha_J,
+		alpha_J_error,
+		alpha_J_mult2,
+		alpha_J_mult2_error);
+
+		error_in_calculate_main_parameters2m(
+		K,
+		K_error,
+		K_mult2,
+		K_mult2_error);
+
+		flag_=true;
+
+
+		this->m_AI=a_I;
+		this->m_AIError=a_I_error;
+		this->m_AJ=a_J;
+		this->m_AJError=a_J_error;
+		this->m_Sigma=sigma;
+		this->m_SigmaError=sigma_error;
+		this->m_C=C;
+		this->m_CError=C_error;
+		this->m_K=K;
+		this->m_KError=K_error;
+		this->m_Lambda=lambda;
+		this->m_LambdaError=lambda_error;
+
+		this->m_AlphaI=alpha_I;
+		this->m_AlphaIError=alpha_I_error;
+		this->m_AlphaJ=alpha_J;
+		this->m_AlphaJError=alpha_J_error;
+
+		this->m_AISbs.resize(d_mult_number);
+		this->m_AJSbs.resize(d_mult_number);
+		this->m_SigmaSbs.resize(d_mult_number);
+		this->m_CSbs.resize(d_mult_number);
+		this->m_KSbs.resize(d_mult_number);
+		this->m_LambdaSbs.resize(d_mult_number);
+
+		this->m_AlphaISbs.resize(d_mult_number);
+		this->m_AlphaJSbs.resize(d_mult_number);
+
+
+		for(k=1;k<=d_mult_number;k++)
+		{
+			this->m_AISbs[k-1]=a_I_mult[k];
+			this->m_AJSbs[k-1]=a_J_mult[k];
+			this->m_SigmaSbs[k-1]=sigma_mult[k];
+			this->m_CSbs[k-1]=C_mult[k];
+			this->m_KSbs[k-1]=K_mult[k];
+			this->m_LambdaSbs[k-1]=lambda_mult[k];
+
+			this->m_AlphaISbs[k-1]=alpha_I_mult[k];
+			this->m_AlphaJSbs[k-1]=alpha_J_mult[k];
+		};
+
+
+
+	label1:;
+
+	symmetric_parameters_for_symmetric_scheme();
+
+
+
+	}
+	catch (...)
+	{ 
+		memory_release_for_calculate_main_parameters2m(
+		nalp_for_lambda_simulation,
+		d_mult_realizations,
+		d_mult_K_realizations,
+
+		lambda_mult,
+		lambda_mult_error,
+
+		C_mult,
+		C_mult_error,
+
+		a_I_mult,
+		a_I_mult_error,
+
+		a_J_mult,
+		a_J_mult_error,
+
+		sigma_mult,
+		sigma_mult_error,
+
+		alpha_I_mult,
+		alpha_I_mult_error,
+
+		alpha_J_mult,
+		alpha_J_mult_error,
+
+		K_C_mult,
+		K_C_mult_error,
+
+		K_mult,
+		K_mult_error,
+
+		Sc_mult,
+		Sc_mult_error,
+
+
+		alp_distr,
+		alp_distr_errors,
+
+		alp_mult_distr,
+		alp_mult_distr_errors);
+		throw;
+	};
+
+
+	memory_release_for_calculate_main_parameters2m(
+	nalp_for_lambda_simulation,
+	d_mult_realizations,
+	d_mult_K_realizations,
+
+	lambda_mult,
+	lambda_mult_error,
+
+	C_mult,
+	C_mult_error,
+
+	a_I_mult,
+	a_I_mult_error,
+
+	a_J_mult,
+	a_J_mult_error,
+
+	sigma_mult,
+	sigma_mult_error,
+
+	alpha_I_mult,
+	alpha_I_mult_error,
+
+	alpha_J_mult,
+	alpha_J_mult_error,
+
+	K_C_mult,
+	K_C_mult_error,
+
+	K_mult,
+	K_mult_error,
+
+	Sc_mult,
+	Sc_mult_error,
+
+
+	alp_distr,
+	alp_distr_errors,
+
+	alp_mult_distr,
+	alp_mult_distr_errors);
+}
+
+void alp_sim::error_in_calculate_main_parameters2m(
+double C,
+double &C_error,
+double C_mult2,
+double C_mult2_error)
+{
+	if(C!=0&&C_mult2!=0)
+	{
+		C_error=fabs(C*C_mult2_error/C_mult2);
+	}
+	else
+	{
+		C_error=C_mult2_error;
+	};
+}
+
+alp_sim::~alp_sim()//destructor
+{
+	long int i;
+
+	if(d_alp_obj)
+	{
+		for(i=0;i<d_n_alp_obj;i++)
+		{
+			delete d_alp_obj->d_elem[i];d_alp_obj->d_elem[i]=NULL;
+		};
+
+		if(d_alp_data)
+		{
+			d_alp_data->d_memory_size_in_MB-=sizeof(alp)*d_n_alp_obj/mb_bytes;
+		};
+
+		delete d_alp_obj;d_alp_obj=NULL;
+	};
+	if(d_alp_data)
+	{
+		d_alp_data->d_memory_size_in_MB-=(double)(sizeof(array_positive<alp*>))/mb_bytes;
+	};
+
+
+}
+
+void alp_sim::kill(
+bool check_time_,
+long int ind1_,
+long int ind2_,
+long int M_min_,
+double lambda_,
+double eps_K_,
+double &K_C_,
+double &K_C_error_,
+long int &level_,
+long int &diff_opt_)
+{
+
+	bool flag=false;
+	long int current_level=(long int)floor(M_min_*0.5);
+	long int recommended_level;
+	//long int number_of_unsucesful_objects=0;
+
+	
+	long int i;
+	for(i=ind1_;i<=ind2_;i++)
+	{
+	
+		alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
+		if(i-ind1_+1>alp_obj_tmp->d_alp_data->d_minimum_realizations_number)
+		{
+			alp_obj_tmp->d_check_time_flag=check_time_;
+			alp_obj_tmp->d_time_error_flag=check_time_;
+		};
+	};
+
+	do{
+		long int i;
+		for(i=ind1_;i<=ind2_;i++)
+		{
+			alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
+			bool flag=false;
+			while(!flag)
+			{
+				alp_obj_tmp->d_sentinels_flag=false;
+				alp_obj_tmp->kill_upto_level(M_min_,current_level);
+				if(!alp_obj_tmp->d_success)
+				{
+					//number_of_unsucesful_objects++;
+					//if(number_of_unsucesful_objects>/*5+*/0.5*(ind2_-ind1_+1)*
+					//	d_alp_obj->d_alp_data->d_eps_K 
+					//	)
+					//{
+						//throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+					//};
+					delete alp_obj_tmp;alp_obj_tmp=NULL;
+					alp_obj_tmp=new alp(d_alp_data);
+					alp_data::assert_mem(alp_obj_tmp);
+
+					if(i-ind1_+1>alp_obj_tmp->d_alp_data->d_minimum_realizations_number)
+					{
+						alp_obj_tmp->d_check_time_flag=check_time_;
+						alp_obj_tmp->d_time_error_flag=check_time_;
+					};
+
+					bool flag=false;
+					while(!flag)
+					{
+						alp_obj_tmp->simulate_alp_upto_the_given_level(M_min_);
+						//if(!alp_obj_tmp->d_success)
+						//{
+						//	number_of_unsucesful_objects++;
+						//	if(number_of_unsucesful_objects>/*5+*/0.5*(ind2_-ind1_+1)*
+						//		d_alp_obj->d_alp_data->d_eps_K 
+						//		)
+						//	{
+								//throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+						//	};
+						//};
+						flag=alp_obj_tmp->d_success;
+					};
+
+				};
+				flag=alp_obj_tmp->d_success;
+			};
+		};
+
+
+		flag=check_K_criterion_during_killing(
+		ind1_,
+		ind2_,
+		lambda_,
+		eps_K_,
+		current_level,
+		recommended_level,
+		diff_opt_,
+		K_C_,
+		K_C_error_);
+
+		current_level=recommended_level;
+
+	}
+	while(!flag);
+
+	level_=current_level;
+
+}
+
+void alp_sim::get_single_realization(
+bool check_time_,
+long int M_min_,
+long int nalp_,
+bool killing_flag_,
+long int level_,
+long int diff_opt_,
+alp *&obj_,
+bool &sucess_flag_,
+double &d_eps_)
+{
+	if(!obj_)
+	{
+		obj_=new alp(d_alp_data);
+		alp_data::assert_mem(obj_);
+		d_alp_data->d_memory_size_in_MB+=sizeof(alp)/mb_bytes;
+	};
+	obj_->d_single_realiztion_calculation_flag=true;
+	obj_->d_check_time_flag=check_time_;
+
+	d_eps_=d_alp_data->Tmin(d_alp_data->d_eps_K,d_alp_data->d_eps_lambda);
+
+	
+
+	alp*&obj=obj_;
+
+	obj->d_diff_opt=diff_opt_;
+
+	obj->d_sentinels_flag=d_alp_data->d_sentinels_flag;
+
+	sucess_flag_=true;
+
+	while(obj->d_nalp<nalp_)
+	{
+		obj->simulate_next_alp();
+		if(!obj->d_success)
+		{
+			sucess_flag_=false;
+			delete obj_;obj_=NULL;
+			d_eps_=d_alp_data->d_eps_lambda;
+			d_alp_data->d_memory_size_in_MB-=sizeof(alp)/mb_bytes;
+			return;
+		};
+	};
+
+
+	if(killing_flag_)
+	{
+		obj->kill_upto_level(M_min_,level_);		
+		if(!obj->d_success)
+		{
+			sucess_flag_=false;
+			delete obj_;obj_=NULL;
+			d_eps_=d_alp_data->d_eps_K;
+			d_alp_data->d_memory_size_in_MB-=sizeof(alp)/mb_bytes;
+			return;
+		};
+	};
+
+}
+
+void alp_sim::quick_test(
+long int trials_number_,
+double max_time_)
+{
+	if(trials_number_<=0)
+	{
+		throw error("Unexpected error in alp_sim::quick_test\n",1);
+	};
+
+	bool check_time_flag=false;
+	if(max_time_>0)
+	{
+		check_time_flag=true;
+	};
+
+	long int alp_number=5;
+	double p_thres=1e-10;
+
+	double lambda_ungapped=this->d_alp_data->d_is->d_ungap_lambda;
+	if(lambda_ungapped<=0)
+	{
+		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+	};
+	long int score_diff=(long int)alp_data::round(-log(p_thres)/lambda_ungapped);
+
+	long int i;
+
+	long int max_number_of_unsuccessful_objects2=(long int)floor(/*5+*/0.5*trials_number_*(d_alp_obj->d_alp_data->d_eps_K+d_alp_obj->d_alp_data->d_eps_lambda));
+	long int number_of_unsuccessful_objects2=0;
+
+	double max_time_store=d_alp_data->d_max_time;
+	
+	if(check_time_flag)
+	{
+		d_alp_data->d_max_time=max_time_;
+	};
+
+	for(i=0;i<trials_number_;i++)
+	{
+
+		alp* alp_obj_tmp=NULL;
+		bool success3=false;
+		while(!success3)
+		{
+			alp_obj_tmp=new alp(d_alp_data);
+			alp_data::assert_mem(alp_obj_tmp);
+
+			d_alp_data->d_memory_size_in_MB+=(double)(sizeof(alp))/mb_bytes;
+
+			alp_obj_tmp->d_check_time_flag=check_time_flag;
+			alp_obj_tmp->d_time_error_flag=check_time_flag;
+
+
+			alp_obj_tmp->simulate_alp_upto_the_given_number(alp_number+1);
+
+			success3=alp_obj_tmp->d_success;
+
+			
+
+			if(!success3)
+			{
+				delete alp_obj_tmp;alp_obj_tmp=NULL;
+				d_alp_data->d_memory_size_in_MB-=(double)(sizeof(alp))/mb_bytes;
+				number_of_unsuccessful_objects2++;
+				if(number_of_unsuccessful_objects2>max_number_of_unsuccessful_objects2)
+				{
+					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+				};
+			};
+		};
+
+		long int last_alp=alp_obj_tmp->d_alp->d_elem[alp_number];
+		long int M_upper_level=last_alp+score_diff;
+		
+		alp_obj_tmp->d_sentinels_flag=false;
+		alp_obj_tmp->kill_upto_level(last_alp,last_alp-score_diff,&M_upper_level);
+		if(!alp_obj_tmp->d_success)
+		{
+			number_of_unsuccessful_objects2++;
+			if(number_of_unsuccessful_objects2>max_number_of_unsuccessful_objects2)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+		};
+
+
+		delete alp_obj_tmp;alp_obj_tmp=NULL;
+		d_alp_data->d_memory_size_in_MB-=(double)(sizeof(alp))/mb_bytes;
+
+	};
+
+	if(check_time_flag)
+	{
+		d_alp_data->d_max_time=max_time_store;
+	};
+}
+
+
+void alp_sim::get_minimal_simulation(
+long int ind1_,
+long int ind2_,
+long int &M_min_,
+long int &nalp_,
+long int &nalp_lambda_,
+bool C_calculation_,
+bool check_time_flag_)
+{
+
+	long int &alp_number=nalp_;
+
+	void **alp_distr=NULL;
+	void **alp_distr_errors=NULL;
+
+	try
+	{
+
+		long int add_alp_number=3;
+		long int add_alp_number_count=0;
+		long int max_alp_number=30;
+
+		if(d_n_alp_obj<ind1_||d_n_alp_obj-1>ind2_)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+		
+
+		alp_number=0;
+
+		//long int nalp_lambda_equilibration=-1;
+
+		//create the objects
+		long int i;
+		for(i=d_n_alp_obj;i<=ind2_;i++)
+		{
+			d_alp_obj->set_elem(i,NULL);
+
+
+			alp *&alp_obj_tmp=d_alp_obj->d_elem[i];
+
+			alp_obj_tmp=new alp(d_alp_data);
+			alp_data::assert_mem(alp_obj_tmp);
+
+			d_alp_data->d_memory_size_in_MB+=sizeof(alp)/mb_bytes;
+			
+
+			alp_obj_tmp->d_check_time_flag=check_time_flag_;
+			alp_obj_tmp->d_time_error_flag=check_time_flag_;
+
+		};
+
+		d_n_alp_obj=ind2_+1;
+	
+
+		bool M_min_flag=false;
+		bool nalp_flag=false;
+
+
+		bool criterion_flag=false;
+		long int number_of_fails=0;
+		long int number_of_fails_threshold=5;
+
+		do{
+			if(alp_number>=max_alp_number)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",1);
+			};
+
+			//long int number_of_unsuccessful_objects=0;
+			long int i;
+			for(i=ind1_;i<=ind2_;i++)
+			{
+				alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
+
+				alp_obj_tmp->d_check_time_flag=check_time_flag_;
+				alp_obj_tmp->d_time_error_flag=check_time_flag_;
+
+
+				if(alp_obj_tmp->d_nalp<alp_number+1)
+				{
+
+					alp_obj_tmp->simulate_alp_upto_the_given_number(alp_number+1);
+
+					//cout<<i<<"\t"<<alp_obj_tmp->d_success<<endl;
+
+					if(!alp_obj_tmp->d_success)
+					{
+						//number_of_unsuccessful_objects++;
+						delete alp_obj_tmp;
+						alp_obj_tmp=NULL;
+
+						//if(number_of_unsuccessful_objects>/*5+*/0.5*(ind2_-ind1_+1)*
+						//	d_alp_obj->d_alp_data->d_eps_lambda*(alp_number+1)
+						//	)
+						//{
+							
+							//throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+						//};
+
+
+						bool success2=false;
+						while(!success2)
+						{
+							alp_obj_tmp=new alp(d_alp_data);
+							alp_data::assert_mem(alp_obj_tmp);
+
+
+							long int j;
+							for(j=0;j<=alp_number;j++)
+							{
+								alp_obj_tmp->simulate_alp_upto_the_given_number(j+1);
+							};
+
+							success2=alp_obj_tmp->d_success;
+
+							
+
+							if(!success2)
+							{
+								delete alp_obj_tmp;
+								alp_obj_tmp=NULL;
+								//number_of_unsuccessful_objects++;
+								//if(number_of_unsuccessful_objects>/*5+*/0.5*(ind2_-ind1_+1)*
+								//	d_alp_obj->d_alp_data->d_eps_lambda*(alp_number+1)
+								//	)
+								//{
+									
+									//throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+								//};
+							};
+
+						};
+					};
+
+				};
+
+			};
+
+			alp_number++;
+			
+
+
+			bool inside_simulation_flag=false;
+
+			double lambda;
+
+			criterion_flag=the_criterion(
+				alp_number,
+				nalp_lambda_,
+				0,
+				ind2_,
+				alp_distr,
+				alp_distr_errors,
+				M_min_,
+				M_min_flag,
+				nalp_flag,
+				inside_simulation_flag,
+				C_calculation_,
+				&lambda);
+
+			if(inside_simulation_flag)
+			{
+				if(lambda<=0)
+				{
+					criterion_flag=false;
+					inside_simulation_flag=false;
+				};
+			}
+			else
+			{
+				criterion_flag=false;
+			};
+			
+			//if(nalp_lambda_equilibration==-1&&nalp_flag)
+			//if(nalp_flag)
+			//{
+			//	nalp_lambda_equilibration=alp_number;
+			//};
+
+			if(!inside_simulation_flag)
+			{
+				number_of_fails++;
+
+				long int i;
+				if(alp_distr)
+				{
+					for(i=1;i<=alp_number;i++)
+					{
+						delete (array_positive<double>*)alp_distr[i];alp_distr[i]=NULL;
+					};
+
+					delete[]alp_distr;alp_distr=NULL;
+				};
+
+				if(alp_distr_errors)
+				{
+					for(i=1;i<=alp_number;i++)
+					{
+						delete (array_positive<double>*)alp_distr_errors[i];alp_distr_errors[i]=NULL;
+					};
+
+					delete[]alp_distr_errors;alp_distr_errors=NULL;
+				};
+
+
+				M_min_flag=false;
+				nalp_flag=false;
+
+
+				alp_distr=NULL;
+				alp_distr_errors=NULL;
+
+				alp_number=0;
+
+				criterion_flag=false;
+				
+
+
+				for(i=ind1_;i<=ind2_;i++)
+				{
+					alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
+					delete alp_obj_tmp;alp_obj_tmp=NULL;
+
+				};
+
+				if(number_of_fails>number_of_fails_threshold)
+				{
+					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+				};
+
+				for(i=ind1_;i<=ind2_;i++)
+				{
+					alp *alp_obj_tmp;
+					alp_obj_tmp=new alp(d_alp_data);
+					alp_data::assert_mem(alp_obj_tmp);
+					d_alp_obj->set_elem(i,alp_obj_tmp);
+
+
+					alp_obj_tmp->d_check_time_flag=check_time_flag_;
+					alp_obj_tmp->d_time_error_flag=check_time_flag_;
+
+				};
+
+				continue;
+
+			};
+
+			if(criterion_flag)
+			{
+				add_alp_number_count++;
+				if(add_alp_number_count<add_alp_number)
+				{
+					criterion_flag=false;
+				};
+
+				if(criterion_flag)
+				{
+					criterion_flag=check_K_criterion(
+					alp_number,
+					ind1_,
+					ind2_,
+					lambda,
+					d_alp_data->d_eps_K,
+					M_min_);
+				};
+
+			}
+			else
+			{
+				add_alp_number_count=0;
+			};
+
+		}
+		while(!criterion_flag);
+
+		
+		//nalp_lambda_=alp_data::Tmax(nalp_lambda_equilibration,nalp_lambda_);
+		//nalp_lambda_=alp_data::Tmin(nalp_lambda_,nalp_);
+
+		nalp_lambda_=nalp_;
+
+	}
+	catch (...)
+	{ 
+		memory_release_for_get_minimal_simulation(
+		nalp_,
+		alp_distr,
+		alp_distr_errors);
+
+		throw;
+	};
+
+	memory_release_for_get_minimal_simulation(
+	nalp_,
+	alp_distr,
+	alp_distr_errors);
+
+}
+
+void alp_sim::memory_release_for_get_minimal_simulation(
+long int nalp_,
+void **&alp_distr,
+void **&alp_distr_errors)
+{
+	//memory release
+	if(alp_distr)
+	{
+		long int i;
+		for(i=1;i<=nalp_;i++)
+		{
+			delete (array_positive<double>*)alp_distr[i];alp_distr[i]=NULL;
+		};
+
+		delete[]alp_distr;alp_distr=NULL;
+	};
+
+	if(alp_distr_errors)
+	{
+		long int i;
+		for(i=1;i<=nalp_;i++)
+		{
+			delete (array_positive<double>*)alp_distr_errors[i];alp_distr_errors[i]=NULL;
+		};
+
+		delete[]alp_distr_errors;alp_distr_errors=NULL;
+	};
+
+}
+
+bool alp_sim::the_criterion(//criteria of stopping of the simulating ALP
+//if the function returns true then calculates optimal M_min and ALP number
+//sets the flags M_min_flag_ and nalp_flag_ checking the corresponding condition
+long int upto_nalp_,
+long int &nalp_for_lambda_simulation_,
+long int ind1_,
+long int ind2_,
+void **&alp_distr,
+void **&alp_distr_errors,
+long int &M_min_,
+bool &M_min_flag_,
+bool &nalp_flag_,
+bool &inside_simulation_flag_,
+bool C_calculation_,
+double *lambda_,
+double *lambda_error_)
+{
+
+	nalp_flag_=false;
+	M_min_flag_=false;
+
+	if(ind1_>ind2_)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+
+
+	double lambda=0;
+	double lambda_error=0;
+
+	double test_difference=0;
+	double test_difference_error=0;
+
+	long int nalp=upto_nalp_;
+
+	if(nalp<1)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+
+	get_and_allocate_alp_distribution(
+	ind1_,
+	ind2_,
+	alp_distr,
+	alp_distr_errors,
+	nalp);
+
+
+	calculate_lambda(
+	true,
+	upto_nalp_,
+	nalp_for_lambda_simulation_,
+	inside_simulation_flag_,
+	alp_distr,
+	alp_distr_errors,
+	lambda,
+	lambda_error,
+	test_difference,
+	test_difference_error);
+
+	if(!inside_simulation_flag_)
+	{
+		return false;
+	};
+
+
+	d_lambda_tmp->set_elem(upto_nalp_,lambda);
+	d_lambda_tmp_errors->set_elem(upto_nalp_,lambda_error);
+
+
+	if(C_calculation_)
+	{
+		double C;
+		double C_error;
+
+		double Sc;
+		double Sc_error;
+
+
+
+		calculate_C(
+		0,
+		upto_nalp_,
+		alp_distr,
+		alp_distr_errors,
+		lambda,
+		lambda_error,
+		C,
+		C_error,
+		Sc,
+		Sc_error);
+
+
+		d_C_tmp->set_elem(upto_nalp_,C);
+		d_C_tmp_errors->set_elem(upto_nalp_,C_error);
+
+	};
+
+
+	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	if(lambda_)
+	{
+		*lambda_=lambda;
+	};
+	if(lambda_error_)
+	{
+		*lambda_error_=lambda_error;
+	};
+
+
+	if(nalp>=1)
+	{
+
+		if(test_difference<=test_difference_error)
+		{
+			nalp_flag_=true;
+			/*
+			M_min_flag_=check_K_criterion(
+			nalp,
+			ind1_,
+			ind2_,
+			lambda,
+			d_alp_data->d_eps_K,
+			M_min_);
+			*/
+			M_min_=0;
+
+			//return M_min_flag_;
+			return true;
+		};
+	};
+
+
+	return false;
+}
+
+double alp_sim::lambda_exp(
+long int &i_,
+double *&exp_array_)
+{
+	if(exp_array_[i_]==-1)
+	{
+		throw error("The program is not able to calculate the parameters; rescaling penalties and scoring matrix might help\n",3);
+	};
+
+	return exp_array_[i_];
+}
+
+void alp_sim::memory_release_for_calculate_FSC(
+double *&exp_array,
+
+double *&delta_E,
+double *&delta_E_error,
+
+double *&delta_E_E,
+double *&delta_E_E_error,
+
+
+double *&delta_I,
+double *&delta_I_error,
+
+double *&delta_J,
+double *&delta_J_error,
+
+double *&delta_I_I,
+double *&delta_I_I_error,
+
+double *&delta_I_J,
+double *&delta_I_J_error,
+
+double *&delta_J_J,
+double *&delta_J_J_error,
+
+double *&cov_J_J,
+double *&cov_J_J_error,
+
+double *&cov_I_J,
+double *&cov_I_J_error,
+
+double *&cov_I_I,
+double *&cov_I_I_error,
+
+double *&cov_E_E,
+double *&cov_E_E_error)
+{
+	//memory release
+	delete[]exp_array;exp_array=NULL;
+
+	delete[]delta_E;delta_E=NULL;
+	delete[]delta_E_error;delta_E_error=NULL;
+	delete[]delta_E_E;delta_E_E=NULL;
+	delete[]delta_E_E_error;delta_E_E_error=NULL;
+
+	delete[]delta_I;delta_I=NULL;
+	delete[]delta_I_error;delta_I_error=NULL;
+	delete[]delta_J;delta_J=NULL;
+	delete[]delta_J_error;delta_J_error=NULL;
+
+	delete[]delta_I_J;delta_I_J=NULL;
+	delete[]delta_I_J_error;delta_I_J_error=NULL;
+	delete[]delta_J_J;delta_J_J=NULL;
+	delete[]delta_J_J_error;delta_J_J_error=NULL;
+	delete[]delta_I_I;delta_I_I=NULL;
+	delete[]delta_I_I_error;delta_I_I_error=NULL;
+
+	delete[]cov_I_J;cov_I_J=NULL;
+	delete[]cov_I_J_error;cov_I_J_error=NULL;
+	delete[]cov_J_J;cov_J_J=NULL;
+	delete[]cov_J_J_error;cov_J_J_error=NULL;
+	delete[]cov_I_I;cov_I_I=NULL;
+	delete[]cov_I_I_error;cov_I_I_error=NULL;
+
+	delete[]cov_E_E;cov_E_E=NULL;
+	delete[]cov_E_E_error;cov_E_E_error=NULL;
+
+}
+
+void alp_sim::calculate_FSC(
+long int nalp_,
+long int ind1_,
+long int ind2_,
+void **alp_distr,
+double lambda_,
+double Sc_,
+//double Sc_error_,
+double &a_I_,
+double &a_I_error_,
+double &a_J_,
+double &a_J_error_,
+double &sigma_,
+double &sigma_error_,
+double &alpha_I_,
+double &alpha_I_error_,
+double &alpha_J_,
+double &alpha_J_error_)
+{
+
+	double *exp_array=NULL;
+
+	double *delta_E=NULL;
+	double *delta_E_error=NULL;
+
+	double *delta_E_E=NULL;
+	double *delta_E_E_error=NULL;
+
+
+	double *delta_I=NULL;
+	double *delta_I_error=NULL;
+
+	double *delta_J=NULL;
+	double *delta_J_error=NULL;
+
+	double *delta_I_I=NULL;
+	double *delta_I_I_error=NULL;
+
+	double *delta_I_J=NULL;
+	double *delta_I_J_error=NULL;
+
+	double *delta_J_J=NULL;
+	double *delta_J_J_error=NULL;
+
+	double *cov_J_J=NULL;
+	double *cov_J_J_error=NULL;
+
+	double *cov_I_J=NULL;
+	double *cov_I_J_error=NULL;
+
+	double *cov_I_I=NULL;
+	double *cov_I_I_error=NULL;
+
+	double *cov_E_E=NULL;
+	double *cov_E_E_error=NULL;
+
+
+	try
+	{
+
+
+		if(nalp_<1)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+		array_positive<double>* tmp=((array_positive<double>*)alp_distr[nalp_]);
+		long int dim=tmp->d_dim;
+
+		exp_array=new double[dim+1];
+		alp_data::assert_mem(exp_array);
+
+
+		long int i;
+		for(i=0;i<=dim;i++)
+		{
+			double tmp=(double)i*lambda_;
+			if(tmp<dbl_max_log)
+			{
+				exp_array[i]=exp(tmp);
+			}
+			else
+			{
+				exp_array[i]=-1;
+			};
+		};
+
+		
+
+
+		delta_E=new double[nalp_];
+		alp_data::assert_mem(delta_E);
+		delta_E_error=new double[nalp_];
+		alp_data::assert_mem(delta_E_error);
+
+		delta_E_E=new double[nalp_];
+		alp_data::assert_mem(delta_E_E);
+		delta_E_E_error=new double[nalp_];
+		alp_data::assert_mem(delta_E_E_error);
+
+		cov_E_E=new double[nalp_];
+		alp_data::assert_mem(cov_E_E);
+		cov_E_E_error=new double[nalp_];
+		alp_data::assert_mem(cov_E_E_error);
+
+
+		delta_I=new double[nalp_];
+		alp_data::assert_mem(delta_I);
+		delta_I_error=new double[nalp_];
+		alp_data::assert_mem(delta_I_error);
+
+		delta_J=new double[nalp_];
+		alp_data::assert_mem(delta_J);
+		delta_J_error=new double[nalp_];
+		alp_data::assert_mem(delta_J_error);
+
+		delta_I_I=new double[nalp_];
+		alp_data::assert_mem(delta_I_I);
+		delta_I_I_error=new double[nalp_];
+		alp_data::assert_mem(delta_I_I_error);
+
+		delta_I_J=new double[nalp_];
+		alp_data::assert_mem(delta_I_J);
+		delta_I_J_error=new double[nalp_];
+		alp_data::assert_mem(delta_I_J_error);
+
+		delta_J_J=new double[nalp_];
+		alp_data::assert_mem(delta_J_J);
+		delta_J_J_error=new double[nalp_];
+		alp_data::assert_mem(delta_J_J_error);
+
+		cov_J_J=new double[nalp_];
+		alp_data::assert_mem(cov_J_J);
+		cov_J_J_error=new double[nalp_];
+		alp_data::assert_mem(cov_J_J_error);
+
+		cov_I_J=new double[nalp_];
+		alp_data::assert_mem(cov_I_J);
+		cov_I_J_error=new double[nalp_];
+		alp_data::assert_mem(cov_I_J_error);
+
+		cov_I_I=new double[nalp_];
+		alp_data::assert_mem(cov_I_I);
+		cov_I_I_error=new double[nalp_];
+		alp_data::assert_mem(cov_I_I_error);
+
+		long int j;
+		for(j=0;j<nalp_;j++)
+		{
+			delta_E[j]=0.0;
+			delta_E_error[j]=0.0;
+
+			delta_E_E[j]=0.0;
+			delta_E_E_error[j]=0.0;
+
+			delta_I[j]=0.0;
+			delta_I_error[j]=0.0;
+			delta_J[j]=0.0;
+			delta_J_error[j]=0.0;
+
+			delta_I_I[j]=0.0;
+
+			delta_I_I_error[j]=0.0;
+			delta_I_J[j]=0.0;
+			delta_I_J_error[j]=0.0;
+			delta_J_J[j]=0.0;
+			delta_J_J_error[j]=0.0;
+		};
+
+		double C_S_constant=1.0;
+
+		if(calculate_C_S_constant_flag)
+		{
+			if(Sc_>0)
+			{
+				C_S_constant=Sc_;
+			};
+		};
+
+		double one_div_C_S_constant=1.0/C_S_constant;
+		
+		
+		for(i=ind1_;i<=ind2_;i++)
+		{
+			alp* alp_obj_tmp=d_alp_obj->d_elem[i];
+
+			long int j;
+			for(j=1;j<=nalp_;j++)
+			{
+				long int j_1=j-1;
+
+				long int &E_j_1=alp_obj_tmp->d_alp->d_elem[j_1];
+				long int &E_j=alp_obj_tmp->d_alp->d_elem[j];
+				double &weight_j=alp_obj_tmp->d_alp_weights->d_elem[j];
+
+				long int &I_j_1=alp_obj_tmp->d_H_I->d_elem[j_1];
+				long int &I_j=alp_obj_tmp->d_H_I->d_elem[j];
+
+				long int &J_j_1=alp_obj_tmp->d_H_J->d_elem[j_1];
+				long int &J_j=alp_obj_tmp->d_H_J->d_elem[j];
+
+				double exp_tmp=lambda_exp(E_j,exp_array)*one_div_C_S_constant;
+
+				double delta_I_tmp=(I_j-I_j_1)*exp_tmp*weight_j;
+				double delta_J_tmp=(J_j-J_j_1)*exp_tmp*weight_j;
+				double delta_E_tmp=(E_j-E_j_1)*exp_tmp*weight_j;
+				double delta_E_E_tmp=(E_j-E_j_1)*(E_j-E_j_1)*exp_tmp*weight_j;
+
+				
+				double delta_I_I_tmp=delta_I_tmp*(I_j-I_j_1);
+				double delta_J_J_tmp=delta_J_tmp*(J_j-J_j_1);
+				double delta_I_J_tmp=delta_I_tmp*(J_j-J_j_1);
+
+	
+
+
+				delta_E[j_1]+=delta_E_tmp;
+				delta_E_error[j_1]+=delta_E_tmp*delta_E_tmp;
+
+				delta_E_E[j_1]+=delta_E_E_tmp;
+				delta_E_E_error[j_1]+=delta_E_E_tmp*delta_E_E_tmp;
+
+				delta_I[j_1]+=delta_I_tmp;
+				delta_I_error[j_1]+=delta_I_tmp*delta_I_tmp;
+				delta_J[j_1]+=delta_J_tmp;
+				delta_J_error[j_1]+=delta_J_tmp*delta_J_tmp;
+
+				delta_I_I[j_1]+=delta_I_I_tmp;
+				delta_I_I_error[j_1]+=delta_I_I_tmp*delta_I_I_tmp;
+
+				delta_I_J[j_1]+=delta_I_J_tmp;
+				delta_I_J_error[j_1]+=delta_I_J_tmp*delta_I_J_tmp;
+
+				delta_J_J[j_1]+=delta_J_J_tmp;
+				delta_J_J_error[j_1]+=delta_J_J_tmp*delta_J_J_tmp;
+				
+			};
+		};
+
+
+		double ind_diff=(double)(ind2_-ind1_+1);
+		for(j=0;j<nalp_;j++)
+		{
+			delta_E[j]/=ind_diff;
+			delta_E_error[j]/=ind_diff;
+			delta_E_error[j]-=delta_E[j]*delta_E[j];
+			delta_E_error[j]/=ind_diff;
+			delta_E_error[j]=alp_reg::sqrt_for_errors(delta_E_error[j]);
+
+			delta_E_E[j]/=ind_diff;
+			delta_E_E_error[j]/=ind_diff;
+			delta_E_E_error[j]-=delta_E_E[j]*delta_E_E[j];
+			delta_E_E_error[j]/=ind_diff;
+
+
+			delta_I[j]/=ind_diff;
+			delta_I_error[j]/=ind_diff;
+			delta_I_error[j]-=delta_I[j]*delta_I[j];
+			delta_I_error[j]/=ind_diff;
+			delta_I_error[j]=alp_reg::sqrt_for_errors(delta_I_error[j]);
+
+			delta_J[j]/=ind_diff;
+			delta_J_error[j]/=ind_diff;
+			delta_J_error[j]-=delta_J[j]*delta_J[j];
+			delta_J_error[j]/=ind_diff;
+			delta_J_error[j]=alp_reg::sqrt_for_errors(delta_J_error[j]);
+
+			delta_I_J[j]/=ind_diff;
+			delta_I_J_error[j]/=ind_diff;
+			delta_I_J_error[j]-=delta_I_J[j]*delta_I_J[j];
+			delta_I_J_error[j]/=ind_diff;
+
+
+			delta_I_I[j]/=ind_diff;
+			delta_I_I_error[j]/=ind_diff;
+			delta_I_I_error[j]-=delta_I_I[j]*delta_I_I[j];
+			delta_I_I_error[j]/=ind_diff;
+
+
+			delta_J_J[j]/=ind_diff;
+			delta_J_J_error[j]/=ind_diff;
+			delta_J_J_error[j]-=delta_J_J[j]*delta_J_J[j];
+			delta_J_J_error[j]/=ind_diff;
+
+
+			cov_I_J[j]=delta_I_J[j]-delta_I[j]*delta_J[j];
+			cov_I_I[j]=delta_I_I[j]-delta_I[j]*delta_I[j];
+			cov_J_J[j]=delta_J_J[j]-delta_J[j]*delta_J[j];
+
+			cov_E_E[j]=delta_E_E[j]-delta_E[j]*delta_E[j];
+
+			cov_I_J_error[j]=alp_data::error_of_the_product(delta_I[j],delta_I_error[j],delta_J[j],delta_J_error[j]);
+			cov_I_J_error[j]=alp_reg::sqrt_for_errors(delta_I_J_error[j]+cov_I_J_error[j]*cov_I_J_error[j]);
+
+			cov_I_I_error[j]=alp_data::error_of_the_product(delta_I[j],delta_I_error[j],delta_I[j],delta_I_error[j]);
+			cov_I_I_error[j]=alp_reg::sqrt_for_errors(delta_I_I_error[j]+cov_I_I_error[j]*cov_I_I_error[j]);
+
+			cov_J_J_error[j]=alp_data::error_of_the_product(delta_J[j],delta_J_error[j],delta_J[j],delta_J_error[j]);
+			cov_J_J_error[j]=alp_reg::sqrt_for_errors(delta_J_J_error[j]+cov_J_J_error[j]*cov_J_J_error[j]);
+
+			cov_E_E_error[j]=alp_data::error_of_the_product(delta_E[j],delta_E_error[j],delta_E[j],delta_E_error[j]);
+			cov_E_E_error[j]=alp_reg::sqrt_for_errors(delta_E_E_error[j]+cov_E_E_error[j]*cov_E_E_error[j]);
+
+		};
+
+
+		//regression
+
+		double beta1=0;
+		double beta1_error=0;
+
+		long int number_of_elements=nalp_;
+
+		bool cut_left_tail=true;
+		bool cut_right_tail=false;
+
+		double y=2;
+
+		long int k1_opt;
+		long int k2_opt;
+
+
+		double delta_I_aver;
+		double delta_I_aver_error;
+
+
+
+		bool res_was_calculated;
+		
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		delta_I,
+		delta_I_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		delta_I_aver,
+		beta1,
+		delta_I_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+
+
+		double delta_J_aver;
+		double delta_J_aver_error;
+
+		
+		
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		delta_J,
+		delta_J_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		delta_J_aver,
+		beta1,
+		delta_J_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+
+		double delta_E_aver;
+		double delta_E_aver_error;
+		
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		delta_E,
+		delta_E_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		delta_E_aver,
+		beta1,
+		delta_E_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+		double cov_I_I_aver;
+		double cov_I_I_aver_error;
+
+		double cov_I_J_aver;
+		double cov_I_J_aver_error;
+
+		double cov_J_J_aver;
+		double cov_J_J_aver_error;
+
+		double cov_E_E_aver;
+		double cov_E_E_aver_error;
+
+
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		cov_I_J,
+		cov_I_J_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		cov_I_J_aver,
+		beta1,
+		cov_I_J_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			//error
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		cov_I_I,
+		cov_I_I_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		cov_I_I_aver,
+		beta1,
+		cov_I_I_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		cov_J_J,
+		cov_J_J_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		cov_J_J_aver,
+		beta1,
+		cov_J_J_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		cov_E_E,
+		cov_E_E_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		cov_E_E_aver,
+		beta1,
+		cov_E_E_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+
+
+		if(delta_E_aver<=0)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+
+
+		a_I_=delta_I_aver/delta_E_aver;
+		a_I_error_=alp_data::error_of_the_ratio(delta_I_aver,delta_I_aver_error,delta_E_aver,delta_E_aver_error);
+		a_J_=delta_J_aver/delta_E_aver;
+		a_J_error_=alp_data::error_of_the_ratio(delta_J_aver,delta_J_aver_error,delta_E_aver,delta_E_aver_error);
+
+
+		sigma_calculation(
+		delta_I_aver,
+		delta_I_aver_error,
+		delta_J_aver,
+		delta_J_aver_error,
+		delta_E_aver,
+		delta_E_aver_error,
+		cov_E_E_aver,
+		cov_E_E_aver_error,
+		cov_I_J_aver,
+		cov_I_J_aver_error,
+		sigma_,
+		sigma_error_);
+
+
+		sigma_calculation(
+		delta_I_aver,
+		delta_I_aver_error,
+		delta_I_aver,
+		delta_I_aver_error,
+		delta_E_aver,
+		delta_E_aver_error,
+		cov_E_E_aver,
+		cov_E_E_aver_error,
+		cov_I_I_aver,
+		cov_I_I_aver_error,
+		alpha_I_,
+		alpha_I_error_);
+
+
+
+		sigma_calculation(
+		delta_J_aver,
+		delta_J_aver_error,
+		delta_J_aver,
+		delta_J_aver_error,
+		delta_E_aver,
+		delta_E_aver_error,
+		cov_E_E_aver,
+		cov_E_E_aver_error,
+		cov_J_J_aver,
+		cov_J_J_aver_error,
+		alpha_J_,
+		alpha_J_error_);
+
+		//if the estimates are negative, replace them by 0.0
+		a_I_=alp_data::Tmax(a_I_,0.0);
+		a_J_=alp_data::Tmax(a_J_,0.0);
+		sigma_=alp_data::Tmax(sigma_,0.0);
+		alpha_I_=alp_data::Tmax(alpha_I_,0.0);
+		alpha_J_=alp_data::Tmax(alpha_J_,0.0);
+
+
+	}
+	catch (...)
+	{ 
+		memory_release_for_calculate_FSC(
+		exp_array,
+
+		delta_E,
+		delta_E_error,
+
+		delta_E_E,
+		delta_E_E_error,
+
+
+		delta_I,
+		delta_I_error,
+
+		delta_J,
+		delta_J_error,
+
+		delta_I_I,
+		delta_I_I_error,
+
+		delta_I_J,
+		delta_I_J_error,
+
+		delta_J_J,
+		delta_J_J_error,
+
+		cov_J_J,
+		cov_J_J_error,
+
+		cov_I_J,
+		cov_I_J_error,
+
+		cov_I_I,
+		cov_I_I_error,
+
+		cov_E_E,
+		cov_E_E_error);
+		throw;
+	};
+
+
+	memory_release_for_calculate_FSC(
+	exp_array,
+
+	delta_E,
+	delta_E_error,
+
+	delta_E_E,
+	delta_E_E_error,
+
+
+	delta_I,
+	delta_I_error,
+
+	delta_J,
+	delta_J_error,
+
+	delta_I_I,
+	delta_I_I_error,
+
+	delta_I_J,
+	delta_I_J_error,
+
+	delta_J_J,
+	delta_J_J_error,
+
+	cov_J_J,
+	cov_J_J_error,
+
+	cov_I_J,
+	cov_I_J_error,
+
+	cov_I_I,
+	cov_I_I_error,
+
+	cov_E_E,
+	cov_E_E_error);
+
+}
+
+void alp_sim::sigma_calculation(
+double delta_I_aver_,
+double delta_I_aver_error_,
+double delta_J_aver_,
+double delta_J_aver_error_,
+double delta_E_aver_,
+double delta_E_aver_error_,
+double cov_E_E_aver_,
+double cov_E_E_aver_error_,
+double cov_I_J_aver_,
+double cov_I_J_aver_error_,
+double &sigma_,
+double &sigma_error_)
+{
+	double nom1_1=delta_I_aver_*delta_J_aver_;
+	double nom2_2=delta_E_aver_*delta_E_aver_;
+
+	double den=nom2_2*delta_E_aver_;
+
+	double nom1=nom1_1*cov_E_E_aver_;
+	double nom2=nom2_2*cov_I_J_aver_;
+
+	sigma_=(nom1+nom2)/den;
+
+	
+	double nom1_sigma_error=alp_data::error_of_the_product(delta_I_aver_,delta_I_aver_error_,delta_J_aver_,delta_J_aver_error_);
+	nom1_sigma_error=alp_data::error_of_the_product(nom1_1,nom1_sigma_error,cov_E_E_aver_,cov_E_E_aver_error_);
+
+	
+	double nom2_sigma_error_2=alp_data::error_of_the_product(delta_E_aver_,delta_E_aver_error_,delta_E_aver_,delta_E_aver_error_);
+	double nom2_sigma_error=alp_data::error_of_the_product(nom2_2,nom2_sigma_error_2,cov_I_J_aver_,cov_I_J_aver_error_);
+
+	
+	double den_sigma_error=alp_data::error_of_the_product(nom2_2,nom2_sigma_error_2,delta_E_aver_,delta_E_aver_error_);
+
+	double nom_sigma_error=alp_data::error_of_the_sum(nom1_sigma_error,nom2_sigma_error);
+
+	sigma_error_=alp_data::error_of_the_ratio(nom1+nom2,nom_sigma_error,den,den_sigma_error);
+
+}
+
+void alp_sim::calculate_C(
+long int starting_point,
+long int nalp_,
+void **alp_distr,
+void **alp_distr_errors,
+double lambda_,
+double lambda_error_,
+double &C_,
+double &C_error_,
+double &Sc_,
+double &Sc_error_)
+{
+
+	double *P=NULL;
+	double *P_errors=NULL;
+	double *values_P_ratio=NULL;
+	double *errors_P_ratio=NULL;
+
+	double *E=NULL;
+	double *E_errors=NULL;
+
+	double *E_T_beta=NULL;
+	double *E_T_beta_errors=NULL;
+
+
+	try
+	{
+
+		long int total_number_of_ALP=nalp_;
+
+		if(total_number_of_ALP<1)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+
+		//1)P(beta=infinity)
+		long int j;
+
+
+		P=new double[total_number_of_ALP+1];
+		alp_data::assert_mem(P);
+		P_errors=new double[total_number_of_ALP+1];
+		alp_data::assert_mem(P_errors);
+
+		P[0]=1.0;
+		P_errors[0]=0.0;
+
+		
+		for(j=1;j<=total_number_of_ALP;j++)
+		{
+			array_positive<double>* tmp=((array_positive<double>*)alp_distr[j]);
+			array_positive<double>* tmp_errors=((array_positive<double>*)alp_distr_errors[j]);
+
+			P[j]=0;
+			P_errors[j]=0;
+			long int i;
+			for(i=0;i<=tmp->d_dim;i++)
+			{
+				P[j]+=tmp->d_elem[i];
+				P_errors[j]+=tmp_errors->d_elem[i];
+			};
+
+			P_errors[j]=alp_reg::sqrt_for_errors(P_errors[j]);
+		};
+
+		
+
+		values_P_ratio=new double[total_number_of_ALP];
+		alp_data::assert_mem(values_P_ratio);
+		errors_P_ratio=new double[total_number_of_ALP];
+		alp_data::assert_mem(errors_P_ratio);
+
+		
+
+		for(j=0;j<total_number_of_ALP;j++)
+		{
+			values_P_ratio[j]=P[j+1]/P[j];
+			errors_P_ratio[j]=alp_data::error_of_the_ratio(P[j+1],P_errors[j+1],P[j],P_errors[j]);
+		};
+
+
+
+		double beta1=0;
+		double beta1_error=0;
+
+		long int number_of_elements=total_number_of_ALP;
+
+		bool cut_left_tail=true;
+		bool cut_right_tail=false;
+
+		double y=2;
+
+		long int k1_opt;
+		long int k2_opt;
+
+
+		double P_beta_inf;
+		double P_beta_inf_error=0;
+
+		bool res_was_calculated;
+		
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements-starting_point,
+		values_P_ratio+starting_point,
+		errors_P_ratio+starting_point,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		P_beta_inf,
+		beta1,
+		P_beta_inf_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+
+		
+
+		if(!res_was_calculated)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+		P_beta_inf=1-P_beta_inf;
+
+		
+		//2)E(exp(lambda*T_beta)) and E(T_beta*exp(lambda*T_beta))
+		E=new double[total_number_of_ALP+1];
+		alp_data::assert_mem(E);
+		E_errors=new double[total_number_of_ALP+1];
+		alp_data::assert_mem(E_errors);
+
+		E_T_beta=new double[total_number_of_ALP+1];
+		alp_data::assert_mem(E_T_beta);
+		E_T_beta_errors=new double[total_number_of_ALP+1];
+		alp_data::assert_mem(E_T_beta);
+
+
+		E[0]=1;
+		E_T_beta[0]=0;
+
+		E_errors[0]=0;
+		E_T_beta_errors[0]=0;
+
+		
+
+
+		for(j=1;j<=total_number_of_ALP;j++)
+		{
+			array_positive<double>* tmp=((array_positive<double>*)alp_distr[j]);
+			array_positive<double>* tmp_errors=((array_positive<double>*)alp_distr_errors[j]);
+
+			E[j]=0;
+			E_T_beta[j]=0;
+
+			E_errors[j]=0;
+			E_T_beta_errors[j]=0;
+
+			long int i;
+			for(i=0;i<=tmp->d_dim;i++)
+			{
+				double tmp_double=exp(lambda_*(double)i);
+				E[j]+=tmp_double*tmp->d_elem[i];
+				E_errors[j]+=tmp_double*tmp_double*tmp_errors->d_elem[i];
+
+				tmp_double=(double)i*exp(lambda_*(double)i);
+				E_T_beta[j]+=tmp_double*tmp->d_elem[i];
+				E_T_beta_errors[j]+=tmp_double*tmp_double*tmp_errors->d_elem[i];
+			};
+
+			E_errors[j]=alp_reg::sqrt_for_errors(E_errors[j]);
+			E_T_beta_errors[j]=alp_reg::sqrt_for_errors(E_T_beta_errors[j]);
+
+		};
+
+
+		double E_aver;
+		double E_aver_error;
+
+		double E_T_beta_diff_aver;
+		double E_T_beta_diff_aver_error;
+
+
+		if(total_number_of_ALP==1)
+		{
+			E_aver=E[1];
+			E_aver_error=E_errors[1];
+
+			E_T_beta_diff_aver=E_T_beta[1]-E_T_beta[0];
+			E_T_beta_diff_aver_error=E_T_beta_errors[1];
+
+		}
+		else
+		{
+			long int number_of_elements=total_number_of_ALP;
+
+			bool cut_left_tail=true;
+			bool cut_right_tail=false;
+
+
+			double beta0;
+			double beta1=0;
+			double beta0_error;
+			double beta1_error=0;
+
+			bool res_was_calculated;
+
+			alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+			0,
+			number_of_elements-starting_point,
+			E+1+starting_point,
+			E_errors+1+starting_point,
+			cut_left_tail,
+			cut_right_tail,
+			y,
+			E_aver,
+			beta1,
+			E_aver_error,
+			beta1_error,
+			k1_opt,
+			k2_opt,
+			res_was_calculated);
+
+
+			if(!res_was_calculated)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+
+
+			number_of_elements=total_number_of_ALP;
+
+
+			alp_reg::robust_regression_sum_with_cut_LSM(
+			0,
+			number_of_elements-starting_point,
+			E_T_beta+1+starting_point,
+			E_T_beta_errors+1+starting_point,
+			cut_left_tail,
+			cut_right_tail,
+			y,
+			beta0,
+			beta1,
+			beta0_error,
+			beta1_error,
+			k1_opt,
+			k2_opt,
+			res_was_calculated);
+
+			
+
+			if(!res_was_calculated)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+
+
+			E_T_beta_diff_aver=beta1;
+			E_T_beta_diff_aver_error=beta1_error;
+
+			
+			
+		};
+
+
+
+		double exp_lambda_error=exp(-lambda_)*lambda_error_;
+		double exp_lambda=(1-exp(-lambda_));
+
+		
+		double den_error=alp_data::error_of_the_product(E_T_beta_diff_aver,E_T_beta_diff_aver_error,exp_lambda,exp_lambda_error);
+		double den=(1-exp(-lambda_))*E_T_beta_diff_aver;
+
+
+		double nom;
+		double nom_error;
+
+		if(calculate_C_S_constant_flag)
+		{
+			Sc_error_=E_aver_error;
+			Sc_=E_aver;
+
+			nom_error=alp_data::error_of_the_product(P_beta_inf,P_beta_inf_error,E_aver,E_aver_error);
+			nom=P_beta_inf*E_aver;
+		}
+		else
+		{
+			double E_aver_sqr_error=alp_data::error_of_the_product(E_aver,E_aver_error,E_aver,E_aver_error);
+			double E_aver_sqr=E_aver*E_aver;
+
+			nom_error=alp_data::error_of_the_product(P_beta_inf,P_beta_inf_error,E_aver_sqr,E_aver_sqr_error);
+			nom=P_beta_inf*E_aver_sqr;
+
+		};
+
+		C_error_=alp_data::error_of_the_ratio(nom,nom_error,den,den_error);
+		C_=nom/den;
+
+
+
+
+	}
+	catch (...)
+	{ 
+		//memory release
+
+		delete[]values_P_ratio;values_P_ratio=NULL;
+		delete[]errors_P_ratio;errors_P_ratio=NULL;
+
+
+		delete[]P;P=NULL;
+		delete[]P_errors;P_errors=NULL;
+
+		delete[]E;E=NULL;
+		delete[]E_T_beta;E_T_beta=NULL;
+		delete[]E_errors;E_errors=NULL;
+		delete[]E_T_beta_errors;E_T_beta_errors=NULL;
+		throw;
+
+	};
+
+	//memory release
+
+	delete[]values_P_ratio;values_P_ratio=NULL;
+	delete[]errors_P_ratio;errors_P_ratio=NULL;
+
+
+	delete[]P;P=NULL;
+	delete[]P_errors;P_errors=NULL;
+
+	delete[]E;E=NULL;
+	delete[]E_T_beta;E_T_beta=NULL;
+	delete[]E_errors;E_errors=NULL;
+	delete[]E_T_beta_errors;E_T_beta_errors=NULL;
+
+
+}
+
+void alp_sim::get_and_allocate_alp_distribution(
+long int ind1_,
+long int ind2_,
+void **&alp_distr,
+void **&alp_distr_errors,
+long int nalp)
+{
+	if(nalp<=0)
+	{
+		if(nalp<0)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+		alp_distr=NULL;
+		alp_distr_errors=NULL;
+
+		return;
+	};
+
+	void **alp_distr_tmp=NULL;
+	void **alp_distr_errors_tmp=NULL;
+
+	long int allocation_dim=nalp;
+	long int allocation_dim_tmp=nalp+1;
+
+	try
+	{
+
+
+		long int i;
+		alp_distr_tmp=new void*[nalp+1];
+		alp_data::assert_mem(alp_distr_tmp);
+
+		alp_distr_errors_tmp=new void*[nalp+1];
+		alp_data::assert_mem(alp_distr_errors_tmp);
+
+		for(i=0;i<=nalp;i++)
+		{
+			alp_distr_tmp[i]=NULL;
+			alp_distr_errors_tmp[i]=NULL;
+		};
+
+
+		for(i=1;i<=nalp-1;i++)
+		{
+			alp_distr_tmp[i]=alp_distr[i];
+			alp_distr_errors_tmp[i]=alp_distr_errors[i];
+		};
+
+		delete[]alp_distr;alp_distr=NULL;
+		delete[]alp_distr_errors;alp_distr_errors=NULL;
+
+		alp_distr=alp_distr_tmp;alp_distr_tmp=NULL;
+		alp_distr_errors=alp_distr_errors_tmp;alp_distr_errors_tmp=NULL;
+
+		allocation_dim=nalp+1;
+
+		
+
+		alp_distr[nalp]=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(alp_distr[nalp]);
+
+		alp_distr_errors[nalp]=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(alp_distr_errors[nalp]);
+
+
+
+		for(i=ind1_;i<=ind2_;i++)
+		{
+			alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
+			long int k=nalp;
+			long int &alp_tmp=alp_obj_tmp->d_alp->d_elem[k];
+			double &weight_tmp=alp_obj_tmp->d_alp_weights->d_elem[k];
+
+
+			((array_positive<double>*)alp_distr[k])->increase_elem_by_x(alp_tmp,weight_tmp);
+			((array_positive<double>*)alp_distr_errors[k])->increase_elem_by_x(alp_tmp,weight_tmp*weight_tmp);
+		};
+
+		double ind_diff=(double)(ind2_-ind1_+1);
+		long int k=nalp;
+		array_positive<double>* tmp=((array_positive<double>*)alp_distr[k]);
+		array_positive<double>* tmp_errors=((array_positive<double>*)alp_distr_errors[k]);
+		long int j;
+		for(j=0;j<=tmp->d_dim;j++)
+		{
+			tmp->d_elem[j]/=ind_diff;
+			tmp_errors->d_elem[j]/=ind_diff;
+			tmp_errors->d_elem[j]-=tmp->d_elem[j]*tmp->d_elem[j];
+			tmp_errors->d_elem[j]/=ind_diff;
+		};
+	}
+
+	catch (...)
+	{ 
+		long int i;
+		if(alp_distr_tmp)
+		{
+			for(i=0;i<=allocation_dim_tmp;i++)
+			{
+				delete (array_positive<double>*)alp_distr_tmp[i];alp_distr_tmp[i]=NULL;
+			};
+			delete []alp_distr_tmp;alp_distr_tmp=NULL;
+		};
+
+		if(alp_distr_errors_tmp)
+		{
+			for(i=0;i<=allocation_dim_tmp;i++)
+			{
+				delete (array_positive<double>*)alp_distr_errors_tmp[i];alp_distr_errors_tmp[i]=NULL;
+			};
+			delete []alp_distr_errors_tmp;alp_distr_errors_tmp=NULL;
+		};
+
+		if(alp_distr)
+		{
+			for(i=0;i<=allocation_dim;i++)
+			{
+				delete (array_positive<double>*)alp_distr[i];alp_distr[i]=NULL;
+			};
+			delete []alp_distr;alp_distr=NULL;
+		};
+
+		if(alp_distr_errors)
+		{
+			for(i=0;i<=allocation_dim;i++)
+			{
+				delete (array_positive<double>*)alp_distr_errors[i];alp_distr_errors[i]=NULL;
+			};
+			delete []alp_distr_errors;alp_distr_errors=NULL;
+		};
+
+		throw;
+	};
+
+
+
+}
+
+bool alp_sim::check_K_criterion(
+long int nalp_,
+long int ind1_,
+long int ind2_,
+double lambda_,
+double eps_K_,
+long int &M_min_)
+{
+	if(nalp_<=0)
+	{
+		throw error("Unexpected error\n",4);
+	};
+	array_positive<double>* diff=NULL;
+
+	try
+	{
+
+		diff=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(diff);
+
+		double sum_of_weights=0;
+		double M_aver=0;
+
+		long int i;
+		for(i=ind1_;i<=ind2_;i++)
+		{
+			alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
+			long int &alp_tmp=alp_obj_tmp->d_alp->d_elem[nalp_];
+			double &weight_tmp=alp_obj_tmp->d_alp_weights->d_elem[nalp_];
+			sum_of_weights+=weight_tmp;
+			M_aver+=alp_tmp*weight_tmp;
+
+			array<long int> *cells_counts=alp_obj_tmp->d_cells_counts;
+
+			long int k;
+			for(k=cells_counts->d_ind0;k<=alp_data::Tmin(alp_tmp,cells_counts->d_dim_plus_d_ind0);k++)
+			{
+				diff->increase_elem_by_x(alp_tmp-k,cells_counts->d_elem[k-cells_counts->d_ind0]*weight_tmp);
+			};
+		};
+
+
+
+		double den=0;
+		for(i=0;i<=diff->d_dim;i++)
+		{
+			den+=exp(-lambda_*(double)i)*diff->d_elem[i];
+		};
+
+
+		if(den<=0||sum_of_weights<=0)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+
+		M_aver/=sum_of_weights;
+
+
+		double delta_val=den*eps_K_*(1-exp(-lambda_));
+
+		long int diff_opt=1;;
+		for(i=diff->d_dim;i>=0;i--)
+		{
+			if(exp(-lambda_*(double)i)*diff->d_elem[i]>delta_val)
+			{
+				diff_opt=i+1;
+				break;
+			};
+		};
+
+		
+
+
+		M_min_=(long int)alp_data::round(M_aver);
+
+
+		delete diff;diff=NULL;
+		if(M_aver<diff_opt)
+		{
+			return false;
+		};
+		
+		return true;
+	}
+	catch (...)
+	{ 
+		delete diff;diff=NULL;
+		throw;
+	};
+
+}
+
+bool alp_sim::check_K_criterion_during_killing(
+long int ind1_,
+long int ind2_,
+double lambda_,
+double eps_K_,
+long int current_level_,
+long int &recommended_level_,
+long int &diff_opt_,
+double &K_C_,
+double &K_C_error_)
+{
+	if(ind1_>ind2_)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+	array_positive<double>* diff=NULL;
+	array_positive<double>* diff_error=NULL;
+
+	try
+	{
+
+		diff=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(diff);
+
+		diff_error=new array_positive<double>(d_alp_data);
+		alp_data::assert_mem(diff_error);
+
+
+		double sum_of_weights=0;
+		double sum_of_weights_error=0;
+
+		double M_aver=0;
+
+		long int i;
+		for(i=ind1_;i<=ind2_;i++)
+		{
+			alp* &alp_obj_tmp=d_alp_obj->d_elem[i];
+			long int &alp_tmp=alp_obj_tmp->d_M;
+			double &weight_tmp=alp_obj_tmp->d_alp_weights->d_elem[alp_obj_tmp->d_nalp_killing];
+			sum_of_weights+=weight_tmp;
+			sum_of_weights_error+=weight_tmp*weight_tmp;
+			M_aver+=alp_tmp*weight_tmp;
+
+
+			array<long int> *cells_counts=alp_obj_tmp->d_cells_counts;
+
+			long int k;
+			for(k=cells_counts->d_ind0;k<=alp_data::Tmin(alp_tmp,cells_counts->d_dim_plus_d_ind0);k++)
+			{
+				double tmp=cells_counts->d_elem[k-cells_counts->d_ind0]*weight_tmp;
+				diff->increase_elem_by_x(alp_tmp-k,tmp);
+				diff_error->increase_elem_by_x(alp_tmp-k,tmp*tmp);
+			};
+		};
+
+
+
+		double tmp2=(double)(ind2_-ind1_+1);
+
+		sum_of_weights/=tmp2;
+		sum_of_weights_error/=tmp2;
+		sum_of_weights_error-=sum_of_weights*sum_of_weights;
+		sum_of_weights_error/=tmp2;
+		sum_of_weights_error=alp_reg::sqrt_for_errors(sum_of_weights_error);
+
+
+		
+		for(i=0;i<=diff->d_dim;i++)
+		{
+			diff->d_elem[i]/=tmp2;
+			diff_error->d_elem[i]/=tmp2;
+			diff_error->d_elem[i]-=diff->d_elem[i]*diff->d_elem[i];
+			diff_error->d_elem[i]/=tmp2;
+		};
+
+
+
+		double den=0;
+		double den_error=0;
+		for(i=0;i<=diff->d_dim;i++)
+		{
+			double tmp=exp(-lambda_*(double)i);
+			den+=tmp*diff->d_elem[i];
+			den_error+=tmp*tmp*diff_error->d_elem[i];
+
+		};
+
+
+
+		den_error=alp_reg::sqrt_for_errors(den_error);
+
+
+		if(den<=0||sum_of_weights<=0)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+		K_C_=sum_of_weights/den;
+		K_C_error_=alp_data::error_of_the_ratio(sum_of_weights,sum_of_weights_error,den,den_error);
+
+
+		M_aver/=tmp2;
+		M_aver/=sum_of_weights;
+
+
+		double delta_val=den*eps_K_*(1-exp(-lambda_));
+
+		long int diff_opt=1;;
+		for(i=diff->d_dim;i>=0;i--)
+		{
+			if(exp(-lambda_*(double)i)*diff->d_elem[i]>delta_val)
+			{
+				diff_opt=i+1;
+				break;
+			};
+		};
+
+		delete diff;diff=NULL;
+		delete diff_error;diff_error=NULL;
+
+		if(M_aver-diff_opt<current_level_)
+		{
+			recommended_level_=(long int)floor(M_aver-diff_opt*1.1);
+			diff_opt_=(long int)ceil(M_aver-recommended_level_);
+			return false;
+		};
+		recommended_level_=current_level_;
+		diff_opt_=(long int)ceil(M_aver-recommended_level_);
+		return true;
+	}
+	catch (...)
+	{ 
+		delete diff;diff=NULL;
+		delete diff_error;diff_error=NULL;
+		throw;
+	};
+
+}
+
+void alp_sim::calculate_lambda(
+bool check_the_criteria_,
+long int nalp_,
+long int &nalp_thr_,
+bool &inside_simulation_flag_,
+void **alp_distr,
+void **alp_distr_errors,
+double &lambda_,
+double &lambda_error_,
+double &test_difference_,
+double &test_difference_error_)
+{
+	long int nalp=nalp_;
+
+	if(nalp<=0)
+	{
+		throw error("Unexpected error\n",4);
+	};
+
+	
+
+	struct_for_lambda_calculation tmp_struct;
+	tmp_struct.d_alp_distr=alp_distr;
+	tmp_struct.d_alp_distr_errors=alp_distr_errors;
+	tmp_struct.d_nalp=nalp;
+	tmp_struct.d_calculate_alp_number=false;
+
+
+	function_type *func=function_for_lambda_calculation;
+	void* func_pointer=&tmp_struct;
+	double a=0;
+	//double b=d_alp_data->d_is->d_lambda*3;
+	double b=d_alp_data->d_is->d_lambda*2;
+	long int n_partition=30;
+	double eps=1e-10;
+	std::vector<double> res;
+
+
+
+	alp_reg::find_tetta_general(
+	func,
+	func_pointer,
+	a,//[a,b] is the interval for search of equation solution
+	b,
+	n_partition,
+	eps,
+	res);
+
+	
+
+
+	inside_simulation_flag_=true;
+	if(res.size()==0)
+	{
+		inside_simulation_flag_=false;
+		return;
+	};
+
+	
+
+	lambda_=get_root(res,d_alp_data->d_is->d_lambda);
+	
+
+	tmp_struct.d_calculate_alp_number=true;
+	double f1=func(lambda_,func_pointer);//cout<<ind1_<<"\t"<<ind2_<<"\t"<<tmp_struct.d_last_sum<<"\t"<<tmp_struct.d_last_sum_error<<endl;
+	nalp_thr_=tmp_struct.d_alp_number;
+	tmp_struct.d_calculate_alp_number=false;
+
+	double slope_error=tmp_struct.d_f_error;
+
+
+	double sum1=tmp_struct.d_last_sum;
+	double sum1_error=tmp_struct.d_last_sum_error;
+
+	double delta_lambda=lambda_/100.0;
+	double f2=func(lambda_+delta_lambda,func_pointer);
+	
+	
+
+	if(delta_lambda==0||f1==f2)
+	{
+		lambda_error_=0.0;
+	}
+	else
+	{
+		double derivative=(f2-f1)/delta_lambda;
+		lambda_error_=fabs(slope_error/derivative);
+	};
+	
+	if(!check_the_criteria_)
+	{
+		return;
+	};
+
+	if(nalp>1)
+	{
+		func(d_lambda_tmp->d_elem[nalp-1],func_pointer);
+	}
+	else
+	{
+		func(d_alp_data->d_is->d_ungap_lambda,func_pointer);
+	};
+
+	
+	
+	double sum2=tmp_struct.d_last_sum;
+	double sum2_error=tmp_struct.d_last_sum_error;
+
+	
+
+	double max_sum=alp_data::Tmax(fabs(sum1),fabs(sum2));
+
+	if(max_sum!=0)
+	{
+		test_difference_=fabs((sum1-sum2)/max_sum);
+		test_difference_error_=0.5*(sum1_error+sum2_error)/max_sum;
+	}
+	else
+	{
+		test_difference_=-1;
+		test_difference_error_=0;
+	};
+
+}
+
+double alp_sim::get_root(
+const std::vector<double> &res_tmp_,
+double point_)
+{
+	if(res_tmp_.size()==0)
+	{
+		//throw error("Error in alp_sim::get_root - the equation does not have roots\n",2);
+		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+	};
+
+	long int i;
+	long int p=0;
+	double d1=fabs(point_-res_tmp_[0]);
+	for(i=1;i<(long int)res_tmp_.size();i++)
+	{
+		double d2=fabs(point_-res_tmp_[i]);
+		if(d2<d1)
+		{
+			p=i;
+			d1=d2;
+		};
+	};
+
+	return res_tmp_[p];
+}
+
+double alp_sim::function_for_lambda_calculation(
+double lambda_,
+void * data_)
+{
+
+	double *expect=NULL;
+	double *expect_errors=NULL;
+
+	try
+	{
+
+		struct_for_lambda_calculation *tmp_struct=(struct_for_lambda_calculation *)data_;
+		void **alp_distr=tmp_struct->d_alp_distr;
+		void **alp_distr_errors=tmp_struct->d_alp_distr_errors;
+		long int nalp=tmp_struct->d_nalp;
+
+		expect=new double[nalp];
+		alp_data::assert_mem(expect);
+		expect_errors=new double[nalp];
+		alp_data::assert_mem(expect_errors);
+
+		if(nalp<1)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+
+
+		long int k;
+		for(k=1;k<=nalp;k++)
+		{
+			array_positive<double>* tmp=((array_positive<double>*)alp_distr[k]);
+			array_positive<double>* tmp_errors=((array_positive<double>*)alp_distr_errors[k]);
+
+			double val=0;
+			double val_error=0;
+
+			long int j;
+			for(j=0;j<=tmp->d_dim;j++)
+			{
+				if(tmp->d_elem[j]<=0)
+				{
+					continue;
+				};
+				double exp_tmp=exp(lambda_*j);
+				val+=exp_tmp*tmp->d_elem[j];
+				val_error+=exp_tmp*exp_tmp*tmp_errors->d_elem[j];
+			};
+			val_error=alp_reg::sqrt_for_errors(val_error);
+			expect[k-1]=val;
+			expect_errors[k-1]=val_error;
+
+
+		};
+
+		tmp_struct->d_last_sum=expect[nalp-1];
+		tmp_struct->d_last_sum_error=expect_errors[nalp-1];
+
+		if(tmp_struct->d_calculate_alp_number)
+		{
+			double tmp=0.0;
+			long int k;
+			for(k=0;k<nalp;k++)
+			{
+				if(expect_errors[k]!=0)
+				{
+					tmp+=1.0/(expect_errors[k]*expect_errors[k]);
+				};
+
+			};
+
+			long int tmp_alp=nalp;
+			double tmp1=0.0;
+			for(k=nalp-1;k>=0;k--)
+			{
+				if(expect_errors[k]!=0)
+				{
+					tmp1+=1.0/(expect_errors[k]*expect_errors[k]);
+				};
+				if(tmp1>0.2*tmp)
+				{
+					tmp_alp=k+1;
+					break;
+				};
+			};
+
+			tmp_struct->d_alp_number=tmp_alp;
+		};
+
+		if(nalp==1)
+		{
+			double tmp=expect[0]-1.0;
+			tmp_struct->d_f_error=expect_errors[0];
+			delete[]expect;expect=NULL;
+			delete[]expect_errors;expect_errors=NULL;
+			return tmp;
+		};
+
+
+		long int min_length=0;
+		long int number_of_elements=nalp;
+		bool cut_left_tail=true;
+		bool cut_right_tail=false;
+		double y=2;
+		double beta0;
+		double beta1;
+		double beta0_error;
+		double beta1_error;
+		long int k1_opt;
+		long int k2_opt;
+
+		bool res_was_calculated;
+
+		alp_reg::robust_regression_sum_with_cut_LSM(
+		min_length,
+		number_of_elements,
+		expect,
+		expect_errors,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		beta0,
+		beta1,
+		beta0_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+
+		delete[]expect;expect=NULL;
+		delete[]expect_errors;expect_errors=NULL;
+
+		tmp_struct->d_f_error=beta1_error;
+		return beta1;
+
+	}
+	catch (...)
+	{ 
+		delete[]expect;expect=NULL;
+		delete[]expect_errors;expect_errors=NULL;
+		throw;
+	};
+
+}
+
diff --git a/src/alp/sls_alp_sim.hpp b/src/alp/sls_alp_sim.hpp
index 527fd73..f6b3404 100644
--- a/src/alp/sls_alp_sim.hpp
+++ b/src/alp/sls_alp_sim.hpp
@@ -1,579 +1,579 @@
-#ifndef INCLUDED_SLS_ALP_SIMULATION
-#define INCLUDED_SLS_ALP_SIMULATION
-
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_alp_sim.hpp
-
-Author: Sergey Sheetlin
-
-Contents: Simulation of Gumbel parameters
-
-******************************************************************************/
-
-
-#include <complex>
-#include <iostream>
-#include <map>
-#include <vector>
-#include <fstream>
-#include <float.h>
-#include <algorithm>
-
-#include "sls_alp_data.hpp"
-#include "sls_alp.hpp"
-#include "sls_alp_regression.hpp"
-
-namespace Sls {
-
-	struct struct_for_lambda_calculation
-	{
-		void **d_alp_distr;
-		void **d_alp_distr_errors;
-		long int d_nalp;
-		double d_f_error;
-
-		double d_last_sum;
-		double d_last_sum_error;
-
-		bool d_calculate_alp_number;
-		long int d_alp_number;
-	};
-
-
-
-
-	class alp_sim{
-
-	
-
-	public:
-
-
-		alp_sim(//constructor
-			alp_data *alp_data_
-			);
-
-
-		~alp_sim();//destructor
-
-		void alp_sim_from_random_seed(//simulation from random seed
-		alp_data *alp_data_);
-
-		void quick_test(//runs quick tests to determine whether the scoring scheme is linear
-		long int trials_number_,
-		double max_time_);
-
-		void get_minimal_simulation(
-		long int ind1_,
-		long int ind2_,
-		long int &M_min_,
-		long int &nalp_,
-		long int &nalp_lambda_,
-		bool C_calculation_,
-		bool check_time_flag_);//simulation using [ind1_,ind2_] range of realizations with an estimation of parameters for accuracy, memory usage and calculation time
-
-
-		void memory_release_for_get_minimal_simulation(
-		long int nalp_,
-		void **&alp_distr,
-		void **&alp_distr_errors);
-
-		bool the_criterion(//criteria of stopping of the simulating ALP
-		//if the function returns true then calculates optimal M_min and ALP number
-		//sets the flags M_min_flag_ and nalp_flag_ checking the corresponding condition
-		long int upto_nalp_,
-		long int &nalp_for_lambda_simulation_,
-		long int ind1_,
-		long int ind2_,
-		void **&alp_distr,
-		void **&alp_distr_errors,
-		long int &M_min_,
-		bool &M_min_flag_,
-		bool &nalp_flag_,
-		bool &inside_simulation_flag_,
-		bool C_calculation_,
-		double *lambda_=NULL,
-		double *lambda_error_=NULL);
-
-		void calculate_lambda(
-		bool check_the_criteria_,
-		long int nalp_,
-		long int &nalp_thr_,
-		bool &inside_simulation_flag_,
-		void **alp_distr,
-		void **alp_distr_errors,
-		double &lambda_,
-		double &lambda_error_,
-		double &test_difference_,
-		double &test_difference_error_);
-
-		void calculate_C(
-		long int starting_point,
-		long int nalp_,
-		void **alp_distr,
-		void **alp_distr_errors,
-		double lambda_,
-		double lambda_error_,
-		double &C_,
-		double &C_error_,
-		double &Sc_,
-		double &Sc_error_);
-
-		void memory_release_for_calculate_FSC(
-		double *&exp_array,
-
-		double *&delta_E,
-		double *&delta_E_error,
-
-		double *&delta_E_E,
-		double *&delta_E_E_error,
-
-
-		double *&delta_I,
-		double *&delta_I_error,
-
-		double *&delta_J,
-		double *&delta_J_error,
-
-		double *&delta_I_I,
-		double *&delta_I_I_error,
-
-		double *&delta_I_J,
-		double *&delta_I_J_error,
-
-		double *&delta_J_J,
-		double *&delta_J_J_error,
-
-		double *&cov_J_J,
-		double *&cov_J_J_error,
-
-		double *&cov_I_J,
-		double *&cov_I_J_error,
-
-		double *&cov_I_I,
-		double *&cov_I_I_error,
-
-		double *&cov_E_E,
-		double *&cov_E_E_error);
-
-
-		void calculate_FSC(
-		long int nalp_,
-		long int ind1_,
-		long int ind2_,
-		void **alp_distr,
-		double lambda_,
-		double Sc_,
-		//double Sc_error_,
-
-		double &a_I_,
-		double &a_I_error_,
-		double &a_J_,
-		double &a_J_error_,
-		double &sigma_,
-		double &sigma_error_,
-		double &alpha_I_,
-		double &alpha_I_error_,
-		double &alpha_J_,
-		double &alpha_J_error_);
-
-		void sigma_calculation(
-		double delta_I_aver_,
-		double delta_I_aver_error_,
-		double delta_J_aver_,
-		double delta_J_aver_error_,
-		double delta_E_aver_,
-		double delta_E_aver_error_,
-		double cov_E_E_aver_,
-		double cov_E_E_aver_error_,
-		double cov_I_J_aver_,
-		double cov_I_J_aver_error_,
-		double &sigma_,
-		double &sigma_error_);
-
-		void get_and_allocate_alp_distribution(
-		long int ind1_,
-		long int ind2_,
-		void **&alp_distr,
-		void **&alp_distr_errors,
-		long int nalp);
-
-		bool check_K_criterion(
-		long int nalp_,
-		long int ind1_,
-		long int ind2_,
-		double lambda_,
-		double eps_K_,
-		long int &M_min_);
-
-		void kill(
-		bool check_time_,
-		long int ind1_,
-		long int ind2_,
-		long int M_min_,
-		double lambda_,
-		double eps_K_,
-		double &K_C_,
-		double &K_C_error_,
-		long int &level_,
-		long int &diff_opt_);
-
-
-		
-		bool check_K_criterion_during_killing2(
-		long int ind1_,
-		long int ind2_,
-		double lambda_,
-		double eps_K_,
-		long int current_level_,
-		long int &recommended_level_,
-		long int &diff_opt_,
-		double &K_C_,
-		double &K_C_error_);
-		
-
-		bool check_K_criterion_during_killing(
-		long int ind1_,
-		long int ind2_,
-		double lambda_,
-		double eps_K_,
-		long int current_level_,
-		long int &recommended_level_,
-		long int &diff_opt_,
-		double &K_C_,
-		double &K_C_error_);
-
-
-
-
-		inline static double lambda_exp(
-		long int &i_,
-		double *&exp_array_);
-
-		void get_single_realization(
-		bool check_time_,
-		long int M_min_,
-		long int nalp_,
-		bool killing_flag_,
-		long int level_,
-		long int diff_opt_,
-		alp *&obj_,
-		bool &sucess_flag_,
-		double &d_eps_);
-
-		void calculate_main_parameters(
-		long int final_realizations_number_lambda_,
-		long int final_realizations_number_killing_,
-		long int nalp,
-		long int nalp_for_lambda_simulation,
-		long int level,
-		bool &inside_simulation_flag,
-		double &lambda,
-		double &lambda_error,
-		double &test_difference,
-		double &test_difference_error,
-		double &C,
-		double &C_error,
-		double &C2,
-		double &C2_error,
-		double &C4,
-		double &C4_error,
-		double &K_C,
-		double &K_C_error,
-		double &a_I,
-		double &a_I_error,
-		double &a_J,
-		double &a_J_error,
-		double &sigma,
-		double &sigma_error,
-		double &alpha_I,
-		double &alpha_I_error,
-		double &alpha_J,
-		double &alpha_J_error,
-		double &K,
-		double &K_error);
-
-		void calculate_main_parameters2(
-		long int final_realizations_number_lambda_,
-		long int final_realizations_number_killing_,
-		long int nalp,
-		long int nalp_for_lambda_simulation,
-		long int level,
-		bool &inside_simulation_flag,
-		double &lambda,
-		double &lambda_error,
-		double &test_difference,
-		double &test_difference_error,
-		double &C,
-		double &C_error,
-		double &C2,
-		double &C2_error,
-		double &C4,
-		double &C4_error,
-		double &K_C,
-		double &K_C_error,
-		double &a_I,
-		double &a_I_error,
-		double &a_J,
-		double &a_J_error,
-		double &sigma,
-		double &sigma_error,
-		double &alpha_I,
-		double &alpha_I_error,
-		double &alpha_J,
-		double &alpha_J_error,
-		double &K,
-		double &K_error);
-
-		void memory_release_for_calculate_main_parameters2m(
-		long int nalp_for_lambda_simulation,
-		long int *&d_mult_realizations,
-		long int *&d_mult_K_realizations,
-
-		double *&lambda_mult,
-		double *&lambda_mult_error,
-
-		double *&C_mult,
-		double *&C_mult_error,
-
-		double *&a_I_mult,
-		double *&a_I_mult_error,
-
-		double *&a_J_mult,
-		double *&a_J_mult_error,
-
-		double *&sigma_mult,
-		double *&sigma_mult_error,
-
-		double *&alpha_I_mult,
-		double *&alpha_I_mult_error,
-
-		double *&alpha_J_mult,
-		double *&alpha_J_mult_error,
-
-		double *&K_C_mult,
-		double *&K_C_mult_error,
-
-		double *&K_mult,
-		double *&K_mult_error,
-
-		double *&Sc_mult,
-		double *&Sc_mult_error,
-
-
-		void **&alp_distr,
-		void **&alp_distr_errors,
-
-		void ***&alp_mult_distr,
-		void ***&alp_mult_distr_errors);
-
-		void calculate_main_parameters2m(
-		long int final_realizations_number_lambda_,
-		long int final_realizations_number_killing_,
-		long int nalp_for_lambda_simulation,
-		long int level,
-		bool &inside_simulation_flag,
-		double &lambda,
-		double &lambda_error,
-		double &test_difference,
-		double &test_difference_error,
-		double &C,
-		double &C_error,
-		double &K_C,
-		double &K_C_error,
-		double &a_I,
-		double &a_I_error,
-		double &a_J,
-		double &a_J_error,
-		double &sigma,
-		double &sigma_error,
-		double &alpha_I,
-		double &alpha_I_error,
-		double &alpha_J,
-		double &alpha_J_error,
-		double &K,
-		double &K_error,
-		bool &flag_);
-
-		void randomize_realizations(
-		long int final_realizations_number_lambda_,
-		long int final_realizations_number_killing_);
-
-		void randomize_realizations_ind(
-		long int ind1_,
-		long int ind2_);
-
-		void generate_random_permulation(
-		long int *perm_,
-		long int dim_);
-
-
-
-
-		static void error_in_calculate_main_parameters2m(
-		double C,
-		double &C_error,
-		double C_mult2,
-		double C_mult2_error);
-
-
-
-
-		void output_main_parameters(
-		double time_,
-		long int nalp,
-		long int nalp_for_lambda_simulation,
-		long int level,
-		long int M_min_,
-		bool &inside_simulation_flag,
-		long int final_realizations_number_lambda_,
-		long int final_realizations_number_killing_);
-
-		void output_main_parameters2(
-		double time_,
-		long int nalp,
-		long int nalp_for_lambda_simulation,
-		long int level,
-		long int M_min_,
-		bool &inside_simulation_flag,
-		long int final_realizations_number_lambda_,
-		long int final_realizations_number_killing_);
-
-		void output_main_parameters2m_new(
-		long int nalp_for_lambda_simulation,
-		long int level,
-		bool &inside_simulation_flag,
-		long int final_realizations_number_lambda_,
-		long int final_realizations_number_killing_);
-
-		void symmetric_parameters_for_symmetric_scheme();
-
-
-
-
-		static double relative_error_in_percents(
-		double val_,
-		double val_error_);
-
-		static double round_double(
-		double val_,
-		long int digits_);
-
-		static long int get_number_of_subsimulations(
-		long int number_of_realizations_);
-
-
-
-		static double function_for_lambda_calculation(
-		double lambda_,
-		void * data_);
-
-		static double get_root(
-		const std::vector<double> &res_tmp_,
-		double point_);
-		
-
-
-
-	public:
-
-
-				
-		alp_data *d_alp_data;//initial data
-		array_positive<alp*> *d_alp_obj;//vector with the alp objects
-		long int d_n_alp_obj;//number of alp objects
-					
-		array_positive<double> *d_lambda_tmp;
-		array_positive<double> *d_lambda_tmp_errors;
-
-		array_positive<double> *d_C_tmp;
-		array_positive<double> *d_C_tmp_errors;
-
-		//Subsimulations' parameters
-
-		//number of subsimulations
-		long int d_mult_number;
-
-
-		//parameters estimations
-
-		double m_Lambda;
-		double m_LambdaError;
-		double m_K;
-		double m_KError;
-		double m_C;
-		double m_CError;
-
-		double m_Sigma;
-		double m_SigmaError;
-
-		double m_GaplessAlpha;
-		double m_GaplessAlphaError;
-
-		double m_GaplessA;
-		double m_GaplessAError;
-
-
-		double m_AlphaI;
-		double m_AlphaIError;
-		double m_AlphaJ;
-		double m_AlphaJError;
-
-		double m_AI;
-		double m_AIError;
-		double m_AJ;
-		double m_AJError;
-
-
-
-		double m_CalcTime;
-
-		long int m_G;
-		long int m_G1;
-		long int m_G2;
-
-		std::vector<double> m_LambdaSbs;
-		std::vector<double> m_KSbs;
-		std::vector<double> m_CSbs;
-
-		std::vector<double> m_SigmaSbs;
-
-		std::vector<double> m_AlphaISbs;
-		std::vector<double> m_AlphaJSbs;
-
-		std::vector<double> m_AISbs;
-		std::vector<double> m_AJSbs;
-
-
-
-	};
-}
-
-#endif
-
+#ifndef INCLUDED_SLS_ALP_SIMULATION
+#define INCLUDED_SLS_ALP_SIMULATION
+
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_alp_sim.hpp
+
+Author: Sergey Sheetlin
+
+Contents: Simulation of Gumbel parameters
+
+******************************************************************************/
+
+
+#include <complex>
+#include <iostream>
+#include <map>
+#include <vector>
+#include <fstream>
+#include <float.h>
+#include <algorithm>
+
+#include "sls_alp_data.hpp"
+#include "sls_alp.hpp"
+#include "sls_alp_regression.hpp"
+
+namespace Sls {
+
+	struct struct_for_lambda_calculation
+	{
+		void **d_alp_distr;
+		void **d_alp_distr_errors;
+		long int d_nalp;
+		double d_f_error;
+
+		double d_last_sum;
+		double d_last_sum_error;
+
+		bool d_calculate_alp_number;
+		long int d_alp_number;
+	};
+
+
+
+
+	class alp_sim{
+
+	
+
+	public:
+
+
+		alp_sim(//constructor
+			alp_data *alp_data_
+			);
+
+
+		~alp_sim();//destructor
+
+		void alp_sim_from_random_seed(//simulation from random seed
+		alp_data *alp_data_);
+
+		void quick_test(//runs quick tests to determine whether the scoring scheme is linear
+		long int trials_number_,
+		double max_time_);
+
+		void get_minimal_simulation(
+		long int ind1_,
+		long int ind2_,
+		long int &M_min_,
+		long int &nalp_,
+		long int &nalp_lambda_,
+		bool C_calculation_,
+		bool check_time_flag_);//simulation using [ind1_,ind2_] range of realizations with an estimation of parameters for accuracy, memory usage and calculation time
+
+
+		void memory_release_for_get_minimal_simulation(
+		long int nalp_,
+		void **&alp_distr,
+		void **&alp_distr_errors);
+
+		bool the_criterion(//criteria of stopping of the simulating ALP
+		//if the function returns true then calculates optimal M_min and ALP number
+		//sets the flags M_min_flag_ and nalp_flag_ checking the corresponding condition
+		long int upto_nalp_,
+		long int &nalp_for_lambda_simulation_,
+		long int ind1_,
+		long int ind2_,
+		void **&alp_distr,
+		void **&alp_distr_errors,
+		long int &M_min_,
+		bool &M_min_flag_,
+		bool &nalp_flag_,
+		bool &inside_simulation_flag_,
+		bool C_calculation_,
+		double *lambda_=NULL,
+		double *lambda_error_=NULL);
+
+		void calculate_lambda(
+		bool check_the_criteria_,
+		long int nalp_,
+		long int &nalp_thr_,
+		bool &inside_simulation_flag_,
+		void **alp_distr,
+		void **alp_distr_errors,
+		double &lambda_,
+		double &lambda_error_,
+		double &test_difference_,
+		double &test_difference_error_);
+
+		void calculate_C(
+		long int starting_point,
+		long int nalp_,
+		void **alp_distr,
+		void **alp_distr_errors,
+		double lambda_,
+		double lambda_error_,
+		double &C_,
+		double &C_error_,
+		double &Sc_,
+		double &Sc_error_);
+
+		void memory_release_for_calculate_FSC(
+		double *&exp_array,
+
+		double *&delta_E,
+		double *&delta_E_error,
+
+		double *&delta_E_E,
+		double *&delta_E_E_error,
+
+
+		double *&delta_I,
+		double *&delta_I_error,
+
+		double *&delta_J,
+		double *&delta_J_error,
+
+		double *&delta_I_I,
+		double *&delta_I_I_error,
+
+		double *&delta_I_J,
+		double *&delta_I_J_error,
+
+		double *&delta_J_J,
+		double *&delta_J_J_error,
+
+		double *&cov_J_J,
+		double *&cov_J_J_error,
+
+		double *&cov_I_J,
+		double *&cov_I_J_error,
+
+		double *&cov_I_I,
+		double *&cov_I_I_error,
+
+		double *&cov_E_E,
+		double *&cov_E_E_error);
+
+
+		void calculate_FSC(
+		long int nalp_,
+		long int ind1_,
+		long int ind2_,
+		void **alp_distr,
+		double lambda_,
+		double Sc_,
+		//double Sc_error_,
+
+		double &a_I_,
+		double &a_I_error_,
+		double &a_J_,
+		double &a_J_error_,
+		double &sigma_,
+		double &sigma_error_,
+		double &alpha_I_,
+		double &alpha_I_error_,
+		double &alpha_J_,
+		double &alpha_J_error_);
+
+		void sigma_calculation(
+		double delta_I_aver_,
+		double delta_I_aver_error_,
+		double delta_J_aver_,
+		double delta_J_aver_error_,
+		double delta_E_aver_,
+		double delta_E_aver_error_,
+		double cov_E_E_aver_,
+		double cov_E_E_aver_error_,
+		double cov_I_J_aver_,
+		double cov_I_J_aver_error_,
+		double &sigma_,
+		double &sigma_error_);
+
+		void get_and_allocate_alp_distribution(
+		long int ind1_,
+		long int ind2_,
+		void **&alp_distr,
+		void **&alp_distr_errors,
+		long int nalp);
+
+		bool check_K_criterion(
+		long int nalp_,
+		long int ind1_,
+		long int ind2_,
+		double lambda_,
+		double eps_K_,
+		long int &M_min_);
+
+		void kill(
+		bool check_time_,
+		long int ind1_,
+		long int ind2_,
+		long int M_min_,
+		double lambda_,
+		double eps_K_,
+		double &K_C_,
+		double &K_C_error_,
+		long int &level_,
+		long int &diff_opt_);
+
+
+		
+		bool check_K_criterion_during_killing2(
+		long int ind1_,
+		long int ind2_,
+		double lambda_,
+		double eps_K_,
+		long int current_level_,
+		long int &recommended_level_,
+		long int &diff_opt_,
+		double &K_C_,
+		double &K_C_error_);
+		
+
+		bool check_K_criterion_during_killing(
+		long int ind1_,
+		long int ind2_,
+		double lambda_,
+		double eps_K_,
+		long int current_level_,
+		long int &recommended_level_,
+		long int &diff_opt_,
+		double &K_C_,
+		double &K_C_error_);
+
+
+
+
+		inline static double lambda_exp(
+		long int &i_,
+		double *&exp_array_);
+
+		void get_single_realization(
+		bool check_time_,
+		long int M_min_,
+		long int nalp_,
+		bool killing_flag_,
+		long int level_,
+		long int diff_opt_,
+		alp *&obj_,
+		bool &sucess_flag_,
+		double &d_eps_);
+
+		void calculate_main_parameters(
+		long int final_realizations_number_lambda_,
+		long int final_realizations_number_killing_,
+		long int nalp,
+		long int nalp_for_lambda_simulation,
+		long int level,
+		bool &inside_simulation_flag,
+		double &lambda,
+		double &lambda_error,
+		double &test_difference,
+		double &test_difference_error,
+		double &C,
+		double &C_error,
+		double &C2,
+		double &C2_error,
+		double &C4,
+		double &C4_error,
+		double &K_C,
+		double &K_C_error,
+		double &a_I,
+		double &a_I_error,
+		double &a_J,
+		double &a_J_error,
+		double &sigma,
+		double &sigma_error,
+		double &alpha_I,
+		double &alpha_I_error,
+		double &alpha_J,
+		double &alpha_J_error,
+		double &K,
+		double &K_error);
+
+		void calculate_main_parameters2(
+		long int final_realizations_number_lambda_,
+		long int final_realizations_number_killing_,
+		long int nalp,
+		long int nalp_for_lambda_simulation,
+		long int level,
+		bool &inside_simulation_flag,
+		double &lambda,
+		double &lambda_error,
+		double &test_difference,
+		double &test_difference_error,
+		double &C,
+		double &C_error,
+		double &C2,
+		double &C2_error,
+		double &C4,
+		double &C4_error,
+		double &K_C,
+		double &K_C_error,
+		double &a_I,
+		double &a_I_error,
+		double &a_J,
+		double &a_J_error,
+		double &sigma,
+		double &sigma_error,
+		double &alpha_I,
+		double &alpha_I_error,
+		double &alpha_J,
+		double &alpha_J_error,
+		double &K,
+		double &K_error);
+
+		void memory_release_for_calculate_main_parameters2m(
+		long int nalp_for_lambda_simulation,
+		long int *&d_mult_realizations,
+		long int *&d_mult_K_realizations,
+
+		double *&lambda_mult,
+		double *&lambda_mult_error,
+
+		double *&C_mult,
+		double *&C_mult_error,
+
+		double *&a_I_mult,
+		double *&a_I_mult_error,
+
+		double *&a_J_mult,
+		double *&a_J_mult_error,
+
+		double *&sigma_mult,
+		double *&sigma_mult_error,
+
+		double *&alpha_I_mult,
+		double *&alpha_I_mult_error,
+
+		double *&alpha_J_mult,
+		double *&alpha_J_mult_error,
+
+		double *&K_C_mult,
+		double *&K_C_mult_error,
+
+		double *&K_mult,
+		double *&K_mult_error,
+
+		double *&Sc_mult,
+		double *&Sc_mult_error,
+
+
+		void **&alp_distr,
+		void **&alp_distr_errors,
+
+		void ***&alp_mult_distr,
+		void ***&alp_mult_distr_errors);
+
+		void calculate_main_parameters2m(
+		long int final_realizations_number_lambda_,
+		long int final_realizations_number_killing_,
+		long int nalp_for_lambda_simulation,
+		long int level,
+		bool &inside_simulation_flag,
+		double &lambda,
+		double &lambda_error,
+		double &test_difference,
+		double &test_difference_error,
+		double &C,
+		double &C_error,
+		double &K_C,
+		double &K_C_error,
+		double &a_I,
+		double &a_I_error,
+		double &a_J,
+		double &a_J_error,
+		double &sigma,
+		double &sigma_error,
+		double &alpha_I,
+		double &alpha_I_error,
+		double &alpha_J,
+		double &alpha_J_error,
+		double &K,
+		double &K_error,
+		bool &flag_);
+
+		void randomize_realizations(
+		long int final_realizations_number_lambda_,
+		long int final_realizations_number_killing_);
+
+		void randomize_realizations_ind(
+		long int ind1_,
+		long int ind2_);
+
+		void generate_random_permulation(
+		long int *perm_,
+		long int dim_);
+
+
+
+
+		static void error_in_calculate_main_parameters2m(
+		double C,
+		double &C_error,
+		double C_mult2,
+		double C_mult2_error);
+
+
+
+
+		void output_main_parameters(
+		double time_,
+		long int nalp,
+		long int nalp_for_lambda_simulation,
+		long int level,
+		long int M_min_,
+		bool &inside_simulation_flag,
+		long int final_realizations_number_lambda_,
+		long int final_realizations_number_killing_);
+
+		void output_main_parameters2(
+		double time_,
+		long int nalp,
+		long int nalp_for_lambda_simulation,
+		long int level,
+		long int M_min_,
+		bool &inside_simulation_flag,
+		long int final_realizations_number_lambda_,
+		long int final_realizations_number_killing_);
+
+		void output_main_parameters2m_new(
+		long int nalp_for_lambda_simulation,
+		long int level,
+		bool &inside_simulation_flag,
+		long int final_realizations_number_lambda_,
+		long int final_realizations_number_killing_);
+
+		void symmetric_parameters_for_symmetric_scheme();
+
+
+
+
+		static double relative_error_in_percents(
+		double val_,
+		double val_error_);
+
+		static double round_double(
+		double val_,
+		long int digits_);
+
+		static long int get_number_of_subsimulations(
+		long int number_of_realizations_);
+
+
+
+		static double function_for_lambda_calculation(
+		double lambda_,
+		void * data_);
+
+		static double get_root(
+		const std::vector<double> &res_tmp_,
+		double point_);
+		
+
+
+
+	public:
+
+
+				
+		alp_data *d_alp_data;//initial data
+		array_positive<alp*> *d_alp_obj;//vector with the alp objects
+		long int d_n_alp_obj;//number of alp objects
+					
+		array_positive<double> *d_lambda_tmp;
+		array_positive<double> *d_lambda_tmp_errors;
+
+		array_positive<double> *d_C_tmp;
+		array_positive<double> *d_C_tmp_errors;
+
+		//Subsimulations' parameters
+
+		//number of subsimulations
+		long int d_mult_number;
+
+
+		//parameters estimations
+
+		double m_Lambda;
+		double m_LambdaError;
+		double m_K;
+		double m_KError;
+		double m_C;
+		double m_CError;
+
+		double m_Sigma;
+		double m_SigmaError;
+
+		double m_GaplessAlpha;
+		double m_GaplessAlphaError;
+
+		double m_GaplessA;
+		double m_GaplessAError;
+
+
+		double m_AlphaI;
+		double m_AlphaIError;
+		double m_AlphaJ;
+		double m_AlphaJError;
+
+		double m_AI;
+		double m_AIError;
+		double m_AJ;
+		double m_AJError;
+
+
+
+		double m_CalcTime;
+
+		long int m_G;
+		long int m_G1;
+		long int m_G2;
+
+		std::vector<double> m_LambdaSbs;
+		std::vector<double> m_KSbs;
+		std::vector<double> m_CSbs;
+
+		std::vector<double> m_SigmaSbs;
+
+		std::vector<double> m_AlphaISbs;
+		std::vector<double> m_AlphaJSbs;
+
+		std::vector<double> m_AISbs;
+		std::vector<double> m_AJSbs;
+
+
+
+	};
+}
+
+#endif
+
diff --git a/src/alp/sls_basic.cpp b/src/alp/sls_basic.cpp
index 6c68012..f5c5a17 100644
--- a/src/alp/sls_basic.cpp
+++ b/src/alp/sls_basic.cpp
@@ -1,172 +1,172 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_basic.cpp
-
-Author: Sergey Sheetlin
-
-Contents: Some basic functions and types
-
-******************************************************************************/
-
-#include "sls_basic.hpp"
-
-using namespace Sls;
-
-double sls_basic::round(//returns nearest integer to x_
-const double &x_)
-{
-	double x_floor=floor(x_);
-	double x_ceil=ceil(x_);
-	if(fabs(x_-x_floor)<0.5)
-	{
-		return x_floor;
-	};
-	return x_ceil;
-}
-
-void sls_basic::get_current_time(
-double &seconds_)
-{
-#ifndef _MSC_VER //UNIX program
-	struct timeval tv;
-	struct timezone tz;
-	gettimeofday(&tv, &tz);
-	seconds_=(double)(tv.tv_sec)+(double)(tv.tv_usec)/1000000.0;
-
-#else
-
-	struct _timeb timebuffer;
-	_ftime( &timebuffer );
-	seconds_=timebuffer.time+(double)(timebuffer.millitm)/1000.0;
-
-#endif
-}
-
-double sls_basic::one_minus_exp_function(
-double y_)
-{
-	if(fabs(y_)>1e-3)
-	{
-		return 1.0-exp(y_);
-	}
-	else
-	{
-		return -(y_*(120+y_*(60+y_*(20+y_*(5.0+y_))))/120.0);
-	};
-}
-
-double sls_basic::normal_probability(
-double x_,
-double eps_)
-{
-
-	if(x_==0)
-	{
-		return 0.5;
-	};
-
-
-	eps_=Tmin(1.0,eps_);
-
-	double x_max=10*eps_+sqrt(Tmax(0.0,-2*log(eps_)));
-
-
-	if(x_>=x_max)
-	{
-		double x=x_/sqrt(2.0);
-		return 1-0.5*exp(-x*x)/(x*sqrt(pi))*(1-1.0/(2*x*2*x));
-	};
-
-	if(x_<=-x_max)
-	{
-		double x=x_/sqrt(2.0);
-		return 0.5*exp(-x*x)/(-x*sqrt(pi))*(1-1.0/(2*x*2*x));
-	};
-
-
-	double const_val=1/sqrt(2.0*pi);
-
-	
-
-
-	long int N=(long int)round(fabs(x_)/eps_)+1;
-	double h=x_/(double)N;
-
-
-
-	double res=0;
-	long int i;
-	for(i=0;i<=N;i++)
-	{
-		double y=h*i;
-		double tmp=exp(-0.5*y*y);
-		if(i==0||i==N)
-		{
-			res+=0.5*tmp;
-		}
-		else
-		{
-			res+=tmp;
-		};
-	};
-
-	res*=h;
-
-	return 0.5+const_val*(res);
-}
-
-double sls_basic::normal_probability(
-double a_,
-double b_,
-double h_,
-long int N_,
-double *p_,
-double x_,
-double eps_)
-{
-	if(x_<a_||x_>b_)
-	{
-		return normal_probability(x_,eps_);
-	};
-
-	long int x_n=(long int)floor((x_-a_)/h_);
-	x_n=Tmin(N_-1,x_n);
-	return p_[x_n]+(p_[x_n+1]-p_[x_n])*(x_-(h_*x_n+a_))/h_;
-}
-
-double sls_basic::ln_one_minus_val(
-double val_)
-{
-	if(val_>1e-8)
-	{
-		return log(1-val_);
-	};
-
-	return -val_-val_*val_/2.0-val_*val_*val_/3.0;
-}
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_basic.cpp
+
+Author: Sergey Sheetlin
+
+Contents: Some basic functions and types
+
+******************************************************************************/
+
+#include "sls_basic.hpp"
+
+using namespace Sls;
+
+double sls_basic::round(//returns nearest integer to x_
+const double &x_)
+{
+	double x_floor=floor(x_);
+	double x_ceil=ceil(x_);
+	if(fabs(x_-x_floor)<0.5)
+	{
+		return x_floor;
+	};
+	return x_ceil;
+}
+
+void sls_basic::get_current_time(
+double &seconds_)
+{
+#ifndef _MSC_VER //UNIX program
+	struct timeval tv;
+	struct timezone tz;
+	gettimeofday(&tv, &tz);
+	seconds_=(double)(tv.tv_sec)+(double)(tv.tv_usec)/1000000.0;
+
+#else
+
+	struct _timeb timebuffer;
+	_ftime( &timebuffer );
+	seconds_=timebuffer.time+(double)(timebuffer.millitm)/1000.0;
+
+#endif
+}
+
+double sls_basic::one_minus_exp_function(
+double y_)
+{
+	if(fabs(y_)>1e-3)
+	{
+		return 1.0-exp(y_);
+	}
+	else
+	{
+		return -(y_*(120+y_*(60+y_*(20+y_*(5.0+y_))))/120.0);
+	};
+}
+
+double sls_basic::normal_probability(
+double x_,
+double eps_)
+{
+
+	if(x_==0)
+	{
+		return 0.5;
+	};
+
+
+	eps_=Tmin(1.0,eps_);
+
+	double x_max=10*eps_+sqrt(Tmax(0.0,-2*log(eps_)));
+
+
+	if(x_>=x_max)
+	{
+		double x=x_/sqrt(2.0);
+		return 1-0.5*exp(-x*x)/(x*sqrt(pi))*(1-1.0/(2*x*2*x));
+	};
+
+	if(x_<=-x_max)
+	{
+		double x=x_/sqrt(2.0);
+		return 0.5*exp(-x*x)/(-x*sqrt(pi))*(1-1.0/(2*x*2*x));
+	};
+
+
+	double const_val=1/sqrt(2.0*pi);
+
+	
+
+
+	long int N=(long int)round(fabs(x_)/eps_)+1;
+	double h=x_/(double)N;
+
+
+
+	double res=0;
+	long int i;
+	for(i=0;i<=N;i++)
+	{
+		double y=h*i;
+		double tmp=exp(-0.5*y*y);
+		if(i==0||i==N)
+		{
+			res+=0.5*tmp;
+		}
+		else
+		{
+			res+=tmp;
+		};
+	};
+
+	res*=h;
+
+	return 0.5+const_val*(res);
+}
+
+double sls_basic::normal_probability(
+double a_,
+double b_,
+double h_,
+long int N_,
+double *p_,
+double x_,
+double eps_)
+{
+	if(x_<a_||x_>b_)
+	{
+		return normal_probability(x_,eps_);
+	};
+
+	long int x_n=(long int)floor((x_-a_)/h_);
+	x_n=Tmin(N_-1,x_n);
+	return p_[x_n]+(p_[x_n+1]-p_[x_n])*(x_-(h_*x_n+a_))/h_;
+}
+
+double sls_basic::ln_one_minus_val(
+double val_)
+{
+	if(val_>1e-8)
+	{
+		return log(1-val_);
+	};
+
+	return -val_-val_*val_/2.0-val_*val_*val_/3.0;
+}
+
diff --git a/src/alp/sls_basic.hpp b/src/alp/sls_basic.hpp
index 6a97cb4..1c6e7f1 100644
--- a/src/alp/sls_basic.hpp
+++ b/src/alp/sls_basic.hpp
@@ -1,212 +1,212 @@
-#ifndef INCLUDED_SLS_BASIC
-#define INCLUDED_SLS_BASIC
-
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_basic.hpp
-
-Author: Sergey Sheetlin
-
-Contents: Some basic functions and types
-
-******************************************************************************/
-
-#ifndef _MSC_VER //UNIX program
-#else
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#ifndef _MSC_VER //UNIX program
-#include <sys/time.h>
-#else
-#include <sys/timeb.h>
-#endif
-
-#include <iomanip>
-#include <cmath>
-#include <string>
-
-namespace Sls { 
-
-	const double pi=3.1415926535897932384626433832795;
-	const double const_val=1/sqrt(2.0*pi);
-	const long int quick_tests_trials_number=100;
-
-	struct error//struct to handle exceptions
-	{
-		std::string st;
-		error(std::string st_,long int error_code_){st=st_;error_code=error_code_;};
-		long int error_code;
-	};
-
-	//structure for user-defined Gumbel parameters without errors
-	struct AlignmentEvaluerParameters
-	{
-		double d_lambda;
-		double d_k;
-		double d_a1;
-		double d_b1;
-		double d_a2;
-		double d_b2;
-		double d_alpha1;
-		double d_beta1;
-		double d_alpha2;
-		double d_beta2;
-		double d_sigma;
-		double d_tau;
-	};
-
-	//structure for user-defined Gumbel parameters with errors
-	struct AlignmentEvaluerParametersWithErrors
-	{
-		double d_lambda;
-		double d_lambda_error;
-
-		double d_k;
-		double d_k_error;
-
-		double d_a1;
-		double d_a1_error;
-
-		double d_b1;
-		double d_b1_error;
-
-		double d_a2;
-		double d_a2_error;
-
-		double d_b2;
-		double d_b2_error;
-
-		double d_alpha1;
-		double d_alpha1_error;
-
-		double d_beta1;
-		double d_beta1_error;
-
-		double d_alpha2;
-		double d_alpha2_error;
-
-		double d_beta2;
-		double d_beta2_error;
-
-		double d_sigma;
-		double d_sigma_error;
-
-		double d_tau;
-		double d_tau_error;
-	};
-
-
-	class sls_basic{
-
-	public:
-
-		template<class T>
-		static inline T Tmax(T i_, T j_)
-		{
-			if(i_>j_)
-			{
-				return i_;
-			};
-			return j_;
-		}
-
-		template<class T>
-		static inline T Tmin(T i_, T j_)
-		{
-			if(i_<j_)
-			{
-				return i_;
-			};
-			return j_;
-		}
-
-		template<class T>
-		static inline T Tmax(T x_,T y_,T z_)
-		{
-			return Tmax(Tmax(x_,y_),z_);
-		}
-
-		template<class T>
-		static inline T Tmin(T x_,T y_,T z_)
-		{
-			return Tmin(Tmin(x_,y_),z_);
-		}
-
-		template<class T>
-		static inline T Tmax(T x_,T y_,T z_,T w_)
-		{
-			return Tmax(Tmax(x_,y_),Tmax(z_,w_));
-		}
-
-		template<class T>
-		static inline T Tmin(T x_,T y_,T z_,T w_)
-		{
-			return Tmin(Tmin(x_,y_),Tmin(z_,w_));
-		}
-
-		static inline void assert_mem(void *pointer_)
-		{
-			if(!pointer_)
-			{
-				throw error("Memory allocation error\n",41);
-			};
-		}
-
-		static double round(//returns nearest integer to x_
-		const double &x_);
-
-		static void get_current_time(
-		double &seconds_);
-
-		static double one_minus_exp_function(
-		double y_);
-
-		static double normal_probability(
-		double x_,
-		double eps_);
-
-		static double normal_probability(
-		double a_,
-		double b_,
-		double h_,
-		long int N_,
-		double *p_,
-		double x_,
-		double eps_);
-
-		static double ln_one_minus_val(
-		double val_);
-
-
-
-	};
-}
-
-#endif
-
+#ifndef INCLUDED_SLS_BASIC
+#define INCLUDED_SLS_BASIC
+
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_basic.hpp
+
+Author: Sergey Sheetlin
+
+Contents: Some basic functions and types
+
+******************************************************************************/
+
+#ifndef _MSC_VER //UNIX program
+#else
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#ifndef _MSC_VER //UNIX program
+#include <sys/time.h>
+#else
+#include <sys/timeb.h>
+#endif
+
+#include <iomanip>
+#include <cmath>
+#include <string>
+
+namespace Sls { 
+
+	const double pi=3.1415926535897932384626433832795;
+	const double const_val=1/sqrt(2.0*pi);
+	const long int quick_tests_trials_number=100;
+
+	struct error//struct to handle exceptions
+	{
+		std::string st;
+		error(std::string st_,long int error_code_){st=st_;error_code=error_code_;};
+		long int error_code;
+	};
+
+	//structure for user-defined Gumbel parameters without errors
+	struct AlignmentEvaluerParameters
+	{
+		double d_lambda;
+		double d_k;
+		double d_a1;
+		double d_b1;
+		double d_a2;
+		double d_b2;
+		double d_alpha1;
+		double d_beta1;
+		double d_alpha2;
+		double d_beta2;
+		double d_sigma;
+		double d_tau;
+	};
+
+	//structure for user-defined Gumbel parameters with errors
+	struct AlignmentEvaluerParametersWithErrors
+	{
+		double d_lambda;
+		double d_lambda_error;
+
+		double d_k;
+		double d_k_error;
+
+		double d_a1;
+		double d_a1_error;
+
+		double d_b1;
+		double d_b1_error;
+
+		double d_a2;
+		double d_a2_error;
+
+		double d_b2;
+		double d_b2_error;
+
+		double d_alpha1;
+		double d_alpha1_error;
+
+		double d_beta1;
+		double d_beta1_error;
+
+		double d_alpha2;
+		double d_alpha2_error;
+
+		double d_beta2;
+		double d_beta2_error;
+
+		double d_sigma;
+		double d_sigma_error;
+
+		double d_tau;
+		double d_tau_error;
+	};
+
+
+	class sls_basic{
+
+	public:
+
+		template<class T>
+		static inline T Tmax(T i_, T j_)
+		{
+			if(i_>j_)
+			{
+				return i_;
+			};
+			return j_;
+		}
+
+		template<class T>
+		static inline T Tmin(T i_, T j_)
+		{
+			if(i_<j_)
+			{
+				return i_;
+			};
+			return j_;
+		}
+
+		template<class T>
+		static inline T Tmax(T x_,T y_,T z_)
+		{
+			return Tmax(Tmax(x_,y_),z_);
+		}
+
+		template<class T>
+		static inline T Tmin(T x_,T y_,T z_)
+		{
+			return Tmin(Tmin(x_,y_),z_);
+		}
+
+		template<class T>
+		static inline T Tmax(T x_,T y_,T z_,T w_)
+		{
+			return Tmax(Tmax(x_,y_),Tmax(z_,w_));
+		}
+
+		template<class T>
+		static inline T Tmin(T x_,T y_,T z_,T w_)
+		{
+			return Tmin(Tmin(x_,y_),Tmin(z_,w_));
+		}
+
+		static inline void assert_mem(void *pointer_)
+		{
+			if(!pointer_)
+			{
+				throw error("Memory allocation error\n",41);
+			};
+		}
+
+		static double round(//returns nearest integer to x_
+		const double &x_);
+
+		static void get_current_time(
+		double &seconds_);
+
+		static double one_minus_exp_function(
+		double y_);
+
+		static double normal_probability(
+		double x_,
+		double eps_);
+
+		static double normal_probability(
+		double a_,
+		double b_,
+		double h_,
+		long int N_,
+		double *p_,
+		double x_,
+		double eps_);
+
+		static double ln_one_minus_val(
+		double val_);
+
+
+
+	};
+}
+
+#endif
+
diff --git a/src/alp/sls_falp_alignment_evaluer.cpp b/src/alp/sls_falp_alignment_evaluer.cpp
index fe490fc..a51f84d 100644
--- a/src/alp/sls_falp_alignment_evaluer.cpp
+++ b/src/alp/sls_falp_alignment_evaluer.cpp
@@ -1,1070 +1,1070 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_fsa1_lib.cpp
-
-Author: Sergey Sheetlin
-
-Contents: library functions of main routines
-
-******************************************************************************/
-
-
-#include "sls_falp_alignment_evaluer.hpp"
-
-#include "sls_fsa1_parameters.hpp"
-#include "sls_fsa1_utils.hpp"
-#include "sls_alp_regression.hpp"
-#include "njn_localmaxstatmatrix.hpp"
-#include "njn_localmaxstatutil.hpp"
-#include "sls_fsa1.hpp"
-
-using namespace std;
-
-
-namespace Sls {
-
-// Write the parameters:
-std::ostream &operator<<(std::ostream &s_,
-const FrameshiftAlignmentEvaluer &g_)
-{
-
-	if(!FALP_pvalues::assert_Gumbel_parameters(
-	g_.d_params)||!g_.isGood())
-	{
-		throw error("Error - the Gumbel parameters are not defined properly in the function \"std::ostream &operator<<\"\n",1);
-	};
-
-	s_<<g_.d_params;
-	return s_;
-}
-
-// Read the parameters:
-std::istream &operator>>(std::istream &s_,
-FrameshiftAlignmentEvaluer &g_)
-{
-	try
-	{
-		g_.d_params.d_params_flag=false;
-		s_>>g_.d_params;
-		g_.d_params.d_params_flag=true;
-
-		//precompute intercepts
-		FALP_pvalues::compute_intercepts(g_.d_params);
-
-		if(!FALP_pvalues::assert_Gumbel_parameters(
-		g_.d_params)||!g_.isGood())
-		{
-			g_.d_params.d_params_flag=false;
-		};
-
-		return s_;
-	}
-	catch (...)
-	{ 
-		g_.d_params.d_params_flag=false;
-		throw;
-	};
-}
-
-//check correctness of the input parameters for gapless alignment
-void FrameshiftAlignmentEvaluer::assert_Gapless_input_parameters(
-long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
-long aaAlphabetSize_,//a number of letters in the amino acid alphabet
-const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
-
-const double *ntFreqs_,//background frequencies of letters in DNA sequences
-const double *aaFreqs_,//background frequencies of letters in amino acid sequences
-double *&ntFreqs_normalized_,//normalized background frequencies of letters in DNA sequences
-double *&aaFreqs_normalized_,//normalized background frequencies of letters in amino acid sequences
-const string function_name_)//"assert_Gapless_input_parameters" is called from "function_name_" function
-{
-	if(!(ntAlphabetSize_>0))
-	{
-		d_params.d_params_flag=false;
-		throw error("Error - the parameter \"ntAlphabetSize_\" in the function \""+function_name_+"\" must be positive\n",1);
-	};
-
-	if(!(aaAlphabetSize_>0))
-	{
-		d_params.d_params_flag=false;
-		throw error("Error - the parameter \"aaAlphabetSize_\" in the function \""+function_name_+"\" must be positive\n",1);
-	};
-
-	long int i;
-	for(i=0;i<ntAlphabetSize_*ntAlphabetSize_*ntAlphabetSize_;i++)
-	{
-		if(!(codonTable_[i]>=0&&codonTable_[i]<aaAlphabetSize_))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the value \"codonTable_["+FSA_utils::long_to_string(i)+"]\" in the function \""+function_name_+"\" is incorrect\n",1);
-		};
-	};
-
-	double sum_nt=0;
-	for(i=0;i<ntAlphabetSize_;i++)
-	{
-		if(ntFreqs_[i]<0)
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the value \"ntFreqs_["+FSA_utils::long_to_string(i)+"]\" in the function \""+function_name_+"\" must be non-negative\n",1);
-		};
-		sum_nt+=ntFreqs_[i];
-	};
-
-	if(sum_nt<=0)
-	{
-		throw error("Error - sum of the frequencies \"ntFreqs_\" is non-positive in the function \""+function_name_+"\"\n",1);
-	};
-
-	ntFreqs_normalized_=new double[ntAlphabetSize_];
-	FSA_utils::assert_mem(ntFreqs_normalized_);
-
-	for(i=0;i<ntAlphabetSize_;i++)
-	{
-		ntFreqs_normalized_[i]=ntFreqs_[i]/sum_nt;
-	};
-
-	double sum_aa=0;
-	for(i=0;i<aaAlphabetSize_;i++)
-	{
-		if(aaFreqs_[i]<0)
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the value \"aaFreqs_["+FSA_utils::long_to_string(i)+"]\" in the function \""+function_name_+"\" must be non-negative\n",1);
-		};
-		sum_aa+=aaFreqs_[i];
-	};
-
-	if(sum_aa<=0)
-	{
-		throw error("Error - sum of the frequencies \"aaFreqs_\" is non-positive in the function \""+function_name_+"\"\n",1);
-	};
-
-	aaFreqs_normalized_=new double[aaAlphabetSize_];
-	FSA_utils::assert_mem(aaFreqs_normalized_);
-
-	for(i=0;i<aaAlphabetSize_;i++)
-	{
-		aaFreqs_normalized_[i]=aaFreqs_[i]/sum_aa;
-	};
-}
-
-//Computes gapless Gumbel parameters:
-void FrameshiftAlignmentEvaluer::initGapless(long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
-long aaAlphabetSize_,//a number of letters in the amino acid alphabet
-const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
-
-const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
-const double *ntFreqs_,//background frequencies of letters in DNA sequences
-const double *aaFreqs_,//background frequencies of letters in amino acid sequences
-double max_time_)//maximum allowed calculation time in seconds
-{
-
-	double *RR1_AA=NULL;
-
-	try
-	{
-
-
-		double CurrentTime1;
-		Sls::FSA_utils::get_current_time(CurrentTime1);
-
-		//check correctness of the input parameters for gapless alignment
-		string function_name="void FrameshiftAlignmentEvaluer::initGapless";
-		double *ntFreqs_normalized=NULL;//normalized background frequencies of letters in DNA sequences
-		double *aaFreqs_normalized=NULL;//normalized background frequencies of letters in amino acid sequences
-		assert_Gapless_input_parameters(
-		ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
-		aaAlphabetSize_,//a number of letters in the amino acid alphabet
-		codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
-		ntFreqs_,//background frequencies of letters in DNA sequences
-		aaFreqs_,//background frequencies of letters in amino acid sequences
-		ntFreqs_normalized,//normalized background frequencies of letters in DNA sequences
-		aaFreqs_normalized,//normalized background frequencies of letters in amino acid sequences
-		function_name);//"assert_Gapless_input_parameters" is called from "function_name_" function
-
-		d_params.d_params_flag=false;
-
-		long int codon_length=3;
-//------
-
-		FSA_utils::extract_AA_frequencies_for_DNA_sequence(
-		codonTable_,//<codon code,AA number>
-		codon_length,//codon length 
-		ntAlphabetSize_,//number of letters for the sequence 1
-		aaAlphabetSize_,//number of letters for the sequence 2
-		ntFreqs_normalized,//nucleotide probabilities
-		RR1_AA);//the resulted frequencies
-
-		if(max_time_<=0)
-		{
-			max_time_=60;
-		};
-		
-		Njn::LocalMaxStatMatrix local_max_stat_matrix(aaAlphabetSize_,
-							  substitutionScoreMatrix_,
-							  RR1_AA,
-							  aaFreqs_normalized,
-							  aaAlphabetSize_,
-							  max_time_);
-
-
-		if(local_max_stat_matrix.getTerminated()) 
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-
-		//calculation of a and sigma
-		double calculation_error=1e-6;
-
-		d_params.gapless_alpha_J = local_max_stat_matrix.getAlpha ();
-		d_params.gapless_alpha_J=FSA_utils::Tmax(d_params.gapless_alpha_J,0.0);
-		d_params.gapless_alpha_J_error = calculation_error;
-
-		d_params.gapless_alpha_I=d_params.gapless_alpha_J*9;
-		d_params.gapless_alpha_I_error = calculation_error*9;
-
-		d_params.gapless_sigma=d_params.gapless_alpha_J*3;
-		d_params.gapless_sigma_error = calculation_error*3;
-
-
-		d_params.gapless_a_J = local_max_stat_matrix.getA ();
-		d_params.gapless_a_J=FSA_utils::Tmax(d_params.gapless_a_J,0.0);
-		d_params.gapless_a_J_error = calculation_error;
-
-		d_params.gapless_a_I = d_params.gapless_a_J*3;
-		d_params.gapless_a_I_error = calculation_error*3;
-
-		//calculation of all required parameters for a gapless case
-		d_params.G=0;
-		d_params.G1=0;
-		d_params.G2=0;
-
-		d_params.lambda = local_max_stat_matrix.getLambda ();
-		d_params.lambda_error = calculation_error;
-
-		d_params.K = local_max_stat_matrix.getK ();
-		d_params.K_error = calculation_error;
-			
-		d_params.C = local_max_stat_matrix.getC ();
-		d_params.C_error = calculation_error;
-
-		if(d_params.C!=0)
-		{
-			d_params.K_C = d_params.K/d_params.C;
-		}
-		else
-		{
-			d_params.K_C = 0;
-		};
-		d_params.K_C_error = calculation_error;
-
-
-		d_params.sigma = d_params.gapless_sigma;
-		d_params.sigma_error = d_params.gapless_sigma_error;
-
-		d_params.alpha_I = d_params.gapless_alpha_I;
-		d_params.alpha_I_error = d_params.gapless_alpha_I_error;
-
-		d_params.alpha_J = d_params.gapless_alpha_J;
-		d_params.alpha_J_error = d_params.gapless_alpha_J_error;
-
-		d_params.a_I = d_params.gapless_a_I;
-		d_params.a_I_error = d_params.gapless_a_I_error;
-
-		d_params.a_J = d_params.gapless_a_J;
-		d_params.a_J_error = d_params.gapless_a_J_error;
-
-
-		std::vector<double > sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.lambda;
-		sbs_arrays[1]=d_params.lambda + calculation_error;
-
-		d_params.m_LambdaSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.K;
-		sbs_arrays[1]=d_params.K+calculation_error;
-
-		d_params.m_KSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.C;
-		sbs_arrays[1]=d_params.C+calculation_error;
-
-		d_params.m_CSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.sigma;
-		sbs_arrays[1]=d_params.sigma + calculation_error;
-
-		d_params.m_SigmaSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.alpha_I;
-		sbs_arrays[1]=d_params.alpha_I + calculation_error;
-
-		d_params.m_AlphaISbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.alpha_J;
-		sbs_arrays[1]=d_params.alpha_J + calculation_error;
-
-		d_params.m_AlphaJSbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.a_I;
-		sbs_arrays[1]=d_params.a_I + calculation_error;
-
-		d_params.m_AISbs=sbs_arrays;
-
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.a_J;
-		sbs_arrays[1]=d_params.a_J + calculation_error;
-
-		d_params.m_AJSbs=sbs_arrays;
-
-		d_params.d_params_flag=true;
-
-		//precompute intercepts
-		FALP_pvalues::compute_intercepts(d_params);
-
-		double CurrentTime2;
-		Sls::FSA_utils::get_current_time(CurrentTime2);
-		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
-
-		delete[]RR1_AA;RR1_AA=NULL;
-
-		if(!FALP_pvalues::assert_Gumbel_parameters(
-		d_params)||!isGood())
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void FrameshiftAlignmentEvaluer::initGapless\"\n",1);
-		};
-
-		delete[]ntFreqs_normalized;
-		delete[]aaFreqs_normalized;
-
-	}
-	catch (...)
-	{ 
-		d_params.d_params_flag=false;
-		delete[]RR1_AA;RR1_AA=NULL;
-		throw;
-	};
-}
-
-
-//Computes gapped Gumbel parameters:
-//The NCBI convention is used for penalizing a gap:
-//For example, a gap of length k is penalized as gapOpen1_+k*gapEpen1_ for sequence #1
-void FrameshiftAlignmentEvaluer::initFrameshift(long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
-long aaAlphabetSize_,//a number of letters in the amino acid alphabet; usually 4
-const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
-//letters are numerated from 0; 
-//each codon defines a code (an integer number from [0,...,ntAlphabetSize_^3 integers];
-//for example, for the DNA alphabet ACGT, 
-//AAA corresponds to codonTable_[0]; AAC corresponds to codonTable_[1] and so on.
-//codonTable_[x] contains an amino acid number such that the amino acid corresponds to a codon with the code x
-//for example, for the amino acid alphabet ARNDCQEGHILKMFPSTWYVBJZX* ("*" defines the stop codons), 
-//if AAC is coded by N (amino acid with the number 2), then codonTable_[1]=2.
-
-const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
-const double *ntFreqs_,//background frequencies of letters in DNA sequences
-const double *aaFreqs_,//background frequencies of letters in amino acid sequences
-long gapOpen1_,//gap opening penalty for sequence #1
-long gapEpen1_,//gap extension penalty for sequence #1
-long gapOpen2_,//gap opening penalty for sequence #2
-long gapEpen2_,//gap extension penalty for sequence #2
-long frameshiftCost_,//frameshift penalty
-bool insertions_after_deletions_,//if true, then insertions after deletions are permitted
-double eps_lambda_,//relative error for the parameter lambda
-double eps_K_,//relative error for the parameter K
-double max_time_,//maximum allowed calculation time in seconds
-double max_mem_,//maximum allowed memory usage in MB
-long randomSeed_,//randomizaton seed
-
-//in the case when max_time_<=0, the following parameters are used:
-long int seq_number_,//a number of alignments
-long int nalp_,//a number of ascending ladder points used in the calculation
-long int number_of_subsets_for_errors_calculation_)//a number of subsets used in the error calculation
-{
-	try
-	{
-
-		double CurrentTime1;
-		Sls::FSA_utils::get_current_time(CurrentTime1);
-
-		//check the input parameters
-		string function_name="void FrameshiftAlignmentEvaluer::initFrameshift";
-		double *ntFreqs_normalized=NULL;//normalized background frequencies of letters in DNA sequences
-		double *aaFreqs_normalized=NULL;//normalized background frequencies of letters in amino acid sequences
-		assert_Gapless_input_parameters(
-		ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
-		aaAlphabetSize_,//a number of letters in the amino acid alphabet
-		codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
-		ntFreqs_,//background frequencies of letters in DNA sequences
-		aaFreqs_,//background frequencies of letters in amino acid sequences
-		ntFreqs_normalized,//normalized background frequencies of letters in DNA sequences
-		aaFreqs_normalized,//normalized background frequencies of letters in amino acid sequences
-		function_name);//"assert_Gapless_input_parameters" is called from "function_name_" function
-
-
-		if(!(gapEpen1_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"gapEpen1_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(gapEpen2_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"gapEpen2_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(frameshiftCost_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"frameshiftCost_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(eps_lambda_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"eps_lambda_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(eps_K_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"eps_K_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(max_mem_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"max_mem_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(seq_number_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"seq_number_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(nalp_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"nalp_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		if(!(number_of_subsets_for_errors_calculation_>0))
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - the parameter \"number_of_subsets_for_errors_calculation_\" in the function \""+function_name+"\" must be positive\n",1);
-		};
-
-		d_params.d_params_flag=false;
-
-		bool library_call_flag=true;//if true, then the additional parameters are used
-		string smatr_file_name="";//scoring matrix file name
-		string RR1_file_name="";//background frequencies file name for the sequence #1
-		string RR2_file_name="";//background frequencies file name for the sequence #2
-		string DNA_codon_table_file_name="";//a name of a file with DNA codon table
-
-		bool gapped_flag=true;//if true, then the gapped alingment is performed
-
-
-		bool forward_and_reverse_screen_output_flag=false;//determines whether the parameters are outputted for forward and reverse calculations
-		double mult_for_is_lambda=1;//multiplier for lambda in the IS
-
-
-		test test1;
-
-		test1.FSA_IS(
-		//additional parameters for the library code
-		library_call_flag,//if true, then the additional parameters are used
-		ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
-		aaAlphabetSize_,//a number of letters in the amino acid alphabet; usually 4
-		codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
-		substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
-		ntFreqs_normalized,//background frequencies of letters in DNA sequences
-		aaFreqs_normalized,//background frequencies of letters in amino acid sequences
-		//additional parameters for the library code - end
-
-		randomSeed_,//randomization number
-		gapOpen1_,//gap opening penalty for the nucleotide sequence #1
-		gapOpen2_,//gap opening penalty for the amino acid sequence #2
-
-		gapEpen1_,//gap extension penalty for the nucleotide sequence #1
-		gapEpen2_,//gap extension penalty for the amino acid sequence #2
-
-		frameshiftCost_,//frameshift penalty gamma
-
-
-		smatr_file_name,//scoring matrix file name
-		RR1_file_name,//background frequencies file name for the sequence #1
-		RR2_file_name,//background frequencies file name for the sequence #2
-		DNA_codon_table_file_name,//a name of a file with DNA codon table
-
-		eps_lambda_,//relative error for lambda calculation
-		eps_K_,//relative error for K calculation
-
-		gapped_flag,//if true, then the gapped alingment is performed
-		max_time_,//maximum allowed calculation time in seconds
-		max_mem_,//maximum allowed memory usage in MB
-
-		seq_number_,//number of tested alignments
-		nalp_,//number of ALPs for the calculation
-		number_of_subsets_for_errors_calculation_,//number of subsets used for the splitting method
-
-		forward_and_reverse_screen_output_flag,//determines whether the parameters are outputted for forward and reverse calculations
-		insertions_after_deletions_,//if true, then insertions after deletions are allowed
-
-		//for test
-		mult_for_is_lambda,//multiplier for lambda in the IS
-
-		//the result
-		d_params);//the resulted parameters
-
-
-		d_params.d_params_flag=true;
-
-		//precompute intercepts
-		//computed in test1.FSA_IS
-
-		delete[]ntFreqs_normalized;
-		delete[]aaFreqs_normalized;
-
-
-		double CurrentTime2;
-		Sls::FSA_utils::get_current_time(CurrentTime2);
-		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
-
-		if(!FALP_pvalues::assert_Gumbel_parameters(
-		d_params)||!isGood())
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void FrameshiftAlignmentEvaluer::initFrameshift\"\n",1);
-		};
-
-
-
-	}
-	catch (...)
-	{ 
-		d_params.d_params_flag=false;
-		throw;
-	};
-
-}
-
-//Initializes Gumbel parameters using precalculated values:
-void FrameshiftAlignmentEvaluer::initParameters(
-const AlignmentEvaluerParameters &parameters_)
-{
-	try
-	{
-		double CurrentTime1;
-		Sls::FSA_utils::get_current_time(CurrentTime1);
-
-		d_params.d_params_flag=false;
-
-		double calculation_error=1e-6;
-
-		d_params.lambda=parameters_.d_lambda;
-		d_params.lambda_error=calculation_error;
-
-		d_params.C=0;
-		d_params.C_error=0;
-
-		d_params.lambda_last_ALP_relative_error=0.0;
-
-
-		d_params.K_C=0.0;
-		d_params.K_C_error=0.0;
-
-		d_params.K=parameters_.d_k;
-		d_params.K_error=calculation_error;
-
-		d_params.a_I=parameters_.d_a1;
-		d_params.a_I_error=calculation_error;
-
-		d_params.a_J=parameters_.d_a2;
-		d_params.a_J_error=calculation_error;
-
-		d_params.sigma=parameters_.d_sigma;
-		d_params.sigma_error=calculation_error;
-
-		d_params.alpha_I=parameters_.d_alpha1;
-		d_params.alpha_I_error=calculation_error;
-
-		d_params.alpha_J=parameters_.d_alpha2;
-		d_params.alpha_J_error=calculation_error;
-
-
-		d_params.gapless_a_I=0.0;
-		d_params.gapless_a_I_error=0.0;
-
-		d_params.gapless_a_J=0.0;
-		d_params.gapless_a_J_error=0.0;
-
-
-
-		d_params.gapless_alpha_I=0.0;
-		d_params.gapless_alpha_I_error=0.0;
-
-		d_params.gapless_alpha_J=0.0;
-		d_params.gapless_alpha_J_error=0.0;
-
-		d_params.gapless_sigma=0.0;
-		d_params.gapless_sigma_error=0.0;
-
-		d_params.G=0;
-		d_params.G1=0;
-		d_params.G2=0;
-
-		d_params.realizations_number=0;
-
-		d_params.m_CalcTime=0;
-
-		//intercepts
-		d_params.b_I=parameters_.d_b1;
-		d_params.b_I_error=calculation_error;
-
-		d_params.b_J=parameters_.d_b2;
-		d_params.b_J_error=calculation_error;
-
-		d_params.beta_I=parameters_.d_beta1;
-		d_params.beta_I_error=calculation_error;
-
-		d_params.beta_J=parameters_.d_beta2;
-		d_params.beta_J_error=calculation_error;
-
-		d_params.tau=parameters_.d_tau;
-		d_params.tau_error=calculation_error;
-
-
-		//arrays initialization
-		std::vector<double > sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.lambda;
-		sbs_arrays[1]=d_params.lambda + calculation_error;
-
-		d_params.m_LambdaSbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.K;
-		sbs_arrays[1]=d_params.K + calculation_error;
-
-		d_params.m_KSbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.C;
-		sbs_arrays[1]=d_params.C + calculation_error;
-
-		d_params.m_CSbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.sigma;
-		sbs_arrays[1]=d_params.sigma + calculation_error;
-
-		d_params.m_SigmaSbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.alpha_I;
-		sbs_arrays[1]=d_params.alpha_I + calculation_error;
-
-		d_params.m_AlphaISbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.alpha_J;
-		sbs_arrays[1]=d_params.alpha_J + calculation_error;
-
-		d_params.m_AlphaJSbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.a_I;
-		sbs_arrays[1]=d_params.a_I + calculation_error;
-
-		d_params.m_AISbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.a_J;
-		sbs_arrays[1]=d_params.a_J + calculation_error;
-
-		d_params.m_AJSbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.b_I;
-		sbs_arrays[1]=d_params.b_I + calculation_error;
-
-		d_params.m_BISbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.b_J;
-		sbs_arrays[1]=d_params.b_J + calculation_error;
-
-		d_params.m_BJSbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.beta_I;
-		sbs_arrays[1]=d_params.beta_I + calculation_error;
-
-		d_params.m_BetaISbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.beta_J;
-		sbs_arrays[1]=d_params.beta_J + calculation_error;
-
-		d_params.m_BetaJSbs=sbs_arrays;
-
-		sbs_arrays.resize(2);
-		sbs_arrays[0]=d_params.tau;
-		sbs_arrays[1]=d_params.tau + calculation_error;
-
-		d_params.m_TauSbs=sbs_arrays;
-
-		d_params.d_params_flag=true;//if true, then the parameters are defined and P-values can be calculated
-
-		FALP_pvalues::compute_tmp_values(d_params);
-
-		if(!FALP_pvalues::assert_Gumbel_parameters(
-		d_params)||!isGood())
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void FrameshiftAlignmentEvaluer::initParameters\"\n",1);
-		};
-
-		double CurrentTime2;
-		Sls::FSA_utils::get_current_time(CurrentTime2);
-		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
-
-	}
-	catch (...)
-	{ 
-		d_params.d_params_flag=false;
-		throw;
-	};
-
-}
-
-void FrameshiftAlignmentEvaluer::initParameters(
-const AlignmentEvaluerParametersWithErrors &parameters_)
-{
-	try
-	{
-		double CurrentTime1;
-		Sls::FSA_utils::get_current_time(CurrentTime1);
-
-		d_params.d_params_flag=false;
-
-		long int array_dim=20;
-
-		long int seed_tmp=12345;
-		srand(seed_tmp);
-
-		d_params.lambda=parameters_.d_lambda;
-		d_params.lambda_error=parameters_.d_lambda_error;
-
-		d_params.C=0;
-		d_params.C_error=0;
-
-		d_params.lambda_last_ALP_relative_error=0.0;
-
-
-		d_params.K_C=0.0;
-		d_params.K_C_error=0.0;
-
-		d_params.K=parameters_.d_k;
-		d_params.K_error=parameters_.d_k_error;
-
-		d_params.a_I=parameters_.d_a1;
-		d_params.a_I_error=parameters_.d_a1_error;
-
-		d_params.a_J=parameters_.d_a2;
-		d_params.a_J_error=parameters_.d_a2_error;
-
-		d_params.sigma=parameters_.d_sigma;
-		d_params.sigma_error=parameters_.d_sigma_error;
-
-		d_params.alpha_I=parameters_.d_alpha1;
-		d_params.alpha_I_error=parameters_.d_alpha1_error;
-
-		d_params.alpha_J=parameters_.d_alpha2;
-		d_params.alpha_J_error=parameters_.d_alpha2_error;
-
-
-		d_params.gapless_a_I=0.0;
-		d_params.gapless_a_I_error=0.0;
-
-		d_params.gapless_a_J=0.0;
-		d_params.gapless_a_J_error=0.0;
-
-
-
-		d_params.gapless_alpha_I=0.0;
-		d_params.gapless_alpha_I_error=0.0;
-
-		d_params.gapless_alpha_J=0.0;
-		d_params.gapless_alpha_J_error=0.0;
-
-		d_params.gapless_sigma=0.0;
-		d_params.gapless_sigma_error=0.0;
-
-		d_params.G=0;
-		d_params.G1=0;
-		d_params.G2=0;
-
-		d_params.realizations_number=0;
-
-		d_params.m_CalcTime=0;
-
-		//intercepts
-		d_params.b_I=parameters_.d_b1;
-		d_params.b_I_error=parameters_.d_b1_error;
-
-		d_params.b_J=parameters_.d_b2;
-		d_params.b_J_error=parameters_.d_b2_error;
-
-		d_params.beta_I=parameters_.d_beta1;
-		d_params.beta_I_error=parameters_.d_beta1_error;
-
-		d_params.beta_J=parameters_.d_beta2;
-		d_params.beta_J_error=parameters_.d_beta2_error;
-
-		d_params.tau=parameters_.d_tau;
-		d_params.tau_error=parameters_.d_tau_error;
-
-		double sqrt_array_dim=sqrt((double)array_dim);
-
-		d_params.m_LambdaSbs.clear();
-		d_params.m_KSbs.clear();
-		d_params.m_CSbs.clear();
-
-		d_params.m_SigmaSbs.clear();
-
-		d_params.m_AlphaISbs.clear();
-		d_params.m_AlphaJSbs.clear();
-
-		d_params.m_AISbs.clear();
-		d_params.m_AJSbs.clear();
-
-		d_params.m_BISbs.clear();
-		d_params.m_BJSbs.clear();
-
-		d_params.m_BetaISbs.clear();
-		d_params.m_BetaJSbs.clear();
-
-		d_params.m_TauSbs.clear();
-
-		long int i;
-		for(i=0;i<array_dim;i++)
-		{
-			d_params.m_LambdaSbs.push_back(d_params.lambda+d_params.lambda_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_KSbs.push_back(d_params.K+d_params.K_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_CSbs.push_back(0);
-
-			d_params.m_SigmaSbs.push_back(d_params.sigma+d_params.sigma_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-
-			d_params.m_AlphaISbs.push_back(d_params.alpha_I+d_params.alpha_I_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_AlphaJSbs.push_back(d_params.alpha_J+d_params.alpha_J_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-
-			d_params.m_AISbs.push_back(d_params.a_I+d_params.a_I_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_AJSbs.push_back(d_params.a_J+d_params.a_J_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-
-			d_params.m_BISbs.push_back(d_params.b_I+d_params.b_I_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_BJSbs.push_back(d_params.b_J+d_params.b_J_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-
-			d_params.m_BetaISbs.push_back(d_params.beta_I+d_params.beta_I_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-			d_params.m_BetaJSbs.push_back(d_params.beta_J+d_params.beta_J_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-
-			d_params.m_TauSbs.push_back(d_params.tau+d_params.tau_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
-		};
-
-		d_params.d_params_flag=true;//if true, then the parameters are defined and P-values can be calculated
-
-		FALP_pvalues::compute_tmp_values(d_params);
-
-		if(!FALP_pvalues::assert_Gumbel_parameters(
-		d_params)||!isGood())
-		{
-			d_params.d_params_flag=false;
-			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void FrameshiftAlignmentEvaluer::initParameters\"\n",1);
-		};
-
-		double CurrentTime2;
-		Sls::FSA_utils::get_current_time(CurrentTime2);
-		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
-
-	}
-	catch (...)
-	{ 
-		d_params.d_params_flag=false;
-		throw;
-	};
-
-}
-
-
-double FrameshiftAlignmentEvaluer::area(double score_,//pairwise alignment score
-double seqlen1_,//length of sequence #1
-double seqlen2_) const//length of sequence #2
-{
-	if(seqlen1_<=0||seqlen2_<=0)
-	{
-		throw error("Error - seqlen1_<=0 or seq2en1_<=0 in \"double FrameshiftAlignmentEvaluer::area\"\n",2);
-	};
-
-	if(!isGood())
-	{
-		throw error("Unexpected error - the Gumbel parameters are not defined properly in \"double FrameshiftAlignmentEvaluer::area\"\n",1);
-	};
-
-	static Sls::FALP_pvalues pvalues_obj;
-
-	double P;
-	double E;
-	double area_res;
-	bool area_is_1_flag=false;
-	bool compute_only_area=true;
-
-	pvalues_obj.get_appr_tail_prob_with_cov_without_errors(
-	d_params,
-	pvalues_obj.blast,
-	score_,
-	seqlen1_,
-	seqlen2_,
-
-	P,
-
-	E,
-
-	area_res,
-	pvalues_obj.a_normal,
-	pvalues_obj.b_normal,
-	pvalues_obj.h_normal,
-	pvalues_obj.N_normal,
-	pvalues_obj.p_normal,
-	area_is_1_flag,
-	compute_only_area);
-
-
-	return area_res;
-
-}
-
-
-void FrameshiftAlignmentEvaluer::calc(double score_,//pairwise alignment score
-double seqlen1_,//length of sequence #1
-double seqlen2_,//length of sequence #2
-double &pvalue_,//resulted P-value
-double &pvalueErr_,//P-value error
-double &evalue_,//resulted E-value
-double &evalueErr_) const//E-value error
-{
-
-	if(seqlen1_<=0||seqlen2_<=0)
-	{
-		throw error("Error - seqlen1_<=0 or seqlen2_<=0 in \"double FrameshiftAlignmentEvaluer::calc\"\n",2);
-	};
-
-	if(!isGood())
-	{
-		throw error("Unexpected error - the Gumbel parameters are not defined properly in \"double FrameshiftAlignmentEvaluer::calc\"\n",1);
-	};
-
-	static Sls::FALP_pvalues pvalues_obj;
-
-	pvalues_obj.calculate_P_values(
-		score_, seqlen1_, seqlen2_,
-		d_params, 
-		pvalue_,
-		pvalueErr_,
-		evalue_,
-		evalueErr_);
-
-}
-
-void FrameshiftAlignmentEvaluer::calc(double score_,//pairwise alignment score
-double seqlen1_,//length of sequence #1
-double seqlen2_,//length of sequence #2
-double &pvalue_,//resulted P-value
-double &evalue_) const//resulted E-value
-{
-	if(seqlen1_<=0||seqlen2_<=0)
-	{
-		throw error("Error - seqlen1_<=0 or seqlen2_<=0 in \"double FrameshiftAlignmentEvaluer::calc\"\n",2);
-	};
-
-	if(!isGood())
-	{
-		throw error("Unexpected error - d_params is not defined in \"double FrameshiftAlignmentEvaluer::calc\"\n",1);
-	};
-
-	static Sls::FALP_pvalues pvalues_obj;
-
-	bool area_is_1_flag=false;
-
-	double area;
-
-
-	pvalues_obj.get_appr_tail_prob_with_cov_without_errors(
-	d_params,
-	pvalues_obj.blast,
-	score_,
-	seqlen1_,
-	seqlen2_,
-
-	pvalue_,
-
-	evalue_,
-
-	area,
-	pvalues_obj.a_normal,
-	pvalues_obj.b_normal,
-	pvalues_obj.h_normal,
-	pvalues_obj.N_normal,
-	pvalues_obj.p_normal,
-	area_is_1_flag);
-}
-
-}
-
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_fsa1_lib.cpp
+
+Author: Sergey Sheetlin
+
+Contents: library functions of main routines
+
+******************************************************************************/
+
+
+#include "sls_falp_alignment_evaluer.hpp"
+
+#include "sls_fsa1_parameters.hpp"
+#include "sls_fsa1_utils.hpp"
+#include "sls_alp_regression.hpp"
+#include "njn_localmaxstatmatrix.hpp"
+#include "njn_localmaxstatutil.hpp"
+#include "sls_fsa1.hpp"
+
+using namespace std;
+
+
+namespace Sls {
+
+// Write the parameters:
+std::ostream &operator<<(std::ostream &s_,
+const FrameshiftAlignmentEvaluer &g_)
+{
+
+	if(!FALP_pvalues::assert_Gumbel_parameters(
+	g_.d_params)||!g_.isGood())
+	{
+		throw error("Error - the Gumbel parameters are not defined properly in the function \"std::ostream &operator<<\"\n",1);
+	};
+
+	s_<<g_.d_params;
+	return s_;
+}
+
+// Read the parameters:
+std::istream &operator>>(std::istream &s_,
+FrameshiftAlignmentEvaluer &g_)
+{
+	try
+	{
+		g_.d_params.d_params_flag=false;
+		s_>>g_.d_params;
+		g_.d_params.d_params_flag=true;
+
+		//precompute intercepts
+		FALP_pvalues::compute_intercepts(g_.d_params);
+
+		if(!FALP_pvalues::assert_Gumbel_parameters(
+		g_.d_params)||!g_.isGood())
+		{
+			g_.d_params.d_params_flag=false;
+		};
+
+		return s_;
+	}
+	catch (...)
+	{ 
+		g_.d_params.d_params_flag=false;
+		throw;
+	};
+}
+
+//check correctness of the input parameters for gapless alignment
+void FrameshiftAlignmentEvaluer::assert_Gapless_input_parameters(
+long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
+long aaAlphabetSize_,//a number of letters in the amino acid alphabet
+const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
+
+const double *ntFreqs_,//background frequencies of letters in DNA sequences
+const double *aaFreqs_,//background frequencies of letters in amino acid sequences
+double *&ntFreqs_normalized_,//normalized background frequencies of letters in DNA sequences
+double *&aaFreqs_normalized_,//normalized background frequencies of letters in amino acid sequences
+const string function_name_)//"assert_Gapless_input_parameters" is called from "function_name_" function
+{
+	if(!(ntAlphabetSize_>0))
+	{
+		d_params.d_params_flag=false;
+		throw error("Error - the parameter \"ntAlphabetSize_\" in the function \""+function_name_+"\" must be positive\n",1);
+	};
+
+	if(!(aaAlphabetSize_>0))
+	{
+		d_params.d_params_flag=false;
+		throw error("Error - the parameter \"aaAlphabetSize_\" in the function \""+function_name_+"\" must be positive\n",1);
+	};
+
+	long int i;
+	for(i=0;i<ntAlphabetSize_*ntAlphabetSize_*ntAlphabetSize_;i++)
+	{
+		if(!(codonTable_[i]>=0&&codonTable_[i]<aaAlphabetSize_))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the value \"codonTable_["+FSA_utils::long_to_string(i)+"]\" in the function \""+function_name_+"\" is incorrect\n",1);
+		};
+	};
+
+	double sum_nt=0;
+	for(i=0;i<ntAlphabetSize_;i++)
+	{
+		if(ntFreqs_[i]<0)
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the value \"ntFreqs_["+FSA_utils::long_to_string(i)+"]\" in the function \""+function_name_+"\" must be non-negative\n",1);
+		};
+		sum_nt+=ntFreqs_[i];
+	};
+
+	if(sum_nt<=0)
+	{
+		throw error("Error - sum of the frequencies \"ntFreqs_\" is non-positive in the function \""+function_name_+"\"\n",1);
+	};
+
+	ntFreqs_normalized_=new double[ntAlphabetSize_];
+	FSA_utils::assert_mem(ntFreqs_normalized_);
+
+	for(i=0;i<ntAlphabetSize_;i++)
+	{
+		ntFreqs_normalized_[i]=ntFreqs_[i]/sum_nt;
+	};
+
+	double sum_aa=0;
+	for(i=0;i<aaAlphabetSize_;i++)
+	{
+		if(aaFreqs_[i]<0)
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the value \"aaFreqs_["+FSA_utils::long_to_string(i)+"]\" in the function \""+function_name_+"\" must be non-negative\n",1);
+		};
+		sum_aa+=aaFreqs_[i];
+	};
+
+	if(sum_aa<=0)
+	{
+		throw error("Error - sum of the frequencies \"aaFreqs_\" is non-positive in the function \""+function_name_+"\"\n",1);
+	};
+
+	aaFreqs_normalized_=new double[aaAlphabetSize_];
+	FSA_utils::assert_mem(aaFreqs_normalized_);
+
+	for(i=0;i<aaAlphabetSize_;i++)
+	{
+		aaFreqs_normalized_[i]=aaFreqs_[i]/sum_aa;
+	};
+}
+
+//Computes gapless Gumbel parameters:
+void FrameshiftAlignmentEvaluer::initGapless(long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
+long aaAlphabetSize_,//a number of letters in the amino acid alphabet
+const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
+
+const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
+const double *ntFreqs_,//background frequencies of letters in DNA sequences
+const double *aaFreqs_,//background frequencies of letters in amino acid sequences
+double max_time_)//maximum allowed calculation time in seconds
+{
+
+	double *RR1_AA=NULL;
+
+	try
+	{
+
+
+		double CurrentTime1;
+		Sls::FSA_utils::get_current_time(CurrentTime1);
+
+		//check correctness of the input parameters for gapless alignment
+		string function_name="void FrameshiftAlignmentEvaluer::initGapless";
+		double *ntFreqs_normalized=NULL;//normalized background frequencies of letters in DNA sequences
+		double *aaFreqs_normalized=NULL;//normalized background frequencies of letters in amino acid sequences
+		assert_Gapless_input_parameters(
+		ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
+		aaAlphabetSize_,//a number of letters in the amino acid alphabet
+		codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
+		ntFreqs_,//background frequencies of letters in DNA sequences
+		aaFreqs_,//background frequencies of letters in amino acid sequences
+		ntFreqs_normalized,//normalized background frequencies of letters in DNA sequences
+		aaFreqs_normalized,//normalized background frequencies of letters in amino acid sequences
+		function_name);//"assert_Gapless_input_parameters" is called from "function_name_" function
+
+		d_params.d_params_flag=false;
+
+		long int codon_length=3;
+//------
+
+		FSA_utils::extract_AA_frequencies_for_DNA_sequence(
+		codonTable_,//<codon code,AA number>
+		codon_length,//codon length 
+		ntAlphabetSize_,//number of letters for the sequence 1
+		aaAlphabetSize_,//number of letters for the sequence 2
+		ntFreqs_normalized,//nucleotide probabilities
+		RR1_AA);//the resulted frequencies
+
+		if(max_time_<=0)
+		{
+			max_time_=60;
+		};
+		
+		Njn::LocalMaxStatMatrix local_max_stat_matrix(aaAlphabetSize_,
+							  substitutionScoreMatrix_,
+							  RR1_AA,
+							  aaFreqs_normalized,
+							  aaAlphabetSize_,
+							  max_time_);
+
+
+		if(local_max_stat_matrix.getTerminated()) 
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+
+		//calculation of a and sigma
+		double calculation_error=1e-6;
+
+		d_params.gapless_alpha_J = local_max_stat_matrix.getAlpha ();
+		d_params.gapless_alpha_J=FSA_utils::Tmax(d_params.gapless_alpha_J,0.0);
+		d_params.gapless_alpha_J_error = calculation_error;
+
+		d_params.gapless_alpha_I=d_params.gapless_alpha_J*9;
+		d_params.gapless_alpha_I_error = calculation_error*9;
+
+		d_params.gapless_sigma=d_params.gapless_alpha_J*3;
+		d_params.gapless_sigma_error = calculation_error*3;
+
+
+		d_params.gapless_a_J = local_max_stat_matrix.getA ();
+		d_params.gapless_a_J=FSA_utils::Tmax(d_params.gapless_a_J,0.0);
+		d_params.gapless_a_J_error = calculation_error;
+
+		d_params.gapless_a_I = d_params.gapless_a_J*3;
+		d_params.gapless_a_I_error = calculation_error*3;
+
+		//calculation of all required parameters for a gapless case
+		d_params.G=0;
+		d_params.G1=0;
+		d_params.G2=0;
+
+		d_params.lambda = local_max_stat_matrix.getLambda ();
+		d_params.lambda_error = calculation_error;
+
+		d_params.K = local_max_stat_matrix.getK ();
+		d_params.K_error = calculation_error;
+			
+		d_params.C = local_max_stat_matrix.getC ();
+		d_params.C_error = calculation_error;
+
+		if(d_params.C!=0)
+		{
+			d_params.K_C = d_params.K/d_params.C;
+		}
+		else
+		{
+			d_params.K_C = 0;
+		};
+		d_params.K_C_error = calculation_error;
+
+
+		d_params.sigma = d_params.gapless_sigma;
+		d_params.sigma_error = d_params.gapless_sigma_error;
+
+		d_params.alpha_I = d_params.gapless_alpha_I;
+		d_params.alpha_I_error = d_params.gapless_alpha_I_error;
+
+		d_params.alpha_J = d_params.gapless_alpha_J;
+		d_params.alpha_J_error = d_params.gapless_alpha_J_error;
+
+		d_params.a_I = d_params.gapless_a_I;
+		d_params.a_I_error = d_params.gapless_a_I_error;
+
+		d_params.a_J = d_params.gapless_a_J;
+		d_params.a_J_error = d_params.gapless_a_J_error;
+
+
+		std::vector<double > sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.lambda;
+		sbs_arrays[1]=d_params.lambda + calculation_error;
+
+		d_params.m_LambdaSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.K;
+		sbs_arrays[1]=d_params.K+calculation_error;
+
+		d_params.m_KSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.C;
+		sbs_arrays[1]=d_params.C+calculation_error;
+
+		d_params.m_CSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.sigma;
+		sbs_arrays[1]=d_params.sigma + calculation_error;
+
+		d_params.m_SigmaSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.alpha_I;
+		sbs_arrays[1]=d_params.alpha_I + calculation_error;
+
+		d_params.m_AlphaISbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.alpha_J;
+		sbs_arrays[1]=d_params.alpha_J + calculation_error;
+
+		d_params.m_AlphaJSbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.a_I;
+		sbs_arrays[1]=d_params.a_I + calculation_error;
+
+		d_params.m_AISbs=sbs_arrays;
+
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.a_J;
+		sbs_arrays[1]=d_params.a_J + calculation_error;
+
+		d_params.m_AJSbs=sbs_arrays;
+
+		d_params.d_params_flag=true;
+
+		//precompute intercepts
+		FALP_pvalues::compute_intercepts(d_params);
+
+		double CurrentTime2;
+		Sls::FSA_utils::get_current_time(CurrentTime2);
+		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
+
+		delete[]RR1_AA;RR1_AA=NULL;
+
+		if(!FALP_pvalues::assert_Gumbel_parameters(
+		d_params)||!isGood())
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void FrameshiftAlignmentEvaluer::initGapless\"\n",1);
+		};
+
+		delete[]ntFreqs_normalized;
+		delete[]aaFreqs_normalized;
+
+	}
+	catch (...)
+	{ 
+		d_params.d_params_flag=false;
+		delete[]RR1_AA;RR1_AA=NULL;
+		throw;
+	};
+}
+
+
+//Computes gapped Gumbel parameters:
+//The NCBI convention is used for penalizing a gap:
+//For example, a gap of length k is penalized as gapOpen1_+k*gapEpen1_ for sequence #1
+void FrameshiftAlignmentEvaluer::initFrameshift(long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
+long aaAlphabetSize_,//a number of letters in the amino acid alphabet; usually 4
+const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
+//letters are numerated from 0; 
+//each codon defines a code (an integer number from [0,...,ntAlphabetSize_^3 integers];
+//for example, for the DNA alphabet ACGT, 
+//AAA corresponds to codonTable_[0]; AAC corresponds to codonTable_[1] and so on.
+//codonTable_[x] contains an amino acid number such that the amino acid corresponds to a codon with the code x
+//for example, for the amino acid alphabet ARNDCQEGHILKMFPSTWYVBJZX* ("*" defines the stop codons), 
+//if AAC is coded by N (amino acid with the number 2), then codonTable_[1]=2.
+
+const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
+const double *ntFreqs_,//background frequencies of letters in DNA sequences
+const double *aaFreqs_,//background frequencies of letters in amino acid sequences
+long gapOpen1_,//gap opening penalty for sequence #1
+long gapEpen1_,//gap extension penalty for sequence #1
+long gapOpen2_,//gap opening penalty for sequence #2
+long gapEpen2_,//gap extension penalty for sequence #2
+long frameshiftCost_,//frameshift penalty
+bool insertions_after_deletions_,//if true, then insertions after deletions are permitted
+double eps_lambda_,//relative error for the parameter lambda
+double eps_K_,//relative error for the parameter K
+double max_time_,//maximum allowed calculation time in seconds
+double max_mem_,//maximum allowed memory usage in MB
+long randomSeed_,//randomizaton seed
+
+//in the case when max_time_<=0, the following parameters are used:
+long int seq_number_,//a number of alignments
+long int nalp_,//a number of ascending ladder points used in the calculation
+long int number_of_subsets_for_errors_calculation_)//a number of subsets used in the error calculation
+{
+	try
+	{
+
+		double CurrentTime1;
+		Sls::FSA_utils::get_current_time(CurrentTime1);
+
+		//check the input parameters
+		string function_name="void FrameshiftAlignmentEvaluer::initFrameshift";
+		double *ntFreqs_normalized=NULL;//normalized background frequencies of letters in DNA sequences
+		double *aaFreqs_normalized=NULL;//normalized background frequencies of letters in amino acid sequences
+		assert_Gapless_input_parameters(
+		ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
+		aaAlphabetSize_,//a number of letters in the amino acid alphabet
+		codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
+		ntFreqs_,//background frequencies of letters in DNA sequences
+		aaFreqs_,//background frequencies of letters in amino acid sequences
+		ntFreqs_normalized,//normalized background frequencies of letters in DNA sequences
+		aaFreqs_normalized,//normalized background frequencies of letters in amino acid sequences
+		function_name);//"assert_Gapless_input_parameters" is called from "function_name_" function
+
+
+		if(!(gapEpen1_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"gapEpen1_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(gapEpen2_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"gapEpen2_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(frameshiftCost_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"frameshiftCost_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(eps_lambda_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"eps_lambda_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(eps_K_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"eps_K_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(max_mem_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"max_mem_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(seq_number_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"seq_number_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(nalp_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"nalp_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		if(!(number_of_subsets_for_errors_calculation_>0))
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - the parameter \"number_of_subsets_for_errors_calculation_\" in the function \""+function_name+"\" must be positive\n",1);
+		};
+
+		d_params.d_params_flag=false;
+
+		bool library_call_flag=true;//if true, then the additional parameters are used
+		string smatr_file_name="";//scoring matrix file name
+		string RR1_file_name="";//background frequencies file name for the sequence #1
+		string RR2_file_name="";//background frequencies file name for the sequence #2
+		string DNA_codon_table_file_name="";//a name of a file with DNA codon table
+
+		bool gapped_flag=true;//if true, then the gapped alingment is performed
+
+
+		bool forward_and_reverse_screen_output_flag=false;//determines whether the parameters are outputted for forward and reverse calculations
+		double mult_for_is_lambda=1;//multiplier for lambda in the IS
+
+
+		test test1;
+
+		test1.FSA_IS(
+		//additional parameters for the library code
+		library_call_flag,//if true, then the additional parameters are used
+		ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
+		aaAlphabetSize_,//a number of letters in the amino acid alphabet; usually 4
+		codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
+		substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
+		ntFreqs_normalized,//background frequencies of letters in DNA sequences
+		aaFreqs_normalized,//background frequencies of letters in amino acid sequences
+		//additional parameters for the library code - end
+
+		randomSeed_,//randomization number
+		gapOpen1_,//gap opening penalty for the nucleotide sequence #1
+		gapOpen2_,//gap opening penalty for the amino acid sequence #2
+
+		gapEpen1_,//gap extension penalty for the nucleotide sequence #1
+		gapEpen2_,//gap extension penalty for the amino acid sequence #2
+
+		frameshiftCost_,//frameshift penalty gamma
+
+
+		smatr_file_name,//scoring matrix file name
+		RR1_file_name,//background frequencies file name for the sequence #1
+		RR2_file_name,//background frequencies file name for the sequence #2
+		DNA_codon_table_file_name,//a name of a file with DNA codon table
+
+		eps_lambda_,//relative error for lambda calculation
+		eps_K_,//relative error for K calculation
+
+		gapped_flag,//if true, then the gapped alingment is performed
+		max_time_,//maximum allowed calculation time in seconds
+		max_mem_,//maximum allowed memory usage in MB
+
+		seq_number_,//number of tested alignments
+		nalp_,//number of ALPs for the calculation
+		number_of_subsets_for_errors_calculation_,//number of subsets used for the splitting method
+
+		forward_and_reverse_screen_output_flag,//determines whether the parameters are outputted for forward and reverse calculations
+		insertions_after_deletions_,//if true, then insertions after deletions are allowed
+
+		//for test
+		mult_for_is_lambda,//multiplier for lambda in the IS
+
+		//the result
+		d_params);//the resulted parameters
+
+
+		d_params.d_params_flag=true;
+
+		//precompute intercepts
+		//computed in test1.FSA_IS
+
+		delete[]ntFreqs_normalized;
+		delete[]aaFreqs_normalized;
+
+
+		double CurrentTime2;
+		Sls::FSA_utils::get_current_time(CurrentTime2);
+		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
+
+		if(!FALP_pvalues::assert_Gumbel_parameters(
+		d_params)||!isGood())
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void FrameshiftAlignmentEvaluer::initFrameshift\"\n",1);
+		};
+
+
+
+	}
+	catch (...)
+	{ 
+		d_params.d_params_flag=false;
+		throw;
+	};
+
+}
+
+//Initializes Gumbel parameters using precalculated values:
+void FrameshiftAlignmentEvaluer::initParameters(
+const AlignmentEvaluerParameters &parameters_)
+{
+	try
+	{
+		double CurrentTime1;
+		Sls::FSA_utils::get_current_time(CurrentTime1);
+
+		d_params.d_params_flag=false;
+
+		double calculation_error=1e-6;
+
+		d_params.lambda=parameters_.d_lambda;
+		d_params.lambda_error=calculation_error;
+
+		d_params.C=0;
+		d_params.C_error=0;
+
+		d_params.lambda_last_ALP_relative_error=0.0;
+
+
+		d_params.K_C=0.0;
+		d_params.K_C_error=0.0;
+
+		d_params.K=parameters_.d_k;
+		d_params.K_error=calculation_error;
+
+		d_params.a_I=parameters_.d_a1;
+		d_params.a_I_error=calculation_error;
+
+		d_params.a_J=parameters_.d_a2;
+		d_params.a_J_error=calculation_error;
+
+		d_params.sigma=parameters_.d_sigma;
+		d_params.sigma_error=calculation_error;
+
+		d_params.alpha_I=parameters_.d_alpha1;
+		d_params.alpha_I_error=calculation_error;
+
+		d_params.alpha_J=parameters_.d_alpha2;
+		d_params.alpha_J_error=calculation_error;
+
+
+		d_params.gapless_a_I=0.0;
+		d_params.gapless_a_I_error=0.0;
+
+		d_params.gapless_a_J=0.0;
+		d_params.gapless_a_J_error=0.0;
+
+
+
+		d_params.gapless_alpha_I=0.0;
+		d_params.gapless_alpha_I_error=0.0;
+
+		d_params.gapless_alpha_J=0.0;
+		d_params.gapless_alpha_J_error=0.0;
+
+		d_params.gapless_sigma=0.0;
+		d_params.gapless_sigma_error=0.0;
+
+		d_params.G=0;
+		d_params.G1=0;
+		d_params.G2=0;
+
+		d_params.realizations_number=0;
+
+		d_params.m_CalcTime=0;
+
+		//intercepts
+		d_params.b_I=parameters_.d_b1;
+		d_params.b_I_error=calculation_error;
+
+		d_params.b_J=parameters_.d_b2;
+		d_params.b_J_error=calculation_error;
+
+		d_params.beta_I=parameters_.d_beta1;
+		d_params.beta_I_error=calculation_error;
+
+		d_params.beta_J=parameters_.d_beta2;
+		d_params.beta_J_error=calculation_error;
+
+		d_params.tau=parameters_.d_tau;
+		d_params.tau_error=calculation_error;
+
+
+		//arrays initialization
+		std::vector<double > sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.lambda;
+		sbs_arrays[1]=d_params.lambda + calculation_error;
+
+		d_params.m_LambdaSbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.K;
+		sbs_arrays[1]=d_params.K + calculation_error;
+
+		d_params.m_KSbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.C;
+		sbs_arrays[1]=d_params.C + calculation_error;
+
+		d_params.m_CSbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.sigma;
+		sbs_arrays[1]=d_params.sigma + calculation_error;
+
+		d_params.m_SigmaSbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.alpha_I;
+		sbs_arrays[1]=d_params.alpha_I + calculation_error;
+
+		d_params.m_AlphaISbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.alpha_J;
+		sbs_arrays[1]=d_params.alpha_J + calculation_error;
+
+		d_params.m_AlphaJSbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.a_I;
+		sbs_arrays[1]=d_params.a_I + calculation_error;
+
+		d_params.m_AISbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.a_J;
+		sbs_arrays[1]=d_params.a_J + calculation_error;
+
+		d_params.m_AJSbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.b_I;
+		sbs_arrays[1]=d_params.b_I + calculation_error;
+
+		d_params.m_BISbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.b_J;
+		sbs_arrays[1]=d_params.b_J + calculation_error;
+
+		d_params.m_BJSbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.beta_I;
+		sbs_arrays[1]=d_params.beta_I + calculation_error;
+
+		d_params.m_BetaISbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.beta_J;
+		sbs_arrays[1]=d_params.beta_J + calculation_error;
+
+		d_params.m_BetaJSbs=sbs_arrays;
+
+		sbs_arrays.resize(2);
+		sbs_arrays[0]=d_params.tau;
+		sbs_arrays[1]=d_params.tau + calculation_error;
+
+		d_params.m_TauSbs=sbs_arrays;
+
+		d_params.d_params_flag=true;//if true, then the parameters are defined and P-values can be calculated
+
+		FALP_pvalues::compute_tmp_values(d_params);
+
+		if(!FALP_pvalues::assert_Gumbel_parameters(
+		d_params)||!isGood())
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void FrameshiftAlignmentEvaluer::initParameters\"\n",1);
+		};
+
+		double CurrentTime2;
+		Sls::FSA_utils::get_current_time(CurrentTime2);
+		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
+
+	}
+	catch (...)
+	{ 
+		d_params.d_params_flag=false;
+		throw;
+	};
+
+}
+
+void FrameshiftAlignmentEvaluer::initParameters(
+const AlignmentEvaluerParametersWithErrors &parameters_)
+{
+	try
+	{
+		double CurrentTime1;
+		Sls::FSA_utils::get_current_time(CurrentTime1);
+
+		d_params.d_params_flag=false;
+
+		long int array_dim=20;
+
+		long int seed_tmp=12345;
+		srand(seed_tmp);
+
+		d_params.lambda=parameters_.d_lambda;
+		d_params.lambda_error=parameters_.d_lambda_error;
+
+		d_params.C=0;
+		d_params.C_error=0;
+
+		d_params.lambda_last_ALP_relative_error=0.0;
+
+
+		d_params.K_C=0.0;
+		d_params.K_C_error=0.0;
+
+		d_params.K=parameters_.d_k;
+		d_params.K_error=parameters_.d_k_error;
+
+		d_params.a_I=parameters_.d_a1;
+		d_params.a_I_error=parameters_.d_a1_error;
+
+		d_params.a_J=parameters_.d_a2;
+		d_params.a_J_error=parameters_.d_a2_error;
+
+		d_params.sigma=parameters_.d_sigma;
+		d_params.sigma_error=parameters_.d_sigma_error;
+
+		d_params.alpha_I=parameters_.d_alpha1;
+		d_params.alpha_I_error=parameters_.d_alpha1_error;
+
+		d_params.alpha_J=parameters_.d_alpha2;
+		d_params.alpha_J_error=parameters_.d_alpha2_error;
+
+
+		d_params.gapless_a_I=0.0;
+		d_params.gapless_a_I_error=0.0;
+
+		d_params.gapless_a_J=0.0;
+		d_params.gapless_a_J_error=0.0;
+
+
+
+		d_params.gapless_alpha_I=0.0;
+		d_params.gapless_alpha_I_error=0.0;
+
+		d_params.gapless_alpha_J=0.0;
+		d_params.gapless_alpha_J_error=0.0;
+
+		d_params.gapless_sigma=0.0;
+		d_params.gapless_sigma_error=0.0;
+
+		d_params.G=0;
+		d_params.G1=0;
+		d_params.G2=0;
+
+		d_params.realizations_number=0;
+
+		d_params.m_CalcTime=0;
+
+		//intercepts
+		d_params.b_I=parameters_.d_b1;
+		d_params.b_I_error=parameters_.d_b1_error;
+
+		d_params.b_J=parameters_.d_b2;
+		d_params.b_J_error=parameters_.d_b2_error;
+
+		d_params.beta_I=parameters_.d_beta1;
+		d_params.beta_I_error=parameters_.d_beta1_error;
+
+		d_params.beta_J=parameters_.d_beta2;
+		d_params.beta_J_error=parameters_.d_beta2_error;
+
+		d_params.tau=parameters_.d_tau;
+		d_params.tau_error=parameters_.d_tau_error;
+
+		double sqrt_array_dim=sqrt((double)array_dim);
+
+		d_params.m_LambdaSbs.clear();
+		d_params.m_KSbs.clear();
+		d_params.m_CSbs.clear();
+
+		d_params.m_SigmaSbs.clear();
+
+		d_params.m_AlphaISbs.clear();
+		d_params.m_AlphaJSbs.clear();
+
+		d_params.m_AISbs.clear();
+		d_params.m_AJSbs.clear();
+
+		d_params.m_BISbs.clear();
+		d_params.m_BJSbs.clear();
+
+		d_params.m_BetaISbs.clear();
+		d_params.m_BetaJSbs.clear();
+
+		d_params.m_TauSbs.clear();
+
+		long int i;
+		for(i=0;i<array_dim;i++)
+		{
+			d_params.m_LambdaSbs.push_back(d_params.lambda+d_params.lambda_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_KSbs.push_back(d_params.K+d_params.K_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_CSbs.push_back(0);
+
+			d_params.m_SigmaSbs.push_back(d_params.sigma+d_params.sigma_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+
+			d_params.m_AlphaISbs.push_back(d_params.alpha_I+d_params.alpha_I_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_AlphaJSbs.push_back(d_params.alpha_J+d_params.alpha_J_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+
+			d_params.m_AISbs.push_back(d_params.a_I+d_params.a_I_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_AJSbs.push_back(d_params.a_J+d_params.a_J_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+
+			d_params.m_BISbs.push_back(d_params.b_I+d_params.b_I_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_BJSbs.push_back(d_params.b_J+d_params.b_J_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+
+			d_params.m_BetaISbs.push_back(d_params.beta_I+d_params.beta_I_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+			d_params.m_BetaJSbs.push_back(d_params.beta_J+d_params.beta_J_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+
+			d_params.m_TauSbs.push_back(d_params.tau+d_params.tau_error*FALP_pvalues::standard_normal()*sqrt_array_dim);
+		};
+
+		d_params.d_params_flag=true;//if true, then the parameters are defined and P-values can be calculated
+
+		FALP_pvalues::compute_tmp_values(d_params);
+
+		if(!FALP_pvalues::assert_Gumbel_parameters(
+		d_params)||!isGood())
+		{
+			d_params.d_params_flag=false;
+			throw error("Error - computation of the Gumbel parameters is unsuccessful in the function \"void FrameshiftAlignmentEvaluer::initParameters\"\n",1);
+		};
+
+		double CurrentTime2;
+		Sls::FSA_utils::get_current_time(CurrentTime2);
+		d_params.m_CalcTime=CurrentTime2-CurrentTime1;
+
+	}
+	catch (...)
+	{ 
+		d_params.d_params_flag=false;
+		throw;
+	};
+
+}
+
+
+double FrameshiftAlignmentEvaluer::area(double score_,//pairwise alignment score
+double seqlen1_,//length of sequence #1
+double seqlen2_) const//length of sequence #2
+{
+	if(seqlen1_<=0||seqlen2_<=0)
+	{
+		throw error("Error - seqlen1_<=0 or seq2en1_<=0 in \"double FrameshiftAlignmentEvaluer::area\"\n",2);
+	};
+
+	if(!isGood())
+	{
+		throw error("Unexpected error - the Gumbel parameters are not defined properly in \"double FrameshiftAlignmentEvaluer::area\"\n",1);
+	};
+
+	static Sls::FALP_pvalues pvalues_obj;
+
+	double P;
+	double E;
+	double area_res;
+	bool area_is_1_flag=false;
+	bool compute_only_area=true;
+
+	pvalues_obj.get_appr_tail_prob_with_cov_without_errors(
+	d_params,
+	pvalues_obj.blast,
+	score_,
+	seqlen1_,
+	seqlen2_,
+
+	P,
+
+	E,
+
+	area_res,
+	pvalues_obj.a_normal,
+	pvalues_obj.b_normal,
+	pvalues_obj.h_normal,
+	pvalues_obj.N_normal,
+	pvalues_obj.p_normal,
+	area_is_1_flag,
+	compute_only_area);
+
+
+	return area_res;
+
+}
+
+
+void FrameshiftAlignmentEvaluer::calc(double score_,//pairwise alignment score
+double seqlen1_,//length of sequence #1
+double seqlen2_,//length of sequence #2
+double &pvalue_,//resulted P-value
+double &pvalueErr_,//P-value error
+double &evalue_,//resulted E-value
+double &evalueErr_) const//E-value error
+{
+
+	if(seqlen1_<=0||seqlen2_<=0)
+	{
+		throw error("Error - seqlen1_<=0 or seqlen2_<=0 in \"double FrameshiftAlignmentEvaluer::calc\"\n",2);
+	};
+
+	if(!isGood())
+	{
+		throw error("Unexpected error - the Gumbel parameters are not defined properly in \"double FrameshiftAlignmentEvaluer::calc\"\n",1);
+	};
+
+	static Sls::FALP_pvalues pvalues_obj;
+
+	pvalues_obj.calculate_P_values(
+		score_, seqlen1_, seqlen2_,
+		d_params, 
+		pvalue_,
+		pvalueErr_,
+		evalue_,
+		evalueErr_);
+
+}
+
+void FrameshiftAlignmentEvaluer::calc(double score_,//pairwise alignment score
+double seqlen1_,//length of sequence #1
+double seqlen2_,//length of sequence #2
+double &pvalue_,//resulted P-value
+double &evalue_) const//resulted E-value
+{
+	if(seqlen1_<=0||seqlen2_<=0)
+	{
+		throw error("Error - seqlen1_<=0 or seqlen2_<=0 in \"double FrameshiftAlignmentEvaluer::calc\"\n",2);
+	};
+
+	if(!isGood())
+	{
+		throw error("Unexpected error - d_params is not defined in \"double FrameshiftAlignmentEvaluer::calc\"\n",1);
+	};
+
+	static Sls::FALP_pvalues pvalues_obj;
+
+	bool area_is_1_flag=false;
+
+	double area;
+
+
+	pvalues_obj.get_appr_tail_prob_with_cov_without_errors(
+	d_params,
+	pvalues_obj.blast,
+	score_,
+	seqlen1_,
+	seqlen2_,
+
+	pvalue_,
+
+	evalue_,
+
+	area,
+	pvalues_obj.a_normal,
+	pvalues_obj.b_normal,
+	pvalues_obj.h_normal,
+	pvalues_obj.N_normal,
+	pvalues_obj.p_normal,
+	area_is_1_flag);
+}
+
+}
+
+
diff --git a/src/alp/sls_falp_alignment_evaluer.hpp b/src/alp/sls_falp_alignment_evaluer.hpp
index f8e3b87..e88a3aa 100644
--- a/src/alp/sls_falp_alignment_evaluer.hpp
+++ b/src/alp/sls_falp_alignment_evaluer.hpp
@@ -1,187 +1,187 @@
-#ifndef INCLUDED_SLS_FALP_LIB
-#define INCLUDED_SLS_FALP_LIB
-
-/* $Id: $
-* ===========================================================================
-*
-*							PUBLIC DOMAIN NOTICE
-*			   National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_fsa1_lib.hpp
-
-Authors: Martin Frith, Sergey Sheetlin
-
-Contents: library functions of main routines
-
-******************************************************************************/
-
-#include <string>
-#include "sls_fsa1_pvalues.hpp"
-
-namespace Sls {
-
-	class FrameshiftAlignmentEvaluer {
-
-
-	//Write the parameters:
-	friend std::ostream &operator<<(std::ostream &s_,
-			const FrameshiftAlignmentEvaluer &g_);
-
-	//Read the parameters:
-	friend std::istream &operator>>(std::istream &s_,
-			FrameshiftAlignmentEvaluer &g_);
-
-	public:
-
-	//Computes gapless Gumbel parameters:
-	void initGapless(long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
-			long aaAlphabetSize_,//a number of letters in the amino acid alphabet
-			const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
-
-			const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
-			const double *ntFreqs_,//background frequencies of letters in DNA sequences
-			const double *aaFreqs_,//background frequencies of letters in amino acid sequences
-			double max_time_=60);//maximum allowed calculation time in seconds
-
-
-	void initFrameshift(long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
-			long aaAlphabetSize_,//a number of letters in the amino acid alphabet
-			const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
-			//letters are numerated from 0; 
-			//each codon defines a code (an integer number from [0,...,ntAlphabetSize_^3-1]);
-			//for example, for the DNA alphabet ACGT, 
-			//AAA corresponds to codonTable_[0]; AAC corresponds to codonTable_[1] and so on.
-			//codonTable_[x] contains an amino acid number such that the amino acid corresponds to a codon with the code x
-			//for example, for the amino acid alphabet ARNDCQEGHILKMFPSTWYVBJZX* ("*" defines the stop codons), 
-			//if AAC is coded by N (amino acid with the number 2), then codonTable_[1]=2.
-
-			const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
-			const double *ntFreqs_,//background frequencies of letters in DNA sequences
-			const double *aaFreqs_,//background frequencies of letters in amino acid sequences
-			long gapOpen1_,//gap opening penalty for sequence #1
-			long gapEpen1_,//gap extension penalty for sequence #1
-			long gapOpen2_,//gap opening penalty for sequence #2
-			long gapEpen2_,//gap extension penalty for sequence #2
-			long frameshiftCost_,//frameshift penalty
-			bool insertions_after_deletions_,//if true, then insertions after deletions are permitted
-			double eps_lambda_,//relative error for the parameter lambda
-			double eps_K_,//relative error for the parameter K
-			double max_time_,//maximum allowed calculation time in seconds
-			double max_mem_,//maximum allowed memory usage in MB
-			long randomSeed_,//randomizaton seed
-
-			//in the case when max_time_<=0, the following parameters are used:
-			long int seq_number_=10000,//a number of alignments
-			long int nalp_=5,//a number of ascending ladder points used in the calculation
-			long int number_of_subsets_for_errors_calculation_=20);//a number of subsets used in the error calculation
-
-
-
-	//Initializes Gumbel parameters using precalculated values:
-	void initParameters(
-	const AlignmentEvaluerParameters &parameters_);//parameters_ must be defined by the user
-
-	void initParameters(
-	const AlignmentEvaluerParametersWithErrors &parameters_);//parameters_ must be defined by the user
-
-	//Computes P-values/E-values
-	//Gumbel parameters must be defined via d_params
-	void calc(double score_,//frameshift alignment score
-			double seqlen1_,//length of sequence #1
-			double seqlen2_,//length of sequence #2
-			double &pvalue_,//resulted P-value
-			double &pvalueErr_,//P-value error
-			double &evalue_,//resulted E-value
-			double &evalueErr_) const;//E-value error
-
-	//Computes P-values/E-values without errors
-	//Gumbel parameters must be defined via d_params
-	void calc(double score_,//frameshift alignment score
-			double seqlen1_,//length of sequence #1
-			double seqlen2_,//length of sequence #2
-			double &pvalue_,//resulted P-value
-			double &evalue_) const;//resulted E-value
-
-	double evalue(double score_,//frameshift alignment score
-			double seqlen1_,//length of sequence #1
-			double seqlen2_) const//length of sequence #2
-	{
-	  return area(score_, seqlen1_, seqlen2_) * evaluePerArea(score_);
-	}
-
-	//Computes P-values from E-values
-	static double pvalue(double evalue_)
-	{
-		return sls_basic::one_minus_exp_function(-evalue_);
-	}
-
-	//The "area" is approximately seqlen1_*seqlen2_, but it is
-	//modified by a finite size correction
-	double area(double score_,//frameshift alignment score
-			double seqlen1_,//length of sequence #1
-			double seqlen2_) const;//length of sequence #2
-
-	double evaluePerArea(double score_) const
-	{
-	  return d_params.K*exp(-d_params.lambda*score_);
-	}
-
-	double bitScore(double score_) const
-	{
-	  return (d_params.lambda*score_-log(d_params.K))/log(2.0);
-	}
-
-
-	//returns "true" if the set of parameters "d_params" is fully defined for P-value calculation
-	bool isGood() const
-	{
-		return d_params.d_params_flag;
-	}
-
-	//provides access to the set of Gumbel parameters
-	const FALP_set_of_parameters &parameters() const { return d_params; }
-
-	private:
-
-	//check correctness of the input parameters for gapless alignment
-	void assert_Gapless_input_parameters(
-			long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
-			long aaAlphabetSize_,//a number of letters in the amino acid alphabet
-			const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
-
-			const double *ntFreqs_,//background frequencies of letters in DNA sequences
-			const double *aaFreqs_,//background frequencies of letters in amino acid sequences
-			double *&ntFreqs_normalized_,//normalized background frequencies of letters in DNA sequences
-			double *&aaFreqs_normalized_,//normalized background frequencies of letters in amino acid sequences
-			const std::string function_name_);//"assert_Gapless_input_parameters" is called from "function_name_" function
-
-	private:
-
-		FALP_set_of_parameters d_params;//set of Gumbel parameters
-
-	};
-}
-
-#endif //! INCLUDED
-
+#ifndef INCLUDED_SLS_FALP_LIB
+#define INCLUDED_SLS_FALP_LIB
+
+/* $Id: $
+* ===========================================================================
+*
+*							PUBLIC DOMAIN NOTICE
+*			   National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_fsa1_lib.hpp
+
+Authors: Martin Frith, Sergey Sheetlin
+
+Contents: library functions of main routines
+
+******************************************************************************/
+
+#include <string>
+#include "sls_fsa1_pvalues.hpp"
+
+namespace Sls {
+
+	class FrameshiftAlignmentEvaluer {
+
+
+	//Write the parameters:
+	friend std::ostream &operator<<(std::ostream &s_,
+			const FrameshiftAlignmentEvaluer &g_);
+
+	//Read the parameters:
+	friend std::istream &operator>>(std::istream &s_,
+			FrameshiftAlignmentEvaluer &g_);
+
+	public:
+
+	//Computes gapless Gumbel parameters:
+	void initGapless(long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
+			long aaAlphabetSize_,//a number of letters in the amino acid alphabet
+			const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
+
+			const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
+			const double *ntFreqs_,//background frequencies of letters in DNA sequences
+			const double *aaFreqs_,//background frequencies of letters in amino acid sequences
+			double max_time_=60);//maximum allowed calculation time in seconds
+
+
+	void initFrameshift(long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
+			long aaAlphabetSize_,//a number of letters in the amino acid alphabet
+			const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
+			//letters are numerated from 0; 
+			//each codon defines a code (an integer number from [0,...,ntAlphabetSize_^3-1]);
+			//for example, for the DNA alphabet ACGT, 
+			//AAA corresponds to codonTable_[0]; AAC corresponds to codonTable_[1] and so on.
+			//codonTable_[x] contains an amino acid number such that the amino acid corresponds to a codon with the code x
+			//for example, for the amino acid alphabet ARNDCQEGHILKMFPSTWYVBJZX* ("*" defines the stop codons), 
+			//if AAC is coded by N (amino acid with the number 2), then codonTable_[1]=2.
+
+			const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
+			const double *ntFreqs_,//background frequencies of letters in DNA sequences
+			const double *aaFreqs_,//background frequencies of letters in amino acid sequences
+			long gapOpen1_,//gap opening penalty for sequence #1
+			long gapEpen1_,//gap extension penalty for sequence #1
+			long gapOpen2_,//gap opening penalty for sequence #2
+			long gapEpen2_,//gap extension penalty for sequence #2
+			long frameshiftCost_,//frameshift penalty
+			bool insertions_after_deletions_,//if true, then insertions after deletions are permitted
+			double eps_lambda_,//relative error for the parameter lambda
+			double eps_K_,//relative error for the parameter K
+			double max_time_,//maximum allowed calculation time in seconds
+			double max_mem_,//maximum allowed memory usage in MB
+			long randomSeed_,//randomizaton seed
+
+			//in the case when max_time_<=0, the following parameters are used:
+			long int seq_number_=10000,//a number of alignments
+			long int nalp_=5,//a number of ascending ladder points used in the calculation
+			long int number_of_subsets_for_errors_calculation_=20);//a number of subsets used in the error calculation
+
+
+
+	//Initializes Gumbel parameters using precalculated values:
+	void initParameters(
+	const AlignmentEvaluerParameters &parameters_);//parameters_ must be defined by the user
+
+	void initParameters(
+	const AlignmentEvaluerParametersWithErrors &parameters_);//parameters_ must be defined by the user
+
+	//Computes P-values/E-values
+	//Gumbel parameters must be defined via d_params
+	void calc(double score_,//frameshift alignment score
+			double seqlen1_,//length of sequence #1
+			double seqlen2_,//length of sequence #2
+			double &pvalue_,//resulted P-value
+			double &pvalueErr_,//P-value error
+			double &evalue_,//resulted E-value
+			double &evalueErr_) const;//E-value error
+
+	//Computes P-values/E-values without errors
+	//Gumbel parameters must be defined via d_params
+	void calc(double score_,//frameshift alignment score
+			double seqlen1_,//length of sequence #1
+			double seqlen2_,//length of sequence #2
+			double &pvalue_,//resulted P-value
+			double &evalue_) const;//resulted E-value
+
+	double evalue(double score_,//frameshift alignment score
+			double seqlen1_,//length of sequence #1
+			double seqlen2_) const//length of sequence #2
+	{
+	  return area(score_, seqlen1_, seqlen2_) * evaluePerArea(score_);
+	}
+
+	//Computes P-values from E-values
+	static double pvalue(double evalue_)
+	{
+		return sls_basic::one_minus_exp_function(-evalue_);
+	}
+
+	//The "area" is approximately seqlen1_*seqlen2_, but it is
+	//modified by a finite size correction
+	double area(double score_,//frameshift alignment score
+			double seqlen1_,//length of sequence #1
+			double seqlen2_) const;//length of sequence #2
+
+	double evaluePerArea(double score_) const
+	{
+	  return d_params.K*exp(-d_params.lambda*score_);
+	}
+
+	double bitScore(double score_) const
+	{
+	  return (d_params.lambda*score_-log(d_params.K))/log(2.0);
+	}
+
+
+	//returns "true" if the set of parameters "d_params" is fully defined for P-value calculation
+	bool isGood() const
+	{
+		return d_params.d_params_flag;
+	}
+
+	//provides access to the set of Gumbel parameters
+	const FALP_set_of_parameters &parameters() const { return d_params; }
+
+	private:
+
+	//check correctness of the input parameters for gapless alignment
+	void assert_Gapless_input_parameters(
+			long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
+			long aaAlphabetSize_,//a number of letters in the amino acid alphabet
+			const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
+
+			const double *ntFreqs_,//background frequencies of letters in DNA sequences
+			const double *aaFreqs_,//background frequencies of letters in amino acid sequences
+			double *&ntFreqs_normalized_,//normalized background frequencies of letters in DNA sequences
+			double *&aaFreqs_normalized_,//normalized background frequencies of letters in amino acid sequences
+			const std::string function_name_);//"assert_Gapless_input_parameters" is called from "function_name_" function
+
+	private:
+
+		FALP_set_of_parameters d_params;//set of Gumbel parameters
+
+	};
+}
+
+#endif //! INCLUDED
+
diff --git a/src/alp/sls_fsa1.cpp b/src/alp/sls_fsa1.cpp
index 66dc2aa..8b93f60 100644
--- a/src/alp/sls_fsa1.cpp
+++ b/src/alp/sls_fsa1.cpp
@@ -1,11589 +1,11589 @@
-/* $Id: $
-* ===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's offical duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_repwords.cpp
-
-Author: Sergey Sheetlin
-
-Contents: Frameshift alignment algorithms 
-
-******************************************************************************/
-
-#include "sls_fsa1.hpp"
-
-using namespace Sls;
-using namespace std;
-
-static bool test_mode=true;//of true, then the test mode is activated
-
-static long int small_long=(long int)((double)LONG_MIN/2.0);
-static long int length_max=1000;
-
-FSA::FSA(//constructor
-
-bool reversed_seq_,//whether the sequences are reversed or not
-string alignment_type_,//type of alignment; possible values "local", "global"
-
-long int rand_,//randomization number
-long int open1_,//gap opening penalty for the nucleotide sequence #1
-long int open2_,//gap opening penalty for the amino acid sequence #2
-
-long int epen1_,//gap extension penalty for the nucleotide sequence #1
-long int epen2_,//gap extension penalty for the amino acid sequence #2
-
-long int gamma_,//frameshift penalty gamma
-
-string smatr_file_name_,//scoring matrix file name
-string RR1_file_name_,//background frequencies file name for the sequence #1
-string RR2_file_name_,//background frequencies file name for the sequence #2
-string DNA_codon_table_file_name_,//a name of a file with DNA codon table
-long int seq1_length_,//length of sequence #1
-long int seq2_length_,//length of sequence #2
-long int seq_number_)//number of tested alignments
-{
-
-	d_alphabet1=NULL;
-	d_alphabet2=NULL;
-
-	d_alphabet1_to_long=NULL;
-	d_alphabet2_to_long=NULL;
-
-	d_smatr=NULL;
-	d_RR1=NULL;
-	d_RR1_sum=NULL;
-	d_RR1_sum_elements=NULL;
-
-	d_RR2=NULL;
-	d_RR2_sum=NULL;
-	d_RR2_sum_elements=NULL;
-
-	d_S_a1=NULL;
-	d_I_a1=NULL;
-	d_D_a1=NULL;
-
-	d_codon_AA=NULL;
-
-	d_seq1=NULL;
-	d_seq2=NULL;
-
-
-	try
-	{
-
-		d_reversed_seq=reversed_seq_;
-		d_alignment_type=alignment_type_;
-
-		long int number_of_AA_RR2;
-		long int number_of_AA_smatr;
-		long int smatr_min;
-
-		FSA_utils::read_smatr(
-		smatr_file_name_,
-		d_smatr,
-		number_of_AA_smatr,
-		smatr_min);
-
-		
-
-		FSA_utils::read_RR(
-		RR1_file_name_,
-		d_RR1,
-		d_RR1_sum,
-		d_RR1_sum_elements,
-		d_number_of_letters1);
-
-
-		FSA_utils::read_RR(
-		RR2_file_name_,
-		d_RR2,
-		d_RR2_sum,
-		d_RR2_sum_elements,
-		number_of_AA_RR2);
-
-
-		if(number_of_AA_RR2==number_of_AA_smatr)
-		{
-			d_number_of_letters2=number_of_AA_smatr;
-		}
-		else
-		{
-			throw error("The number of letters is different in the files "+smatr_file_name_+" and "+RR2_file_name_+"\n",3);
-		};
-
-		long int number_of_letters1_tmp;//number of letters for the sequence 1
-		long int number_of_letters2_tmp;//number of letters for the sequence 2
-
-		FSA_utils::read_codon_AA_file(
-		DNA_codon_table_file_name_,
-		number_of_letters1_tmp,//number of letters for the sequence 1
-		number_of_letters2_tmp,//number of letters for the sequence 2
-
-		d_alphabet1,//alphabet letters for the sequence #1
-		d_alphabet2,//alphabet letters for the sequence #2
-
-		d_alphabet1_to_long,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-		d_alphabet2_to_long,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-		d_codon_length,//codon length 
-		d_codon_AA);//<codon code,AA number>
-
-
-		if(d_number_of_letters1!=number_of_letters1_tmp)
-		{
-			throw error("The number of letters is different in the files "+DNA_codon_table_file_name_+" and "+RR1_file_name_+"\n",3);
-		};
-		if(d_number_of_letters2!=number_of_letters2_tmp)
-		{
-			throw error("The number of letters is different in the files "+DNA_codon_table_file_name_+" and "+RR2_file_name_+"\n",3);
-		};
-
-		d_open1=open1_;
-		d_open2=open2_;
-
-		d_epen1=epen1_;
-		d_epen2=epen2_;
-
-		d_gamma=gamma_;
-
-		d_seq1_length=seq1_length_;//length of sequence #1
-		d_seq2_length=seq2_length_;//length of sequence #2
-		d_seq_number=seq_number_;//number of tested alignments
-
-
-
-		//randomization
-		long int random_factor=rand_;
-
-
-		if(random_factor<0)
-		{
-			random_factor=(long int)time(NULL);
-			#ifndef _MSC_VER //UNIX program
-				struct timeval tv;
-				struct timezone tz;
-				gettimeofday(&tv, &tz);
-				random_factor+=tv.tv_usec*10000000;
-			#else
-				struct _timeb timebuffer;
-				char *timeline;
-				_ftime( &timebuffer );
-				timeline = ctime( & ( timebuffer.time ) );
-				rand_+=timebuffer.millitm*10000000;
-			#endif
-
-			random_factor=abs(random_factor);
-
-			d_rand_flag=false;
-
-		};
-
-		d_random_factor=random_factor;
-		cout<<"Random seed "<<d_random_factor<<endl;
-
-		FSA_utils::srand2(d_random_factor);
-
-		FSA_utils::get_memory_for_matrix(d_seq1_length+1,d_seq2_length+1,d_S_a1);
-		FSA_utils::get_memory_for_matrix(d_seq1_length+1,d_seq2_length+1,d_I_a1);
-		FSA_utils::get_memory_for_matrix(d_seq1_length+1,d_seq2_length+1,d_D_a1);
-
-		d_seq1=new long int[d_seq1_length];
-		d_seq2=new long int[d_seq2_length];
-
-	}
-	catch (...)
-	{
-		this->~FSA();
-		throw;
-	};
-
-}
-
-FSA::~FSA()
-{
-	if(d_smatr)
-	{
-		FSA_utils::delete_memory_for_matrix(d_number_of_letters2,d_smatr);
-	};
-
-	delete[]d_RR1;
-	delete[]d_RR2;
-	delete[]d_RR1_sum;
-	delete[]d_RR2_sum;
-	delete[]d_RR1_sum_elements;
-	delete[]d_RR2_sum_elements;
-	delete[]d_alphabet1;
-	delete[]d_alphabet2;
-
-	delete[]d_alphabet1_to_long;
-	delete[]d_alphabet2_to_long;
-	delete[]d_codon_AA;
-
-	if(d_S_a1)
-	{
-		FSA_utils::delete_memory_for_matrix(d_seq1_length+1,d_S_a1);
-	};
-	if(d_I_a1)
-	{
-		FSA_utils::delete_memory_for_matrix(d_seq1_length+1,d_I_a1);
-	};
-	if(d_D_a1)
-	{
-		FSA_utils::delete_memory_for_matrix(d_seq1_length+1,d_D_a1);
-	};
-
-
-}
-
-long int FSA::random_AA1()
-{
-	return FSA_utils::random_long(
-		FSA_utils::ran2(),
-			d_number_of_letters1,
-			d_RR1_sum,
-			d_RR1_sum_elements);
-}
-
-long int FSA::random_AA2()
-{
-	return FSA_utils::random_long(
-		FSA_utils::ran2(),
-			d_number_of_letters2,
-			d_RR2_sum,
-			d_RR2_sum_elements);
-}
-
-
-
-long int FSA::convert_codon_into_AA(
-long int *codon_)
-{
-	return FSA_utils::convert_codon_into_AA(
-			d_codon_length,//codon length 
-			d_codon_AA,//<codon code,AA number>
-			d_number_of_letters1,//number of letters for the sequence 1
-			codon_);
-}
-
-void FSA::classical_global_alignment(
-long int *seq1_,//sequence #1
-long int *seq2_,//sequence #2
-FSA *FAS_object_,//a pointer to FSA object
-void*par_)//additonal parameters
-{
-
-	bool local_flag=(FAS_object_->d_alignment_type=="local");
-
-	long int init_for_S=-inf;
-	if(local_flag)
-	{
-		init_for_S=0;
-	};
-
-	long int i,j;
-	//initial conditions
-	for(i=0;i<=FAS_object_->d_seq1_length;i++)
-	{
-		if(local_flag)
-		{
-			FAS_object_->d_D_a1[i][0]=-inf;
-		}
-		else
-		{
-			FAS_object_->d_D_a1[i][0]=-FAS_object_->d_open1-FAS_object_->d_epen1*i;
-		};
-
-		FAS_object_->d_S_a1[i][0]=init_for_S;
-		FAS_object_->d_I_a1[i][0]=-inf;
-	};
-
-	for(j=0;j<=FAS_object_->d_seq2_length;j++)
-	{
-		FAS_object_->d_S_a1[0][j]=init_for_S;
-		FAS_object_->d_D_a1[0][j]=-inf;
-		if(local_flag)
-		{
-			FAS_object_->d_I_a1[0][j]=-inf;
-		}
-		else
-		{
-			FAS_object_->d_I_a1[0][j]=-FAS_object_->d_open2-FAS_object_->d_epen2*j;
-		};
-
-	};
-
-	FAS_object_->d_S_a1[0][0]=0;
-
-	for(i=1;i<=FAS_object_->d_seq1_length;i++)
-	{
-		for(j=1;j<=FAS_object_->d_seq2_length;j++)
-		{
-
-			FAS_object_->d_I_a1[i][j]=FSA_utils::Tmax(FAS_object_->d_S_a1[i][j-1]-FAS_object_->d_open2-FAS_object_->d_epen2,FAS_object_->d_I_a1[i][j-1]-FAS_object_->d_epen2);
-			FAS_object_->d_D_a1[i][j]=FSA_utils::Tmax(FAS_object_->d_S_a1[i-1][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-1][j]-FAS_object_->d_epen1);
-
-			long int smart_score=FAS_object_->d_smatr[seq1_[i-1]][seq2_[j-1]];
-			FAS_object_->d_S_a1[i][j]=
-				FSA_utils::Tmax(
-					init_for_S,
-					FSA_utils::Tmax(FAS_object_->d_S_a1[i-1][j-1],FAS_object_->d_D_a1[i-1][j-1],FAS_object_->d_I_a1[i-1][j-1])+smart_score
-					);
-			
-		};
-	};
-
-	long int score=FAS_object_->d_S_a1[0][0];
-	for(i=0;i<=FAS_object_->d_seq1_length;i++)
-	{
-		for(j=0;j<=FAS_object_->d_seq2_length;j++)
-		{
-			score=FSA_utils::Tmax(score,
-				FSA_utils::Tmax(FAS_object_->d_S_a1[i][j],FAS_object_->d_D_a1[i][j],FAS_object_->d_I_a1[i][j])
-				);
-		};
-	};
-
-	struct_for_alignment &tmp_obj=*((struct_for_alignment*)par_);
-	tmp_obj.d_score=score;
-
-}
-
-
-void FSA::a1_global_alignment(
-long int *seq1_,//sequence #1
-long int *seq2_,//sequence #2
-FSA *FAS_object_,//a pointer to FSA object
-void*par_)//additonal parameters
-{
-	bool local_flag=(FAS_object_->d_alignment_type=="local");
-
-	long int init_for_S=-inf;
-	if(local_flag)
-	{
-		init_for_S=0;
-	};
-
-
-	long int i,j;
-	//initial conditions
-	for(i=0;i<=FAS_object_->d_seq1_length;i++)
-	{
-		long int i_div_3;
-
-		if(local_flag)
-		{
-			FAS_object_->d_D_a1[i][0]=-inf;
-		}
-		else
-		{
-			if(i%3==0)
-			{
-				i_div_3=i/3;
-				FAS_object_->d_D_a1[i][0]=-FAS_object_->d_open1-FAS_object_->d_epen1*i_div_3;
-			};
-
-			if(i%3==1)
-			{
-				i_div_3=(i-1)/3;
-				FAS_object_->d_D_a1[i][0]=-FAS_object_->d_open1-FAS_object_->d_epen1*i_div_3-FAS_object_->d_gamma;
-			};
-
-			if(i%3==2)
-			{
-				i_div_3=(i+1)/3;
-				FAS_object_->d_D_a1[i][0]=-FAS_object_->d_open1-FAS_object_->d_epen1*i_div_3-FAS_object_->d_gamma;
-			};
-
-			i_div_3=(long int)floor((double)i/3.0);
-			FAS_object_->d_D_a1[i][0]=-FAS_object_->d_open1-FAS_object_->d_epen1*i_div_3;
-			
-		};
-
-
-		FAS_object_->d_S_a1[i][0]=init_for_S;
-		FAS_object_->d_I_a1[i][0]=-inf;
-	};
-
-	for(j=0;j<=FAS_object_->d_seq2_length;j++)
-	{
-		FAS_object_->d_S_a1[0][j]=init_for_S;
-		FAS_object_->d_D_a1[0][j]=-inf;
-		if(local_flag)
-		{
-			FAS_object_->d_I_a1[0][j]=-inf;
-		}
-		else
-		{
-			FAS_object_->d_I_a1[0][j]=-FAS_object_->d_open2-FAS_object_->d_epen2*j;
-		};
-
-		FAS_object_->d_S_a1[1][j]=init_for_S;
-		FAS_object_->d_D_a1[1][j]=-inf;
-		if(local_flag)
-		{
-			FAS_object_->d_I_a1[1][j]=-inf;
-		}
-		else
-		{
-			FAS_object_->d_I_a1[1][j]=-FAS_object_->d_open2-FAS_object_->d_epen2*j;
-		};
-
-		FAS_object_->d_S_a1[2][j]=init_for_S;
-		FAS_object_->d_D_a1[2][j]=-inf;
-		if(local_flag)
-		{
-			FAS_object_->d_I_a1[2][j]=-inf;
-		}
-		else
-		{
-			FAS_object_->d_I_a1[2][j]=-FAS_object_->d_open2-FAS_object_->d_epen2*j;
-		};
-	};
-
-	FAS_object_->d_S_a1[0][0]=0;
-	FAS_object_->d_S_a1[1][0]=0;
-	FAS_object_->d_S_a1[2][0]=0;
-
-	for(i=3;i<=FAS_object_->d_seq1_length;i++)
-	{
-		for(j=1;j<=FAS_object_->d_seq2_length;j++)
-		{
-
-			FAS_object_->d_I_a1[i][j]=FSA_utils::Tmax(FAS_object_->d_S_a1[i][j-1]-FAS_object_->d_open2-FAS_object_->d_epen2,FAS_object_->d_I_a1[i][j-1]-FAS_object_->d_epen2);
-			
-			if(i==2)
-			{
-				FAS_object_->d_S_a1[i][j]=init_for_S;
-
-				FAS_object_->d_D_a1[i][j]=FAS_object_->d_D_a1[i-1][j];
-
-				//FAS_object_->d_D_a1[i][j]=
-				//	Tmax(FAS_object_->d_S_a1[i-2][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-2][j]-FAS_object_->d_epen1)-FAS_object_->d_gamma;
-
-				continue;
-			};
-			if(i==3)
-			{
-				long int smart_score=FAS_object_->d_smatr[FAS_object_->convert_codon_into_AA(seq1_+i-3)][seq2_[j-1]];
-				FAS_object_->d_S_a1[i][j]=FSA_utils::Tmax(
-
-					//for local alignment
-					init_for_S,
-					
-					FSA_utils::Tmax(FAS_object_->d_S_a1[i-3][j-1],FAS_object_->d_D_a1[i-3][j-1],FAS_object_->d_I_a1[i-3][j-1])+smart_score,
-					FSA_utils::Tmax(FAS_object_->d_S_a1[i-2][j-1],FAS_object_->d_D_a1[i-2][j-1],FAS_object_->d_I_a1[i-2][j-1])+smart_score-FAS_object_->d_gamma
-					
-					);
-
-				FAS_object_->d_D_a1[i][j]=FSA_utils::Tmax(
-					
-					FSA_utils::Tmax(FAS_object_->d_S_a1[i-3][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-3][j]-FAS_object_->d_epen1),
-					FSA_utils::Tmax(FAS_object_->d_S_a1[i-2][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-2][j]-FAS_object_->d_epen1)-FAS_object_->d_gamma
-
-					);
-				continue;
-				
-			};
-			if(i>=4)
-			{
-
-				long int smart_score=FAS_object_->d_smatr[FAS_object_->convert_codon_into_AA(seq1_+i-3)][seq2_[j-1]];
-				FAS_object_->d_S_a1[i][j]=FSA_utils::Tmax(
-					
-					//for local alignment
-					init_for_S,
-					
-					FSA_utils::Tmax(FAS_object_->d_S_a1[i-3][j-1],FAS_object_->d_D_a1[i-3][j-1],FAS_object_->d_I_a1[i-3][j-1])+smart_score,
-					
-					FSA_utils::Tmax(
-					FSA_utils::Tmax(FAS_object_->d_S_a1[i-2][j-1],FAS_object_->d_D_a1[i-2][j-1],FAS_object_->d_I_a1[i-2][j-1]),
-					FSA_utils::Tmax(FAS_object_->d_S_a1[i-4][j-1],FAS_object_->d_D_a1[i-4][j-1],FAS_object_->d_I_a1[i-4][j-1])
-					)+smart_score-FAS_object_->d_gamma
-					
-					);
-
-				FAS_object_->d_D_a1[i][j]=FSA_utils::Tmax(
-					
-					FSA_utils::Tmax(FAS_object_->d_S_a1[i-3][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-3][j]-FAS_object_->d_epen1),
-					FSA_utils::Tmax(FAS_object_->d_S_a1[i-2][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-2][j]-FAS_object_->d_epen1)-FAS_object_->d_gamma,
-					FSA_utils::Tmax(FAS_object_->d_S_a1[i-4][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-4][j]-FAS_object_->d_epen1)-FAS_object_->d_gamma
-
-					);
-
-			};
-
-
-
-		};
-	};
-
-	long int score=FAS_object_->d_S_a1[0][0];
-	for(i=0;i<=FAS_object_->d_seq1_length;i++)
-	{
-		for(j=0;j<=FAS_object_->d_seq2_length;j++)
-		{
-			score=FSA_utils::Tmax(score,
-				FSA_utils::Tmax(FAS_object_->d_S_a1[i][j],FAS_object_->d_D_a1[i][j],FAS_object_->d_I_a1[i][j])
-				);
-		};
-	};
-
-	struct_for_alignment &tmp_obj=*((struct_for_alignment*)par_);
-	tmp_obj.d_score=score;
-
-	bool test_flag=false;
-	if(test_flag)
-	{
-		FSA_utils::print_matrix(
-		"d_S_a1.out",
-		FAS_object_->d_seq1_length+1,
-		FAS_object_->d_seq2_length+1,
-		FAS_object_->d_S_a1);
-
-		FSA_utils::print_matrix(
-		"d_I_a1.out",
-		FAS_object_->d_seq1_length+1,
-		FAS_object_->d_seq2_length+1,
-		FAS_object_->d_I_a1);
-
-		FSA_utils::print_matrix(
-		"d_D_a1.out",
-		FAS_object_->d_seq1_length+1,
-		FAS_object_->d_seq2_length+1,
-		FAS_object_->d_D_a1);
-
-
-	};
-}
-
-void FSA::DNA_AA_global(
-string distr_file_name_,
-alignment_function_type *alignment_function_)
-{
-	bool test_out=false;
-
-	ofstream ftest;
-	if(test_out)
-	{
-		string test_out_st="sss.out";
-		ftest.open(test_out_st.data());
-		if(!ftest)
-		{
-			throw error("Error - the file "+test_out_st+" is not found\n",1);
-		};
-
-		
-	};
-
-	ofstream f(distr_file_name_.data());
-	if(!f)
-	{
-		throw error("Error - the file "+distr_file_name_+" is not found\n",3);
-	};
-
-
-	array_v<double> distr(this);
-
-
-	long int s;
-	long int score_max=small_long,score_min=-small_long;
-
-	for(s=0;s<d_seq_number;s++)
-	{
-
-		if(test_out)
-		{
-			ftest<<">seq"<<s<<"\n";
-		};
-
-		long int i,j;
-		//generate sequence #1
-		for(i=0;i<d_seq1_length;i++)
-		{
-			d_seq1[i]=random_AA1();
-			if(test_out)
-			{
-				ftest<<this->d_alphabet1[d_seq1[i]];
-			};
-		};
-		if(test_out)
-		{
-			ftest<<"\n";
-		};
-
-		//generate sequence #2
-		for(j=0;j<d_seq2_length;j++)
-		{
-			d_seq2[j]=random_AA2();
-			if(test_out)
-			{
-				ftest<<this->d_alphabet2[d_seq2[j]];
-			};
-
-		};
-		if(test_out)
-		{
-			ftest<<"\n";
-		};
-
-		if(d_reversed_seq)
-		{
-			FSA_utils::reverse_sequence(//reverse the letters of the sequence
-			d_seq1,
-			d_seq1_length);
-
-			FSA_utils::reverse_sequence(//reverse the letters of the sequence
-			d_seq2,
-			d_seq2_length);
-		};
-
-		struct_for_alignment tmp_str;
-
-		alignment_function_(
-		d_seq1,//sequence #1
-		d_seq2,//sequence #2
-		this,
-		(void*)(&tmp_str));
-
-		long int score=tmp_str.d_score;
-		if(s==0)
-		{
-			score_max=score;
-			score_min=score;
-		}
-		else
-		{
-			score_max=FSA_utils::Tmax(score_max,score);
-			score_min=FSA_utils::Tmin(score_min,score);
-		};
-
-		distr.increase_elem_by_1(score);
-
-		if(test_out)
-		{
-			cout<<score<<endl;
-		};
-
-		if((s+1)%1000==0)
-		{
-			cout<<s+1<<endl;
-		};
-	};
-
-	f<<score_max+1<<endl;
-	for(s=0;s<=score_max;s++)
-	{
-		f<<s<<"\t"<<distr.d_elem[s-distr.d_ind0]<<endl;
-	};
-
-	f.close();
-}
-
-void FSA::AA_AA_global(
-string distr_file_name_,
-alignment_function_type *alignment_function_)
-{
-	ofstream f(distr_file_name_.data());
-	if(!f)
-	{
-		throw error("Error - the file "+distr_file_name_+" is not found\n",3);
-	};
-
-	array_v<double> distr(this);
-
-
-	long int s;
-	long int score_max=small_long,score_min=-small_long;
-
-	for(s=0;s<d_seq_number;s++)
-	{
-		long int i,j;
-		//generate sequence #1
-
-		for(i=0;i<d_seq1_length;i++)
-		{
-			d_seq1[i]=random_AA2();
-		};
-		//generate sequence #2
-		for(j=0;j<d_seq2_length;j++)
-		{
-			d_seq2[j]=random_AA2();
-		};
-
-		if(d_reversed_seq)
-		{
-			FSA_utils::reverse_sequence(//reverse the letters of the sequence
-			d_seq1,
-			d_seq1_length);
-
-			FSA_utils::reverse_sequence(//reverse the letters of the sequence
-			d_seq2,
-			d_seq2_length);
-		};
-
-		struct_for_alignment tmp_str;
-
-		alignment_function_(
-		d_seq1,//sequence #1
-		d_seq2,//sequence #2
-		this,
-		(void*)(&tmp_str));
-
-		long int score=tmp_str.d_score;
-		if(s==0)
-		{
-			score_max=score;
-			score_min=score;
-		}
-		else
-		{
-			score_max=FSA_utils::Tmax(score_max,score);
-			score_min=FSA_utils::Tmin(score_min,score);
-		};
-
-		distr.increase_elem_by_1(score);
-
-		if((s+1)%1000==0)
-		{
-			cout<<s+1<<endl;
-		};
-	};
-
-	f<<score_max+1<<endl;
-	for(s=0;s<=score_max;s++)
-	{
-		f<<s<<"\t"<<distr.d_elem[s-distr.d_ind0]<<endl;
-	};
-
-	f.close();
-}
-
-void FSA::DNA_to_3_frames_AA_global(
-string distr_file_name_,
-alignment_function_type *alignment_function_)
-{
-	bool frame_output_flag=false;
-	long int s;
-	double *freqs_from_frames=new double [d_number_of_letters2];
-	for(s=0;s<d_number_of_letters2;s++)
-	{
-		freqs_from_frames[s]=0;
-	};
-
-	ofstream f(distr_file_name_.data());
-	if(!f)
-	{
-		throw error("Error - the file "+distr_file_name_+" is not found\n",3);
-	};
-
-	array_v<double> distr(this);
-
-
-	
-	long int score_max=small_long,score_min=-small_long;
-
-	for(s=0;s<d_seq_number;s++)
-	{
-		long int i,j;
-		//generate sequence #1
-		for(i=0;i<d_seq1_length;i++)
-		{
-			d_seq1[i]=random_AA1();
-		};
-		//generate sequence #2
-		for(j=0;j<d_seq2_length;j++)
-		{
-			d_seq2[j]=random_AA2();
-		};
-
-		if(d_reversed_seq)
-		{
-			FSA_utils::reverse_sequence(//reverse the letters of the sequence
-			d_seq1,
-			d_seq1_length);
-
-			FSA_utils::reverse_sequence(//reverse the letters of the sequence
-			d_seq2,
-			d_seq2_length);
-		};
-
-		struct_for_alignment tmp_str;
-
-		long int score=0;
-
-		long int v;
-		for(v=0;v<d_codon_length;v++)
-		{
-			long int length1_tmp=this->d_seq1_length;
-
-			long int length1_v_div_3=(long int)floor((double)(length1_tmp-v)/3.0);
-
-			long int *seq1_AA=new long int[length1_v_div_3];
-
-			long int j;
-			for(j=0;j<length1_v_div_3;j++)
-			{
-				long int ind=v+j*3;
-				seq1_AA[j]=convert_codon_into_AA(d_seq1+ind);
-				freqs_from_frames[seq1_AA[j]]++;
-			};
-
-
-			this->d_seq1_length=length1_v_div_3;
-
-			alignment_function_(
-			seq1_AA,//sequence #1
-			d_seq2,//sequence #2
-			this,
-			(void*)(&tmp_str));
-
-			this->d_seq1_length=length1_tmp;
-
-			if(v==0)
-			{
-				score=tmp_str.d_score;
-			}
-			else
-			{
-				score=FSA_utils::Tmax(score,tmp_str.d_score);
-			};
-
-			delete[]seq1_AA;
-		};
-
-		if(s==0)
-		{
-			score_max=score;
-			score_min=score;
-		}
-		else
-		{
-			score_max=FSA_utils::Tmax(score_max,score);
-			score_min=FSA_utils::Tmin(score_min,score);
-		};
-
-		distr.increase_elem_by_1(score);
-
-		if((s+1)%1000==0)
-		{
-			cout<<s+1<<endl;
-		};
-	};
-
-	f<<score_max+1<<endl;
-	for(s=0;s<=score_max;s++)
-	{
-		f<<s<<"\t"<<distr.d_elem[s-distr.d_ind0]<<endl;
-	};
-
-	f.close();
-
-	string frames_file_name="RR25_from_frames.in";
-	ofstream freqf;
-	
-	if(frame_output_flag)
-	{
-		freqf.open(frames_file_name.data());
-		if(!freqf)
-		{
-			throw error("Error - the file "+frames_file_name+" is not found\n",3);
-		};
-	};
-
-	double sum=0;
-	for(s=0;s<d_number_of_letters2;s++)
-	{
-		sum+=freqs_from_frames[s];
-	};
-
-	if(frame_output_flag)
-	{
-		freqf<<d_number_of_letters2<<endl;
-		for(s=0;s<d_number_of_letters2;s++)
-		{
-			freqf<<freqs_from_frames[s]/sum<<endl;
-		};
-
-		freqf.close();
-	};
-
-	delete[]freqs_from_frames;
-
-	
-}
-
-
-//general important sampling
-
-IS1_general::IS1_general(
-long int alphabet_letters_number1_,//number of letters in the sequence #1
-long int alphabet_letters_number2_,//number of letters in the sequence #2
-double *RR1_,//background probability for the sequence #1
-double *RR2_,//background probability for the sequence #2
-long int number_of_states_,//number of states
-double **transition_probabilities_,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
-pair<long int, long int> *states_description_,//description of the states; the index is a state number
-double ***states_distr_)//distributions of the states; the index is a state number
-{
-	d_alphabet_letters_number1=alphabet_letters_number1_;
-	d_alphabet_letters_number2=alphabet_letters_number2_;
-	d_RR1=RR1_;
-	d_RR2=RR2_;
-	d_number_of_states=number_of_states_;
-	d_states_description=states_description_;
-	d_states_distr=states_distr_;
-
-	if(d_number_of_states<=0)
-	{
-		throw error("Error - incorrect parameter number_of_states_ in IS1_general::IS1_general\n",1);
-	};
-
-	d_states_distr_dimensions=new pair<long int, long int>[d_number_of_states];
-	FSA_utils::assert_mem(d_states_distr_dimensions);
-
-	d_states_sum_distr=new double*[d_number_of_states];
-	FSA_utils::assert_mem(d_states_sum_distr);
-
-	long int max_dim=d_number_of_states;
-
-	d_max_dim1=-1;
-	d_max_dim2=-1;
-
-	long int s;
-	for(s=0;s<d_number_of_states;s++)
-	{
-		d_max_dim1=FSA_utils::Tmax(d_max_dim1,d_states_description[s].first);
-		d_max_dim2=FSA_utils::Tmax(d_max_dim2,d_states_description[s].second);
-
-		long int dim1=FSA_utils::power_long(alphabet_letters_number1_,d_states_description[s].first);
-		long int dim2=FSA_utils::power_long(alphabet_letters_number2_,d_states_description[s].second);
-
-
-		d_states_distr_dimensions[s]=make_pair(dim1,dim2);
-
-		max_dim=FSA_utils::Tmax(max_dim,dim1*dim2);
-
-		IS1_general::generate_one_state_sum_distr(//calculates sum-distributions corresponded to the input parameters
-		d_states_distr_dimensions[s],//dimensions of the matrix state_distr_
-		d_states_distr[s],//state distribution in the same format as in d_states_distr[s]
-		d_states_sum_distr[s]);//the result; the dimention is state_distr__dim1 x state_distr__dim2
-
-	};
-
-
-	d_states_sum_distr_elements_for_all_states=new long int[max_dim];
-	FSA_utils::assert_mem(d_states_sum_distr_elements_for_all_states);
-
-	
-
-	long int i;
-	for(i=0;i<max_dim;i++)
-	{
-		d_states_sum_distr_elements_for_all_states[i]=i;
-	};
-
-	FSA_utils::get_memory_for_matrix(d_number_of_states,d_number_of_states,d_transition_probabilities_sum);
-	FSA_utils::get_memory_for_matrix(d_number_of_states,d_number_of_states,d_transition_probabilities);
-
-	double eps=1e-5;
-
-	for(s=0;s<d_number_of_states;s++)
-	{
-		double sum_tmp=0;
-		long int s2;
-		for(s2=0;s2<d_number_of_states;s2++)
-		{
-			d_transition_probabilities[s][s2]=transition_probabilities_[s][s2];
-			d_transition_probabilities_sum[s][s2]=transition_probabilities_[s][s2];
-			sum_tmp+=transition_probabilities_[s][s2];
-		};
-		if(fabs(sum_tmp-1.0)>eps)
-		{
-			throw error("Unexpected error in the parameter transition_probabilities_ of the function IS1_general::IS1_general\n",1);
-		};
-
-		for(s2=0;s2<d_number_of_states;s2++)
-		{
-			d_transition_probabilities[s][s2]/=sum_tmp;
-		};
-
-		FSA_utils::convert_distr_into_sum(//calculates and allocates sum-distribution
-		d_number_of_states,//dimension
-		d_transition_probabilities_sum[s]);//the result; the dimention is state_distr__dim1 x state_distr__dim2
-
-	};
-
-
-	d_tmp_letters=new pair<long int*, long int*>[d_number_of_states];
-	FSA_utils::assert_mem(d_tmp_letters);
-
-	for(s=0;s<d_number_of_states;s++)
-	{
-		d_tmp_letters[s].first=new long int[d_states_description[s].first];
-		FSA_utils::assert_mem(d_tmp_letters[s].first);
-		d_tmp_letters[s].second=new long int[d_states_description[s].second];
-		FSA_utils::assert_mem(d_tmp_letters[s].second);
-	};
-
-	allocate_states_distr_sums();
-
-}
-
-IS1_general::~IS1_general()
-{
-	deallocate_states_distr_sums();
-
-	delete[]d_states_distr_dimensions;
-
-	long int s;
-	for(s=0;s<d_number_of_states;s++)
-	{
-		delete[]d_states_sum_distr[s];
-	};
-
-	delete[]d_states_sum_distr_elements_for_all_states;
-	
-	FSA_utils::delete_memory_for_matrix(d_number_of_states,d_transition_probabilities_sum);
-	FSA_utils::delete_memory_for_matrix(d_number_of_states,d_transition_probabilities);
-
-
-	for(s=0;s<d_number_of_states;s++)
-	{
-		delete[]d_tmp_letters[s].first;
-		delete[]d_tmp_letters[s].second;
-	};
-	delete[]d_tmp_letters;
-
-}
-
-void IS1_general::allocate_states_distr_sums()//allocates d_states_distr_sums
-{
-	long int*letters1=new long int[d_max_dim1];
-	FSA_utils::assert_mem(letters1);
-
-	long int*letters2=new long int[d_max_dim2];
-	FSA_utils::assert_mem(letters2);
-
-
-	long int s,x1,x2;
-
-	d_states_distr_sums=new double ****[d_number_of_states];
-	FSA_utils::assert_mem(d_states_distr_sums);
-
-	for(s=0;s<d_number_of_states;s++)
-	{
-		d_states_distr_sums[s]=new double ***[d_states_description[s].first+1];
-		FSA_utils::assert_mem(d_states_distr_sums[s]);
-
-		long int dim1;
-		long int dim2;
-
-		for(x1=0;x1<=d_states_description[s].first;x1++)
-		{
-			dim1=FSA_utils::power_long(d_alphabet_letters_number1,x1);
-
-			d_states_distr_sums[s][x1]=new double **[d_states_description[s].second+1];
-			FSA_utils::assert_mem(d_states_distr_sums[s][x1]);
-
-			for(x2=0;x2<=d_states_description[s].second;x2++)
-			{
-				dim2=FSA_utils::power_long(d_alphabet_letters_number2,x2);
-
-				FSA_utils::get_memory_for_matrix(
-				dim1,
-				dim2,
-				d_states_distr_sums[s][x1][x2]);
-
-				long int i1,i2;
-				for(i1=0;i1<dim1;i1++)
-				{
-
-					long int v;
-
-					code_to_letters(//returns a unique code for the array of letters
-					i1,//input code
-					d_alphabet_letters_number1,//total number of letters
-					x1,//dimension of the array with letters
-					letters1);//array of letters; the result
-
-					for(v=x1;v<d_states_description[s].first;v++)
-					{
-						letters1[v]=0;
-					};
-
-					long int code1=letters_to_code(//returns a unique code for the array of letters
-					d_alphabet_letters_number1,//total number of letters
-					d_states_description[s].first,//dimension of the array with letters
-					letters1);//array of letters
-
-					long int len1=FSA_utils::power_long(d_alphabet_letters_number1,d_states_description[s].first-x1)-1;
-
-					double mult1=1.0;
-					for(v=0;v<x1;v++)
-					{
-						mult1*=d_RR1[letters1[v]];
-					};
-
-
-					for(i2=0;i2<dim2;i2++)
-					{
-
-						code_to_letters(//returns a unique code for the array of letters
-						i2,//input code
-						d_alphabet_letters_number2,//total number of letters
-						x2,//dimension of the array with letters
-						letters2);//array of letters; the result
-
-						for(v=x2;v<d_states_description[s].second;v++)
-						{
-							letters2[v]=0;
-						};
-
-						long int code2=letters_to_code(//returns a unique code for the array of letters
-						d_alphabet_letters_number2,//total number of letters
-						d_states_description[s].second,//dimension of the array with letters
-						letters2);//array of letters
-
-						long int len2=FSA_utils::power_long(d_alphabet_letters_number2,d_states_description[s].second-x2)-1;
-
-						double mult2=1.0;
-						for(v=0;v<x2;v++)
-						{
-							mult2*=d_RR2[letters2[v]];
-						};
-
-						double sum_tmp=0;
-						long int v1,v2;
-						for(v1=code1;v1<=code1+len1;v1++)
-						{
-							for(v2=code2;v2<=code2+len2;v2++)
-							{
-								sum_tmp+=d_states_distr[s][v1][v2];
-							};
-						};
-
-						if(sum_tmp!=0&&(mult1==0||mult2==0))
-						{
-							throw error("The parameters d_states_distr and d_RR1 and d_RR2 are contradictory in IS1_general::allocate_states_distr_sums()\n",1);
-						};
-
-						if(mult1==0||mult2==0)
-						{
-							d_states_distr_sums[s][x1][x2][i1][i2]=0;
-						}
-						else
-						{
-							d_states_distr_sums[s][x1][x2][i1][i2]=sum_tmp/(mult1*mult2);
-						};
-
-
-
-
-
-					};
-				};
-			};
-		};
-	};
-
-	delete[]letters1;
-	delete[]letters2;
-
-	//calculate matrices for infinite sums
-
-	
-	{
-		long int code1=0;
-		long int code2=0;
-		long int x1=0;
-		long int x2=0;
-
-		calculate_inverse_matrices_for_the_infinite_sums(
-			code1,
-			code2,
-			&d_A1_inv,
-			&d_A2_inv,
-			x1,
-			x2);
-	};
-
-}
-
-void IS1_general::deallocate_states_distr_sums()//deallocates d_states_distr_sums
-{
-	long int s,x1,x2;
-
-	for(s=0;s<d_number_of_states;s++)
-	{
-
-		long int dim1;
-
-		for(x1=0;x1<=d_states_description[s].first;x1++)
-		{
-			dim1=FSA_utils::power_long(d_alphabet_letters_number1,x1);
-
-
-			for(x2=0;x2<=d_states_description[s].second;x2++)
-			{
-
-				FSA_utils::delete_memory_for_matrix(
-				dim1,
-				d_states_distr_sums[s][x1][x2]);
-			};
-
-			delete[]d_states_distr_sums[s][x1];
-		};
-
-		delete[] d_states_distr_sums[s];
-	};
-
-	delete[]d_states_distr_sums;
-}
-
-
-long int IS1_general::letters_to_code(//returns a unique code for the array of letters
-long int letters_number_,//total number of letters
-long int letters_dim_,//dimension of the array with letters
-long int* letters_)//array of letters
-{
-	if(test_mode)
-	{
-		if(letters_dim_<=0)
-		{
-			if(letters_dim_<0)
-			{
-				throw error("Unexpected error\n",1);
-			};
-			return 0;
-		};
-
-		if(letters_number_<=0)
-		{
-			throw error("Unexpected error\n",1);
-		};
-
-		long int i;
-		for(i=0;i<letters_dim_;i++)
-		{
-			if(letters_[i]<0||letters_[i]>=letters_number_)
-			{
-				throw error("Unexpected error\n",1);
-			};
-		};
-	};
-
-	long int res=letters_[0];
-	long int i;
-	for(i=1;i<letters_dim_;i++)
-	{
-		res=res*letters_number_+letters_[i];
-	};
-
-	return res;
-}
-
-void IS1_general::code_to_letters(//returns a unique code for the array of letters
-long int code_,//input code
-long int letters_number_,//total number of letters
-long int letters_dim_,//dimension of the array with letters
-long int*letters_)//array of letters; the result
-{
-	if(test_mode)
-	{
-		if(letters_dim_<=0)
-		{
-			if(letters_dim_<0)
-			{
-				throw error("Unexpected error\n",1);
-			};
-			return;
-		};
-
-		if(code_<0)
-		{
-			throw error("Unexpected error\n",1);
-		};
-
-		if(letters_number_<=0)
-		{
-			throw error("Unexpected error\n",1);
-		};
-
-	};
-
-	long int i;
-	for(i=letters_dim_-1;i>=0;i--)
-	{
-		letters_[i]=code_%letters_number_;
-		code_=(code_-letters_[i])/letters_number_;
-	};
-
-	if(test_mode)
-	{
-		if(code_!=0)
-		{
-			throw error("Unexpected error\n",1);
-		};
-	};
-
-}
-
-long int IS1_general::matr_indexes_to_code(
-long int code1_,//code #1
-long int code1_number_,//the range of code1_ is [0,code1_number_-1]
-long int code2_,//code #2
-long int code2_number_)//the range of code2_ is [0,code2_number_-1]
-{
-	if(test_mode)
-	{
-		if(code1_number_<=0||code2_number_<=0)
-		{
-			throw error("Unexpected error\n",1);
-		};
-
-		if(code2_<0||code2_>=code2_number_||code1_<0||code1_>=code1_number_)
-		{
-			throw error("Unexpected error\n",1);
-		};
-	};
-
-	return code1_*code2_number_+code2_;
-}
-
-void IS1_general::code_to_matr_indexes(
-long int code_,//input code
-long int &code1_,//code #1; the result
-long int code1_number_,//the range of code1_ is [0,code1_number_-1]
-long int &code2_,//code #2; the result
-long int code2_number_)//the range of code2_ is [0,code2_number_-1]
-{
-	if(test_mode)
-	{
-		if(code1_number_<=0||code2_number_<=0)
-		{
-			throw error("Unexpected error\n",1);
-		};
-	};
-
-	code2_=code_%code2_number_;
-	code1_=(code_-code2_)/code2_number_;
-
-	if(test_mode)
-	{
-
-		if(code2_<0||code2_>=code2_number_||code1_<0||code1_>=code1_number_)
-		{
-			throw error("Unexpected error\n",1);
-		};
-	};
-}
-
-double ** IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-long int alphabet_letters_number1_,//number of letters in the sequence #1
-long int alphabet_letters_number2_,//number of letters in the sequence #2
-pair<long int, long int> state_description_)//state description
-{
-	double ** res=NULL;
-
-	long int dim1=FSA_utils::power_long(alphabet_letters_number1_,state_description_.first);
-	long int dim2=FSA_utils::power_long(alphabet_letters_number2_,state_description_.second);
-
-	FSA_utils::get_memory_for_matrix(dim1,dim2,res);
-
-	return res;
-}
-
-void IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-double **&state_distr_,
-long int alphabet_letters_number1_,//number of letters in the sequence #1
-pair<long int, long int> state_description_)//state description
-{
-	long int dim1=FSA_utils::power_long(alphabet_letters_number1_,state_description_.first);
-
-	FSA_utils::delete_memory_for_matrix(dim1,state_distr_);
-	state_distr_=NULL;
-}
-
-
-void IS1_general::generate_one_state_sum_distr(//calculates sum-distributions corresponded to the input parameters
-pair<long int, long int> state_distr_dims_,//dimensions of the matrix state_distr_
-double **state_distr_,//state distribution in the same format as in d_states_distr[s]
-double *&state_sum_distr_)//the result; the dimention is state_distr__dim1 x state_distr__dim2
-{
-	long int dim1=state_distr_dims_.first;
-	long int dim2=state_distr_dims_.second;
-
-	long int dim=dim1*dim2;
-
-	state_sum_distr_=new double [dim];
-	FSA_utils::assert_mem(state_sum_distr_);
-
-	long int i,j;
-	for(i=0;i<dim1;i++)
-	{
-		for(j=0;j<dim2;j++)
-		{
-			long int code=matr_indexes_to_code(
-			i,//code #1
-			dim1,//the range of code1_ is [0,code1_number_-1]
-			j,//code #2
-			dim2);//the range of code2_ is [0,code2_number_-1]
-
-			state_sum_distr_[code]=state_distr_[i][j];
-
-			if(test_mode)
-			{
-				if(code<0||code>=dim)
-				{
-					throw error("Error - code<0||code>=dim\n",1);
-				};
-			};
-
-		};
-	};
-	
-	FSA_utils::convert_distr_into_sum(//convert distr_[0], distr_[1], distr_[2],... into distr_[0], distr_[0]+distr_[1], distr_[0]+distr_[1]+distr_[2],...
-	dim,
-	state_sum_distr_);
-}
-
-void IS1_general::generate_random_letters_in_a_given_state(
-long int state_number_,//state number
-long int *letters1_,//the resulted letters for the sequence 1; the array must be allocated
-long int *letters2_)//the resulted letters for the sequence 2; the array must be allocated
-{
-	long int dim1=d_states_distr_dimensions[state_number_].first;
-	long int dim2=d_states_distr_dimensions[state_number_].second;
-
-	long int dim=dim1*dim2;
-
-	long int code=FSA_utils::random_long(
-		FSA_utils::ran2(),
-		dim,
-		d_states_sum_distr[state_number_],
-		d_states_sum_distr_elements_for_all_states);
-
-		long int code1;
-		long int code2;
-
-		code_to_matr_indexes(
-		code,
-		code1,
-		dim1,
-		code2,
-		dim2);
-
-		code_to_letters(//returns a unique code for the array of letters
-		code1,//input code
-		//dim1,//total number of letters
-		d_alphabet_letters_number1,
-		d_states_description[state_number_].first,//dimension of the array with letters
-		letters1_);//array of letters; the result
-
-		code_to_letters(//returns a unique code for the array of letters
-		code2,//input code
-		//dim2,//total number of letters
-		d_alphabet_letters_number2,
-		d_states_description[state_number_].second,//dimension of the array with letters
-		letters2_);//array of letters; the result
-
-
-}
-
-void IS1_general::one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
-long int current_state_,//the current state
-long int *seq1_add_letters_,//letters for the sequence #1; the array must be allocated
-long int *seq2_add_letters_,//letters for the sequence #2; the array must be allocated
-long int &new_state_)//a new state
-{
-	//generate a new state
-	new_state_=FSA_utils::random_long(
-		FSA_utils::ran2(),
-		d_number_of_states,
-		d_transition_probabilities_sum[current_state_],
-		d_states_sum_distr_elements_for_all_states);
-
-	generate_random_letters_in_a_given_state(
-		new_state_,//state number
-		seq1_add_letters_,//the resulted letters for the sequence 1; the array must be allocated
-		seq2_add_letters_);//the resulted letters for the sequence 2; the array must be allocated
-
-
-}
-
-//-------------------------------------------------------------------
-//the importance sampling simulation object
-
-IS1_general_simulation::IS1_general_simulation(
-IS1_general *IS1_general_obj_,
-long int initial_state_,//initial state for the IS
-long int max_seq1_length_,//maximum sequence length
-long int max_seq2_length_,//maximum sequence length
-double *initial_distr_)//initial distribution of states; initial_state_ is ignored if d_initial_distr_ is defined
-{
-	d_IS1_general_obj=IS1_general_obj_;
-	d_max_seq1_length=max_seq1_length_;
-	d_max_seq2_length=max_seq2_length_;
-
-	d_seq1=new long int [d_max_seq1_length];
-	FSA_utils::assert_mem(d_seq1);
-
-	d_seq2=new long int [d_max_seq2_length];
-	FSA_utils::assert_mem(d_seq2);
-
-	d_seq1_current_length=0;
-	d_seq2_current_length=0;
-
-	d_initial_state=initial_state_;
-	d_current_state=initial_state_;
-
-	d_initial_distr_sum=NULL;
-	if(initial_distr_)
-	{
-		double eps_tmp=1e-10;
-		double sum_tmp=0;
-		d_initial_distr_sum=new double[IS1_general_obj_->d_number_of_states];
-		FSA_utils::assert_mem(d_initial_distr_sum);
-		long int i;
-		for(i=0;i<IS1_general_obj_->d_number_of_states;i++)
-		{
-			d_initial_distr_sum[i]=initial_distr_[i];
-			sum_tmp+=initial_distr_[i];
-		};
-		if(fabs(sum_tmp-1.0)>=eps_tmp)
-		{
-			throw error("Unexpected error - the sum of probablities in initial_distr_ is not 1.0 in IS1_general_simulation::IS1_general_simulation\n",1);
-		};
-
-		FSA_utils::convert_distr_into_sum(//convert distr_[0], distr_[1], distr_[2],... into distr_[0], distr_[0]+distr_[1], distr_[0]+distr_[1]+distr_[2],...
-			IS1_general_obj_->d_number_of_states,
-			d_initial_distr_sum);
-
-		d_current_state=FSA_utils::random_long<long int>(
-		FSA_utils::ran2(),
-		d_IS1_general_obj->d_number_of_states,
-		d_initial_distr_sum);
-
-
-	};
-
-
-	//weights calculation
-	long int depth1=-1;
-	long int depth2=-1;
-
-	long int s;
-	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-	{
-		depth1=FSA_utils::Tmax(depth1,d_IS1_general_obj->d_states_description[s].first);
-		depth2=FSA_utils::Tmax(depth2,d_IS1_general_obj->d_states_description[s].second);
-	};
-
-	d_W1_step1=depth1+1;
-	d_W1_step2=depth2+1;
-
-	depth1+=d_W1_step1;
-	depth2+=d_W1_step2;
-
-	d_W1=new two_dim_layer<double>* [d_IS1_general_obj->d_number_of_states];
-	FSA_utils::assert_mem(d_W1);
-
-	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-	{
-		d_W1[s]=new two_dim_layer<double> (
-			max_seq1_length_,
-			max_seq2_length_,
-			depth1,
-			depth2,
-			0);
-
-	};
-
-}
-
-
-IS1_general_simulation::IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
-IS1_general_simulation *IS1_general_simulation_)//maximum sequence length
-{
-	d_IS1_general_obj=IS1_general_simulation_->d_IS1_general_obj;
-	d_max_seq1_length=IS1_general_simulation_->d_W1_seq1_current_length;
-	d_max_seq2_length=IS1_general_simulation_->d_W1_seq2_current_length;
-
-	d_seq1_current_length=IS1_general_simulation_->d_seq1_current_length;
-	d_seq2_current_length=IS1_general_simulation_->d_seq2_current_length;
-
-	d_seq1=new long int [d_seq1_current_length];
-	FSA_utils::assert_mem(d_seq1);
-
-	d_seq2=new long int [d_seq2_current_length];
-	FSA_utils::assert_mem(d_seq2);
-
-
-	d_initial_state=IS1_general_simulation_->d_initial_state;
-	d_current_state=IS1_general_simulation_->d_current_state;
-
-	d_initial_distr_sum=NULL;
-	if(IS1_general_simulation_->d_initial_distr_sum)
-	{
-		d_initial_distr_sum=new double[IS1_general_simulation_->d_IS1_general_obj->d_number_of_states];
-		FSA_utils::assert_mem(d_initial_distr_sum);
-		long int i;
-		for(i=0;i<IS1_general_simulation_->d_IS1_general_obj->d_number_of_states;i++)
-		{
-			d_initial_distr_sum[i]=IS1_general_simulation_->d_initial_distr_sum[i];
-		};
-	};
-
-	//weights calculation
-	long int depth1=-1;
-	long int depth2=-1;
-
-	long int s;
-	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-	{
-		depth1=FSA_utils::Tmax(depth1,d_IS1_general_obj->d_states_description[s].first);
-		depth2=FSA_utils::Tmax(depth2,d_IS1_general_obj->d_states_description[s].second);
-	};
-
-	d_W1_step1=depth1+1;
-	d_W1_step2=depth2+1;
-
-	depth1+=d_W1_step1;
-	depth2+=d_W1_step2;
-
-	d_W1=new two_dim_layer<double>* [d_IS1_general_obj->d_number_of_states];
-	FSA_utils::assert_mem(d_W1);
-
-	d_W1_seq1_current_length=IS1_general_simulation_->d_W1_seq1_current_length;;
-	d_W1_seq2_current_length=IS1_general_simulation_->d_W1_seq2_current_length;;
-
-
-	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-	{
-		d_W1[s]=new two_dim_layer<double> (//constructor; copies data from two_dim_layer_ with minimally allocated memory
-		d_W1_seq1_current_length,
-		d_W1_seq2_current_length,
-		IS1_general_simulation_->d_W1[s]);
-	};
-
-
-	//copy sequences
-	for(s=0;s<d_seq1_current_length;s++)
-	{
-		d_seq1[s]=IS1_general_simulation_->d_seq1[s];
-	};
-
-	for(s=0;s<d_seq2_current_length;s++)
-	{
-		d_seq2[s]=IS1_general_simulation_->d_seq2[s];
-	};
-
-
-}
-
-
-IS1_general_simulation::~IS1_general_simulation()
-{
-	delete[]d_seq1;
-	delete[]d_seq2;
-	delete[]d_initial_distr_sum;
-
-	//weights calculation
-	long int s;
-	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-	{
-		delete d_W1[s];
-	};
-}
-
-void IS1_general_simulation::init()//initialization for a new sequence generation
-{
-	d_seq1_current_length=0;
-	d_seq2_current_length=0;
-
-	d_current_state=d_initial_state;
-
-	if(d_initial_distr_sum)
-	{
-		d_current_state=FSA_utils::random_long<long int>(
-		FSA_utils::ran2(),
-		d_IS1_general_obj->d_number_of_states,
-		d_initial_distr_sum);
-	};
-
-	//weights calculation
-	d_W1_seq1_current_length=-1;
-	d_W1_seq2_current_length=-1;
-
-}
-
-void IS1_general_simulation::simulate_upto_target_lengths(
-long int target_seq1_length_,//target length of the sequence #1
-long int target_seq2_length_)//target length of the sequence #2
-{
-	
-	long int new_state;
-
-	while((d_seq1_current_length<target_seq1_length_)||(d_seq2_current_length<target_seq2_length_))
-	{
-		long int expected_len1=d_seq1_current_length+d_IS1_general_obj->d_max_dim1;
-		long int expected_len2=d_seq2_current_length+d_IS1_general_obj->d_max_dim2;
-
-
-		if(expected_len1>d_max_seq1_length||expected_len2>d_max_seq2_length)
-		{
-			throw error("Error - please increase maximum allowed sequence length in IS1_general_simulation::simulate_upto_target_lengths\n",1);
-		};
-
-		d_IS1_general_obj->one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
-		d_current_state,//the current state
-		d_seq1+d_seq1_current_length,//letters for the sequence #1; the array must be allocated
-		d_seq2+d_seq2_current_length,//letters for the sequence #2; the array must be allocated
-		new_state);//a new state
-
-
-		d_current_state=new_state;
-
-		d_seq1_current_length+=d_IS1_general_obj->d_states_description[d_current_state].first;
-		d_seq2_current_length+=d_IS1_general_obj->d_states_description[d_current_state].second;
-
-	};
-	
-}
-
-//weights calculation
-void IS1_general_simulation::calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
-long int target_length1_,//target length for sequence #1
-long int target_length2_,//target length for sequence #2
-long int i1_,//the first index (corresponded to the sequence #1)
-long int i2_)//the second index (corresponded to the sequence #2)
-{
-	if(i1_>d_max_seq1_length||i2_>d_max_seq2_length)
-	{
-		throw error("Unexpected error - i1_>d_max_seq1_length||i2_>d_max_seq2_length in IS1_general_simulation::calculate_weight_W1_one_step\n",1);
-	};
-
-	if(i1_==0&&i2_==0)
-	{
-
-		long int s;
-		for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-		{
-			d_W1[s]->set_element(i1_,i2_,0);
-		};
-
-		d_W1[d_initial_state]->set_element(i1_,i2_,1.0);
-
-		if(d_initial_distr_sum)
-		{
-			s=0;
-			d_W1[s]->set_element(i1_,i2_,d_initial_distr_sum[s]);
-
-			for(s=1;s<d_IS1_general_obj->d_number_of_states;s++)
-			{
-				d_W1[s]->set_element(i1_,i2_,d_initial_distr_sum[s]-d_initial_distr_sum[s-1]);
-			};
-		};
-
-		return;
-	};
-	
-
-	long int s;
-	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-	{
-
-		long int dim1_tmp=d_IS1_general_obj->d_states_description[s].first;
-		long int diff1=-dim1_tmp+i1_;
-
-		long int dim2_tmp=d_IS1_general_obj->d_states_description[s].second;
-		long int diff2=-dim2_tmp+i2_;
-
-		long int code1=-1;
-		long int code2=-1;
-
-
-		double w_tmp=0;
-
-		if(diff1>=0&&diff2>=0)
-		{
-
-			
-			long int x1;
-			long int tmp_d=i1_-target_length1_;
-			if(-tmp_d>=0)
-			{
-				x1=dim1_tmp;
-			}
-			else
-			{
-				if(tmp_d>=dim1_tmp)
-				{
-					x1=0;
-				}
-				else
-				{
-					x1=dim1_tmp-tmp_d;
-				};
-			};
-
-			long int x2;
-			tmp_d=i2_-target_length2_;
-			if(-tmp_d>=0)
-			{
-				x2=dim2_tmp;
-			}
-			else
-			{
-				if(tmp_d>=dim2_tmp)
-				{
-					x2=0;
-				}
-				else
-				{
-					x2=dim2_tmp-tmp_d;
-				};
-			};
-
-		code1=d_IS1_general_obj->letters_to_code(//returns a unique code for the array of letters
-			d_IS1_general_obj->d_alphabet_letters_number1,//total number of letters
-			x1,//dimension of the array with letters
-			d_seq1+diff1);//array of letters
-
-		code2=d_IS1_general_obj->letters_to_code(//returns a unique code for the array of letters
-			d_IS1_general_obj->d_alphabet_letters_number2,//total number of letters
-			x2,//dimension of the array with letters
-			d_seq2+diff2);//array of letters
-
-
-			double q2=d_IS1_general_obj->d_states_distr_sums[s][x1][x2][code1][code2];
-
-
-
-
-			long int x;
-			for(x=0;x<d_IS1_general_obj->d_number_of_states;x++)
-			{
-				w_tmp+=d_IS1_general_obj->d_transition_probabilities[x][s]*d_W1[x]->get_element(i1_-dim1_tmp,i2_-dim2_tmp);
-			};
-			w_tmp*=q2;
-		};
-
-
-		d_W1[s]->set_element(i1_,i2_,w_tmp);
-
-
-	};
-
-}
-
-void IS1_general_simulation::calculate_weight_W1_upto_target_lengths(
-long int target_seq1_length_,//target length of the sequence #1
-long int target_seq2_length_,//target length of the sequence #2
-long int seq1_length_tmp_,//the weights are calculated upto this length for the sequence #1
-long int seq2_length_tmp_)//the weights are calculated upto this length for the sequence #2
-{
-	if(d_W1_seq1_current_length==-1&&d_W1_seq2_current_length==-1)
-	{
-		calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
-		target_seq1_length_,
-		target_seq2_length_,
-		0,//the first index (corresponded to the sequence #1)
-		0);//the second index (corresponded to the sequence #2)
-
-		d_W1_seq1_current_length=0;
-		d_W1_seq2_current_length=0;
-	};
-
-
-	long int ind1,ind2;
-
-	for(ind1=d_W1_seq1_current_length+1;ind1<=seq1_length_tmp_;ind1++)
-	{
-
-
-		long int s;
-		for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-		{
-			d_W1[s]->set_max_ind(ind1,d_W1_seq2_current_length);
-		};
-
-		long int i2;
-		for(i2=0;i2<=d_W1_seq2_current_length;i2++)
-		{
-			calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
-			target_seq1_length_,
-			target_seq2_length_,
-			ind1,//the first index (corresponded to the sequence #1)
-			i2);//the second index (corresponded to the sequence #2)
-		};
-
-	};
-
-	d_W1_seq1_current_length=target_seq1_length_;
-
-	for(ind2=d_W1_seq2_current_length+1;ind2<=seq2_length_tmp_;ind2++)
-	{
-
-		long int s;
-		for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-		{
-			d_W1[s]->set_max_ind(seq1_length_tmp_,ind2);
-		};
-
-		long int i1;
-		for(i1=0;i1<=seq1_length_tmp_;i1++)
-		{
-			calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
-			target_seq1_length_,
-			target_seq2_length_,
-			i1,//the first index (corresponded to the sequence #1)
-			ind2);//the second index (corresponded to the sequence #2)
-		};
-
-	};
-	
-	d_W1_seq2_current_length=target_seq2_length_;
-
-}
-
-void IS1_general_simulation::calculate_weight_W1_for_fixed_lengths_using_recursions(
-long int target_seq1_length_,//target length of the sequence #1
-long int target_seq2_length_,//target length of the sequence #2
-double &weight_,//the resulted weight
-bool save_matrices_,
-std::vector<std::vector<double> > *A1_,
-std::vector<std::vector<double> > *A2_)
-{
-	map<long int,bool> ind1_flag;
-	map<long int,bool> ind2_flag;
-	if(save_matrices_)
-	{
-		long int dimA1=0;
-		long int dimA2=0;
-
-		long int s;
-		for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-		{
-			long int dim1_tmp=d_IS1_general_obj->d_states_description[s].first;
-			long int dim2_tmp=d_IS1_general_obj->d_states_description[s].second;
-
-			if(dim1_tmp==0)
-			{
-				dimA2++;
-				ind2_flag[s]=true;
-			};
-
-			if(dim2_tmp==0)
-			{
-				dimA1++;
-				ind1_flag[s]=true;
-			};
-
-		};
-
-		if(save_matrices_)
-		{
-			A1_->clear();
-			A2_->clear();
-
-			if(dimA1>0)
-			{
-				A1_->resize(dimA1,std::vector<double> (dimA1+1,1));
-			};
-
-			if(dimA2>0)
-			{
-				A2_->resize(dimA2,std::vector<double> (dimA2+1,1));
-			};
-		};
-
-	};
-	
-	long int i1_ind_max=target_seq1_length_+d_IS1_general_obj->d_max_dim1-1;
-	long int i2_ind_max=target_seq2_length_+d_IS1_general_obj->d_max_dim2-1;
-
-	long int s;
-	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-	{
-		d_W1[s]->set_max_ind(i1_ind_max,i2_ind_max);
-	};
-
-	long int seq1_length_tmp=target_seq1_length_+d_IS1_general_obj->d_max_dim1-1;
-	long int seq2_length_tmp=target_seq2_length_+d_IS1_general_obj->d_max_dim2-1;
-
-	calculate_weight_W1_upto_target_lengths(
-		target_seq1_length_,//target length of the sequence #1
-		target_seq2_length_,//target length of the sequence #2
-		seq1_length_tmp,
-		seq2_length_tmp);
-
-
-	array_v<double> *sum_over_ind1=new array_v<double>[d_IS1_general_obj->d_number_of_states];
-	array_v<double> *sum_over_ind2=new array_v<double>[d_IS1_general_obj->d_number_of_states];
-
-	
-	{
-		
-		//index #1
-		long int s;
-
-		long int i1;
-		for(i1=-d_IS1_general_obj->d_max_dim1;i1<0;i1++)
-		{
-			for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-			{
-				sum_over_ind2[s].set_elem(i1,0);
-			};
-		};
-
-
-		
-		for(i1=0;i1<=i1_ind_max;i1++)
-		{
-
-			if(save_matrices_)
-			{
-				if(i1!=target_seq1_length_)
-				{
-					continue;
-				};
-			};
-
-			bool explicit_dependency_flag=true;
-
-			loop1:;
-
-			vector<double> x2_vect;
-
-			long int ind_count=-1;
-			
-			
-
-			for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-			{
-
-				long int dim1_tmp=d_IS1_general_obj->d_states_description[s].first;
-				long int dim2_tmp=d_IS1_general_obj->d_states_description[s].second;
-
-				
-
-				if(explicit_dependency_flag)
-				{
-					if(dim1_tmp==0)
-					{
-						continue;
-					};
-				}
-				else
-				{
-					if(dim1_tmp!=0)
-					{
-						continue;
-					};
-					
-				};
-
-				double x2_vect_elem=0;
-
-
-	//------------------------------------------
-				long int diff1=-dim1_tmp+i1;
-
-
-				double w_tmp=0;
-				double q2=0;
-
-				if(diff1>=0)
-				{
-					long int code1=-1;
-					long int code2=0;
-
-					
-					long int x1;
-					long int tmp_d=i1-target_seq1_length_;
-					if(-tmp_d>=0)
-					{
-						x1=dim1_tmp;
-					}
-					else
-					{
-						if(tmp_d>=dim1_tmp)
-						{
-							x1=0;
-						}
-						else
-						{
-							x1=dim1_tmp-tmp_d;
-						};
-					};
-
-					
-
-					long int x2=0;
-
-				code1=d_IS1_general_obj->letters_to_code(//returns a unique code for the array of letters
-					d_IS1_general_obj->d_alphabet_letters_number1,//total number of letters
-					x1,//dimension of the array with letters
-					d_seq1+diff1);//array of letters
-
-
-					q2=d_IS1_general_obj->d_states_distr_sums[s][x1][x2][code1][code2];
-					
-
-
-					if(save_matrices_)
-					{
-						if(i1==target_seq1_length_)
-						{
-							if(!explicit_dependency_flag)
-							{
-								if(dim1_tmp==0)
-								{
-									ind_count++;
-
-									long int ind_count2=-1;
-									long int s1;
-									for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
-									{
-										if(ind2_flag[s1])
-										{
-											ind_count2++;
-
-											(*A2_)[ind_count][ind_count2]=d_IS1_general_obj->d_transition_probabilities[s1][s]*q2;
-
-											if(s==s1)
-											{
-												(*A2_)[ind_count][ind_count2]-=1.0;
-											};
-
-										};
-									};
-								};
-							};
-						};
-						continue;
-					};
-
-
-		//------------------------------------------
-
-
-					long int s1;
-					if(explicit_dependency_flag)
-					{
-						for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
-						{
-							w_tmp+=d_IS1_general_obj->d_transition_probabilities[s1][s]*sum_over_ind2[s1].get_elem(i1-dim1_tmp);
-						};
-
-						w_tmp*=q2;
-					}
-					else
-					{
-						long int s1;
-						for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
-						{
-							if(!(d_IS1_general_obj->d_states_description[s1].first==0))
-							{
-								x2_vect_elem-=d_IS1_general_obj->d_transition_probabilities[s1][s]*sum_over_ind2[s1].get_elem(i1-dim1_tmp);
-							};
-
-						};
-
-						x2_vect_elem*=q2;
-
-					};
-
-
-
-
-					
-					
-
-				};
-
-				long int ii2;
-				for(ii2=0;ii2<dim2_tmp;ii2++)
-				{
-					double ww=d_W1[s]->get_element(i1,target_seq2_length_+ii2);
-					if(explicit_dependency_flag)
-					{
-						w_tmp+=ww;
-					}
-					else
-					{
-						x2_vect_elem-=ww;
-					};
-				};
-
-
-
-
-				if(explicit_dependency_flag)
-				{
-					sum_over_ind2[s].set_elem(i1,w_tmp);
-				}
-				else
-				{
-					x2_vect.push_back(x2_vect_elem);
-				};
-
-			};
-
-			if(explicit_dependency_flag)
-			{
-				explicit_dependency_flag=false;
-				goto loop1;
-			};
-
-			if(!explicit_dependency_flag)
-			{
-				if(d_IS1_general_obj->d_A2_inv.size()>0)
-				{
-					
-					std::vector<double> res2;
-					
-					FSA_utils::multiply_matrix_and_vector(
-						d_IS1_general_obj->d_A2_inv,
-						x2_vect,
-						res2);
-						
-
-
-					long int dimA2=0;
-
-					long int s;
-					for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-					{
-
-						long int dim1_t=d_IS1_general_obj->d_states_description[s].first;
-
-
-						if(dim1_t==0)
-						{
-							sum_over_ind2[s].set_elem(i1,res2[dimA2]);
-							dimA2++;
-						};
-
-
-					};
-
-				};
-
-			};
-
-		};
-	};
-
-
-//============================================================================================
-
-	{
-		//index #2
-		long int s;
-
-		long int i2;
-		for(i2=-d_IS1_general_obj->d_max_dim2;i2<0;i2++)
-		{
-			for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-			{
-				sum_over_ind1[s].set_elem(i2,0);
-			};
-		};
-
-
-		
-		for(i2=0;i2<=i2_ind_max;i2++)
-		{
-
-			if(save_matrices_)
-			{
-				if(i2!=target_seq2_length_)
-				{
-					continue;
-				};
-			};
-
-			bool explicit_dependency_flag=true;
-
-			loop2:;
-
-			vector<double> x1_vect;
-
-			long int ind_count=-1;
-			
-
-			for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-			{
-
-
-				long int dim1_tmp=d_IS1_general_obj->d_states_description[s].first;
-				long int dim2_tmp=d_IS1_general_obj->d_states_description[s].second;
-
-				if(explicit_dependency_flag)
-				{
-					if(dim2_tmp==0)
-					{
-						continue;
-					};
-				}
-				else
-				{
-					if(dim2_tmp!=0)
-					{
-						continue;
-					};
-				};
-
-				double x1_vect_elem=0;
-
-
-	//------------------------------------------
-				long int diff2=-dim2_tmp+i2;
-
-
-				double w_tmp=0;
-
-				double q2=0;
-
-				if(diff2>=0)
-				{
-					long int code1=0;
-					long int code2=-1;
-
-					
-					long int x2;
-					long int tmp_d=i2-target_seq2_length_;
-					if(-tmp_d>=0)
-					{
-						x2=dim2_tmp;
-					}
-					else
-					{
-						if(tmp_d>=dim2_tmp)
-						{
-							x2=0;
-						}
-						else
-						{
-							x2=dim2_tmp-tmp_d;
-						};
-					};
-
-					
-
-					long int x1=0;
-
-
-				code2=d_IS1_general_obj->letters_to_code(//returns a unique code for the array of letters
-					d_IS1_general_obj->d_alphabet_letters_number2,//total number of letters
-					x2,//dimension of the array with letters
-					d_seq2+diff2);//array of letters
-
-
-					q2=d_IS1_general_obj->d_states_distr_sums[s][x1][x2][code1][code2];
-
-					if(save_matrices_)
-					{
-						if(i2==target_seq2_length_)
-						{
-							if(!explicit_dependency_flag)
-							{
-								if(dim2_tmp==0)
-								{
-									ind_count++;
-
-									long int ind_count2=-1;
-									long int s1;
-									for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
-									{
-										if(ind1_flag[s1])
-										{
-											ind_count2++;
-
-											(*A1_)[ind_count][ind_count2]=d_IS1_general_obj->d_transition_probabilities[s1][s]*q2;
-
-											if(s==s1)
-											{
-												(*A1_)[ind_count][ind_count2]-=1.0;
-											};
-
-										};
-									};
-								};
-							};
-						};
-						continue;
-					};
-
-
-		//------------------------------------------
-
-
-					long int s1;
-					if(explicit_dependency_flag)
-					{
-						for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
-						{
-							w_tmp+=d_IS1_general_obj->d_transition_probabilities[s1][s]*sum_over_ind1[s1].get_elem(i2-dim2_tmp);
-						};
-
-						w_tmp*=q2;
-					}
-					else
-					{
-						long int s1;
-						for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
-						{
-							if(!(d_IS1_general_obj->d_states_description[s1].second==0))
-							{
-								x1_vect_elem-=d_IS1_general_obj->d_transition_probabilities[s1][s]*sum_over_ind1[s1].get_elem(i2-dim2_tmp);
-							};
-
-						};
-
-						x1_vect_elem*=q2;
-
-					};
-
-
-
-				};
-
-				long int ii1;
-				for(ii1=0;ii1<dim1_tmp;ii1++)
-				{
-					double ww=d_W1[s]->get_element(target_seq1_length_+ii1,i2);
-					if(explicit_dependency_flag)
-					{
-						w_tmp+=ww;
-					}
-					else
-					{
-						x1_vect_elem-=ww;
-					};
-
-				};
-
-				if(explicit_dependency_flag)
-				{
-					sum_over_ind1[s].set_elem(i2,w_tmp);
-				}
-				if(!explicit_dependency_flag)
-				{
-					x1_vect.push_back(x1_vect_elem);
-				};
-
-
-			};
-
-			if(explicit_dependency_flag)
-			{
-				explicit_dependency_flag=false;
-				goto loop2;
-			};
-
-			if(!explicit_dependency_flag)
-			{
-				if(d_IS1_general_obj->d_A2_inv.size()>0)
-				{
-					
-					std::vector<double> res1;
-					
-					FSA_utils::multiply_matrix_and_vector(
-						d_IS1_general_obj->d_A1_inv,
-						x1_vect,
-						res1);
-						
-
-
-					long int dimA1=0;
-					
-
-					long int s;
-					for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-					{
-						
-						long int dim2_t=d_IS1_general_obj->d_states_description[s].second;
-
-
-						if(dim2_t==0)
-						{
-							sum_over_ind1[s].set_elem(i2,res1[dimA1]);
-							
-							dimA1++;
-						};
-
-					};
-
-				};
-
-			};
-
-
-
-		};
-
-	};
-
-	weight_=0;
-
-	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-	{
-		long int dim1_tmp=d_IS1_general_obj->d_states_description[s].first;
-		long int dim2_tmp=d_IS1_general_obj->d_states_description[s].second;
-
-		long int i1;
-		for(i1=0;i1<dim1_tmp;i1++)
-		{
-			weight_+=sum_over_ind2[s].get_elem(target_seq1_length_+i1);
-		};
-
-		long int i2;
-		for(i2=0;i2<dim2_tmp;i2++)
-		{
-			weight_+=sum_over_ind1[s].get_elem(target_seq2_length_+i2);
-		};
-
-		for(i1=0;i1<dim1_tmp;i1++)
-		{
-			for(i2=0;i2<dim2_tmp;i2++)
-			{
-				weight_-=d_W1[s]->get_element(target_seq1_length_+i1,target_seq2_length_+i2);
-			};
-		};
-
-		
-	};
-
-
-	delete[]sum_over_ind1;
-	delete[]sum_over_ind2;
-
-
-
-}
-
-//================================
-void IS1_general::calculate_inverse_matrices_for_the_infinite_sums(
-long int code1_,
-long int code2_,
-std::vector<std::vector<double> > *A1_inv_,
-std::vector<std::vector<double> > *A2_inv_,
-long int x1_,
-long int x2_)
-{
-	std::vector<std::vector<double> > A1;
-	std::vector<std::vector<double> > A2;
-
-	map<long int,bool> ind1_flag;
-	map<long int,bool> ind2_flag;
-
-	{
-		long int dimA1=0;
-		long int dimA2=0;
-
-		long int s;
-		for(s=0;s<d_number_of_states;s++)
-		{
-			long int dim1_tmp=d_states_description[s].first;
-			long int dim2_tmp=d_states_description[s].second;
-
-			if(dim1_tmp==0)
-			{
-				dimA2++;
-				ind2_flag[s]=true;
-			};
-
-			if(dim2_tmp==0)
-			{
-				dimA1++;
-				ind1_flag[s]=true;
-			};
-
-		};
-
-		
-		
-
-		if(x1_>=0)
-		{
-			A1.clear();
-			(*A1_inv_).clear();
-			if(dimA1>0)
-			{
-				A1.resize(dimA1,std::vector<double> (dimA1+1,1));
-			};
-			
-		};
-
-
-		if(x2_>=0)
-		{
-			A2.clear();
-			(*A2_inv_).clear();
-			if(dimA2>0)
-			{
-				A2.resize(dimA2,std::vector<double> (dimA2+1,1));
-			};
-		};
-
-
-	};
-	
-
-	if(x1_>=0)
-	{
-		
-		//index #1
-		long int s;
-		long int ind_count=-1;
-
-		for(s=0;s<d_number_of_states;s++)
-		{
-			long int dim1_tmp=d_states_description[s].first;
-
-			if(dim1_tmp!=0)
-			{
-				continue;
-			};
-
-
-			double q2=0;
-
-			long int code1=code1_;
-			long int code2=0;
-
-			
-			long int x1=x1_;
-			long int x2=0;
-
-			q2=d_states_distr_sums[s][x1][x2][code1][code2];
-			
-
-
-			ind_count++;
-
-			long int ind_count2=-1;
-			long int s1;
-			for(s1=0;s1<d_number_of_states;s1++)
-			{
-				if(ind2_flag[s1])
-				{
-					ind_count2++;
-
-					A2[ind_count][ind_count2]=d_transition_probabilities[s1][s]*q2;
-
-					if(s==s1)
-					{
-						A2[ind_count][ind_count2]-=1.0;
-					};
-
-				};
-			};
-
-		};
-
-
-
-
-		if(A2.size()>0)
-		{
-			double inside_eps=1e-12;
-			std::vector<double> x2;
-			FSA_utils::Gauss(
-				A2,//matrix n*(n+1)
-				x2,//solution
-				inside_eps,
-				A2_inv_);
-		};
-
-		
-
-	};
-
-//============================================================================================
-
-	if(x2_>=0)
-	{
-		//index #2
-		long int s;
-
-		
-
-		long int ind_count=-1;
-
-		for(s=0;s<d_number_of_states;s++)
-		{
-			long int dim2_tmp=d_states_description[s].second;
-
-			if(dim2_tmp!=0)
-			{
-				continue;
-			};
-
-
-
-			double q2=0;
-
-			long int code1=0;
-			long int code2=code2_;
-
-			
-			long int x2=x2_;
-			long int x1=0;
-
-
-
-			q2=d_states_distr_sums[s][x1][x2][code1][code2];
-
-			ind_count++;
-
-			long int ind_count2=-1;
-			long int s1;
-			for(s1=0;s1<d_number_of_states;s1++)
-			{
-				if(ind1_flag[s1])
-				{
-					ind_count2++;
-
-					A1[ind_count][ind_count2]=d_transition_probabilities[s1][s]*q2;
-
-					if(s==s1)
-					{
-						A1[ind_count][ind_count2]-=1.0;
-					};
-
-				};
-			};
-
-
-
-		};
-
-
-
-		if(A1.size()>0)
-		{
-			double inside_eps=1e-12;
-			std::vector<double> x1;
-			FSA_utils::Gauss(
-				A1,//matrix n*(n+1)
-				x1,//solution
-				inside_eps,
-				A1_inv_);
-		};
-
-	};
-
-
-}
-
-//================================
-void IS1_general_simulation::calculate_weight_W1_for_fixed_lengths_using_infinite_sums(
-long int target_seq1_length_,//target length of the sequence #1
-long int target_seq2_length_,//target length of the sequence #2
-double &weight_)//the resulted weight
-{
-	weight_=0;
-
-	long int margin2=FSA_utils::Tmax(d_IS1_general_obj->d_max_dim2,(long int)200);
-	long int margin1=FSA_utils::Tmax(d_IS1_general_obj->d_max_dim1,3*margin2);
-
-	margin1=FSA_utils::Tmin(margin1,d_W1[0]->d_max_ind1-target_seq1_length_);
-	margin2=FSA_utils::Tmin(margin2,d_W1[0]->d_max_ind2-target_seq2_length_);
-
-	//if(d_W1_seq1_current_length==0&&d_W1_seq2_current_length==0)
-	{
-		calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
-		target_seq1_length_,
-		target_seq2_length_,
-		0,//the first index (corresponded to the sequence #1)
-		0);//the second index (corresponded to the sequence #2)
-	};
-
-	d_W1_seq1_current_length=-1;
-	d_W1_seq2_current_length=-1;
-
-	while(d_W1_seq1_current_length<target_seq1_length_+margin1)
-	{
-
-		d_W1_seq1_current_length++;
-
-		long int i1_ind_max=d_W1_seq1_current_length;
-
-		long int i2_ind_max=FSA_utils::Tmax(target_seq2_length_+d_IS1_general_obj->d_max_dim2-1,d_W1_seq2_current_length);
-
-		if(d_W1_seq1_current_length>=target_seq1_length_||
-			d_W1_seq1_current_length<=target_seq1_length_+d_IS1_general_obj->d_max_dim1-1)
-		{
-			i2_ind_max=FSA_utils::Tmax(target_seq2_length_+margin2,d_W1_seq2_current_length);
-		};
-
-		long int s;
-		for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-		{
-			d_W1[s]->set_max_ind(i1_ind_max,i2_ind_max);
-		};
-
-		long int i2;
-		for(i2=0;i2<=i2_ind_max;i2++)
-		{
-
-
-			calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
-			target_seq1_length_,
-			target_seq2_length_,
-			d_W1_seq1_current_length,//the first index (corresponded to the sequence #1)
-			i2);//the second index (corresponded to the sequence #2)
-
-			{
-				
-
-				long int i1=d_W1_seq1_current_length;
-
-				long int i1_diff=i1-target_seq1_length_;
-				long int i2_diff=i2-target_seq2_length_;
-
-				for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
-				{
-
-					if(i1_diff>=0&&i2_diff>=0&&
-						(i1_diff<d_IS1_general_obj->d_states_description[s].first||
-						i2_diff<d_IS1_general_obj->d_states_description[s].second)
-						)
-					{
-						weight_+=d_W1[s]->get_element(i1,i2);
-					};
-
-				};
-			};
-
-		};
-	};
-
-}
-
-void test::normalize_state_distributions(
-long int alphabet_letters_number1_,//number of letters in the sequence #1
-long int alphabet_letters_number2_,//number of letters in the sequence #2
-
-long int number_of_states_,//number of states
-
-pair<long int, long int> *states_description_,//description of the states; the index is a state number
-double ***states_distr_)//distributions of the states; the index is a state number
-{
-	long int s;
-	for(s=0;s<number_of_states_;s++)
-	{
-		long int dim1=FSA_utils::power_long(alphabet_letters_number1_,states_description_[s].first);
-		long int dim2=FSA_utils::power_long(alphabet_letters_number2_,states_description_[s].second);
-
-		double sum_tmp=0;
-		long int i1,i2;
-		for(i1=0;i1<dim1;i1++)
-		{
-			for(i2=0;i2<dim2;i2++)
-			{
-				sum_tmp+=states_distr_[s][i1][i2];
-			};
-		};
-
-		if(sum_tmp<=0)
-		{
-			throw error("Error: the distribution defined by states_distr_ in test::normalize_state_distributions is incorrect\n",1);
-		};
-
-		for(i1=0;i1<dim1;i1++)
-		{
-			for(i2=0;i2<dim2;i2++)
-			{
-				states_distr_[s][i1][i2]/=sum_tmp;
-			};
-		};
-
-	};
-}
-
-//=============================
-void test::FSA_IS_transition_probabilities_calculation(
-bool &FSA_flag,
-double ***&states_distr,
-
-bool &cs_flag,
-double ***&states_distr_cs,
-
-bool &sim_flag,
-double ***&states_distr_sim,
-
-long int &number_of_states,
-long int &alphabet_letters_number1,
-long int &alphabet_letters_number2,
-pair<long int, long int> *&states_description,
-long int &codon_length,
-long int *&codon_AA,
-double *&RR1,
-double *&RR2,
-map<string, long int> &state_name_into_number,
-long int **&smatr,
-double &ungappedlambda)
-{
-	long int *letters1=new long int[4];
-	long int *letters2=new long int[1];
-	long int *codon_tmp=new long int[3];
-
-	long int s;
-	for(s=0;s<number_of_states;s++)
-	{
-
-		long int i1,i2;
-
-		long int max_ind1=FSA_utils::power_long(alphabet_letters_number1,states_description[s].first);
-		long int max_ind2=FSA_utils::power_long(alphabet_letters_number2,states_description[s].second);
-
-		for(i1=0;i1<max_ind1;i1++)
-		{
-			IS1_general::code_to_letters(//returns a unique code for the array of letters
-			i1,//input code
-			alphabet_letters_number1,//total number of letters
-			states_description[s].first,//dimension of the array with letters
-			letters1);//array of letters; the result
-
-			double tmp1=1;
-			long int t1;
-			for(t1=0;t1<states_description[s].first;t1++)
-			{
-				tmp1*=RR1[letters1[t1]];
-			};
-
-			long int AA1=0;
-
-			if(s==state_name_into_number["S1"])
-			{
-				AA1=FSA_utils::convert_codon_into_AA(
-				codon_length,//codon length 
-				codon_AA,//<codon code,AA number>
-				alphabet_letters_number1,//number of letters for the sequence 1
-				letters1);
-			};
-
-			if(s==state_name_into_number["S3"])
-			{
-				AA1=FSA_utils::convert_codon_into_AA(
-				codon_length,//codon length 
-				codon_AA,//<codon code,AA number>
-				alphabet_letters_number1,//number of letters for the sequence 1
-				letters1+1);
-			};
-
-			//simplified sampling
-			if(sim_flag)
-			{
-				if(s==0)
-				{
-					states_distr_sim[1][i1][0]=tmp1;
-				};
-			};
-			//simplified sampling - end
-
-
-
-			for(i2=0;i2<max_ind2;i2++)
-			{
-				IS1_general::code_to_letters(//returns a unique code for the array of letters
-				i2,//input code
-				alphabet_letters_number2,//total number of letters
-				states_description[s].second,//dimension of the array with letters
-				letters2);//array of letters; the result
-
-				double tmp2=1;
-				long int t2;
-				for(t2=0;t2<states_description[s].second;t2++)
-				{
-					tmp2*=RR2[letters2[t2]];
-				};
-
-					if(s==state_name_into_number["D1"]||s==state_name_into_number["D2"]||
-						s==state_name_into_number["D3"]||s==state_name_into_number["I"]||
-					s==state_name_into_number["F"])
-					{
-						if(FSA_flag)
-						{
-							states_distr[s][i1][i2]=tmp1*tmp2;
-						};
-						continue;
-					};
-
-				//crude sampling
-				if(cs_flag)
-				{
-					if(s==0)
-					{
-						states_distr_cs[0][i1][i2]=tmp1*tmp2;
-					};
-				};
-				//crude sampling - end
-
-				//simplified sampling
-				if(sim_flag)
-				{
-					if(s==0)
-					{
-						states_distr_sim[0][i1][i2]=tmp1*tmp2*exp(ungappedlambda*smatr[AA1][letters2[0]]);
-
-						if(i1==0)
-						{
-							states_distr_sim[2][0][i2]=tmp2;
-						};
-
-					};
-				};
-				//simplified sampling - end
-
-
-
-				if(s==state_name_into_number["S1"]||s==state_name_into_number["S3"])
-				{
-					if(FSA_flag)
-					{
-						states_distr[s][i1][i2]=tmp1*tmp2*exp(ungappedlambda*smatr[AA1][letters2[0]]);
-					};
-					continue;
-				};
-
-				if(s==state_name_into_number["S2"])
-				{
-					double tmp3=0;
-
-					long int a1;
-					for(a1=0;a1<alphabet_letters_number1;a1++)
-					{
-						codon_tmp[0]=a1;
-						codon_tmp[1]=letters1[0];
-						codon_tmp[2]=letters1[1];
-
-
-						AA1=FSA_utils::convert_codon_into_AA(
-						codon_length,//codon length 
-						codon_AA,//<codon code,AA number>
-						alphabet_letters_number1,//number of letters for the sequence 1
-						codon_tmp);
-
-						tmp3+=RR1[a1]*exp(ungappedlambda*smatr[AA1][letters2[0]]);
-
-
-					};
-
-					if(FSA_flag)
-					{
-						states_distr[s][i1][i2]=tmp1*tmp2*tmp3;
-					};
-					continue;
-				};
-
-
-
-			};
-
-		};
-
-
-	};
-
-	delete[]letters1;
-	delete[]letters2;
-	delete[]codon_tmp;
-}
-
-void test::combine_parameters_from_forward_and_reversed_calculations_generalized(
-Sls::FALP_set_of_parameters &par_,//parameters from forward calculation
-Sls::FALP_set_of_parameters &par_reversed_,//parameters from reversed calculation
-Sls::FALP_set_of_parameters &par_result_)//the result
-{
-
-	long int c12=par_.realizations_number+par_reversed_.realizations_number;
-	if(c12<=0)
-	{
-		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-	};
-	double c1=(double)par_.realizations_number/(double)c12;
-	double c2=(double)par_reversed_.realizations_number/(double)c12;
-
-	par_result_.lambda=c1*par_.lambda+c2*par_reversed_.lambda;
-	par_result_.lambda_error=FSA_utils::error_of_the_sum(//v1_+v2_
-								c1*par_.lambda_error,
-								c2*par_reversed_.lambda_error);
-
-		
-
-	par_result_.C=par_.C;
-	par_result_.C_error=par_.C_error;
-
-	par_result_.K_C=par_reversed_.K_C;
-	par_result_.K_C_error=par_reversed_.K_C_error;
-
-	par_result_.K=par_.C*par_reversed_.K_C;
-	par_result_.K_error=FSA_utils::error_of_the_product(//v1_*v2_
-								par_.C,
-								par_.C_error,
-								par_reversed_.K_C,
-								par_reversed_.K_C_error);
-
-	par_result_.a_I=c1*par_.a_I+c2*par_reversed_.a_I;
-	par_result_.a_I=FSA_utils::Tmax(par_result_.a_I,0.0);
-	par_result_.a_I_error=FSA_utils::error_of_the_sum(//v1_+v2_
-								c1*par_.a_I_error,
-								c2*par_reversed_.a_I_error);
-
-	par_result_.a_J=c1*par_.a_J+c2*par_reversed_.a_J;
-	par_result_.a_J=FSA_utils::Tmax(par_result_.a_J,0.0);
-	par_result_.a_J_error=FSA_utils::error_of_the_sum(//v1_+v2_
-								c1*par_.a_J_error,
-								c2*par_reversed_.a_J_error);
-
-	par_result_.sigma=c1*par_.sigma+c2*par_reversed_.sigma;
-	par_result_.sigma=FSA_utils::Tmax(par_result_.sigma,0.0);
-	par_result_.sigma_error=FSA_utils::error_of_the_sum(//v1_+v2_
-								c1*par_.sigma_error,
-								c2*par_reversed_.sigma_error);
-
-	par_result_.alpha_I=c1*par_.alpha_I+c2*par_reversed_.alpha_I;
-	par_result_.alpha_I=FSA_utils::Tmax(par_result_.alpha_I,0.0);
-	par_result_.alpha_I_error=FSA_utils::error_of_the_sum(//v1_+v2_
-								c1*par_.alpha_I_error,
-								c2*par_reversed_.alpha_I_error);
-
-	par_result_.alpha_J=c1*par_.alpha_J+c2*par_reversed_.alpha_J;
-	par_result_.alpha_J=FSA_utils::Tmax(par_result_.alpha_J,0.0);
-	par_result_.alpha_J_error=FSA_utils::error_of_the_sum(//v1_+v2_
-								c1*par_.alpha_J_error,
-								c2*par_reversed_.alpha_J_error);
-
-
-
-	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-	par_result_.G=0;
-	par_result_.G1=0;
-	par_result_.G2=0;
-
-	/*
-	par_result_.G=par_.G;
-	par_result_.G1=par_.G1;
-	par_result_.G2=par_.G2;
-	*/
-
-
-	size_t size_tmp=par_.m_LambdaSbs.size();
-
-	if(size_tmp!=par_reversed_.m_LambdaSbs.size()||
-		size_tmp!=par_reversed_.m_KSbs.size()||
-		size_tmp!=par_reversed_.m_K_CSbs.size()||
-		size_tmp!=par_.m_CSbs.size()||
-		size_tmp!=par_reversed_.m_CSbs.size()||
-		size_tmp!=par_.m_SigmaSbs.size()||
-		size_tmp!=par_reversed_.m_SigmaSbs.size()||
-		size_tmp!=par_.m_AlphaISbs.size()||
-		size_tmp!=par_reversed_.m_AlphaISbs.size()||
-		size_tmp!=par_.m_AlphaJSbs.size()||
-		size_tmp!=par_reversed_.m_AlphaJSbs.size()||
-		size_tmp!=par_.m_AISbs.size()||
-		size_tmp!=par_reversed_.m_AISbs.size()||
-		size_tmp!=par_.m_AJSbs.size()||
-		size_tmp!=par_reversed_.m_AJSbs.size()
-		)
-	{
-		throw error("Unexpected error in combine_parameters_from_forward_and_reversed_calculations_generalized\n",1);
-	};
-
-	par_result_.m_LambdaSbs.resize(size_tmp);
-	par_result_.m_KSbs.resize(size_tmp);
-	
-	par_result_.m_K_CSbs.resize(size_tmp);
-
-	par_result_.m_CSbs.resize(size_tmp);
-
-	par_result_.m_SigmaSbs.resize(size_tmp);
-	par_result_.m_AlphaISbs.resize(size_tmp);
-	par_result_.m_AlphaJSbs.resize(size_tmp);
-
-	par_result_.m_AISbs.resize(size_tmp);
-	par_result_.m_AJSbs.resize(size_tmp);
-
-
-	long int k;
-	for(k=0;k<(long int)size_tmp;k++)
-	{
-		par_result_.m_LambdaSbs[k]=c1*par_.m_LambdaSbs[k]+c2*par_reversed_.m_LambdaSbs[k];
-		par_result_.m_KSbs[k]=par_.m_CSbs[k]*par_reversed_.m_K_CSbs[k];
-		
-		par_result_.m_K_CSbs[k]=par_reversed_.m_K_CSbs[k];
-
-		par_result_.m_CSbs[k]=par_.m_CSbs[k];
-
-		par_result_.m_SigmaSbs[k]=c1*par_.m_SigmaSbs[k]+c2*par_reversed_.m_SigmaSbs[k];
-		par_result_.m_SigmaSbs[k]=FSA_utils::Tmax(par_result_.m_SigmaSbs[k],0.0);
-
-		par_result_.m_AlphaISbs[k]=c1*par_.m_AlphaISbs[k]+c2*par_reversed_.m_AlphaISbs[k];
-		par_result_.m_AlphaISbs[k]=FSA_utils::Tmax(par_result_.m_AlphaISbs[k],0.0);
-
-		par_result_.m_AlphaJSbs[k]=c1*par_.m_AlphaJSbs[k]+c2*par_reversed_.m_AlphaJSbs[k];
-		par_result_.m_AlphaJSbs[k]=FSA_utils::Tmax(par_result_.m_AlphaJSbs[k],0.0);
-
-		par_result_.m_AISbs[k]=c1*par_.m_AISbs[k]+c2*par_reversed_.m_AISbs[k];
-		par_result_.m_AISbs[k]=FSA_utils::Tmax(par_result_.m_AISbs[k],0.0);
-
-		par_result_.m_AJSbs[k]=c1*par_.m_AJSbs[k]+c2*par_reversed_.m_AJSbs[k];
-		par_result_.m_AJSbs[k]=FSA_utils::Tmax(par_result_.m_AJSbs[k],0.0);
-	};
-
-
-}
-
-void test::delete_mult_states_type(
-mult_states_type *&states_old1)
-{
-	if(states_old1)
-	{
-		long int kk1;
-		for(kk1=0;kk1<states_old1->d_number_of_realizations;kk1++)
-		{
-			
-
-			delete states_old1->d_states[kk1].d_M_array;
-			delete states_old1->d_states[kk1].d_seq1_length_array;
-			delete states_old1->d_states[kk1].d_seq2_length_array;
-			delete states_old1->d_states[kk1].d_distance_along_direction_1_array;
-			delete states_old1->d_states[kk1].d_distance_along_direction_2_array;
-			delete states_old1->d_states[kk1].d_ALP_weights_array;
-
-			delete states_old1->d_states[kk1].d_IS1_general_simulation;
-			delete states_old1->d_states[kk1].d_two_dim_layer_alignment_algorithm;
-
-		};
-
-		delete[]states_old1->d_states;
-
-		delete states_old1;states_old1=NULL;
-	};
-}
-
-//for test
-void test::compare_mult_states(
-mult_states_type *states_old_,
-mult_states_type *states_new_)
-{
-	if(states_old_->d_average_ALP_pos1!=states_new_->d_average_ALP_pos1)
-	{
-		cout<<"states_old_->d_average_ALP_pos1!=states_new_->d_average_ALP_pos1\n";
-	};
-
-	if(states_old_->d_average_ALP_pos2!=states_new_->d_average_ALP_pos2)
-	{
-		cout<<"states_old_->d_average_ALP_pos2!=states_new_->d_average_ALP_pos2\n";
-	};
-	if(states_old_->d_average_ALP_pos1_mult_ALP_pos2!=states_new_->d_average_ALP_pos1_mult_ALP_pos2)
-	{
-		cout<<"states_old_->d_average_ALP_pos1_mult_ALP_pos2!=states_new_->d_average_ALP_pos1_mult_ALP_pos2\n";
-	};
-	if(states_old_->d_average_expanding_length1!=states_new_->d_average_expanding_length1)
-	{
-		cout<<"states_old_->d_average_expanding_length1!=states_new_->d_average_expanding_length1\n";
-	};
-	if(states_old_->d_average_expanding_length1_mult_expanding_length2!=states_new_->d_average_expanding_length1_mult_expanding_length2)
-	{
-		cout<<"states_old_->d_average_expanding_length1_mult_expanding_length2!=states_new_->d_average_expanding_length1_mult_expanding_length2\n";
-	};
-	if(states_old_->d_average_expanding_length2!=states_new_->d_average_expanding_length2)
-	{
-		cout<<"states_old_->d_average_expanding_length2!=states_new_->d_average_expanding_length2\n";
-	};
-	if(states_old_->d_number_of_ALP!=states_new_->d_number_of_ALP)
-	{
-		cout<<"states_old_->d_number_of_ALP!=states_new_->d_number_of_ALP\n";
-	};
-	if(states_old_->d_number_of_realizations!=states_new_->d_number_of_realizations)
-	{
-		cout<<"states_old_->d_number_of_realizations!=states_new_->d_number_of_realizations\n";
-	};
-	if(states_old_->d_total_calculation_time!=states_new_->d_total_calculation_time)
-	{
-		//cout<<"states_old_->d_total_calculation_time!=states_new_->d_total_calculation_time\n";
-	};
-	if(states_old_->d_states!=states_new_->d_states)
-	{
-		//cout<<"states_old_->d_states!=states_new_->d_states\n";
-	};
-
-	long int k;
-
-	for(k=0;
-		k<FSA_utils::Tmin(states_old_->d_number_of_realizations,states_new_->d_number_of_realizations);
-		//k<1;
-		k++)
-	{
-		if(states_old_->d_states[k].d_ALP_number!=states_new_->d_states[k].d_ALP_number)
-		{
-			//cout<<k<<"\tstates_old_->d_states[k].d_ALP_number!=states_new_->d_states[k].d_ALP_number\n";
-		};
-
-		if(states_old_->d_states[k].d_two_dim_layer_alignment_algorithm!=states_new_->d_states[k].d_two_dim_layer_alignment_algorithm)
-		{
-			//cout<<k<<"\tstates_old_->d_states[k].d_two_dim_layer_alignment_algorithm!=states_new_->d_states[k].d_two_dim_layer_alignment_algorithm\n";
-		};
-
-		if(states_old_->d_states[k].d_IS1_general_simulation!=states_new_->d_states[k].d_IS1_general_simulation)
-		{
-			//cout<<k<<"\tstates_old_->d_states[k].d_IS1_general_simulation!=states_new_->d_states[k].d_IS1_general_simulation\n";
-		};
-
-
-		long int i;
-		for(i=0;i<=FSA_utils::Tmin(states_old_->d_states[k].d_ALP_number,states_new_->d_states[k].d_ALP_number);i++)
-		{
-			if(states_old_->d_states[k].d_ALP_weights_array->get_elem(i)!=states_new_->d_states[k].d_ALP_weights_array->get_elem(i))
-			{
-				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_ALP_weights_array->get_elem(i)!=states_new_->d_states[k].d_ALP_weights_array->get_elem(i)\n";
-			};
-
-			if(states_old_->d_states[k].d_distance_along_direction_1_array->get_elem(i)!=states_new_->d_states[k].d_distance_along_direction_1_array->get_elem(i))
-			{
-				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_distance_along_direction_1_array->get_elem(i)!=states_new_->d_states[k].d_distance_along_direction_1_array->get_elem(i)\n";
-			};
-			if(states_old_->d_states[k].d_distance_along_direction_2_array->get_elem(i)!=states_new_->d_states[k].d_distance_along_direction_2_array->get_elem(i))
-			{
-				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_distance_along_direction_2_array->get_elem(i)!=states_new_->d_states[k].d_distance_along_direction_2_array->get_elem(i)\n";
-			};
-			if(states_old_->d_states[k].d_M_array->get_elem(i)!=states_new_->d_states[k].d_M_array->get_elem(i))
-			{
-				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_M_array->get_elem(i)!=states_new_->d_states[k].d_M_array->get_elem(i)\n";
-			};
-			if(states_old_->d_states[k].d_seq1_length_array->get_elem(i)!=states_new_->d_states[k].d_seq1_length_array->get_elem(i))
-			{
-				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_seq1_length_array->get_elem(i)!=states_new_->d_states[k].d_seq1_length_array->get_elem(i)\n";
-			};
-			if(states_old_->d_states[k].d_seq2_length_array->get_elem(i)!=states_new_->d_states[k].d_seq2_length_array->get_elem(i))
-			{
-				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_seq2_length_array->get_elem(i)!=states_new_->d_states[k].d_seq2_length_array->get_elem(i)\n";
-			};
-
-		};
-
-
-
-	};
-
-}
-
-//*****************************
-
-void test::FSA_Align(
-
-long int open1_,//gap opening penalty for the nucleotide sequence #1
-long int open2_,//gap opening penalty for the amino acid sequence #2
-
-long int epen1_,//gap extension penalty for the nucleotide sequence #1
-long int epen2_,//gap extension penalty for the amino acid sequence #2
-
-long int gamma_,//frameshift penalty gamma
-
-string smatr_file_name_,//scoring matrix file name
-string DNA_codon_table_file_name_,//a name of a file with DNA codon table
-
-bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
-
-string input_sequences_,//name of file with sequences for alignment (align mode)
-string output_sequences_,//name of output file with alignment scores (align mode)
-string gumbelparin_file_name_)//Gumbel parameters input file name
-{
-
-	double time0_start;
-	FSA_utils::get_current_time(time0_start);
-
-	Sls::FALP_set_of_parameters gumbelparin;//the resulted parameters
-
-	if(gumbelparin_file_name_!="")
-	{
-		fsa_par::Read_Params(
-		gumbelparin,
-		gumbelparin_file_name_);
-
-		FALP_pvalues::compute_intercepts(gumbelparin);
-	};
-
-	static Sls::FALP_pvalues pvalues_obj;
-
-	long int **smatr=NULL;
-
-
-	char *alphabet1=NULL;//alphabet letters for the sequence #1
-	char *alphabet2=NULL;//alphabet letters for the sequence #2
-
-	long int *alphabet1_to_long=NULL;//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-	long int *alphabet2_to_long=NULL;//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-	long int codon_length;//codon length 
-	long int *codon_AA=NULL;//<codon code,AA number>
-
-
-//====================================================
-
-
-	long int number_of_AA_smatr;
-	long int smatr_min;
-
-	FSA_utils::read_smatr(
-	smatr_file_name_,
-	smatr,
-	number_of_AA_smatr,
-	smatr_min);
-
-//====================================================================================
-
-	long int number_of_letters1_tmp;//number of letters for the sequence 1
-	long int number_of_letters2_tmp;//number of letters for the sequence 2
-
-	FSA_utils::read_codon_AA_file(
-	DNA_codon_table_file_name_,
-	number_of_letters1_tmp,//number of letters for the sequence 1
-	number_of_letters2_tmp,//number of letters for the sequence 2
-
-	alphabet1,//alphabet letters for the sequence #1
-	alphabet2,//alphabet letters for the sequence #2
-
-	alphabet1_to_long,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-	alphabet2_to_long,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-	codon_length,//codon length 
-	codon_AA);//<codon code,AA number>
-
-	if(number_of_AA_smatr!=number_of_letters2_tmp)
-	{
-		throw error("Error - different numbers of amino acids in the files "+smatr_file_name_+", "+DNA_codon_table_file_name_+"\n",1);
-	};
-
-
-
-	long int number_of_sequences;
-	string *headers;
-	long int *lengths1;//lengths of the sequences #1
-	long int *lengths2;//lengths of the sequences #2
-	long int **sequences1;
-	long int **sequences2;
-
-	FSA_utils::read_sequences_for_alingment(
-
-	input_sequences_,
-
-	number_of_letters1_tmp,//number of letters for the sequence 1
-	number_of_letters2_tmp,//number of letters for the sequence 2
-
-	alphabet1,//alphabet letters for the sequence #1
-	alphabet2,//alphabet letters for the sequence #2
-
-	number_of_sequences,
-
-	headers,
-	lengths1,
-	lengths2,
-	sequences1,//the first index numerates sequences; the second - sequence letters
-	sequences2);
-
-	long int k;
-
-	long int max_ind1=-1;
-	long int max_ind2=-1;
-	for(k=0;k<number_of_sequences;k++)
-	{
-		max_ind1=FSA_utils::Tmax(max_ind1,lengths1[k]);
-		max_ind2=FSA_utils::Tmax(max_ind2,lengths2[k]);
-	};
-
-	if(max_ind1==0||max_ind2==0)
-	{
-		throw error("Error in the file "+input_sequences_+"\n",1);
-	};
-
-
-//---------two dim alignment algorithm---------------
-
-	long int var_num_dim=1000;
-	long int *var_num=new long int[var_num_dim];
-	long int i;
-	for(i=0;i<var_num_dim;i++)
-	{
-		var_num[i]=-1;
-	};
-
-	var_num['S']=0;
-	var_num['D']=1;
-	var_num['I']=2;
-
-
-	data_for_FSA_alignment data_test;
-
-	data_test.d_alphabet_letters_number1=number_of_letters1_tmp;
-
-	data_test.d_open1=open1_;
-	data_test.d_open2=open2_;
-
-	data_test.d_epen1=epen1_;
-	data_test.d_epen2=epen2_;
-
-	data_test.d_gamma=gamma_;
-
-	data_test.d_smatr=smatr;
-
-	data_test.d_codon_AA=codon_AA;
-
-	data_test.d_insertions_after_deletions=insertions_after_deletions_;
-
-	//data_test.d_alignment_type="global";
-	data_test.d_alignment_type="local";
-
-	long int depth1=4;//the maximum difference of the first index in the dynamic equations
-	long int depth2=1;//the maximum difference of the second index in the dynamic equations
-
-
-
-	long int number_of_variables_for_the_alignment=3;
-
-	two_dim_layer_alignment_algorithm<long int>* two_dim_layer_alignment_algorithm_test=NULL;
-
-
-
-	two_dim_layer_alignment_algorithm_test=
-	new two_dim_layer_alignment_algorithm<long int>(
-	number_of_variables_for_the_alignment,//total number of variables in dynamic equations
-	depth1,//the maximum difference of the first index in the dynamic equations
-	depth2,//the maximum difference of the second index in the dynamic equations
-	max_ind1,//max of the index #1 (minimum index is 0 by default)
-	max_ind2,//max of the index #2 (minimum index is 0 by default)
-	0,//null element of T
-	var_num);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
-
-	two_dim_layer_alignment_algorithm_test->d_two_dim_layer_alignment_function=test::two_dim_layer_alignment_function_FSA;
-	two_dim_layer_alignment_algorithm_test->d_two_dim_layer_boundary_function=test::two_dim_layer_alignment_function_FSA;
-	two_dim_layer_alignment_algorithm_test->d_par=&data_test;
-
-
-	two_dim_layer_alignment_algorithm_test->d_M_flag=true;
-	two_dim_layer_alignment_algorithm_test->d_E_flag=false;
-
-	two_dim_layer_alignment_algorithm_test->d_scores_counts_flag=false;
-
-	ofstream fout(output_sequences_.data());
-	if(!fout)
-	{
-		throw error("Error - the file "+output_sequences_+" is not found\n",1);
-	};
-
-	//calculate alingment scores and P-values
-	for(k=0;k<number_of_sequences;k++)
-	{
-		two_dim_layer_alignment_algorithm_test->init();
-
-		data_test.d_seq1=sequences1[k];
-		data_test.d_seq2=sequences2[k];
-
-		two_dim_layer_alignment_algorithm_test->align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-		//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-		lengths1[k],//target length of the sequence #1
-		lengths2[k]);//target length of the sequence #2
-		fout<<headers[k]<<endl;
-		fout<<two_dim_layer_alignment_algorithm_test->d_M;
-
-		if(gumbelparin_file_name_!="")
-		{
-				vector<double> P_values;
-				vector<double> P_values_errors;
-
-				vector<double> E_values;
-				vector<double> E_values_errors;
-
-
-				pvalues_obj.calculate_P_values(
-				two_dim_layer_alignment_algorithm_test->d_M,
-				two_dim_layer_alignment_algorithm_test->d_M,
-				lengths1[k],
-				lengths2[k],
-				gumbelparin,
-				P_values,
-				P_values_errors,
-				E_values,
-				E_values_errors);
-
-
-				if(P_values.size()==1&&P_values_errors.size()==1)
-				{
-					fout<<"\t"<<P_values[0]<<"\t"<<P_values_errors[0];
-				};
-
-				if(E_values.size()==1&&E_values_errors.size()==1)
-				{
-					fout<<"\t"<<E_values[0]<<"\t"<<E_values_errors[0];
-				};
-
-		};
-		fout<<endl;
-	};
-
-	fout.close();
-
-	delete[]headers;
-	delete[]lengths1;
-	delete[]lengths2;
-
-	
-	for(k=0;k<number_of_sequences;k++)
-	{
-		delete[]sequences1[k];
-		delete[]sequences2[k];
-	};
-
-	delete[]sequences1;
-	delete[]sequences2;
-	delete[]var_num;
-
-	delete two_dim_layer_alignment_algorithm_test;
-
-	double time0_end;
-	FSA_utils::get_current_time(time0_end);
-
-	cout<<"Total calculation time\t"<<time0_end-time0_start<<endl;
-
-}
-
-//*****************************
-void test::input_data_for_the_constructor(
-
-string DNA_codon_table_file_name_,//a name of a file with DNA codon table
-string smatr_file_name_,//scoring matrix file name
-string RR1_file_name_,//probabilities1 file name
-string RR2_file_name_,//probabilities2 file name
-
-long int &alphabetSize1_,
-long int &alphabetSize2_,
-long int **&substitutionScoreMatrix_,
-double *&letterFreqs1_,
-double *&letterFreqs2_,
-
-char *&alphabet1_,//alphabet letters for the sequence #1
-char *&alphabet2_,//alphabet letters for the sequence #2
-
-long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-long int &codon_length_,//codon length 
-long int *&codon_AA_)//<codon code,AA number>
-{
-
-	long int number_of_AA_smatr;
-	long int smatr_min;
-
-
-	FSA_utils::read_smatr(
-	smatr_file_name_,
-	substitutionScoreMatrix_,
-	number_of_AA_smatr,
-	smatr_min);
-
-
-	FSA_utils::read_RR(
-	RR1_file_name_,
-	letterFreqs1_,
-	alphabetSize1_,
-	4);
-
-
-	FSA_utils::read_RR(
-	RR2_file_name_,
-	letterFreqs2_,
-	alphabetSize2_,
-	25);
-
-
-
-	if(number_of_AA_smatr!=alphabetSize2_)
-	{
-		throw error("Error - different number of letters in the files "+smatr_file_name_+", "+RR2_file_name_+"\n",1);
-	};
-
-//====================================================================================
-
-	long int number_of_letters1_tmp;//number of letters for the sequence 1
-	long int number_of_letters2_tmp;//number of letters for the sequence 2
-
-
-	FSA_utils::read_codon_AA_file(
-	DNA_codon_table_file_name_,
-	number_of_letters1_tmp,//number of letters for the sequence 1
-	number_of_letters2_tmp,//number of letters for the sequence 2
-
-	alphabet1_,//alphabet letters for the sequence #1
-	alphabet2_,//alphabet letters for the sequence #2
-
-	alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-	alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-	codon_length_,//codon length 
-	codon_AA_);//<codon code,AA number>
-
-
-
-	if(alphabetSize1_!=number_of_letters1_tmp)
-	{
-		throw error("The numbers of letters is different in the files "+DNA_codon_table_file_name_+" and "+RR1_file_name_+"\n",3);
-	};
-	if(alphabetSize2_!=number_of_letters2_tmp)
-	{
-		throw error("The numbers of letters is different in the files "+DNA_codon_table_file_name_+" and "+RR2_file_name_+"\n",3);
-	};
-
-}
-
-void test::FSA_IS(
-//additional parameters for the library code
-bool library_call_flag_,//if true, then the additional parameters are used
-long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
-long aaAlphabetSize_,//a number of letters in the amino acid alphabet; usually 4
-const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
-const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
-const double *ntFreqs_,//background frequencies of letters in DNA sequences
-const double *aaFreqs_,//background frequencies of letters in amino acid sequences
-//additional parameters for the library code - end
-
-long int rand_,//randomization number
-long int open1_,//gap opening penalty for the nucleotide sequence #1
-long int open2_,//gap opening penalty for the amino acid sequence #2
-
-long int epen1_,//gap extension penalty for the nucleotide sequence #1
-long int epen2_,//gap extension penalty for the amino acid sequence #2
-
-long int gamma_,//frameshift penalty gamma
-
-string smatr_file_name_,//scoring matrix file name
-string RR1_file_name_,//background frequencies file name for the sequence #1
-string RR2_file_name_,//background frequencies file name for the sequence #2
-string DNA_codon_table_file_name_,//a name of a file with DNA codon table
-
-double eps_lambda_,//relative error for lambda calculation
-double eps_K_,//relative error for K calculation
-
-bool gapped_flag_,//if true, then the gapped alingment is performed
-double max_time_,//maximum allowed calculation time in seconds
-double max_mem_,//maximum allowed memory usage in MB
-
-//additional parameters
-long int seq_number_,//number of tested alignments
-long int nalp_,//number of ALPs for the calculation
-long int number_of_subsets_for_errors_calculation_,//number of subsets used for the splitting method
-bool forward_and_reverse_screen_output_flag_,//determines whether the parameters are outputted for forward and reverse calculations
-bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
-
-//for test
-double mult_for_is_lambda_,//multiplier for lambda in the IS
-
-//the result
-Sls::FALP_set_of_parameters &par_result_,//the resulted parameters
-Sls::par_test1_type *par_test1_)//for tests
-{
-	double seconds1;
-	FSA_utils::get_current_time(seconds1);
-
-	FSA_utils::process_random_factor(
-	rand_);
-
-	double empirical_mem_coeff=2.5;
-
-	double max_mem_for_states_alloc=max_mem_*1048576/empirical_mem_coeff;//maximum allocatin size for states in bytes
-	double max_number_of_states=FSA_utils::Tmin((double)inf,max_mem_for_states_alloc/sizeof(state_type));
-
-	//the parameters
-
-	bool FSA_flag=true;//if true, then FSA IS is performed
-	bool cs_flag=true;//if true, then crude sampling simulation is also performed
-	bool sim_flag=false;//flag for the simplified IS technique
-
-	double eps_K=eps_K_;//relative error for K
-
-	long int depth1=4;//the maximum difference of the first index in the dynamic equations
-	long int depth2=1;//the maximum difference of the second index in the dynamic equations
-
-	long int max_ind2=10000;//max of the index #2
-	long int max_ind1=max_ind2*3;//max of the index #1
-
-
-	long int target_ALP=nalp_;
-	
-
-	long int number_of_realizations=seq_number_;
-	long int number_of_sets=number_of_subsets_for_errors_calculation_;//number of sets for error calculation
-
-	bool futher_expanding=true;
-	long int number_of_cs_steps_for_expanding=max_ind2;
-
-	long int mult_margin=5;
-	long int add_margin=100;
-
-	bool lambda_output_flag=false;
-
-#ifdef _MSDOS_
-	string lambda_file_name="lambda_"+FSA_utils::long_to_string(rand_)+".out";
-#else
-	string lambda_file_name="/net/frosty/vol/export1/sls/ff1/res1/lambda_"+FSA_utils::long_to_string(rand_)+".out";
-#endif
-
-//-------------------------------------------------
-
-	//bool add_fake_state_flag=true;
-	bool add_fake_state_flag=false;
-
-	FSA_utils::srand2(rand_);
-	if(!library_call_flag_)
-	{
-		cout<<"Randomization factor\t"<<rand_<<endl;
-	};
-
-	long int alphabet_letters_number1;//number of letters in the sequence #1
-	long int alphabet_letters_number2;//number of letters in the sequence #2
-	double *RR1=NULL;//background probability for the sequence #1
-	double *RR2=NULL;//background probability for the sequence #2
-	long int number_of_states=7;//number of states
-	if(add_fake_state_flag)
-	{
-		number_of_states++;
-	};
-	double **transition_probabilities=NULL;//transition probabilities between states; matrix d_number_of_states x d_number_of_states
-	pair<long int, long int> *states_description=NULL;//description of the states; the index is a state number
-	double ***states_distr=NULL;//distributions of the states; the index is a state number
-								//the second and the third indexes correspond to an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-
-	double ***states_distr_reversed=NULL;
-
-//crude sampling
-	pair<long int, long int> *states_description_cs=NULL;
-	double ***states_distr_cs=NULL;
-	double **transition_probabilities_cs=NULL;
-//crude sampling - end
-
-//simplified sampling
-	double ***states_distr_sim=NULL;
-//simplified sampling - end
-
-	double *RR1_sum=NULL;
-	long int *RR1_sum_elements=NULL;
-	double *RR2_sum=NULL;
-	long int *RR2_sum_elements=NULL;
-
-	long int **smatr=NULL;
-
-	double ungappedlambda;
-
-	d_IS1=NULL;
-	d_IS1_general_simulation=NULL;
-
-	double *RR1_AA=NULL;
-
-
-//===============================================
-
-	char *alphabet1=NULL;//alphabet letters for the sequence #1
-	char *alphabet2=NULL;//alphabet letters for the sequence #2
-
-	long int *alphabet1_to_long=NULL;//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-	long int *alphabet2_to_long=NULL;//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-	long int codon_length;//codon length 
-	long int *codon_AA=NULL;//<codon code,AA number>
-	long int *codon_reversed_AA=NULL;//<codon code,AA number>
-
-
-//====================================================
-
-	{
-		
-		if(!library_call_flag_)
-		{
-			input_data_for_the_constructor(
-
-			DNA_codon_table_file_name_,//a name of a file with DNA codon table
-			smatr_file_name_,//scoring matrix file name
-			RR1_file_name_,//probabilities1 file name
-			RR2_file_name_,//probabilities2 file name
-
-			alphabet_letters_number1,
-			alphabet_letters_number2,
-			smatr,
-			RR1,
-			RR2,
-
-			alphabet1,//alphabet letters for the sequence #1
-			alphabet2,//alphabet letters for the sequence #2
-
-			alphabet1_to_long,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-			alphabet2_to_long,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-			codon_length,//codon length 
-			codon_AA);//<codon code,AA number>
-		}
-		else
-		{
-			alphabet_letters_number1=ntAlphabetSize_;
-			alphabet_letters_number2=aaAlphabetSize_;
-
-			RR1=new double[ntAlphabetSize_];
-			RR2=new double[aaAlphabetSize_];
-
-			alphabet1=new char[ntAlphabetSize_];//alphabet letters for the sequence #1
-			alphabet2=new char[aaAlphabetSize_];//alphabet letters for the sequence #2
-
-
-			long int i,j;
-			for(i=0;i<ntAlphabetSize_;i++)
-			{
-				RR1[i]=ntFreqs_[i];
-				alphabet1[i]=(char)(i+1);
-			};
-
-			for(i=0;i<aaAlphabetSize_;i++)
-			{
-				RR2[i]=aaFreqs_[i];
-				alphabet2[i]=(char)(i+1);
-			};
-
-			FSA_utils::get_memory_for_matrix(aaAlphabetSize_,aaAlphabetSize_,smatr);
-			for(i=0;i<aaAlphabetSize_;i++)
-			{
-				for(j=0;j<aaAlphabetSize_;j++)
-				{
-					smatr[i][j]=substitutionScoreMatrix_[i][j];
-				};
-			};
-			
-
-			alphabet1_to_long=new long int [length_max];
-			FSA_utils::assert_mem(alphabet1_to_long);
-			alphabet2_to_long=new long int [length_max];
-			FSA_utils::assert_mem(alphabet2_to_long);
-
-			long int k;
-			for(k=0;k<length_max;k++)
-			{
-				alphabet1_to_long[k]=-1;
-				alphabet2_to_long[k]=-1;
-			};
-
-			for(k=0;k<alphabet_letters_number1;k++)
-			{
-				alphabet1_to_long[(size_t)alphabet1[k]]=k;
-			};
-			for(k=0;k<alphabet_letters_number2;k++)
-			{
-				alphabet2_to_long[(size_t)alphabet2[k]]=k;
-			};
-
-
-			codon_length=3;//codon length 
-
-			long int number_of_codons=1;
-			for(k=0;k<codon_length;k++)
-			{
-				number_of_codons*=alphabet_letters_number1;
-			};
-
-			codon_AA=new long int [number_of_codons];
-			FSA_utils::assert_mem(codon_AA);
-
-			for(k=0;k<number_of_codons;k++)
-			{
-				codon_AA[k]=codonTable_[k];//<codon code,AA number>
-			};
-
-
-		};
-
-		long int number_of_AA_smatr=alphabet_letters_number2;
-		long int smatr_min;
-
-		long int number_of_letters1_tmp=alphabet_letters_number1;
-		long int number_of_letters2_tmp=alphabet_letters_number2;
-
-		FSA_utils::calculate_RR_sum(
-		RR1,
-		number_of_letters1_tmp,
-		RR1_sum,
-		RR1_sum_elements);
-
-		FSA_utils::calculate_RR_sum(
-		RR2,
-		number_of_letters2_tmp,
-		RR2_sum,
-		RR2_sum_elements);
-
-		FSA_utils::smatr_min(
-		smatr,
-		number_of_AA_smatr,
-		smatr_min);
-
-		{
-			FSA_utils::remove_zero_probabilities(
-			RR1,
-			RR1_sum,
-			RR1_sum_elements,
-			alphabet_letters_number1,
-			RR2,
-			RR2_sum,
-			RR2_sum_elements,
-			alphabet_letters_number2,
-			smatr,
-			number_of_AA_smatr,
-			smatr_min,
-
-			number_of_letters1_tmp,//number of letters for the sequence 1
-			number_of_letters2_tmp,//number of letters for the sequence 2
-
-			alphabet1,//alphabet letters for the sequence #1
-			alphabet2,//alphabet letters for the sequence #2
-
-			alphabet1_to_long,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-			alphabet2_to_long,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-			codon_length,//codon length 
-			codon_AA);//<codon code,AA number>
-
-		};
-
-
-//====================================================================================
-
-		data_for_lambda_equation_FSA func_pointer;
-
-		func_pointer.d_number_of_letters1=alphabet_letters_number1;
-		func_pointer.d_number_of_letters2=alphabet_letters_number2;
-		func_pointer.d_smatr=smatr;
-		func_pointer.d_RR1=RR1;
-		func_pointer.d_RR2=RR2;
-
-		func_pointer.d_codon_length=codon_length;
-
-
-		if(futher_expanding)
-		{
-			FSA_utils::reverse_codons(
-			codon_AA,//<codon code,AA number>; original codons
-			alphabet_letters_number1,//number of letters for the sequence #1
-			codon_length,//codon length 
-			codon_reversed_AA);//<codon code,AA number>; reversed codons
-
-		};
-
-		func_pointer.d_codon_AA=codon_AA;
-
-		calculate_ungapped_lambda_general(
-		lambda_equation_FSA,
-		(void*) &func_pointer,
-		ungappedlambda);
-
-		ungappedlambda*=mult_for_is_lambda_;
-		//cout<<"Multiplier for IS lambda\t"<<mult_for_is_lambda_<<endl;
-
-		//gapless calculaton begin
-		double GaplessTimePortion=0.5;
-
-		double GaplessCalculationTime=max_time_;
-
-		if(max_time_<=0)
-		{
-			GaplessCalculationTime=120;
-		};
-
-		if(gapped_flag_)
-		{
-			//Gapless calculation may take only a portion of maximum allowed calculation time in the case of gapped calculation 
-			GaplessCalculationTime*=GaplessTimePortion;
-		};
-
-
-
-		
-
-		FSA_utils::extract_AA_frequencies_for_DNA_sequence(
-		codon_AA,//<codon code,AA number>
-		codon_length,//codon length 
-		number_of_letters1_tmp,//number of letters for the sequence 1
-		number_of_letters2_tmp,//number of letters for the sequence 2
-		RR1,//nucleotide probabilities
-		RR1_AA);//the resulted frequencies
-
-		
-		Njn::LocalMaxStatMatrix local_max_stat_matrix(number_of_letters2_tmp,
-							  smatr,
-							  RR1_AA,
-							  RR2,
-							  number_of_letters2_tmp,
-							  GaplessCalculationTime);
-
-		if(local_max_stat_matrix.getTerminated()) 
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-
-		//calculation of a and sigma
-		double calculation_error=1e-6;
-
-		par_result_.gapless_alpha_J = local_max_stat_matrix.getAlpha ();
-		par_result_.gapless_alpha_J=FSA_utils::Tmax(par_result_.gapless_alpha_J,0.0);
-		par_result_.gapless_alpha_J_error = calculation_error;
-
-		par_result_.gapless_alpha_I=par_result_.gapless_alpha_J*9;
-		par_result_.gapless_alpha_I_error = calculation_error*9;
-
-		par_result_.gapless_sigma=par_result_.gapless_alpha_J*3;
-		par_result_.gapless_sigma_error = calculation_error*3;
-
-
-		par_result_.gapless_a_J = local_max_stat_matrix.getA ();
-		par_result_.gapless_a_J=FSA_utils::Tmax(par_result_.gapless_a_J,0.0);
-		par_result_.gapless_a_J_error = calculation_error;
-
-		par_result_.gapless_a_I = par_result_.gapless_a_J*3;
-		par_result_.gapless_a_I_error = calculation_error*3;
-
-
-
-		if(!gapped_flag_) {
-
-
-			//calculation of all required parameters for a gapless case
-			par_result_.G=0;
-			par_result_.G1=0;
-			par_result_.G2=0;
-
-			par_result_.lambda = local_max_stat_matrix.getLambda ();
-			par_result_.lambda_error = calculation_error;
-
-			par_result_.K = local_max_stat_matrix.getK ();
-			par_result_.K_error = calculation_error;
-				
-			par_result_.C = local_max_stat_matrix.getC ();;
-			par_result_.C_error = calculation_error;
-
-			if(par_result_.C!=0)
-			{
-				par_result_.K_C = par_result_.K/par_result_.C;
-			}
-			else
-			{
-				par_result_.K_C = 0;
-			};
-			par_result_.K_C_error = calculation_error;
-
-
-			par_result_.sigma = par_result_.gapless_sigma;
-			par_result_.sigma_error = par_result_.gapless_sigma_error;
-
-			par_result_.alpha_I = par_result_.gapless_alpha_I;
-			par_result_.alpha_I_error = par_result_.gapless_alpha_I_error;
-
-			par_result_.alpha_J = par_result_.gapless_alpha_J;
-			par_result_.alpha_J_error = par_result_.gapless_alpha_J_error;
-
-			par_result_.a_I = par_result_.gapless_a_I;
-			par_result_.a_I_error = par_result_.gapless_a_I_error;
-
-			par_result_.a_J = par_result_.gapless_a_J;
-			par_result_.a_J_error = par_result_.gapless_a_J_error;
-
-
-			std::vector<double > sbs_arrays;
-
-			sbs_arrays.resize(2);
-			sbs_arrays[0]=par_result_.lambda;
-			sbs_arrays[1]=par_result_.lambda + calculation_error;
-
-			par_result_.m_LambdaSbs=sbs_arrays;
-
-
-			sbs_arrays.resize(2);
-			sbs_arrays[0]=par_result_.K;
-			sbs_arrays[1]=par_result_.K+calculation_error;
-
-			par_result_.m_KSbs=sbs_arrays;
-
-
-			sbs_arrays.resize(2);
-			sbs_arrays[0]=par_result_.C;
-			sbs_arrays[1]=par_result_.C+calculation_error;
-
-			par_result_.m_CSbs=sbs_arrays;
-
-
-			sbs_arrays.resize(2);
-			sbs_arrays[0]=par_result_.sigma;
-			sbs_arrays[1]=par_result_.sigma + calculation_error;
-
-			par_result_.m_SigmaSbs=sbs_arrays;
-
-
-			sbs_arrays.resize(2);
-			sbs_arrays[0]=par_result_.alpha_I;
-			sbs_arrays[1]=par_result_.alpha_I + calculation_error;
-
-			par_result_.m_AlphaISbs=sbs_arrays;
-
-
-			sbs_arrays.resize(2);
-			sbs_arrays[0]=par_result_.alpha_J;
-			sbs_arrays[1]=par_result_.alpha_J + calculation_error;
-
-			par_result_.m_AlphaJSbs=sbs_arrays;
-
-
-			sbs_arrays.resize(2);
-			sbs_arrays[0]=par_result_.a_I;
-			sbs_arrays[1]=par_result_.a_I + calculation_error;
-
-			par_result_.m_AISbs=sbs_arrays;
-
-
-			sbs_arrays.resize(2);
-			sbs_arrays[0]=par_result_.a_J;
-			sbs_arrays[1]=par_result_.a_J + calculation_error;
-
-			par_result_.m_AJSbs=sbs_arrays;
-
-
-			FSA_flag=false;//if true, then FSA IS is performed
-			cs_flag=false;//if true, then crude sampling simulation is also performed
-			sim_flag=false;//flag for the simplified IS technique
-			futher_expanding=false;
-
-		};
-
-
-		//gapless calculation end
-
-	};
-
-	//possible choice #1
-	//long int minopen=FSA_utils::Tmin(open1_,open2_);
-	//long int minepen=FSA_utils::Tmin(epen1_,epen2_);
-
-	//possible choice #2
-	//long int minopen=FSA_utils::Tmax(open1_,open2_);
-	//long int minepen=FSA_utils::Tmax(epen1_,epen2_);
-
-	//possible choice #3
-	long int minopen=(long int)FSA_utils::round((double)(open1_+open2_)*0.5);
-	long int minepen=(long int)FSA_utils::round((double)(epen1_+epen2_)*0.5);
-
-	long int choice_of_IS_weights=1;
-
-
-	long int gamma=gamma_;
-
-
-	map<string, long int> state_name_into_number;
-	map<long int,string> state_number_into_name;
-
-	
-	
-	state_name_into_number["S1"]=0;
-	state_name_into_number["S2"]=1;
-	state_name_into_number["S3"]=2;
-	state_name_into_number["D1"]=3;
-	state_name_into_number["D2"]=4;
-	state_name_into_number["D3"]=5;
-	state_name_into_number["I"]=6;
-	if(add_fake_state_flag)
-	{
-		state_name_into_number["F"]=7;
-	}
-	else
-	{
-		state_name_into_number["F"]=-1;
-	};
-
-
-
-	state_number_into_name[0]="S1";
-	state_number_into_name[1]="S2";
-	state_number_into_name[2]="S3";
-	state_number_into_name[3]="D1";
-	state_number_into_name[4]="D2";
-	state_number_into_name[5]="D3";
-	state_number_into_name[6]="I";
-	if(add_fake_state_flag)
-	{
-		state_number_into_name[7]="F";
-	};
-
-	states_description=new pair<long int, long int>[number_of_states];
-	FSA_utils::assert_mem(states_description);
-
-	states_description[state_name_into_number["S1"]]=make_pair(3,1);
-	states_description[state_name_into_number["S2"]]=make_pair(2,1);
-	states_description[state_name_into_number["S3"]]=make_pair(4,1);
-	states_description[state_name_into_number["D1"]]=make_pair(3,0);
-	states_description[state_name_into_number["D2"]]=make_pair(2,0);
-	states_description[state_name_into_number["D3"]]=make_pair(4,0);
-	states_description[state_name_into_number["I"]]=make_pair(0,1);
-	if(add_fake_state_flag)
-	{
-		states_description[state_name_into_number["F"]]=make_pair(0,0);
-	};
-
-	if(FSA_flag)
-	{
-		FSA_utils::get_memory_for_matrix(number_of_states,number_of_states,transition_probabilities);
-
-		if(choice_of_IS_weights==1)
-		{
-			transition_probabilities[0][0]=((-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda)))/(1 - exp(gamma*ungappedlambda) + exp(minepen*ungappedlambda) + exp((gamma + minepen)*ungappedlambda) + 4*exp((minepen - minopen)*ungappedlambda) + 2*exp((gamma + minepen - minopen)*ungappedlambda));
-			transition_probabilities[0][1]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[0][2]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[0][3]=exp((gamma + minepen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[0][4]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[0][5]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[0][6]=((2 + exp(gamma*ungappedlambda))*exp(minepen*ungappedlambda))/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[1][0]=((-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda)))/(1 - exp(gamma*ungappedlambda) + exp(minepen*ungappedlambda) + exp((gamma + minepen)*ungappedlambda) + 4*exp((minepen - minopen)*ungappedlambda) + 2*exp((gamma + minepen - minopen)*ungappedlambda));
-			transition_probabilities[1][1]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[1][2]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[1][3]=exp((gamma + minepen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[1][4]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[1][5]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[1][6]=((2 + exp(gamma*ungappedlambda))*exp(minepen*ungappedlambda))/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[2][0]=((-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda)))/(1 - exp(gamma*ungappedlambda) + exp(minepen*ungappedlambda) + exp((gamma + minepen)*ungappedlambda) + 4*exp((minepen - minopen)*ungappedlambda) + 2*exp((gamma + minepen - minopen)*ungappedlambda));
-			transition_probabilities[2][1]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[2][2]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[2][3]=exp((gamma + minepen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[2][4]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[2][5]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[2][6]=((2 + exp(gamma*ungappedlambda))*exp(minepen*ungappedlambda))/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
-			transition_probabilities[3][0]=(-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
-			transition_probabilities[3][1]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
-			transition_probabilities[3][2]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
-			transition_probabilities[3][3]=(-1 + exp(gamma*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
-			transition_probabilities[3][4]=exp(-((gamma + minepen)*ungappedlambda))/2.;
-			transition_probabilities[3][5]=exp(-((gamma + minepen)*ungappedlambda))/2.;
-			transition_probabilities[3][6]=0;
-			transition_probabilities[4][0]=(-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
-			transition_probabilities[4][1]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
-			transition_probabilities[4][2]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
-			transition_probabilities[4][3]=(-1 + exp(gamma*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
-			transition_probabilities[4][4]=exp(-((gamma + minepen)*ungappedlambda))/2.;
-			transition_probabilities[4][5]=exp(-((gamma + minepen)*ungappedlambda))/2.;
-			transition_probabilities[4][6]=0;
-			transition_probabilities[5][0]=(-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
-			transition_probabilities[5][1]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
-			transition_probabilities[5][2]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
-			transition_probabilities[5][3]=(-1 + exp(gamma*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
-			transition_probabilities[5][4]=exp(-((gamma + minepen)*ungappedlambda))/2.;
-			transition_probabilities[5][5]=exp(-((gamma + minepen)*ungappedlambda))/2.;
-			transition_probabilities[5][6]=0;
-			transition_probabilities[6][0]=1 - exp(-(gamma*ungappedlambda)) - exp(-(minepen*ungappedlambda)) + 2*exp(-((gamma + minepen)*ungappedlambda));
-			transition_probabilities[6][1]=((-1 + exp(minepen*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda)))/2.;
-			transition_probabilities[6][2]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
-			transition_probabilities[6][3]=0;
-			transition_probabilities[6][4]=0;
-			transition_probabilities[6][5]=0;
-			transition_probabilities[6][6]=exp(-(minepen*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda));
-		};
-
-		//for test
-		if(choice_of_IS_weights==2)
-		{
-			transition_probabilities[0][0]=1/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[0][1]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[0][2]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[0][3]=exp((-epen1_ - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[0][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[0][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[0][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[1][0]=1/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[1][1]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[1][2]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[1][3]=exp((-epen1_ - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[1][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[1][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[1][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[2][0]=1/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[2][1]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[2][2]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[2][3]=exp((-epen1_ - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[2][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[2][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[2][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[3][0]=1/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[3][1]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[3][2]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[3][3]=exp(-(epen1_*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[3][4]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[3][5]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[3][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[4][0]=1/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[4][1]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[4][2]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[4][3]=exp(-(epen1_*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[4][4]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[4][5]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[4][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[5][0]=1/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[5][1]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[5][2]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[5][3]=exp(-(epen1_*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[5][4]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[5][5]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[5][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
-			transition_probabilities[6][0]=1/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
-			transition_probabilities[6][1]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
-			transition_probabilities[6][2]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
-			transition_probabilities[6][3]=0;
-			transition_probabilities[6][4]=0;
-			transition_probabilities[6][5]=0;
-			transition_probabilities[6][6]=exp(-(epen2_*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
-		};
-
-		if(choice_of_IS_weights==3)
-		{
-			transition_probabilities[0][0]=1/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[0][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[0][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[0][3]=exp((-epen1_ - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[0][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[0][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[0][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[1][0]=1/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[1][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[1][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[1][3]=exp((-epen1_ - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[1][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[1][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[1][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[2][0]=1/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[2][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[2][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[2][3]=exp((-epen1_ - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[2][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[2][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[2][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[3][0]=1/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[3][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[3][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[3][3]=exp(-(epen1_*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[3][4]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[3][5]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[3][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[4][0]=1/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[4][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[4][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[4][3]=exp(-(epen1_*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[4][4]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[4][5]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[4][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[5][0]=1/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[5][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[5][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[5][3]=exp(-(epen1_*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[5][4]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[5][5]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[5][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
-			transition_probabilities[6][0]=1/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
-			transition_probabilities[6][1]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
-			transition_probabilities[6][2]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
-			transition_probabilities[6][3]=0;
-			transition_probabilities[6][4]=0;
-			transition_probabilities[6][5]=0;
-			transition_probabilities[6][6]=exp(-(epen2_*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
-		};
-		//for test
-
-		//introducing a fake state
-		if(add_fake_state_flag)
-		{
-			long int i;
-			for(i=0;i<number_of_states;i++)
-			{
-				transition_probabilities[i][state_name_into_number["F"]]=0;
-				transition_probabilities[state_name_into_number["F"]][i]=0;
-			};
-
-			transition_probabilities[state_name_into_number["F"]][state_name_into_number["S1"]]=1.0/3.0;
-			transition_probabilities[state_name_into_number["F"]][state_name_into_number["S2"]]=1.0/3.0;
-			transition_probabilities[state_name_into_number["F"]][state_name_into_number["S3"]]=1.0-1.0/3.0-1.0/3.0;
-
-		};
-
-
-		//test transition probablities
-		long int i,j;
-		for(i=0;i<number_of_states;i++)
-		{
-			for(j=0;j<number_of_states;j++)
-			{
-				if(transition_probabilities[i][j]<0)
-				{
-					throw error("Error - transition probablities of the importance sampling are negative;\nthe method is not applicable for the input scoring scheme\n",1);
-				};
-			};
-		};
-	
-	};
-
-//crude sampling
-
-	long int number_of_states_cs=1;
-
-	if(cs_flag)
-	{
-		states_description_cs=new pair<long int, long int>[number_of_states_cs];
-		FSA_utils::assert_mem(states_description_cs);
-
-		states_description_cs[0]=make_pair(3,1);
-
-		FSA_utils::get_memory_for_matrix(number_of_states_cs,number_of_states_cs,transition_probabilities_cs);
-		transition_probabilities_cs[0][0]=1;
-	};
-
-//crude sampling - end
-
-
-//=========================
-
-	long int s;
-
-	if(FSA_flag)
-	{
-		states_distr=new double **[number_of_states];
-
-		long int s;
-		for(s=0;s<number_of_states;s++)
-		{
-			states_distr[s]=IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-				alphabet_letters_number1,//number of letters in the sequence #1
-				alphabet_letters_number2,//number of letters in the sequence #2
-				states_description[s]);//state description
-
-		};
-	};
-
-	if(futher_expanding&&FSA_flag)
-	{
-		states_distr_reversed=new double **[number_of_states];
-
-		long int s;
-		for(s=0;s<number_of_states;s++)
-		{
-			states_distr_reversed[s]=IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-				alphabet_letters_number1,//number of letters in the sequence #1
-				alphabet_letters_number2,//number of letters in the sequence #2
-				states_description[s]);//state description
-
-		};
-
-	};
-
-
-	if(cs_flag)
-	{
-		states_distr_cs=new double **[number_of_states_cs];
-
-		long int s;
-		for(s=0;s<number_of_states_cs;s++)
-		{
-			states_distr_cs[s]=IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-				alphabet_letters_number1,//number of letters in the sequence #1
-				alphabet_letters_number2,//number of letters in the sequence #2
-				states_description_cs[s]);//state description
-
-		};
-
-	};
-
-//=========================
-	FSA_IS_transition_probabilities_calculation(
-	FSA_flag,
-	states_distr,
-
-	cs_flag,
-	states_distr_cs,
-
-	sim_flag,
-	states_distr_sim,
-
-	number_of_states,
-	alphabet_letters_number1,
-	alphabet_letters_number2,
-	states_description,
-	codon_length,
-	codon_AA,
-	RR1,
-	RR2,
-	state_name_into_number,
-	smatr,
-	ungappedlambda);
-
-	if(futher_expanding&&FSA_flag)
-	{
-		bool cs_flag_tmp=false;
-		bool sim_flag_tmp=false;
-
-		FSA_IS_transition_probabilities_calculation(
-		FSA_flag,
-		states_distr_reversed,
-
-		cs_flag_tmp,
-		states_distr_cs,
-
-		sim_flag_tmp,
-		states_distr_sim,
-
-		number_of_states,
-		alphabet_letters_number1,
-		alphabet_letters_number2,
-		states_description,
-		codon_length,
-		codon_reversed_AA,
-		RR1,
-		RR2,
-		state_name_into_number,
-		smatr,
-		ungappedlambda);
-
-	};
-
-//=========================
-
-	if(futher_expanding&&FSA_flag)
-	{
-		normalize_state_distributions(
-		alphabet_letters_number1,//number of letters in the sequence #1
-		alphabet_letters_number2,//number of letters in the sequence #2
-		number_of_states,//number of states
-		states_description,//description of the states; the index is a state number
-		states_distr_reversed);//distributions of the states; the index is a state number
-
-	};
-
-	if(FSA_flag)
-	{
-		normalize_state_distributions(
-		alphabet_letters_number1,//number of letters in the sequence #1
-		alphabet_letters_number2,//number of letters in the sequence #2
-		number_of_states,//number of states
-		states_description,//description of the states; the index is a state number
-		states_distr);//distributions of the states; the index is a state number
-
-	};
-
-	if(cs_flag)
-	{
-		normalize_state_distributions(
-		alphabet_letters_number1,//number of letters in the sequence #1
-		alphabet_letters_number2,//number of letters in the sequence #2
-		number_of_states_cs,//number of states
-		states_description_cs,//description of the states; the index is a state number
-		states_distr_cs);//distributions of the states; the index is a state number
-
-	};
-
-//=========================
-
-	IS1_general* IS1_reversed=NULL;
-	if(FSA_flag&&futher_expanding)
-	{
-		IS1_reversed=new IS1_general(
-		alphabet_letters_number1,//number of letters in the sequence #1
-		alphabet_letters_number2,//number of letters in the sequence #2
-		RR1,//background probability for the sequence #1
-		RR2,//background probability for the sequence #2
-		number_of_states,//number of states
-		transition_probabilities,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
-		states_description,//description of the states; the index is a state number
-		states_distr_reversed);//distributions of the states; the index is a state number
-
-	};
-
-
-	if(FSA_flag)
-	{
-		d_IS1=new IS1_general(
-		alphabet_letters_number1,//number of letters in the sequence #1
-		alphabet_letters_number2,//number of letters in the sequence #2
-		RR1,//background probability for the sequence #1
-		RR2,//background probability for the sequence #2
-		number_of_states,//number of states
-		transition_probabilities,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
-		states_description,//description of the states; the index is a state number
-		states_distr);//distributions of the states; the index is a state number
-
-	};
-
-
-	//crude sampling 
-
-
-	IS1_general* IS1_cs=NULL;
-	if(cs_flag)
-	{
-		IS1_cs=new IS1_general(
-		alphabet_letters_number1,//number of letters in the sequence #1
-		alphabet_letters_number2,//number of letters in the sequence #2
-		RR1,//background probability for the sequence #1
-		RR2,//background probability for the sequence #2
-		number_of_states_cs,//number of states
-		transition_probabilities_cs,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
-		states_description_cs,//description of the states; the index is a state number
-		states_distr_cs);//distributions of the states; the index is a state number
-	};
-	//crude sampling - end
-
-
-	ofstream lambda_out;
-
-	if(lambda_output_flag)
-	{
-		lambda_out.open(lambda_file_name.data());
-		if(!lambda_out)
-		{
-			throw error("Error - the file "+lambda_file_name+" is not found\n",1);
-		};
-	};
-
-
-	long int var_num_dim=1000;
-	long int *var_num=new long int[var_num_dim];
-	long int i;
-	for(i=0;i<var_num_dim;i++)
-	{
-		var_num[i]=-1;
-	};
-
-	var_num['S']=0;
-	var_num['D']=1;
-	var_num['I']=2;
-
-
-	data_for_FSA_alignment data_test;
-	
-
-	data_test.d_alphabet_letters_number1=alphabet_letters_number1;
-
-	data_test.d_open1=open1_;
-	data_test.d_open2=open2_;
-
-	data_test.d_epen1=epen1_;
-	data_test.d_epen2=epen2_;
-
-	data_test.d_gamma=gamma_;
-
-	data_test.d_smatr=smatr;
-
-	data_test.d_codon_AA=codon_AA;
-
-	data_test.d_insertions_after_deletions=insertions_after_deletions_;
-
-	data_test.d_alignment_type="global";
-	//data_test.d_alignment_type="local";
-
-	if(lambda_output_flag)
-	{
-		lambda_out<<open1_<<"\t"<<epen1_<<"\t"<<open2_<<"\t"<<epen2_<<"\t"<<gamma_<<"\t"<<number_of_realizations<<"\t"<<target_ALP<<endl;
-		lambda_out<<"lambda\t";
-		lambda_out<<"C\t";
-		lambda_out<<"a_I\t";
-		lambda_out<<"a_J\t";
-		lambda_out<<"sigma\t";
-		lambda_out<<"alpha_I\t";
-		lambda_out<<"alpha_J\t";
-		lambda_out<<"K_C\t";
-		lambda_out<<endl;
-
-	};
-
-
-	long int number_of_variables_for_the_alignment=3;
-
-
-	two_dim_layer_alignment_algorithm<long int>* two_dim_layer_alignment_algorithm_test=NULL;
-
-	Sls::FALP_set_of_parameters par;
-
-	double time0_start;
-	FSA_utils::get_current_time(time0_start);
-
-	bool accuracy_is_achieved_flag=false;
-
-//--------------------------
-		//crude sampling
-		string M_distr_file_name_cs=lambda_file_name+"_M_cs.out";
-		data_for_FSA_alignment data_test_cs;
-
-		IS1_general_simulation *IS1_general_simulation_cs=NULL;
-		two_dim_layer_alignment_algorithm<long int> *two_dim_layer_alignment_algorithm_test_cs=NULL;
-
-		//crude sampling - end
-//--------------------------
-
-	long int M_thr_estimation_direct=0;//average score threshold corresponded to target_ALP_
-
-
-	if(FSA_flag)
-	{
-		long int initial_state=state_name_into_number["S1"];
-
-		if(add_fake_state_flag)
-		{
-			initial_state=state_name_into_number["F"];
-		};
-
-
-
-		d_IS1_general_simulation=new IS1_general_simulation(
-		d_IS1,
-		initial_state,//initial state for the IS
-		max_ind1*mult_margin+add_margin,//maximum sequence length
-		max_ind2*mult_margin+3*add_margin);//maximum sequence length
-
-
-		data_test.d_seq1=d_IS1_general_simulation->d_seq1;//sequence #1
-		data_test.d_seq2=d_IS1_general_simulation->d_seq2;//sequence #2
-	
-
-		two_dim_layer_alignment_algorithm_test=
-		new two_dim_layer_alignment_algorithm<long int>(
-		number_of_variables_for_the_alignment,//total number of variables in dynamic equations
-		depth1,//the maximum difference of the first index in the dynamic equations
-		depth2,//the maximum difference of the second index in the dynamic equations
-		max_ind1,//max of the index #1 (minimum index is 0 by default)
-		max_ind2,//max of the index #2 (minimum index is 0 by default)
-		0,//null element of T
-		var_num);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
-
-
-
-
-		//string M_distr_file_name="M_distr_FSA.out";
-		string M_distr_file_name=lambda_file_name+"_M.out";
-
-		if(par_test1_)
-		{
-			M_distr_file_name=par_test1_->d_gumbelparout_file_name;
-		};
-
-		
-		two_dim_layer_alignment_algorithm_test->d_two_dim_layer_alignment_function=test::two_dim_layer_alignment_function_FSA;
-		two_dim_layer_alignment_algorithm_test->d_two_dim_layer_boundary_function=test::two_dim_layer_alignment_function_FSA;
-		two_dim_layer_alignment_algorithm_test->d_par=&data_test;
-
-
-		two_dim_layer_alignment_algorithm_test->d_M_flag=true;
-		two_dim_layer_alignment_algorithm_test->d_E_flag=false;
-
-		two_dim_layer_alignment_algorithm_test->d_scores_counts_flag=false;
-
-
-		double fraction_of_ALP_opt=0.5;
-
-
-		{
-
-			//bool futher_expanding_tmp=true;
-			bool futher_expanding_tmp=false;
-			
-
-			long int limit2=max_ind2;
-
-			two_dim_layer_alignment_algorithm_test->d_scores_counts_flag=futher_expanding_tmp;
-			two_dim_layer_alignment_algorithm_test->d_FSC_flag=true;
-
-
-
-			//additional test whether the scoring scheme is logarithmic
-
-			double time_for_one_realization_without_killing=0;
-			double time_for_one_realization_with_killing=0;
-			long int M_thr_estimation_direct_from_the_minimal_test;
-
-			{
-				double time_tmp00;
-				double time_tmp11;
-				
-
-				double ending_time_tmp2=-1;
-				bool stopped_by_ending_time_flag_tmp2;
-				long int number_of_realizations_with_ending_time_tmp2;
-				double ending_time_to_test_logarithmic_regime2=-1;
-
-				bool inside_simulation_flag=true;
-				bool save_states_flag=false;
-				mult_states_type *states_old1=NULL;
-				mult_states_type *states_new1=NULL;
-				bool futher_expanding_test=true;
-				long int M_thr=-inf;
-
-				//number of test realizations for the test
-				long int number_of_realizations_test=1;
-				long int number_of_sets_test=1;
-				
-
-
-				try
-				{
-
-					two_dim_layer_alignment_algorithm_test->d_scores_counts_flag=true;
-					bool parameters_are_not_calculated=true;
-
-					
-
-					FSA_utils::get_current_time(time_tmp00);
-
-					bool compute_allocated_memory_flag_tmp=false;
-					double allocated_memory_tmp;
-
-
-					//without expanding with calculation of M-threshold
-					collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-					compute_allocated_memory_flag_tmp,
-					allocated_memory_tmp,
-
-					number_of_realizations_test,
-					M_distr_file_name,
-					*two_dim_layer_alignment_algorithm_test,
-					*d_IS1_general_simulation,
-					target_ALP,//target ALP number
-					ungappedlambda,
-					limit2,
-
-					number_of_sets_test,
-					par,
-					inside_simulation_flag,
-					false,
-					false,
-
-					ending_time_tmp2,
-					stopped_by_ending_time_flag_tmp2,
-					number_of_realizations_with_ending_time_tmp2,
-
-					ending_time_to_test_logarithmic_regime2,
-
-					save_states_flag,
-					states_old1,
-					states_new1,
-					M_thr_estimation_direct,
-
-					//futher_expanding_test,
-					false,
-					M_thr,
-					IS1_cs,
-					&eps_K,
-					&number_of_cs_steps_for_expanding,
-					parameters_are_not_calculated);
-
-					FSA_utils::get_current_time(time_tmp11);
-
-					time_for_one_realization_without_killing=(time_tmp11-time_tmp00)/(double)number_of_realizations_test;
-					if(time_for_one_realization_without_killing<0)
-					{
-						time_for_one_realization_without_killing=0;
-					};
-
-					{
-						
-
-						bool compute_allocated_memory_flag_tmp=false;
-						double allocated_memory_tmp;
-
-						//test with expanding
-						collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-						compute_allocated_memory_flag_tmp,
-						allocated_memory_tmp,
-
-
-						number_of_realizations_test,
-						M_distr_file_name,
-						*two_dim_layer_alignment_algorithm_test,
-						*d_IS1_general_simulation,
-						target_ALP,//target ALP number
-						ungappedlambda,
-						limit2,
-
-						number_of_sets_test,
-						par,
-						inside_simulation_flag,
-						false,
-						false,
-
-						ending_time_tmp2,
-						stopped_by_ending_time_flag_tmp2,
-						number_of_realizations_with_ending_time_tmp2,
-
-						ending_time_to_test_logarithmic_regime2,
-
-						save_states_flag,
-						states_old1,
-						states_new1,
-						M_thr_estimation_direct_from_the_minimal_test,
-
-						futher_expanding_test,
-						M_thr_estimation_direct,
-						IS1_cs,
-						&eps_K,
-						&number_of_cs_steps_for_expanding,
-						parameters_are_not_calculated);
-
-						M_thr_estimation_direct_from_the_minimal_test=(long int)FSA_utils::round(0.5*(M_thr_estimation_direct_from_the_minimal_test+
-							M_thr_estimation_direct));
-					};
-
-
-					two_dim_layer_alignment_algorithm_test->d_scores_counts_flag=false;
-
-
-				}
-				catch (error er)
-				{ 
-					if(er.error_code==10)
-					{
-						throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-					}
-					else
-					{
-						throw error(er.st,er.error_code);
-					};
-
-				};
-
-				double time_tmp22;
-				FSA_utils::get_current_time(time_tmp22);
-
-				time_for_one_realization_with_killing=(time_tmp22-time_tmp11)/(double)number_of_realizations_test;
-				if(time_for_one_realization_with_killing<0)
-				{
-					time_for_one_realization_with_killing=0;
-				};
-
-
-			};
-
-
-
-
-			//automatic adjusment of ALP number
-			if(max_time_>0)
-			{
-				if(!library_call_flag_)
-				{
-					cout<<"\nPreliminary stage...\n";
-				};
-
-				double mult_for_prediction=1.0;
-
-				double mult0=0.5;
-				double mult1=0.5*mult0;
-
-				long int max_number_of_realizations0=100;
-				
-
-
-
-				long int number_of_realizations0=max_number_of_realizations0;
-
-				//long int number_of_realizations1_without_extending=number_of_realizations0;
-				long int number_of_realizations1_with_extending=100;
-
-				long int number_of_sets1_without_extending=5;
-				long int number_of_sets1_with_extending=1;
-				
-
-				//double max_calculation_time_for_preliminary_stage=60;//in seconds
-				double max_calculation_time_for_preliminary_stage=inf;//in seconds
-
-				double time_preliminary_stage_expected=
-					//time_for_one_realization_with_killing*number_of_realizations1_with_extending+
-					//number_of_realizations1_without_extending*time_for_one_realization_without_killing;
-					time_for_one_realization_with_killing*number_of_realizations1_with_extending;
-
-				if(max_calculation_time_for_preliminary_stage<time_preliminary_stage_expected)
-				{
-					max_calculation_time_for_preliminary_stage=1.5*time_preliminary_stage_expected;
-				};
-
-				if(max_calculation_time_for_preliminary_stage>max_time_*mult0)
-				{
-					max_calculation_time_for_preliminary_stage=max_time_*mult0;
-				};
-
-				if(!library_call_flag_)
-				{
-					cout<<"Maximum time for the preliminary stage: "<<max_calculation_time_for_preliminary_stage<<" sec\n\n";
-				};
-
-
-
-				bool test_output1=false;
-
-				
-				ofstream ff;
-
-				if(test_output1)
-				{
-					string fn="ALP_stat_test1.out";
-
-					ff.open(fn.data());
-					if(!ff)
-					{
-						throw error("Error - file "+fn+" is not found\n",1);
-					};
-
-
-					ff<<"number of realizations\t\
-number of ALP\t\
-time per one cell (ALP)\t\
-ALP position for seq #1\t\
-ALP position for seq #2\t\
-product of positions\t\
-expected relative error of lambda\t\
-time per one cell (expanding)\t\
-expanding length for seq #1\t\
-expanding length for seq #2\t\
-product of lengths\n";
-				};
-
-
-				bool save_states_flag=true;
-				mult_states_type *states_old1=NULL;
-				mult_states_type *states_new1=new mult_states_type;
-				Sls::FALP_set_of_parameters par1;
-
-				bool further_expanding_tmp1=true;
-
-				long int ALP_max_number=10;
-
-				long int ALP1_start=3;
-
-				vector<bool> ALP_flag(ALP_max_number+1,false);
-
-
-				long int ALP1=ALP1_start;
-				
-				
-
-				long int count_tmp1=0;
-				vector<double> lambda_relative_errors;
-				
-				long int number_of_ALP_for_errors=1;
-
-				double L1=0;
-				double L2=0;
-				double L1_L2=0;
-
-				double X1;
-				double X2;
-				double X1_X2;
-
-				double time_cell_ALP=0;
-				double time_cell_exp=0;
-				double time_exp=0;
-
-				long int ALP_opt=3;
-				double error_opt=inf;
-				mult_states_type *states_opt=NULL;
-				long int expected_number_of_realizations1_opt=0;
-				
-
-				long int delete_old_object_flag=0;
-
-				bool inside_simulation_flag;
-
-				long int count_of_failed_relative_errors_max=3;
-				long int count_of_failed_relative_errors=0;
-				bool flag1=true;
-				double total_time_without_extending=0;
-				double total_time_without_extending_opt=0;
-
-				long int number_of_realizations1=0;
-				long int number_of_sets1=0;
-
-				while(flag1)
-				{
-					
-					Sls::FALP_set_of_parameters par1_old;
-
-					if(states_old1)
-					{
-						par1_old=par1;
-					};
-
-					
-					double ending_time_tmp1=-1.0;
-					bool stopped_by_ending_time_flag_tmp1;
-					long int number_of_realizations_with_ending_time_tmp1;
-					double ending_time_to_test_logarithmic_regime1;
-					long int M_thr=-inf;
-
-						bool compute_allocated_memory_flag_tmp;
-						double allocated_memory_tmp;
-
-					
-					if(count_tmp1==0)
-					{
-						compute_allocated_memory_flag_tmp=true;
-						allocated_memory_tmp=0;
-
-						number_of_realizations1=number_of_realizations1_with_extending;
-						number_of_sets1=number_of_sets1_with_extending;
-						ending_time_to_test_logarithmic_regime1=time0_start+FSA_utils::Tmin(max_calculation_time_for_preliminary_stage,mult1*max_time_);
-						M_thr=M_thr_estimation_direct_from_the_minimal_test;
-					}
-					else
-					{
-						compute_allocated_memory_flag_tmp=false;
-
-						//number_of_realizations1=number_of_realizations1_without_extending;
-						number_of_sets1=number_of_sets1_without_extending;
-						ending_time_to_test_logarithmic_regime1=-1;
-					};
-
-					double time_without_extending_tmp1;
-					FSA_utils::get_current_time(time_without_extending_tmp1);
-
-					collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-					compute_allocated_memory_flag_tmp,
-					allocated_memory_tmp,
-
-					number_of_realizations1,
-					M_distr_file_name,
-					*two_dim_layer_alignment_algorithm_test,
-					*d_IS1_general_simulation,
-					ALP1,//target ALP number
-					ungappedlambda,
-					limit2,
-					number_of_sets1,
-					par1,
-					inside_simulation_flag,
-					false,
-					false,
-
-					ending_time_tmp1,
-					stopped_by_ending_time_flag_tmp1,
-					number_of_realizations_with_ending_time_tmp1,
-
-					ending_time_to_test_logarithmic_regime1,
-
-					save_states_flag,
-					states_old1,
-					states_new1,
-					M_thr_estimation_direct,
-
-					false,
-					M_thr,
-					IS1_cs,
-					&eps_K,
-					&number_of_cs_steps_for_expanding);
-
-					if(compute_allocated_memory_flag_tmp)
-					{
-						if(allocated_memory_tmp>0)
-						{
-							max_number_of_states=FSA_utils::round(FSA_utils::Tmin((double)inf,max_mem_for_states_alloc/allocated_memory_tmp/((double)((ALP1+1)*(ALP1+1))/(double)(ALP1*ALP1))/2.0));
-						};
-					}
-					else
-					{
-						max_number_of_states/=(double)((ALP1+1)*(ALP1+1))/(double)(ALP1*ALP1);
-					};
-
-
-
-					double time_without_extending_tmp2;
-					FSA_utils::get_current_time(time_without_extending_tmp2);
-
-
-					total_time_without_extending+=time_without_extending_tmp2-time_without_extending_tmp1;
-
-
-					if(further_expanding_tmp1)
-					{
-						delete_mult_states_type(states_old1);
-						
-						states_old1=states_new1;
-						states_new1=new mult_states_type;
-
-						bool compute_allocated_memory_flag_tmp=false;
-						double allocated_memory_tmp;
-
-
-						collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-						compute_allocated_memory_flag_tmp,
-						allocated_memory_tmp,
-
-						number_of_realizations1,
-						M_distr_file_name,
-						*two_dim_layer_alignment_algorithm_test,
-						*d_IS1_general_simulation,
-						ALP1,//target ALP number
-						ungappedlambda,
-						limit2,
-						number_of_sets1,
-						par1,
-						inside_simulation_flag,
-						false,
-						false,
-
-						ending_time_tmp1,
-						stopped_by_ending_time_flag_tmp1,
-						number_of_realizations_with_ending_time_tmp1,
-
-						ending_time_to_test_logarithmic_regime1,
-
-						save_states_flag,
-						states_old1,
-						states_new1,
-						M_thr_estimation_direct,
-
-						further_expanding_tmp1,
-						M_thr,
-						IS1_cs,
-						&eps_K,
-						&number_of_cs_steps_for_expanding);
-
-
-						time_cell_exp=states_new1->d_total_calculation_time;
-						time_exp=time_cell_exp;
-
-						states_new1->d_total_calculation_time=states_old1->d_total_calculation_time;
-
-
-						delete_mult_states_type(states_old1);
-						states_old1=NULL;
-
-
-					};
-
-					count_tmp1++;
-
-					if(inside_simulation_flag)
-					{
-						if(!library_call_flag_)
-						{
-							cout<<"ALP#="<<ALP1<<"; realizations#="<<number_of_realizations1<<"; time="<<states_new1->d_total_calculation_time<<"\n";
-						};
-						ALP_flag[ALP1]=true;
-					}
-					else
-					{
-						if(!library_call_flag_)
-						{
-							cout<<"ALP#="<<ALP1<<"; realizations#="<<number_of_realizations1<<"; time="<<states_new1->d_total_calculation_time<<": the calculation is not successful\n";
-						};
-					};
-
-					X1=states_new1->d_average_ALP_pos1/(double)states_new1->d_number_of_ALP;
-					X2=states_new1->d_average_ALP_pos2/(double)states_new1->d_number_of_ALP;
-					X1_X2=states_new1->d_average_ALP_pos1_mult_ALP_pos2/((double)(states_new1->d_number_of_ALP*states_new1->d_number_of_ALP));
-
-					if(further_expanding_tmp1)
-					{
-						L1=states_new1->d_average_expanding_length1;
-						L2=states_new1->d_average_expanding_length2;
-						L1_L2=states_new1->d_average_expanding_length1_mult_expanding_length2;
-
-
-						if(states_new1->d_total_number_of_exp_cells>0)
-						{
-							time_cell_exp=time_exp/(double)states_new1->d_total_number_of_exp_cells;
-						}
-						else
-						{
-							throw error("Unexpected error\n",1);
-						};
-					};
-
-					double time_cell_ALP_tmp=states_new1->d_total_calculation_time/((double)states_new1->d_total_number_of_ALP_cells);
-
-					time_cell_ALP=time_cell_ALP_tmp;
-
-					if(test_output1)
-					{
-						ff<<number_of_realizations1<<"\t"<<states_new1->d_number_of_ALP<<"\t"
-							<<time_cell_ALP<<"\t"
-							<<X1<<"\t"
-							<<X2<<"\t"
-							<<X1_X2;
-
-					};
-
-
-
-
-
-
-					//check relative errors
-					if(ALP_flag[ALP1]&&ALP_flag[ALP1-1])
-					{
-
-
-						
-						double T_per_realization=(2*ALP1*ALP1*X1_X2*time_cell_ALP+(ALP1*(X1*L2+X2*L1)+L1_L2)*time_cell_exp);
-
-						if(T_per_realization<=0)
-						{
-							throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-						};
-
-						long int expected_number_of_realizations1=(long int)FSA_utils::round(
-							FSA_utils::Tmin(max_number_of_states,
-							mult_for_prediction*(max_time_-time_exp)
-							/T_per_realization)
-							);
-
-						expected_number_of_realizations1=FSA_utils::Tmax(expected_number_of_realizations1,(long int)1);
-
-
-						double lambda_error1=par1.lambda_last_ALP_relative_error;
-
-
-						lambda_error1*=sqrt((double)number_of_realizations1/(2.0*(double)expected_number_of_realizations1));
-
-						lambda_relative_errors.push_back(lambda_error1);
-						if(!library_call_flag_)
-						{
-							cout<<"Expected lambda relative error for ALP#="<<ALP1<<" is "<<lambda_error1<<endl<<endl;
-						};
-
-						if(test_output1)
-						{
-							ff<<"\t"<<lambda_error1;
-						};
-
-						long int vect_size=(long int)lambda_relative_errors.size();
-						if(vect_size>=number_of_ALP_for_errors)
-						{
-							double average_relative_error=0;
-
-							long int j;
-							for(j=0;j<number_of_ALP_for_errors;j++)
-							{
-								average_relative_error+=lambda_relative_errors[vect_size-1-j];
-							};
-
-							average_relative_error/=(double)number_of_ALP_for_errors;
-
-
-							if(average_relative_error<eps_lambda_)
-							{
-								flag1=false;
-							};
-
-							delete_old_object_flag++;
-
-
-							if(average_relative_error<error_opt)
-							{
-								total_time_without_extending_opt=total_time_without_extending;
-
-								count_of_failed_relative_errors=0;
-								ALP_opt=ALP1;
-								error_opt=average_relative_error;
-
-								expected_number_of_realizations1_opt=expected_number_of_realizations1;
-
-								//calculaton of the fraction of ALP
-								double nom=ALP1*ALP1*X1_X2*time_cell_ALP;
-								fraction_of_ALP_opt=nom/T_per_realization;
-
-
-								if(states_opt==states_old1)
-								{
-									states_old1=NULL;
-								};
-
-								delete_mult_states_type(states_opt);
-								states_opt=states_new1;
-
-								delete_old_object_flag=-2;
-
-							}
-							else
-							{
-								if(count_of_failed_relative_errors_max>0)
-								{
-									count_of_failed_relative_errors++;
-									if(count_of_failed_relative_errors>count_of_failed_relative_errors_max)
-									{
-										flag1=false;
-									};
-								};
-							};
-						};
-					}
-					else
-					{
-						if(test_output1)
-						{
-							ff<<"\t#N/A";
-						};
-						if(!library_call_flag_)
-						{
-							cout<<endl;
-						};
-					};
-
-
-					if(test_output1)
-					{
-
-						if(further_expanding_tmp1)
-						{
-							ff<<"\t"<<time_cell_exp<<"\t"
-							<<L1<<"\t"
-							<<L2<<"\t"
-							<<L1_L2;
-						}
-						else
-						{
-							ff<<"\t#N/A\t"
-							<<"#N/A\t"
-							<<"#N/A\t"
-							<<"#N/A";
-
-						};
-
-						
-					};
-
-
-
-					if(ALP1>=ALP_max_number)
-					{
-						flag1=false;
-					};
-					//cout<<ALP1<<endl;
-
-
-					double time0_current;
-					FSA_utils::get_current_time(time0_current);
-
-					//time limits
-					if(time0_current-time0_start>=max_time_*mult1||time0_current-time0_start>=max_calculation_time_for_preliminary_stage)
-					{
-						flag1=false;
-					};
-
-					if(test_output1)
-					{
-						ff<<"\t"<<time0_current-time0_start-time_exp<<"\t"<<states_new1->d_total_calculation_time;
-						ff<<"\n";
-					};
-
-					//deallocate and allocate memory
-					if(states_opt!=states_old1)
-					{
-						delete_mult_states_type(states_old1);
-					};
-
-
-					states_old1=states_new1;
-					states_new1=new mult_states_type;
-
-
-					if(!flag1)
-					{
-						break;
-					};
-
-					//increase number of ALP
-					ALP1++;
-
-					//prediction of the time required for the calculation with the new number of ALP=ALP1
-					long int ALP1_corrected=FSA_utils::Tmax(ALP1,ALP1_start+number_of_ALP_for_errors+1);
-					double T_per_realization=(2*ALP1_corrected*ALP1_corrected*X1_X2*time_cell_ALP+(ALP1_corrected*(X1*L2+X2*L1)+L1_L2)*time_cell_exp);
-
-					if(T_per_realization<=0)
-					{
-						throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-					};
-
-					
-					number_of_realizations1=(long int)FSA_utils::round(
-						FSA_utils::Tmin(max_number_of_states,
-						FSA_utils::Tmin(mult0*max_calculation_time_for_preliminary_stage,mult1*(max_time_-time_exp))
-						/T_per_realization)
-						);
-
-					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-					//number_of_realizations1=FSA_utils::Tmin(max_number_of_realizations0,number_of_realizations1);
-
-
-					if(further_expanding_tmp1)
-					{
-						further_expanding_tmp1=false;
-					};					
-				};
-
-
-				if(test_output1)
-				{
-					ff.close();
-				};
-
-				if(states_opt!=states_old1)
-				{
-					delete_mult_states_type(states_old1);
-				};
-				if(states_opt!=states_new1)
-				{
-					delete_mult_states_type(states_new1);
-				};
-
-				if(!states_opt)
-				{
-					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-				};
-
-
-				if(eps_lambda_>0)
-				{
-					if(error_opt<eps_lambda_)
-					{
-						accuracy_is_achieved_flag=true;
-						//number of realizations is too large for the requested accuracy
-						//decreasing number of realizations
-						double coeff=error_opt/eps_lambda_;
-						coeff=coeff*coeff;
-						expected_number_of_realizations1_opt=(long int)FSA_utils::round(
-							FSA_utils::Tmin(max_number_of_states,
-							coeff*expected_number_of_realizations1_opt));
-						expected_number_of_realizations1_opt=FSA_utils::Tmax(number_of_realizations0,expected_number_of_realizations1_opt);
-					}
-					else
-					{
-						expected_number_of_realizations1_opt*=8;
-					};
-				}
-				else
-				{
-					expected_number_of_realizations1_opt*=8;
-				};
-
-				expected_number_of_realizations1_opt=(long int)FSA_utils::round(
-					FSA_utils::Tmin((double)max_number_of_states,
-					(double)expected_number_of_realizations1_opt));
-
-				if(!library_call_flag_)
-				{
-					cout<<"\n--------------\n";
-					cout<<"\nOptimal ALP# for the forward and reverse stages is\t"<<ALP_opt<<endl;
-					cout<<"\n--------------\n";
-
-					if(accuracy_is_achieved_flag)
-					{
-						cout<<"The input relative error for lambda can be acheived with this number of realizations\n";
-					};
-					cout<<endl;
-
-				};
-
-
-				double time_tmp2;
-				FSA_utils::get_current_time(time_tmp2);
-
-				double tmp2=(max_time_-(time_tmp2-time0_start)+states_opt->d_total_calculation_time)*fraction_of_ALP_opt
-				//-states_opt->d_total_calculation_time;
-				-total_time_without_extending_opt;
-
-				if(tmp2<0)
-				{
-					tmp2=0;
-				};
-
-				double ending_time_tmp2=time_tmp2+tmp2;
-
-				bool stopped_by_ending_time_flag_tmp2;
-				long int number_of_realizations_with_ending_time_tmp2;
-				double ending_time_to_test_logarithmic_regime2=-1;
-				long int M_thr=-inf;
-
-				//final calculation
-				if(!library_call_flag_)
-				{
-					cout<<"Forward stage...\n\n";
-				};
-				save_states_flag=true;
-				states_new1=NULL;
-				states_new1=new mult_states_type;
-				
-				bool compute_allocated_memory_flag_tmp=false;
-				double allocated_memory_tmp;
-
-				collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-				compute_allocated_memory_flag_tmp,
-				allocated_memory_tmp,
-
-
-				expected_number_of_realizations1_opt,
-				M_distr_file_name,
-				*two_dim_layer_alignment_algorithm_test,
-				*d_IS1_general_simulation,
-				ALP_opt,//target ALP number
-				ungappedlambda,
-				limit2,
-				number_of_sets,
-				par,
-				inside_simulation_flag,
-				false,
-				true&&forward_and_reverse_screen_output_flag_,
-
-				ending_time_tmp2,
-				stopped_by_ending_time_flag_tmp2,
-				number_of_realizations_with_ending_time_tmp2,
-
-				ending_time_to_test_logarithmic_regime2,
-
-				save_states_flag,
-				states_opt,
-				states_new1,
-				M_thr_estimation_direct,
-
-				false,
-				M_thr,
-				IS1_cs,
-				&eps_K,
-				&number_of_cs_steps_for_expanding);
-
-				number_of_realizations=expected_number_of_realizations1_opt;
-				target_ALP=ALP_opt;
-
-				if(stopped_by_ending_time_flag_tmp2)
-				{
-					if(!library_call_flag_)
-					{
-						cout<<"Number of realizations of the forward stage is\t"<<number_of_realizations_with_ending_time_tmp2<<endl<<endl;
-						cout<<"Parameters estimation from the forward stage\n";
-					};
-					number_of_realizations=number_of_realizations_with_ending_time_tmp2;
-
-
-					save_states_flag=false;
-					ending_time_tmp2=-1;
-					mult_states_type *states_new1_tmp=NULL;
-
-					bool compute_allocated_memory_flag_tmp=false;
-					double allocated_memory_tmp;
-
-
-					collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-					compute_allocated_memory_flag_tmp,
-					allocated_memory_tmp,
-
-					number_of_realizations,
-					M_distr_file_name,
-					*two_dim_layer_alignment_algorithm_test,
-					*d_IS1_general_simulation,
-					ALP_opt,//target ALP number
-					ungappedlambda,
-					limit2,
-
-					number_of_sets,
-					par,
-					inside_simulation_flag,
-					forward_and_reverse_screen_output_flag_,
-					false,
-
-					ending_time_tmp2,
-					stopped_by_ending_time_flag_tmp2,
-					number_of_realizations_with_ending_time_tmp2,
-
-					ending_time_to_test_logarithmic_regime2,
-
-					save_states_flag,
-					states_new1,
-					states_new1_tmp,
-					M_thr_estimation_direct,
-
-					false,
-					M_thr,
-					IS1_cs,
-					&eps_K,
-					&number_of_cs_steps_for_expanding);
-				};
-
-				if(!inside_simulation_flag)
-				{
-					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-				};
-
-
-				delete_mult_states_type(states_new1);
-				delete_mult_states_type(states_opt);
-
-
-
-			};
-
-
-			if(max_time_<=0)
-			{
-				if(!library_call_flag_)
-				{
-					cout<<"\nForward stage...\n\n";
-				};
-
-				double ending_time_tmp2=-1;
-				bool stopped_by_ending_time_flag_tmp2;
-				long int number_of_realizations_with_ending_time_tmp2;
-				double ending_time_to_test_logarithmic_regime2=-1;
-				long int M_thr=-inf;
-
-				bool inside_simulation_flag=true;
-				bool save_states_flag=false;
-				mult_states_type *states_old1=NULL;
-				mult_states_type *states_new1=NULL;
-
-				bool compute_allocated_memory_flag_tmp=false;
-				double allocated_memory_tmp;
-
-				collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-				compute_allocated_memory_flag_tmp,
-				allocated_memory_tmp,
-
-				number_of_realizations,
-				M_distr_file_name,
-				*two_dim_layer_alignment_algorithm_test,
-				*d_IS1_general_simulation,
-				target_ALP,//target ALP number
-				ungappedlambda,
-				limit2,
-
-				number_of_sets,
-				par,
-				inside_simulation_flag,
-				forward_and_reverse_screen_output_flag_,
-				true&&forward_and_reverse_screen_output_flag_,
-
-				ending_time_tmp2,
-				stopped_by_ending_time_flag_tmp2,
-				number_of_realizations_with_ending_time_tmp2,
-
-				ending_time_to_test_logarithmic_regime2,
-
-				save_states_flag,
-				states_old1,
-				states_new1,
-				M_thr_estimation_direct,
-
-				futher_expanding_tmp,
-				M_thr,
-				IS1_cs,
-				&eps_K,
-				&number_of_cs_steps_for_expanding);
-
-
-				if(!inside_simulation_flag)
-				{
-					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-				};
-
-
-			};
-
-			double time0_end;
-			FSA_utils::get_current_time(time0_end);
-
-			if(!library_call_flag_)
-			{
-				cout<<"Time of the forward stage\t"<<time0_end-time0_start<<endl;
-			};
-
-
-			
-
-			if(lambda_output_flag)
-			{
-				lambda_out<<par.lambda<<"\t";lambda_out<<par.lambda_error<<"\t";
-				lambda_out<<par.C<<"\t";lambda_out<<par.C_error<<"\t";
-				lambda_out<<par.a_I<<"\t";lambda_out<<par.a_I_error<<"\t";
-				lambda_out<<par.a_J<<"\t";lambda_out<<par.a_J_error<<"\t";
-				lambda_out<<par.sigma<<"\t";lambda_out<<par.sigma_error<<"\t";
-				lambda_out<<par.alpha_I<<"\t";lambda_out<<par.alpha_I_error<<"\t";
-				lambda_out<<par.alpha_J<<"\t";lambda_out<<par.alpha_J_error<<"\t";
-
-				if(futher_expanding_tmp)
-				{
-					lambda_out<<par.K_C<<"\t";lambda_out<<par.K_C_error<<"\t";
-				}
-				else
-				{
-					lambda_out<<"#N/A\t";
-				};
-
-			};
-
-
-
-		};
-	};
-
-
-
-
-//reversed FSA sampling
-	string M_distr_file_name_reversed=lambda_file_name+"_M_reversed.out";
-	data_for_FSA_alignment data_test_reversed;
-
-	IS1_general_simulation *IS1_general_simulation_reversed=NULL;
-	two_dim_layer_alignment_algorithm<long int> *two_dim_layer_alignment_algorithm_test_reversed=NULL;
-
-	Sls::FALP_set_of_parameters par_reversed;
-
-
-	if(FSA_flag&&futher_expanding)
-	{
-		long int initial_state=state_name_into_number["S1"];
-
-		if(add_fake_state_flag)
-		{
-			initial_state=state_name_into_number["F"];
-		};
-
-
-		IS1_general_simulation_reversed=new IS1_general_simulation(
-		IS1_reversed,
-		initial_state,//initial state for the IS
-		max_ind1*mult_margin+add_margin,//maximum sequence length
-		max_ind2*mult_margin+3*add_margin);//maximum sequence length
-
-
-
-
-		data_test_reversed=data_test;
-		data_test_reversed.d_codon_AA=codon_reversed_AA;
-
-
-		data_test_reversed.d_seq1=IS1_general_simulation_reversed->d_seq1;//sequence #1
-		data_test_reversed.d_seq2=IS1_general_simulation_reversed->d_seq2;//sequence #2
-	
-
-
-		
-
-
-
-		two_dim_layer_alignment_algorithm_test_reversed=
-		new two_dim_layer_alignment_algorithm<long int>(
-		number_of_variables_for_the_alignment,//total number of variables in dynamic equations
-		depth1,//the maximum difference of the first index in the dynamic equations
-		depth2,//the maximum difference of the second index in the dynamic equations
-		max_ind1,//max of the index #1 (minimum index is 0 by default)
-		max_ind2,//max of the index #2 (minimum index is 0 by default)
-		0,//null element of T
-		var_num);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
-
-
-
-
-		
-		two_dim_layer_alignment_algorithm_test_reversed->d_two_dim_layer_alignment_function=test::two_dim_layer_alignment_function_FSA;
-		two_dim_layer_alignment_algorithm_test_reversed->d_two_dim_layer_boundary_function=test::two_dim_layer_alignment_function_FSA;
-		two_dim_layer_alignment_algorithm_test_reversed->d_par=&data_test_reversed;
-
-
-		two_dim_layer_alignment_algorithm_test_reversed->d_M_flag=true;
-		two_dim_layer_alignment_algorithm_test_reversed->d_E_flag=false;
-		two_dim_layer_alignment_algorithm_test_reversed->d_scores_counts_flag=false;
-
-
-
-		
-		{
-			two_dim_layer_alignment_algorithm_test_reversed->d_scores_counts_flag=true;
-			two_dim_layer_alignment_algorithm_test_reversed->d_FSC_flag=true;
-
-			if(!library_call_flag_)
-			{
-				cout<<"\n--------------\n";
-				cout<<"\nReverse stage...\n\n";
-			};
-
-			double time1_start;
-			FSA_utils::get_current_time(time1_start);
-
-			long int limit2=max_ind2;
-			long int M_thr_estimation_reverse;
-
-			
-
-			bool inside_simulation_flag=true;
-			long int M_thr=M_thr_estimation_direct;
-			if(!library_call_flag_)
-			{
-				cout<<"Score threshold for the reverse stage is \t"<<M_thr<<endl;
-			};
-			
-
-			if(max_time_>0)
-			{
-
-
-				if(!accuracy_is_achieved_flag)
-				{
-					number_of_realizations*=8;
-				};
-
-
-
-				double ending_time_tmp3=time0_start+max_time_;
-				bool stopped_by_ending_time_flag_tmp3;
-				long int number_of_realizations_with_ending_time_tmp3;
-				double ending_time_to_test_logarithmic_regime3=-1;
-				
-
-
-				bool save_states_flag=true;
-				mult_states_type *states_old1=NULL;
-				mult_states_type *states_new1=NULL;
-				states_new1=new mult_states_type;
-
-				bool compute_allocated_memory_flag_tmp=false;
-				double allocated_memory_tmp;
-
-				collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-				compute_allocated_memory_flag_tmp,
-				allocated_memory_tmp,
-
-				number_of_realizations,
-				M_distr_file_name_reversed,
-				*two_dim_layer_alignment_algorithm_test_reversed,
-				*IS1_general_simulation_reversed,
-				target_ALP,//target ALP number
-				ungappedlambda,
-				limit2,
-
-				number_of_sets,
-				par_reversed,
-				inside_simulation_flag,
-				//forward_and_reverse_screen_output_flag_,
-				false,
-				true&&forward_and_reverse_screen_output_flag_,
-
-				ending_time_tmp3,
-				stopped_by_ending_time_flag_tmp3,
-				number_of_realizations_with_ending_time_tmp3,
-
-				ending_time_to_test_logarithmic_regime3,
-
-				save_states_flag,
-				states_old1,
-				states_new1,
-				M_thr_estimation_reverse,
-
-				futher_expanding,
-				M_thr,
-				IS1_cs,
-				&eps_K,
-				&number_of_cs_steps_for_expanding);
-
-				
-
-
-				if(stopped_by_ending_time_flag_tmp3)
-				{
-					if(!library_call_flag_)
-					{
-						cout<<"Number of realizations of the reverse stage is\t"<<number_of_realizations_with_ending_time_tmp3<<endl<<endl;
-						cout<<"Parameters estimation from the reverse stage\n";
-					};
-					number_of_realizations=number_of_realizations_with_ending_time_tmp3;
-					//number_of_realizations_reverse_final=number_of_realizations_with_ending_time_tmp3;
-
-					save_states_flag=false;
-					ending_time_tmp3=-1;
-					mult_states_type *states_new1_tmp=NULL;
-
-					bool compute_allocated_memory_flag_tmp=false;
-					double allocated_memory_tmp;
-
-
-					collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-					compute_allocated_memory_flag_tmp,
-					allocated_memory_tmp,
-
-					number_of_realizations,
-					M_distr_file_name_reversed,
-					*two_dim_layer_alignment_algorithm_test_reversed,
-					*IS1_general_simulation_reversed,
-					target_ALP,//target ALP number
-					ungappedlambda,
-					limit2,
-
-					number_of_sets,
-					par_reversed,
-					inside_simulation_flag,
-					forward_and_reverse_screen_output_flag_,
-					false,
-
-					ending_time_tmp3,
-					stopped_by_ending_time_flag_tmp3,
-					number_of_realizations_with_ending_time_tmp3,
-
-					ending_time_to_test_logarithmic_regime3,
-
-					save_states_flag,
-					states_new1,
-					states_new1_tmp,
-					M_thr_estimation_reverse,
-
-					futher_expanding,
-					M_thr,
-					IS1_cs,
-					&eps_K,
-					&number_of_cs_steps_for_expanding);
-				};
-
-				delete_mult_states_type(states_new1);
-
-			}
-			else
-			{
-				double ending_time_tmp3=-1;
-				bool stopped_by_ending_time_flag_tmp3;
-				long int number_of_realizations_with_ending_time_tmp3;
-				double ending_time_to_test_logarithmic_regime3=-1;
-
-				bool save_states_flag=false;
-				mult_states_type *states_old1=NULL;
-				mult_states_type *states_new1=NULL;
-
-				bool compute_allocated_memory_flag_tmp=false;
-				double allocated_memory_tmp;
-
-				collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-				compute_allocated_memory_flag_tmp,
-				allocated_memory_tmp,
-
-				number_of_realizations,
-				M_distr_file_name_reversed,
-				*two_dim_layer_alignment_algorithm_test_reversed,
-				*IS1_general_simulation_reversed,
-				target_ALP,//target ALP number
-				ungappedlambda,
-				limit2,
-
-				number_of_sets,
-				par_reversed,
-				inside_simulation_flag,
-				forward_and_reverse_screen_output_flag_,
-				true&&forward_and_reverse_screen_output_flag_,
-
-				ending_time_tmp3,
-				stopped_by_ending_time_flag_tmp3,
-				number_of_realizations_with_ending_time_tmp3,
-
-				ending_time_to_test_logarithmic_regime3,
-
-				save_states_flag,
-				states_old1,
-				states_new1,
-				M_thr_estimation_reverse,
-
-				futher_expanding,
-				M_thr,
-				IS1_cs,
-				&eps_K,
-				&number_of_cs_steps_for_expanding);
-
-				
-
-			};
-
-			if(!inside_simulation_flag)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-
-			double time1_end;
-			FSA_utils::get_current_time(time1_end);
-
-			if(!library_call_flag_)
-			{
-				cout<<"Time of the reverse stage\t"<<time1_end-time1_start<<endl;
-			};
-
-
-			if(lambda_output_flag)
-			{
-				lambda_out<<par_reversed.lambda<<"\t";lambda_out<<par_reversed.lambda_error<<"\t";
-				lambda_out<<par_reversed.C<<"\t";lambda_out<<par_reversed.C_error<<"\t";
-				lambda_out<<par_reversed.a_I<<"\t";lambda_out<<par_reversed.a_I_error<<"\t";
-				lambda_out<<par_reversed.a_J<<"\t";lambda_out<<par_reversed.a_J_error<<"\t";
-				lambda_out<<par_reversed.sigma<<"\t";lambda_out<<par_reversed.sigma_error<<"\t";
-				lambda_out<<par_reversed.alpha_I<<"\t";lambda_out<<par_reversed.alpha_I_error<<"\t";
-				lambda_out<<par_reversed.alpha_J<<"\t";lambda_out<<par_reversed.alpha_J_error<<"\t";
-
-				if(futher_expanding)
-				{
-					lambda_out<<par_reversed.K_C<<"\t";lambda_out<<par_reversed.K_C_error<<"\t";
-				}
-				else
-				{
-					lambda_out<<"#N/A\t";
-				};
-
-
-			};
-
-
-		};
-	};
-
-
-
-
-
-
-
-
-	if(FSA_flag&&futher_expanding)
-	{
-		combine_parameters_from_forward_and_reversed_calculations_generalized(
-		par,//parameters from forward calculation
-		par_reversed,//parameters from reversed calculation
-		par_result_);
-
-		//assign gap penalties for the FSC
-		par_result_.G=FSA_utils::Tmin(data_test.d_open1+data_test.d_epen1,
-			data_test.d_open2+data_test.d_epen2,
-			data_test.d_gamma);
-
-		par_result_.G1=par_result_.G;
-		par_result_.G2=par_result_.G;
-	};
-//reversed FSA sampling - end
-
-
-
-
-
-	delete[]var_num;
-
-
-	delete[]RR1;
-	delete[]RR2;
-
-	delete[]RR1_sum;
-	delete[]RR2_sum;
-
-	delete[]RR1_sum_elements;
-	delete[]RR2_sum_elements;
-
-	FSA_utils::delete_memory_for_matrix(alphabet_letters_number1,smatr);
-	FSA_utils::delete_memory_for_matrix(number_of_states,transition_probabilities);
-
-	if(futher_expanding&&FSA_flag)
-	{
-		
-		delete two_dim_layer_alignment_algorithm_test_reversed;
-		delete IS1_general_simulation_reversed;
-		delete IS1_reversed;
-
-		for(s=0;s<number_of_states;s++)
-		{
-			IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-				states_distr_reversed[s],
-				alphabet_letters_number1,//number of letters in the sequence #1
-				states_description[s]);//state description
-		};
-
-		delete[]states_distr_reversed;
-
-		delete[]codon_reversed_AA;
-
-	};
-
-	delete[]codon_AA;
-
-	//crude sampling
-	if(cs_flag)
-	{
-
-		FSA_utils::delete_memory_for_matrix(number_of_states_cs,transition_probabilities_cs);
-		
-		delete two_dim_layer_alignment_algorithm_test_cs;
-		delete IS1_general_simulation_cs;
-		delete IS1_cs;
-
-		long int s;
-		for(s=0;s<number_of_states_cs;s++)
-		{
-			IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-				states_distr_cs[s],
-				alphabet_letters_number1,//number of letters in the sequence #1
-				states_description_cs[s]);//state description
-		};
-
-		delete[]states_description_cs;
-
-	};
-	//crude sampling - end
-
-
-	if(FSA_flag)
-	{
-		delete two_dim_layer_alignment_algorithm_test;
-		delete d_IS1_general_simulation;
-		delete d_IS1;
-
-
-		long int s;
-		for(s=0;s<number_of_states;s++)
-		{
-			IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-				states_distr[s],
-				alphabet_letters_number1,//number of letters in the sequence #1
-				states_description[s]);//state description
-		};
-
-		delete[]states_description;
-	};
-
-	delete[]RR1_AA;
-
-
-
-	if(lambda_output_flag)
-	{
-		lambda_out<<endl;
-		lambda_out.close();
-	};
-
-	//precompute intercepts
-	par_result_.d_params_flag=true;
-	FALP_pvalues::compute_intercepts(par_result_);
-
-	double seconds2;
-	FSA_utils::get_current_time(seconds2);
-
-	par_result_.m_CalcTime=seconds2-seconds1;
-
-
-}
-
-//-------------------------------------------------------------------
-void test::collect_and_output_M_distr_upto_fixed_lengths(
-long int number_of_realizations_,
-string M_distr_file_name_,
-two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-IS1_general_simulation &IS1_general_simulation_test_,
-long int target_seq1_length_,//target length of the sequence #1
-long int target_seq2_length_)//target length of the sequence #2
-{
-	//for test - begin
-	bool test_flag=false;
-
-		
-	string input_file_name="sss.out";
-
-	long int number_of_letters1;//number of letters for the sequence 1
-	long int number_of_letters2;//number of letters for the sequence 2
-
-	char *alphabet1;//alphabet letters for the sequence #1
-	char *alphabet2;//alphabet letters for the sequence #2
-
-	long int number_of_sequences;
-
-	string *headers;
-	long int *lengths1;//lengths of the sequences #1
-	long int *lengths2;//lengths of the sequences #2
-	long int **sequences1=NULL;//the first index numerates sequences; the second - sequence letters
-	long int **sequences2=NULL;
-
-	if(test_flag)
-	{
-
-		long int *alphabet1_to_long=NULL;//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-		long int *alphabet2_to_long=NULL;//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-		long int codon_length;//codon length 
-		long int *codon_AA=NULL;//<codon code,AA number>
-
-		string DNA_codon_table_file_name="test_input_files/codon_AA.in";//a name of a file with DNA codon table
-
-
-
-
-		FSA_utils::read_codon_AA_file(
-		DNA_codon_table_file_name,
-		number_of_letters1,//number of letters for the sequence 1
-		number_of_letters2,//number of letters for the sequence 2
-
-		alphabet1,//alphabet letters for the sequence #1
-		alphabet2,//alphabet letters for the sequence #2
-
-		alphabet1_to_long,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-		alphabet2_to_long,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-		codon_length,//codon length 
-		codon_AA);//<codon code,AA number>
-
-		FSA_utils::read_sequences_for_alingment(
-
-			input_file_name,
-
-			number_of_letters1,//number of letters for the sequence 1
-			number_of_letters2,//number of letters for the sequence 2
-
-			alphabet1,//alphabet letters for the sequence #1
-			alphabet2,//alphabet letters for the sequence #2
-
-			number_of_sequences,
-
-			headers,
-			lengths1,//lengths of the sequences #1
-			lengths2,//lengths of the sequences #2
-			sequences1,//the first index numerates sequences; the second - sequence letters
-			sequences2);
-	};
-
-	//for test - end
-
-	if(!two_dim_layer_alignment_algorithm_test_.d_M_flag)
-	{
-		throw error("Error - two_dim_layer_alignment_algorithm_test_.d_M_flag must be true in test::collect_and_output_M_distr_upto_fixed_lengths\n",1);
-	};
-
-	ofstream fM;
-
-	array_v<double> *distrM=NULL;
-	array_v<double> *distrM_error=NULL;
-	long int score_max=-inf;
-
-	//distribution of M
-
-	fM.open(M_distr_file_name_.data());
-	if(!fM)
-	{
-		throw error("Error - the file "+M_distr_file_name_+" is not found\n",3);
-	};
-
-
-	distrM=new array_v<double>(NULL);
-	distrM_error=new array_v<double>(NULL);
-
-
-
-	//--------------------
-
-	long int k;
-	for(k=1;k<=number_of_realizations_;k++)
-	{
-
-		IS1_general_simulation_test_.init();
-		IS1_general_simulation_test_.simulate_upto_target_lengths(
-		target_seq1_length_,
-		target_seq2_length_);
-
-
-		/*
-		double weight;
-		if(0)
-		{
-			IS1_general_simulation_test_.calculate_weight_W1_for_fixed_lengths_using_infinite_sums(
-			target_seq1_length_,//target length of the sequence #1
-			target_seq2_length_,//target length of the sequence #2
-			weight);//the resulted weight
-		};
-		*/
-
-		//weights calculation
-		IS1_general_simulation_test_.d_W1_seq1_current_length=-1;
-		IS1_general_simulation_test_.d_W1_seq2_current_length=-1;
-
-		double weight2;
-
-		{
-			IS1_general_simulation_test_.calculate_weight_W1_for_fixed_lengths_using_recursions(
-			target_seq1_length_,//target length of the sequence #1
-			target_seq2_length_,//target length of the sequence #2
-			weight2);//the resulted weight
-		};
-
-
-
-
-		two_dim_layer_alignment_algorithm_test_.init();
-
-		if(test_flag)
-		{
-			data_for_FSA_alignment &data=*(data_for_FSA_alignment*)two_dim_layer_alignment_algorithm_test_.d_par;
-
-			data.d_seq1=sequences1[k-1];
-			data.d_seq2=sequences2[k-1];
-		};
-
-		two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-		//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-		target_seq1_length_,//target length of the sequence #1
-		target_seq2_length_);//target length of the sequence #2
-
-		score_max=FSA_utils::Tmax(score_max,two_dim_layer_alignment_algorithm_test_.d_M);
-		double w_tmp=1/weight2;
-		distrM->increase_elem_by_x(two_dim_layer_alignment_algorithm_test_.d_M,w_tmp);
-		distrM_error->increase_elem_by_x(two_dim_layer_alignment_algorithm_test_.d_M,w_tmp*w_tmp);
-
-		if(test_flag)
-		{
-			cout<<two_dim_layer_alignment_algorithm_test_.d_M<<endl;
-		};
-		
-
-		if(k%100==0)
-		{
-			cout<<k<<endl;
-		};
-
-	};
-
-	long int s;
-
-	//convert into tail
-	for(s=score_max-1;s>=0;s--)
-	{
-		distrM->d_elem[s-distrM->d_ind0]+=distrM->d_elem[s+1-distrM->d_ind0];
-		distrM_error->d_elem[s-distrM->d_ind0]+=distrM_error->d_elem[s+1-distrM->d_ind0];
-	};
-
-	for(s=0;s<=score_max;s++)
-	{
-		distrM->d_elem[s-distrM->d_ind0]/=(double)number_of_realizations_;
-		distrM_error->d_elem[s-distrM->d_ind0]/=(double)number_of_realizations_;
-		distrM_error->d_elem[s-distrM->d_ind0]-=distrM->d_elem[s-distrM->d_ind0]*distrM->d_elem[s-distrM->d_ind0];
-		distrM_error->d_elem[s-distrM->d_ind0]/=(double)number_of_realizations_;
-		distrM_error->d_elem[s-distrM->d_ind0]=FSA_utils::sqrt_plus(distrM_error->d_elem[s-distrM->d_ind0]);
-
-	};
-
-
-
-	fM<<score_max+1<<endl;
-	for(s=0;s<=score_max;s++)
-	{
-		fM<<s<<"\t"<<distrM->d_elem[s-distrM->d_ind0]<<"\t"<<distrM_error->d_elem[s-distrM->d_ind0]<<endl;
-	};
-
-	fM.close();
-
-
-	delete distrM;
-	delete distrM_error;
-
-
-}
-
-//===============================
-void test::compare_direct_and_reverse_sampling(
-long int number_of_realizations_,
-long int seq2_length_,
-two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-IS1_general_simulation &IS1_general_simulation_test_,
-two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_reverse_,
-IS1_general_simulation &IS1_general_simulation_test_reverse_,
-IS1_general *IS1_general_cs_)
-{
-
-	cout<<endl;
-
-	cout<<"Starting...\n";
-
-	long int k;
-	for(k=1;k<=number_of_realizations_;k++)
-	{
-
-		
-		
-
-		IS1_general_simulation_test_.init();
-
-		IS1_general_simulation_test_.d_W1_seq1_current_length=-1;
-		IS1_general_simulation_test_.d_W1_seq2_current_length=-1;
-
-		two_dim_layer_alignment_algorithm_test_.init();
-
-
-
-		long int seq1_length=0;
-		long int seq2_length=0;
-
-		long int current_state=0;//the current state
-		long int new_state;
-
-		long int M_direct;
-		long int M_reverse;
-
-		long int j;
-		for(j=1;j<=seq2_length_;j++)
-		{
-			IS1_general_cs_->one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
-			current_state,//the current state
-			IS1_general_simulation_test_.d_seq1+seq1_length,//letters for the sequence #1; the array must be allocated
-			IS1_general_simulation_test_.d_seq2+seq2_length,//letters for the sequence #2; the array must be allocated
-			new_state);//a new state
-
-			seq1_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;
-			seq2_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;
-
-			two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-			//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-			seq1_length,//target length of the sequence #1
-			seq2_length);//target length of the sequence #2
-		};
-
-		M_direct=two_dim_layer_alignment_algorithm_test_.d_M;
-
-//--------
-		IS1_general_simulation_test_reverse_.init();
-
-		IS1_general_simulation_test_reverse_.d_W1_seq1_current_length=-1;
-		IS1_general_simulation_test_reverse_.d_W1_seq2_current_length=-1;
-
-		two_dim_layer_alignment_algorithm_test_reverse_.init();
-//--------
-
-		long int t1=seq1_length;
-		long int t2=seq2_length;
-
-		for(j=1;j<=seq2_length_;j++)
-		{
-			
-			long int ii;
-			for(ii=0;ii<two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;ii++)
-			{
-				seq1_length--;
-				IS1_general_simulation_test_reverse_.d_seq1[t1-1-seq1_length]=
-					IS1_general_simulation_test_.d_seq1[seq1_length];
-
-			};
-
-
-			for(ii=0;ii<two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;ii++)
-			{
-				seq2_length--;
-				IS1_general_simulation_test_reverse_.d_seq2[t2-1-seq2_length]=
-					IS1_general_simulation_test_.d_seq2[seq2_length];
-
-			};
-			
-
-
-
-			two_dim_layer_alignment_algorithm_test_reverse_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-			//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-			j*two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1,//target length of the sequence #1
-			j*two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2);//target length of the sequence #2
-
-			
-		};
-
-		M_reverse=two_dim_layer_alignment_algorithm_test_reverse_.d_M;
-
-		
-
-		if(M_direct!=M_reverse)
-		{
-			cout<<M_direct<<"\t"<<M_reverse<<endl;
-		};
-
-
-		if(k%100==0)
-		{
-			cout<<k<<endl;
-		};
-
-	};
-
-	cout<<"Finished!\n";
-
-}
-
-//-------------------------------------------------------------------
-
-long int test::realization_number_into_set_number(//numeration of sets starts from 1
-long int &realization_number_,//realization order number; the numeration starts from 0
-long int &number_of_realizations_set_)//total number of sets
-{
-	return (realization_number_/number_of_realizations_set_)+1;
-}
-
-pair<long int,long int> test::set_number_boundaries(//boundaries of realization order numbers for the set; numeration of realizations starts from 0
-long int &set_number_,//set order number; the numeration starts from 1
-long int &number_of_realizations_set_)//total number of realizations per set
-{
-	pair<long int,long int> res;
-	res.first=(set_number_-1)*number_of_realizations_set_;
-	res.second=res.first+number_of_realizations_set_-1;
-	return res;
-}
-
-void test::collect_and_output_E_distr_upto_fixed_ALP(
-long int number_of_realizations_,
-string E_distr_file_name_,
-two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-IS1_general_simulation &IS1_general_simulation_test_,
-long int target_ALP_,//target ALP number
-double ungapped_lambda_,
-long int limit2_,
-long int number_of_sets_,//number of sets for error calculation
-Sls::FALP_set_of_parameters &par_,
-bool screen_output_flag_,
-
-bool futher_expanding_,
-IS1_general *IS1_general_cs_,
-double *eps_K_,//relative error for K
-long int *number_of_cs_steps_for_expanding_)
-{
-
-	
-
-	double &lambda_out_=par_.lambda;
-	double &lambda_out_error_=par_.lambda_error;
-	double &C_=par_.C;
-	double &C_error_=par_.C_error;
-
-	double &a_I_=par_.a_I;
-	double &a_I_error_=par_.a_I_error;
-	double &a_J_=par_.a_J;
-	double &a_J_error_=par_.a_J_error;
-	double &sigma_=par_.sigma;
-	double &sigma_error_=par_.sigma_error;
-	double &alpha_I_=par_.alpha_I;
-	double &alpha_I_error_=par_.alpha_I_error;
-	double &alpha_J_=par_.alpha_J;
-	double &alpha_J_error_=par_.alpha_J_error;
-
-	double &K_C_=par_.K_C;
-	double &K_C_error_=par_.K_C_error;
-
-
-
-	bool average_set_results_flag=false;
-
-	{
-		long int number_of_realizations_tmp=(number_of_realizations_/number_of_sets_)*number_of_sets_;
-		if(number_of_realizations_tmp<number_of_realizations_)
-		{
-			number_of_realizations_=number_of_realizations_tmp+number_of_sets_;
-		};
-	};
-
-	long int number_of_realizations_set=number_of_realizations_/number_of_sets_;
-
-	//------------------------------------------------------
-
-	bool output_flag=false;
-
-	if(!two_dim_layer_alignment_algorithm_test_.d_M_flag)
-	{
-		throw error("Error - two_dim_layer_alignment_algorithm_test_.d_E_flag must be true in test::collect_and_output_E_distr_upto_fixed_ALP\n",1);
-	};
-
-	ofstream fE;
-	ofstream fE_summary;
-
-
-
-	array_v<double> ***distrE=new array_v<double> **[number_of_sets_+1];
-	FSA_utils::assert_mem(distrE);
-	array_v<double> ***distrE_errors=new array_v<double> **[number_of_sets_+1];
-	FSA_utils::assert_mem(distrE_errors);
-
-	long int **score_max=new long int*[number_of_sets_+1];//statistic
-	FSA_utils::assert_mem(score_max);
-
-	long int k1;
-	for(k1=0;k1<=number_of_sets_;k1++)
-	{
-		distrE[k1]=new array_v<double>*[target_ALP_+1];
-		FSA_utils::assert_mem(distrE[k1]);
-		distrE_errors[k1]=new array_v<double>*[target_ALP_+1];
-		FSA_utils::assert_mem(distrE_errors[k1]);
-		score_max[k1]=new long int[target_ALP_+1];
-		FSA_utils::assert_mem(score_max[k1]);
-
-		long int k;
-		for(k=0;k<=target_ALP_;k++)
-		{
-			distrE[k1][k]=new array_v<double>(NULL);
-			FSA_utils::assert_mem(distrE[k1][k]);
-
-			distrE_errors[k1][k]=new array_v<double>(NULL);
-			FSA_utils::assert_mem(distrE_errors[k1][k]);
-
-			score_max[k1][k]=-inf;
-		};
-
-	};
-
-	//distribution of E
-	if(output_flag)
-	{
-		fE.open(E_distr_file_name_.data());
-		if(!fE)
-		{
-			throw error("Error - the file "+E_distr_file_name_+" is not found\n",3);
-		};
-
-		string E_distr_file_name_summary=E_distr_file_name_+"_summary";
-		fE_summary.open(E_distr_file_name_summary.data());
-		if(!fE_summary)
-		{
-			throw error("Error - the file "+E_distr_file_name_summary+" is not found\n",3);
-		};
-	};
-
-
-
-
-	long int k;
-
-
-	array_positive<double> *diff=new array_positive<double>[number_of_sets_+1];//statistic
-	array_positive<double> *diff_errors=new array_positive<double>[number_of_sets_+1];//statistic
-	
-
-
-	array_positive<long int> *distance_along_direction_1=new array_positive<long int>[number_of_realizations_];//statistic
-	array_positive<long int> *distance_along_direction_2=new array_positive<long int>[number_of_realizations_];//statistic
-
-	array_positive<double> *ALP_weight=new array_positive<double>[number_of_realizations_];//statistic
-	array_positive<long int> *ALP_edge_max=new array_positive<long int>[number_of_realizations_];//statistic
-
-	//--------------------
-
-	
-
-	double *sum_of_weights=new double[number_of_sets_+1];//statistic;
-	double *sum_of_weights_error=new double[number_of_sets_+1];//statistic;
-
-	for(k1=0;k1<=number_of_sets_;k1++)
-	{
-		sum_of_weights[k1]=0;//statistic
-		sum_of_weights_error[k1]=0;//statistic
-	};
-
-	long int M_threshold=(long int)ceil(log((*eps_K_)*(1.0-ungapped_lambda_))/ungapped_lambda_);
-	M_threshold*=2;
-
-	if(M_threshold>=0)
-	{
-		M_threshold=-1;
-	};
-
-	two_dim_layer_alignment_algorithm_test_.d_M_threshold=M_threshold;
-	
-	long int M_max=0;
-
-	for(k=0;k<number_of_realizations_;k++)
-	{
-		long int sn=realization_number_into_set_number(k,number_of_realizations_set);
-
-		
-		
-
-		IS1_general_simulation_test_.init();
-
-		IS1_general_simulation_test_.d_W1_seq1_current_length=-1;
-		IS1_general_simulation_test_.d_W1_seq2_current_length=-1;
-
-		two_dim_layer_alignment_algorithm_test_.init();
-
-		long int current_ALP_number=0;
-		long int current_M=0;
-		distrE[0][current_ALP_number]->increase_elem_by_x(current_M,1.0);
-
-		distrE[sn][current_ALP_number]->increase_elem_by_x(current_M,1.0);
-		
-		distance_along_direction_1[k].set_elem(current_ALP_number,0);
-		distance_along_direction_2[k].set_elem(current_ALP_number,0);
-
-		ALP_weight[k].set_elem(current_ALP_number,1.0);
-		ALP_edge_max[k].set_elem(current_ALP_number,0);
-
-		score_max[0][current_ALP_number]=current_M;
-		score_max[sn][current_ALP_number]=current_M;
-
-		long int seq1_length=0;
-		long int seq2_length=0;
-
-
-		//weights calculation
-		double weight2;
-		double tmp_w=1;
-		double tmp_w2=1;
-
-
-		while(current_ALP_number<target_ALP_)
-		{
-
-			seq1_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;
-			seq2_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;
-
-			if(seq1_length>two_dim_layer_alignment_algorithm_test_.d_max_ind1||
-				seq2_length>two_dim_layer_alignment_algorithm_test_.d_max_ind2)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-
-
-			IS1_general_simulation_test_.simulate_upto_target_lengths(
-			seq1_length,
-			seq2_length);
-
-
-			IS1_general_simulation_test_.calculate_weight_W1_upto_target_lengths(
-			seq1_length,//target length of the sequence #1
-			seq2_length,//target length of the sequence #2
-			seq1_length,//the weights are calculated upto this length for the sequence #1
-			seq2_length);//the weights are calculated upto this length for the sequence #2
-
-
-			two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-			//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-			seq1_length,//target length of the sequence #1
-			seq2_length);//target length of the sequence #2
-
-
-			if(two_dim_layer_alignment_algorithm_test_.d_M>current_M)
-			{//new ALP found
-
-				current_M=two_dim_layer_alignment_algorithm_test_.d_M;
-				current_ALP_number++;
-
-
-
-				IS1_general_simulation_test_.calculate_weight_W1_for_fixed_lengths_using_recursions(
-				seq1_length,//target length of the sequence #1
-				seq2_length,//target length of the sequence #2
-				weight2);//the resulted weight
-
-
-
-				score_max[0][current_ALP_number]=FSA_utils::Tmax(score_max[0][current_ALP_number],current_M);
-				score_max[sn][current_ALP_number]=FSA_utils::Tmax(score_max[sn][current_ALP_number],current_M);
-
-				tmp_w=1/weight2;
-				tmp_w2=tmp_w*tmp_w;
-
-				
-
-				distrE[0][current_ALP_number]->increase_elem_by_x(current_M,tmp_w);
-				distrE[sn][current_ALP_number]->increase_elem_by_x(current_M,tmp_w);
-				
-				distrE_errors[0][current_ALP_number]->increase_elem_by_x(current_M,tmp_w2);
-				distrE_errors[sn][current_ALP_number]->increase_elem_by_x(current_M,tmp_w2);
-
-				distance_along_direction_1[k].set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_1);
-				distance_along_direction_2[k].set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_2);
-
-				ALP_weight[k].set_elem(current_ALP_number,tmp_w);
-				ALP_edge_max[k].set_elem(current_ALP_number,current_M);
-
-				M_max=FSA_utils::Tmax(current_M,M_max);
-
-		
-			};
-
-			if(seq2_length>limit2_)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-
-
-
-
-
-		};
-
-	
-
-		if((k+1)%100==0)
-		{
-			cout<<k+1<<endl;
-		};
-
-		//expanding
-		if(futher_expanding_)
-		{
-			long int current_state=0;//the current state
-			long int new_state;
-
-			long int j;
-			for(j=1;j<=*number_of_cs_steps_for_expanding_;j++)
-			{
-				IS1_general_cs_->one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
-				current_state,//the current state
-				IS1_general_simulation_test_.d_seq1+seq1_length,//letters for the sequence #1; the array must be allocated
-				IS1_general_simulation_test_.d_seq2+seq2_length,//letters for the sequence #2; the array must be allocated
-				new_state);//a new state
-
-				seq1_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;
-				seq2_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;
-
-				two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-				//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-				seq1_length,//target length of the sequence #1
-				seq2_length);//target length of the sequence #2
-
-				long int &M=two_dim_layer_alignment_algorithm_test_.d_M;
-				long int &E=two_dim_layer_alignment_algorithm_test_.d_E;
-
-				if(E-M<M_threshold)
-				{
-					break;
-				};
-
-
-			};
-
-			IS1_general_simulation_test_.d_seq1_current_length=seq1_length;
-			IS1_general_simulation_test_.d_seq2_current_length=seq2_length;
-
-
-		};
-		
-
-
-		//collect differences
-		if(two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag&&futher_expanding_)
-		{
-			//sum of weigths
-			sum_of_weights[0]+=tmp_w;
-			sum_of_weights[sn]+=tmp_w;
-			sum_of_weights_error[0]+=tmp_w2;
-			sum_of_weights_error[sn]+=tmp_w2;
-
-			long int &M=two_dim_layer_alignment_algorithm_test_.d_M;
-			long int ii;
-			for(ii=FSA_utils::Tmax(M_threshold,two_dim_layer_alignment_algorithm_test_.d_scores_counts.d_ind0);ii<=FSA_utils::Tmin(M,two_dim_layer_alignment_algorithm_test_.d_scores_counts.d_dim_plus_d_ind0);ii++)
-			{
-				long int diff_tmp=(M-ii);
-				double diff_tmp_weight=two_dim_layer_alignment_algorithm_test_.d_scores_counts.get_elem(ii)*tmp_w;
-				double diff_tmp_weight2=diff_tmp_weight*diff_tmp_weight;
-
-				diff[0].increase_elem_by_x(diff_tmp,diff_tmp_weight);
-				diff[sn].increase_elem_by_x(diff_tmp,diff_tmp_weight);
-
-				diff_errors[0].increase_elem_by_x(diff_tmp,diff_tmp_weight2);
-				diff_errors[sn].increase_elem_by_x(diff_tmp,diff_tmp_weight2);
-			};
-
-		};
-
-
-	};
-
-
-	
-	for(k1=0;k1<=number_of_sets_;k1++)
-	{
-		long int number_of_realizations_tmp=number_of_realizations_set;
-		if(k1==0)
-		{
-			number_of_realizations_tmp=number_of_realizations_;
-		};
-
-		for(k=0;k<=target_ALP_;k++)
-		{
-			long int j;
-			for(j=distrE[k1][k]->d_ind0;j<=score_max[k1][k];j++)
-			{
-				distrE[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
-				distrE_errors[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
-				distrE_errors[k1][k]->increase_elem_by_x(j,-distrE[k1][k]->get_elem(j)*distrE[k1][k]->get_elem(j));
-				distrE_errors[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
-			};
-		};
-	};
-
-	double *lambda_out_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(lambda_out_vect);
-
-	double *lambda_out_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(lambda_out_error_vect);
-
-
-	double *C_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(C_vect);
-
-	double *C_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(C_error_vect);
-
-
-	{
-
-		long int nalp=target_ALP_;
-
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-			bool check_the_criteria=false;
-			long int nalp_thr;
-			bool inside_simulation_flag;
-			void **alp_distr=(void**)distrE[k1];
-			void **alp_distr_errors=(void**)distrE_errors[k1];
-			double ungapped_lambda=ungapped_lambda_;
-			double lambda;
-			double lambda_error;
-
-			fsa_par::calculate_lambda(
-			check_the_criteria,
-			nalp,
-			nalp_thr,
-			inside_simulation_flag,
-			alp_distr,
-			alp_distr_errors,
-			ungapped_lambda,
-			lambda,
-			lambda_error);
-
-			if(!inside_simulation_flag)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-
-
-			lambda_out_vect[k1]=lambda;
-			lambda_out_error_vect[k1]=lambda_error;
-		};
-
-		
-		lambda_out_=lambda_out_vect[0];
-		lambda_out_error_=lambda_out_error_vect[0];
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"Lambda\t"<<lambda_out_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			lambda_out_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			lambda_out_vect+1);
-
-			if(average_set_results_flag)
-			{
-				lambda_out_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				lambda_out_vect+1);
-
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<lambda_out_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<lambda_out_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_LambdaSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_LambdaSbs.push_back(lambda_out_vect[k1]);
-		};
-
-
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-
-			void **alp_distr=(void**)distrE[k1];
-			void **alp_distr_errors=(void**)distrE_errors[k1];
-
-			long int starting_point=0;
-			bool inside_simulation_flag;
-
-			fsa_par::calculate_C(
-			starting_point,
-			nalp,
-			alp_distr,
-			alp_distr_errors,
-			lambda_out_vect[k1],
-			lambda_out_error_vect[k1],
-			C_vect[k1],
-			C_error_vect[k1],
-			inside_simulation_flag);
-
-			if(!inside_simulation_flag)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-		};
-
-		C_=C_vect[0];
-		C_error_=C_error_vect[0];
-
-		if(screen_output_flag_)
-		{
-			cout<<"C\t"<<C_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			C_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			C_vect+1);
-
-			if(average_set_results_flag)
-			{
-				C_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				C_vect+1);
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<C_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<C_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_CSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_CSbs.push_back(C_vect[k1]);
-		};
-
-	};
-
-
-
-	for(k=0;k<=target_ALP_;k++)
-	{
-
-		if(output_flag)
-		{
-			long int s;
-
-			double sum_tmp=0;
-			double sum_tmp_error=0;
-
-			fE<<k<<endl;
-			fE<<score_max[0][k]+1<<endl;
-
-			for(s=0;s<=score_max[0][k];s++)
-			{
-				fE<<s<<"\t"<<distrE[0][k]->d_elem[s-distrE[0][k]->d_ind0]<<"\t"<<FSA_utils::sqrt_plus(distrE_errors[0][k]->d_elem[s-distrE_errors[0][k]->d_ind0])<<endl;
-				sum_tmp+=distrE[0][k]->d_elem[s-distrE[0][k]->d_ind0]*exp((double)s*ungapped_lambda_);
-				sum_tmp_error+=FSA_utils::sqrt_plus(distrE_errors[0][k]->d_elem[s-distrE_errors[0][k]->d_ind0])*exp((double)s*ungapped_lambda_);
-			};
-			fE<<endl;
-
-			fE_summary<<k<<"\t"<<sum_tmp<<"\t"<<sum_tmp_error<<endl;
-		};
-	};
-
-
-	double *K_C_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(K_C_vect);
-
-	double *K_C_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(K_C_error_vect);
-
-
-	//calculation of the ratio K/C
-	if(two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag&&futher_expanding_)
-	{
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-			long int number_of_realizations_tmp=number_of_realizations_set;
-			if(k1==0)
-			{
-				number_of_realizations_tmp=number_of_realizations_;
-			};
-
-			long int ii;
-			for(ii=0;ii<=diff[k1].d_dim;ii++)
-			{
-				diff[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
-				diff_errors[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
-				diff_errors[k1].increase_elem_by_x(ii,-diff[k1].get_elem(ii)*diff[k1].get_elem(ii));
-				diff_errors[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
-				double tmp=FSA_utils::sqrt_plus(diff_errors[k1].get_elem(ii));
-				diff_errors[k1].set_elem(ii,tmp);
-			};
-
-			
-
-			sum_of_weights[k1]/=(double)number_of_realizations_tmp;
-			sum_of_weights_error[k1]/=(double)number_of_realizations_tmp;
-			sum_of_weights_error[k1]-=sum_of_weights[k1]*sum_of_weights[k1];
-			sum_of_weights_error[k1]/=(double)number_of_realizations_tmp;
-			sum_of_weights_error[k1]=FSA_utils::sqrt_plus(sum_of_weights_error[k1]);
-		
-
-			double den=0;
-			double den_error=0;
-			for(ii=0;ii<=diff[k1].d_dim;ii++)
-			{
-				double tmp=exp(-lambda_out_vect[k1]*(double)ii);
-				den+=tmp*diff[k1].get_elem(ii);
-				den_error+=tmp*tmp*diff_errors[k1].get_elem(ii)*diff_errors[k1].get_elem(ii);
-
-			};
-
-
-			den_error=FSA_utils::sqrt_plus(den_error);
-
-			K_C_vect[k1]=sum_of_weights[k1]/den;
-			K_C_error_vect[k1]=FSA_utils::error_of_the_ratio(sum_of_weights[k1],sum_of_weights_error[k1],den,den_error);
-
-		};
-
-		K_C_=K_C_vect[0];
-		K_C_error_=K_C_error_vect[0];
-
-
-		if(output_flag)
-		{
-			fE<<endl;
-			fE<<"K/C distributions\n";
-			fE<<diff[0].d_dim+1<<endl;
-			long int ii;
-			for(ii=0;ii<=diff[0].d_dim;ii++)
-			{
-				//double tmp=exp(-lambda_out_*(double)ii);
-				fE<<ii<<"\t"<<diff[0].get_elem(ii)/sum_of_weights[0]<<"\t"<<diff_errors[0].get_elem(ii)/sum_of_weights[0]<<endl;
-			};
-
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<"K/C\t"<<K_C_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			K_C_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			K_C_vect+1);
-
-			if(average_set_results_flag)
-			{
-				K_C_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				K_C_vect+1);
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<K_C_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<K_C_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_K_CSbs.clear();
-		par_.m_KSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_K_CSbs.push_back(K_C_vect[k1]);
-			par_.m_KSbs.push_back(K_C_vect[k1]*C_vect[k1]);
-		};
-
-
-
-
-	};
-
-
-	double *a_I_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(a_I_vect);
-	double *a_I_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(a_I_error_vect);
-	double *a_J_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(a_J_vect);
-	double *a_J_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(a_J_error_vect);
-	double *sigma_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(sigma_vect);
-	double *sigma_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(sigma_error_vect);
-	double *alpha_I_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(alpha_I_vect);
-	double *alpha_I_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(alpha_I_error_vect);
-	double *alpha_J_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(alpha_J_vect);
-	double *alpha_J_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(alpha_J_error_vect);
-
-
-	//FSC
-	{
-		long int k1;
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-
-			pair<long int,long int> boundaries;
-			if(k1==0)
-			{
-				boundaries.first=0;
-				boundaries.second=number_of_realizations_-1;
-			}
-			else
-			{
-				boundaries=set_number_boundaries(//boundaries of realization order numbers for the set; numeration of realizations starts from 0
-				k1,//set order number; the numeration starts from 1
-				number_of_realizations_set);//total number of sets
-			};
-
-			bool inside_simulation_flag;
-
-			fsa_par::calculate_FSC(
-			target_ALP_,
-			boundaries.first,
-			boundaries.second,
-			
-
-			lambda_out_vect[k1],
-
-			M_max,
-
-			distance_along_direction_1,
-			distance_along_direction_2,
-
-			ALP_weight,
-			ALP_edge_max,
-
-			a_I_vect[k1],
-			a_I_error_vect[k1],
-			a_J_vect[k1],
-			a_J_error_vect[k1],
-			sigma_vect[k1],
-			sigma_error_vect[k1],
-			alpha_I_vect[k1],
-			alpha_I_error_vect[k1],
-			alpha_J_vect[k1],
-			alpha_J_error_vect[k1],
-			inside_simulation_flag);
-
-			if(!inside_simulation_flag)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-		};
-
-		a_I_=a_I_vect[0];
-		a_I_error_=a_I_error_vect[0];
-		a_J_=a_J_vect[0];
-		a_J_error_=a_J_error_vect[0];
-		sigma_=sigma_vect[0];
-		sigma_error_=sigma_error_vect[0];
-		alpha_I_=alpha_I_vect[0];
-		alpha_I_error_=alpha_I_error_vect[0];
-		alpha_J_=alpha_J_vect[0];
-		alpha_J_error_=alpha_J_error_vect[0];
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"a_I\t"<<a_I_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			a_I_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			a_I_vect+1);
-
-			if(average_set_results_flag)
-			{
-				a_I_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				a_I_vect+1);
-
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<a_I_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<a_I_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_AISbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_AISbs.push_back(a_I_vect[k1]);
-		};
-
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"a_J\t"<<a_J_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			a_J_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			a_J_vect+1);
-
-			if(average_set_results_flag)
-			{
-				a_J_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				a_J_vect+1);
-
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<a_J_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<a_J_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_AJSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_AJSbs.push_back(a_J_vect[k1]);
-		};
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"sigma\t"<<sigma_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			sigma_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			sigma_vect+1);
-
-			if(average_set_results_flag)
-			{
-				sigma_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				sigma_vect+1);
-
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<sigma_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<sigma_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_SigmaSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_SigmaSbs.push_back(sigma_vect[k1]);
-		};
-
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"alpha_I\t"<<alpha_I_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			alpha_I_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			alpha_I_vect+1);
-
-			if(average_set_results_flag)
-			{
-				alpha_I_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				alpha_I_vect+1);
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<alpha_I_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<alpha_I_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_AlphaISbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_AlphaISbs.push_back(alpha_I_vect[k1]);
-		};
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"alpha_J\t"<<alpha_J_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			alpha_J_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			alpha_J_vect+1);
-
-			if(average_set_results_flag)
-			{
-				alpha_J_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				alpha_J_vect+1);
-
-				cout<<"\t"<<alpha_J_;
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<alpha_J_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_AlphaJSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_AlphaJSbs.push_back(alpha_J_vect[k1]);
-		};
-
-	};
-
-
-
-	if(output_flag)
-	{
-		fE.close();
-		fE_summary.close();
-	};
-
-
-	if(score_max)
-	{
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-			delete[]score_max[k1];
-		};
-		delete []score_max;
-	};
-
-	if(distrE)
-	{
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-			for(k=0;k<=target_ALP_;k++)
-			{
-				delete distrE[k1][k];
-			};
-			delete []distrE[k1];
-		};
-		delete []distrE;
-	};
-
-	if(distrE_errors)
-	{
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-			for(k=0;k<=target_ALP_;k++)
-			{
-				delete distrE_errors[k1][k];
-			};
-			delete []distrE_errors[k1];
-		};
-		delete []distrE_errors;
-	};
-	
-
-
-	//FSC
-	delete[]distance_along_direction_1;
-	delete[]distance_along_direction_2;
-	delete[]ALP_weight;
-	delete[]ALP_edge_max;
-
-
-
-	delete[]lambda_out_vect;
-	delete[]lambda_out_error_vect;
-	delete[]C_vect;
-	delete[]C_error_vect;
-	delete[]K_C_vect;
-	delete[]K_C_error_vect;
-	delete[]a_I_vect;
-	delete[]a_I_error_vect;
-	delete[]a_J_vect;
-	delete[]a_J_error_vect;
-	delete[]sigma_vect;
-	delete[]sigma_error_vect;
-	delete[]alpha_I_vect;
-	delete[]alpha_I_error_vect;
-	delete[]alpha_J_vect;
-	delete[]alpha_J_error_vect;
-
-}
-
-void test::restore_arrays(
-long int k_,
-mult_states_type *states_old_,
-two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-IS1_general_simulation &IS1_general_simulation_test_)
-{
-
-	if(!states_old_)
-	{
-		throw error("Unexpected error in test::restore_arrays\n",1);
-	};
-
-	test::restore_arrays(
-	states_old_->d_states[k_].d_two_dim_layer_alignment_algorithm,
-	states_old_->d_states[k_].d_IS1_general_simulation,
-	two_dim_layer_alignment_algorithm_test_,
-	IS1_general_simulation_test_);
-	
-}
-
-
-void test::restore_arrays(
-two_dim_layer_alignment_algorithm<long int> *two_dim_layer_alignment_algorithm_test_from_,
-IS1_general_simulation *IS1_general_simulation_test_from_,
-two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-IS1_general_simulation &IS1_general_simulation_test_)
-{
-
-	if(!two_dim_layer_alignment_algorithm_test_from_||!IS1_general_simulation_test_from_)
-	{
-		throw error("Unexpected error in test::restore_arrays\n",1);
-	};
-	
-	//alignment object - begin
-	long int i;
-	for(i=0;i<two_dim_layer_alignment_algorithm_test_.d_number_of_variables;i++)
-	{
-		two_dim_layer<long int>::copy_2_into_1_two_dim_layer(
-		two_dim_layer_alignment_algorithm_test_.d_vars[i],
-		two_dim_layer_alignment_algorithm_test_from_->d_vars[i]);
-	};
-	two_dim_layer_alignment_algorithm_test_.d_current_align_ind1=two_dim_layer_alignment_algorithm_test_from_->d_current_align_ind1;
-	two_dim_layer_alignment_algorithm_test_.d_current_align_ind2=two_dim_layer_alignment_algorithm_test_from_->d_current_align_ind2;
-	//alignment object - end
-
-	//IS1_general_simulation object - begin
-	//restore the sequences
-	IS1_general_simulation_test_.d_seq1_current_length=IS1_general_simulation_test_from_->d_seq1_current_length;
-	IS1_general_simulation_test_.d_seq2_current_length=IS1_general_simulation_test_from_->d_seq2_current_length;
-
-	for(i=0;i<IS1_general_simulation_test_from_->d_seq1_current_length;i++)
-	{
-		IS1_general_simulation_test_.d_seq1[i]=IS1_general_simulation_test_from_->d_seq1[i];
-	};
-
-	for(i=0;i<IS1_general_simulation_test_from_->d_seq2_current_length;i++)
-	{
-		IS1_general_simulation_test_.d_seq2[i]=IS1_general_simulation_test_from_->d_seq2[i];
-	};
-
-	//restore the layers for weights
-	IS1_general_simulation_test_.d_current_state=IS1_general_simulation_test_from_->d_current_state;
-	IS1_general_simulation_test_.d_W1_seq1_current_length=IS1_general_simulation_test_from_->d_W1_seq1_current_length;
-	IS1_general_simulation_test_.d_W1_seq2_current_length=IS1_general_simulation_test_from_->d_W1_seq2_current_length;
-
-	for(i=0;i<IS1_general_simulation_test_.d_IS1_general_obj->d_number_of_states;i++)
-	{
-		two_dim_layer<double>::copy_2_into_1_two_dim_layer(
-		IS1_general_simulation_test_.d_W1[i],
-		IS1_general_simulation_test_from_->d_W1[i]);
-	};
-
-
-
-	//IS1_general_simulation object - end
-
-}
-
-void test::collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-bool compute_allocated_memory_flag_,//if true then total allocated memory is computed in allocated_memory_
-double &allocated_memory_,
-
-long int number_of_realizations_,
-string E_distr_file_name_,
-two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-IS1_general_simulation &IS1_general_simulation_test_,
-long int target_ALP_,//target ALP number
-double ungapped_lambda_,
-long int limit2_,
-long int number_of_sets_,//number of sets for error calculation
-Sls::FALP_set_of_parameters &par_,
-bool &inside_simulation_flag_,
-bool screen_output_flag_,
-bool screen_output_k_flag_,
-
-double ending_time_,
-bool &stopped_by_ending_time_flag_,
-long int &number_of_realizations_with_ending_time_,
-
-double ending_time_to_test_logarithmic_regime_,
-
-bool save_states_flag_,
-mult_states_type *states_old_,//NULL or defined
-mult_states_type *&states_new_,//resulted value
-long int &M_thr_estimation_,//average score threshold corresponded to target_ALP_
-
-bool futher_expanding_,
-long int M_thr_,//the expanding starts from the ALP with the score >=M_thr_; used if >=0
-IS1_general *IS1_general_cs_,
-double *eps_K_,//relative error for K
-long int *number_of_cs_steps_for_expanding_,
-bool parameters_are_not_calculated_)
-{
-
-	if(!save_states_flag_&&ending_time_>=0)
-	{
-		throw error("Error - !save_states_flag_&&ending_time_>=0 in test::collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states\n",1);
-	};
-
-	if(compute_allocated_memory_flag_)
-	{
-		allocated_memory_=sizeof(state_type);
-	};
-
-	stopped_by_ending_time_flag_=false;
-
-	inside_simulation_flag_=true;
-
-	double time1=0;
-	if(save_states_flag_||ending_time_>=0)
-	{
-		FSA_utils::get_current_time(time1);
-	};
-	
-
-	double &lambda_out_=par_.lambda;
-	double &lambda_out_error_=par_.lambda_error;
-	double &C_=par_.C;
-	double &C_error_=par_.C_error;
-
-	double &a_I_=par_.a_I;
-	double &a_I_error_=par_.a_I_error;
-	double &a_J_=par_.a_J;
-	double &a_J_error_=par_.a_J_error;
-	double &sigma_=par_.sigma;
-	double &sigma_error_=par_.sigma_error;
-	double &alpha_I_=par_.alpha_I;
-	double &alpha_I_error_=par_.alpha_I_error;
-	double &alpha_J_=par_.alpha_J;
-	double &alpha_J_error_=par_.alpha_J_error;
-
-	double &K_C_=par_.K_C;
-	double &K_C_error_=par_.K_C_error;
-
-
-
-	bool average_set_results_flag=false;
-
-	if(save_states_flag_)
-	{
-		states_new_->d_total_number_of_exp_cells=0;
-
-		if(!states_old_)
-		{
-			states_new_->d_total_number_of_ALP_cells=0;
-			states_new_->d_total_number_of_ALPs=0;
-		}
-		else
-		{
-			states_new_->d_total_number_of_ALP_cells=states_old_->d_total_number_of_ALP_cells;
-			states_new_->d_total_number_of_ALPs=states_old_->d_total_number_of_ALPs;
-		};
-	};
-
-
-	{
-		long int number_of_realizations_tmp=(number_of_realizations_/number_of_sets_)*number_of_sets_;
-		if(number_of_realizations_tmp<number_of_realizations_)
-		{
-			number_of_realizations_=number_of_realizations_tmp+number_of_sets_;
-		};
-	};
-
-	long int number_of_realizations_set=number_of_realizations_/number_of_sets_;
-
-	long int number_of_realizations_old=0;
-	long int number_of_realizations_max=number_of_realizations_;
-
-	if(states_old_)
-	{
-		//number_of_realizations_min=FSA_utils::Tmin(number_of_realizations_,states_old_->d_number_of_realizations);
-		number_of_realizations_max=FSA_utils::Tmax(number_of_realizations_,states_old_->d_number_of_realizations);
-		number_of_realizations_old=states_old_->d_number_of_realizations;
-
-
-	};
-
-	long int number_of_realizations_before_loop=number_of_realizations_;
-	if(save_states_flag_)
-	{
-		states_new_->d_number_of_realizations=number_of_realizations_max;
-		//allocate states
-		states_new_->d_states=new state_type[states_new_->d_number_of_realizations];
-		if(compute_allocated_memory_flag_)
-		{
-			allocated_memory_+=states_new_->d_number_of_realizations*sizeof(state_type);
-		};
-
-		long int ii;
-		for(ii=0;ii<states_new_->d_number_of_realizations;ii++)
-		{
-			long int target_ALP_tmp;
-			if(number_of_realizations_>number_of_realizations_old)
-			{
-				if(ii<number_of_realizations_old)
-				{
-					target_ALP_tmp=FSA_utils::Tmax(target_ALP_,states_old_->d_states[ii].d_ALP_number);
-				}
-				else
-				{
-					target_ALP_tmp=target_ALP_;
-				};
-			}
-			else
-			{
-				if(ii<number_of_realizations_)
-				{
-					target_ALP_tmp=FSA_utils::Tmax(target_ALP_,states_old_->d_states[ii].d_ALP_number);
-				}
-				else
-				{
-					target_ALP_tmp=states_old_->d_states[ii].d_ALP_number;
-				};
-			};
-
-			states_new_->d_states[ii].d_ALP_number=target_ALP_tmp;
-			
-
-			states_new_->d_states[ii].d_IS1_general_simulation=NULL;
-			states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm=NULL;
-			states_new_->d_states[ii].d_expanding_finished_flag=false;
-
-
-			states_new_->d_states[ii].d_ALP_weights_array=NULL;
-			states_new_->d_states[ii].d_M_array=NULL;
-			states_new_->d_states[ii].d_seq1_length_array=NULL;
-			states_new_->d_states[ii].d_seq2_length_array=NULL;
-			states_new_->d_states[ii].d_distance_along_direction_1_array=NULL;
-			states_new_->d_states[ii].d_distance_along_direction_2_array=NULL;
-
-
-			
-		};
-
-		
-
-		if(states_old_)
-		{
-
-
-			long int ii;
-			for(ii=0;ii<states_old_->d_number_of_realizations;ii++)
-			{
-				//allocate memory
-				
-				states_new_->d_states[ii].d_ALP_weights_array=new array_positive<double>;
-				states_new_->d_states[ii].d_M_array=new array_positive<long int>;
-				states_new_->d_states[ii].d_seq1_length_array=new array_positive<long int>;
-				states_new_->d_states[ii].d_seq2_length_array=new array_positive<long int>;
-				states_new_->d_states[ii].d_distance_along_direction_1_array=new array_positive<long int>;
-				states_new_->d_states[ii].d_distance_along_direction_2_array=new array_positive<long int>;
-
-
-
-				long int k;
-				for(k=0;k<=states_old_->d_states[ii].d_ALP_number;k++)
-				{
-					states_new_->d_states[ii].d_ALP_weights_array->set_elem(k,states_old_->d_states[ii].d_ALP_weights_array->get_elem(k));
-					states_new_->d_states[ii].d_M_array->set_elem(k,states_old_->d_states[ii].d_M_array->get_elem(k));
-					states_new_->d_states[ii].d_seq1_length_array->set_elem(k,states_old_->d_states[ii].d_seq1_length_array->get_elem(k));
-					states_new_->d_states[ii].d_seq2_length_array->set_elem(k,states_old_->d_states[ii].d_seq2_length_array->get_elem(k));
-					states_new_->d_states[ii].d_distance_along_direction_1_array->set_elem(k,states_old_->d_states[ii].d_distance_along_direction_1_array->get_elem(k));
-					states_new_->d_states[ii].d_distance_along_direction_2_array->set_elem(k,states_old_->d_states[ii].d_distance_along_direction_2_array->get_elem(k));
-
-				};
-			};
-
-			for(ii=number_of_realizations_;ii<states_old_->d_number_of_realizations;ii++)
-			{
-
-
-				states_new_->d_states[ii].d_IS1_general_simulation=
-				new IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
-				states_old_->d_states[ii].d_IS1_general_simulation);//maximum sequence length
-
-				states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm=
-				new two_dim_layer_alignment_algorithm<long int>(
-				states_old_->d_states[ii].d_seq1_length_array->get_elem(states_old_->d_states[ii].d_ALP_number),//target length of the sequence #1
-				states_old_->d_states[ii].d_seq2_length_array->get_elem(states_old_->d_states[ii].d_ALP_number),//target length of the sequence #2
-				states_old_->d_states[ii].d_two_dim_layer_alignment_algorithm);
-			};
-		};
-
-
-
-	};
-
-	//------------------------------------------------------
-
-	bool output_flag=false;
-
-	if(!two_dim_layer_alignment_algorithm_test_.d_M_flag)
-	{
-		throw error("Error - two_dim_layer_alignment_algorithm_test_.d_E_flag must be true in test::collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states\n",1);
-	};
-
-	ofstream fE;
-	ofstream fE_summary;
-
-
-
-
-	array_v<double> ***distrE=new array_v<double> **[number_of_sets_+1];
-	FSA_utils::assert_mem(distrE);
-	array_v<double> ***distrE_errors=new array_v<double> **[number_of_sets_+1];
-	FSA_utils::assert_mem(distrE_errors);
-
-	long int **score_max=new long int*[number_of_sets_+1];//statistic
-	FSA_utils::assert_mem(score_max);
-
-	long int k1;
-	for(k1=0;k1<=number_of_sets_;k1++)
-	{
-		distrE[k1]=new array_v<double>*[target_ALP_+1];
-		FSA_utils::assert_mem(distrE[k1]);
-		distrE_errors[k1]=new array_v<double>*[target_ALP_+1];
-		FSA_utils::assert_mem(distrE_errors[k1]);
-		score_max[k1]=new long int[target_ALP_+1];
-		FSA_utils::assert_mem(score_max[k1]);
-
-		long int k;
-		for(k=0;k<=target_ALP_;k++)
-		{
-			distrE[k1][k]=new array_v<double>(NULL);
-			FSA_utils::assert_mem(distrE[k1][k]);
-
-			distrE_errors[k1][k]=new array_v<double>(NULL);
-			FSA_utils::assert_mem(distrE_errors[k1][k]);
-
-			score_max[k1][k]=-inf;
-		};
-
-	};
-
-	//distribution of E
-
-	if(output_flag)
-	{
-		fE.open(E_distr_file_name_.data());
-		if(!fE)
-		{
-			throw error("Error - the file "+E_distr_file_name_+" is not found\n",3);
-		};
-
-		string E_distr_file_name_summary=E_distr_file_name_+"_summary";
-		fE_summary.open(E_distr_file_name_summary.data());
-		if(!fE_summary)
-		{
-			throw error("Error - the file "+E_distr_file_name_summary+" is not found\n",3);
-		};
-	};
-
-
-
-
-	long int k;
-
-
-	array_positive<double> *diff=new array_positive<double>[number_of_sets_+1];//statistic
-	array_positive<double> *diff_errors=new array_positive<double>[number_of_sets_+1];//statistic
-	
-
-
-	array_positive<long int> *distance_along_direction_1=new array_positive<long int>[number_of_realizations_max];//statistic
-	array_positive<long int> *distance_along_direction_2=new array_positive<long int>[number_of_realizations_max];//statistic
-
-	array_positive<double> *ALP_weight=new array_positive<double>[number_of_realizations_max];//statistic
-	array_positive<long int> *ALP_edge_max=new array_positive<long int>[number_of_realizations_max];//statistic
-
-	//--------------------
-
-	
-	double *sum_of_weights=new double[number_of_sets_+1];//statistic;
-	double *sum_of_weights_error=new double[number_of_sets_+1];//statistic;
-
-	for(k1=0;k1<=number_of_sets_;k1++)
-	{
-		sum_of_weights[k1]=0;//statistic
-		sum_of_weights_error[k1]=0;//statistic
-	};
-
-	long int M_threshold=(long int)ceil(log((*eps_K_)*(1.0-ungapped_lambda_))/ungapped_lambda_);
-	M_threshold*=2;
-
-
-	if(M_threshold>=0)
-	{
-		M_threshold=-1;
-	};
-
-	two_dim_layer_alignment_algorithm_test_.d_M_threshold=M_threshold;
-	
-	long int M_max=0;
-
-	if(save_states_flag_)
-	{
-		states_new_->d_average_ALP_pos1=0;
-		states_new_->d_average_ALP_pos2=0;
-		states_new_->d_average_ALP_pos1_mult_ALP_pos2=0;
-
-		states_new_->d_average_expanding_length1=0;
-		states_new_->d_average_expanding_length2=0;
-		states_new_->d_average_expanding_length1_mult_expanding_length2=0;
-	};
-
-
-	//variables for saving the state at the moment when M_thr_ is reached
-
-	two_dim_layer_alignment_algorithm<long int> *two_dim_layer_alignment_algorithm_test_M_thr=NULL;
-	IS1_general_simulation *IS1_general_simulation_M_thr=NULL;
-
-	bool M_thr_flag=(M_thr_>0)&&futher_expanding_;
-
-	long int seq1_length_M_thr=0;
-	long int seq2_length_M_thr=0;
-
-	long int not_all_ALP_are_sampled=0;
-
-	bool stop_loop_flag=false;
-	for(k=0;k<number_of_realizations_;k++)
-	{
-
-		//allocate memory
-		if(save_states_flag_)
-		{
-			if(k>=number_of_realizations_old)
-			{
-				states_new_->d_states[k].d_ALP_weights_array=new array_positive<double>;
-				states_new_->d_states[k].d_M_array=new array_positive<long int>;
-				states_new_->d_states[k].d_seq1_length_array=new array_positive<long int>;
-				states_new_->d_states[k].d_seq2_length_array=new array_positive<long int>;
-				states_new_->d_states[k].d_distance_along_direction_1_array=new array_positive<long int>;
-				states_new_->d_states[k].d_distance_along_direction_2_array=new array_positive<long int>;
-
-				
-			};
-		};
-
-
-		long int sn=realization_number_into_set_number(k,number_of_realizations_set);
-
-
-		IS1_general_simulation_test_.init();
-
-		IS1_general_simulation_test_.d_W1_seq1_current_length=-1;
-		IS1_general_simulation_test_.d_W1_seq2_current_length=-1;
-
-		two_dim_layer_alignment_algorithm_test_.init();
-
-		long int current_ALP_number=0;
-		long int current_M=0;
-		distrE[0][current_ALP_number]->increase_elem_by_x(current_M,1.0);
-
-		distrE[sn][current_ALP_number]->increase_elem_by_x(current_M,1.0);
-		
-		distance_along_direction_1[k].set_elem(current_ALP_number,0);
-		distance_along_direction_2[k].set_elem(current_ALP_number,0);
-
-		ALP_weight[k].set_elem(current_ALP_number,1.0);
-		ALP_edge_max[k].set_elem(current_ALP_number,0);
-
-		score_max[0][current_ALP_number]=current_M;
-		score_max[sn][current_ALP_number]=current_M;
-
-
-		long int seq1_length=0;
-		long int seq2_length=0;
-
-		if(save_states_flag_)
-		{
-			if(!states_old_||k>=number_of_realizations_old)
-			{
-				states_new_->d_states[k].d_ALP_weights_array->set_elem(0,1.0);
-				states_new_->d_states[k].d_M_array->set_elem(0,0);
-				states_new_->d_states[k].d_seq1_length_array->set_elem(0,0);
-				states_new_->d_states[k].d_seq2_length_array->set_elem(0,0);
-				states_new_->d_states[k].d_distance_along_direction_1_array->set_elem(0,0);
-				states_new_->d_states[k].d_distance_along_direction_2_array->set_elem(0,0);
-
-			};
-		};
-
-
-		//weights calculation
-		double weight2=1;
-		double tmp_w=1;
-		double tmp_w2=1;
-
-		double tmp_w_M_thr=0;
-		double tmp_w2_M_thr=0;
-
-
-		bool M_thr_var_are_saved=false;
-
-		bool restored_flag=false;
-		bool flag_tmp3=false;
-
-		
-		while((current_ALP_number<target_ALP_)||(M_thr_flag&&!M_thr_var_are_saved))
-		{
-			bool ALP_stat_flag=(current_ALP_number<target_ALP_);
-
-			
-			if(ALP_stat_flag&&M_thr_var_are_saved)
-			{
-				flag_tmp3=true;
-			};
-
-
-			seq1_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;
-			seq2_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;
-
-
-			if(seq1_length>two_dim_layer_alignment_algorithm_test_.d_max_ind1||
-				seq2_length>two_dim_layer_alignment_algorithm_test_.d_max_ind2)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-
-
-			bool new_calculation_flag=true;
-
-			if(states_old_)
-			{
-				if(k<number_of_realizations_old)
-				{
-					if(current_ALP_number<states_old_->d_states[k].d_ALP_number)
-					{
-						new_calculation_flag=false;
-					};
-
-				};
-			};
-			
-
-			bool ALP_flag=false;
-
-
-			if(new_calculation_flag)
-			{
-				if(states_old_)
-				{
-					if(k<number_of_realizations_old)
-					{
-						if(current_ALP_number==states_old_->d_states[k].d_ALP_number&&!restored_flag)
-						{//restore the state; 				seq1_length, seq2_length was increased, require correction
-
-							restored_flag=true;
-
-							restore_arrays(
-							k,
-							states_old_,
-							two_dim_layer_alignment_algorithm_test_,
-							IS1_general_simulation_test_);
-
-
-						};
-					};
-				};
-
-				if(save_states_flag_)
-				{
-					long int seq1_length_prev=IS1_general_simulation_test_.d_W1_seq1_current_length;
-					long int seq2_length_prev=IS1_general_simulation_test_.d_W1_seq2_current_length;
-
-					states_new_->d_total_number_of_ALP_cells+=
-						seq1_length*seq2_length-seq1_length_prev*seq2_length_prev;
-				};
-
-
-
-
-				IS1_general_simulation_test_.simulate_upto_target_lengths(
-				seq1_length,
-				seq2_length);
-
-
-				IS1_general_simulation_test_.calculate_weight_W1_upto_target_lengths(
-				seq1_length,//target length of the sequence #1
-				seq2_length,//target length of the sequence #2
-				seq1_length,//the weights are calculated upto this length for the sequence #1
-				seq2_length);//the weights are calculated upto this length for the sequence #2
-
-
-
-				two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-				//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-				seq1_length,//target length of the sequence #1
-				seq2_length);//target length of the sequence #2
-
-
-				ALP_flag=(two_dim_layer_alignment_algorithm_test_.d_M>current_M);
-
-				if(save_states_flag_)
-				{
-					if(ALP_flag)
-					{
-						states_new_->d_total_number_of_ALPs++;
-					};
-				};
-			};
-
-
-			if(states_old_)
-			{
-				if(!new_calculation_flag)
-				{
-					ALP_flag=(seq1_length==states_old_->d_states[k].d_seq1_length_array->get_elem(current_ALP_number+1))&&
-						(seq2_length==states_old_->d_states[k].d_seq2_length_array->get_elem(current_ALP_number+1));
-
-					
-
-					if(ALP_flag)
-					{
-						//restore the state
-
-						two_dim_layer_alignment_algorithm_test_.d_M=states_old_->d_states[k].d_M_array->get_elem(current_ALP_number+1);
-
-						weight2=states_old_->d_states[k].d_ALP_weights_array->get_elem(current_ALP_number+1);
-
-						two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_1=
-							states_old_->d_states[k].d_distance_along_direction_1_array->get_elem(current_ALP_number+1);
-
-						two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_2=
-							states_old_->d_states[k].d_distance_along_direction_2_array->get_elem(current_ALP_number+1);
-
-
-					};
-
-				};
-			};
-
-			if(ALP_flag)
-			{//new ALP found
-
-				current_M=two_dim_layer_alignment_algorithm_test_.d_M;
-				current_ALP_number++;
-
-
-
-				if(new_calculation_flag)
-				{
-					IS1_general_simulation_test_.calculate_weight_W1_for_fixed_lengths_using_recursions(
-					seq1_length,//target length of the sequence #1
-					seq2_length,//target length of the sequence #2
-					weight2);//the resulted weight
-
-					if(save_states_flag_)
-					{
-						states_new_->d_states[k].d_ALP_weights_array->set_elem(current_ALP_number,weight2);
-						states_new_->d_states[k].d_distance_along_direction_1_array->set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_1);
-						states_new_->d_states[k].d_distance_along_direction_2_array->set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_2);
-						states_new_->d_states[k].d_M_array->set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_M);
-						states_new_->d_states[k].d_seq1_length_array->set_elem(current_ALP_number,seq1_length);
-						states_new_->d_states[k].d_seq2_length_array->set_elem(current_ALP_number,seq2_length);
-					};
-
-
-
-				};
-
-
-
-
-				if(ALP_stat_flag)
-				{
-					score_max[0][current_ALP_number]=FSA_utils::Tmax(score_max[0][current_ALP_number],current_M);
-					score_max[sn][current_ALP_number]=FSA_utils::Tmax(score_max[sn][current_ALP_number],current_M);
-				};
-
-				if(weight2<=0)
-				{
-					inside_simulation_flag_=false;
-					tmp_w=0;
-				}
-				else
-				{
-					tmp_w=1/weight2;
-				};
-
-				tmp_w2=tmp_w*tmp_w;
-
-			
-
-				if(ALP_stat_flag)
-				{
-					distrE[0][current_ALP_number]->increase_elem_by_x(current_M,tmp_w);
-					distrE[sn][current_ALP_number]->increase_elem_by_x(current_M,tmp_w);
-					
-					distrE_errors[0][current_ALP_number]->increase_elem_by_x(current_M,tmp_w2);
-					distrE_errors[sn][current_ALP_number]->increase_elem_by_x(current_M,tmp_w2);
-
-					distance_along_direction_1[k].set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_1);
-					distance_along_direction_2[k].set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_2);
-
-					ALP_weight[k].set_elem(current_ALP_number,tmp_w);
-					ALP_edge_max[k].set_elem(current_ALP_number,current_M);
-
-
-					M_max=FSA_utils::Tmax(current_M,M_max);
-				};
-
-				
-
-		
-			};
-
-			if(seq2_length>limit2_)
-			{
-				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-			};
-
-
-			
-
-			
-			bool save_flag_tmp=((current_ALP_number==target_ALP_)&&!M_thr_flag)||
-			(M_thr_flag&&(two_dim_layer_alignment_algorithm_test_.d_M>=M_thr_)&&(current_ALP_number>=target_ALP_));
-			
-			if(save_flag_tmp)
-			{//save the matrices for weights and alingment matrix
-
-
-				if(states_old_)
-				{
-					if(k<number_of_realizations_old)
-					{
-						if(current_ALP_number==states_old_->d_states[k].d_ALP_number&&!restored_flag)
-						{//restore the state; 				
-
-							restored_flag=true;
-
-							restore_arrays(
-							k,
-							states_old_,
-							two_dim_layer_alignment_algorithm_test_,
-							IS1_general_simulation_test_);
-
-
-						};
-					};
-				};
-
-				//save states
-				if(save_states_flag_)
-				{
-
-					states_new_->d_states[k].d_ALP_number=current_ALP_number;
-
-					states_new_->d_states[k].d_IS1_general_simulation=
-					new IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
-					&IS1_general_simulation_test_);//maximum sequence length
-
-					states_new_->d_states[k].d_two_dim_layer_alignment_algorithm=
-					new two_dim_layer_alignment_algorithm<long int>(
-					seq1_length,//target length of the sequence #1
-					seq2_length,//target length of the sequence #2
-					&two_dim_layer_alignment_algorithm_test_);
-
-					states_new_->d_average_ALP_pos1+=seq1_length;
-					states_new_->d_average_ALP_pos2+=seq2_length;
-					states_new_->d_average_ALP_pos1_mult_ALP_pos2+=seq1_length*seq2_length;
-				};
-
-
-			};
-
-			//check wheter we reached the score threshold M_thr_
-
-			if(M_thr_flag&&(two_dim_layer_alignment_algorithm_test_.d_M>=M_thr_)&&!M_thr_var_are_saved)
-			{
-
-				M_thr_var_are_saved=true;
-				tmp_w_M_thr=tmp_w;
-				tmp_w2_M_thr=tmp_w2;
-
-				delete IS1_general_simulation_M_thr;
-
-				IS1_general_simulation_M_thr=
-				new IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
-				&IS1_general_simulation_test_);//maximum sequence length
-
-				delete two_dim_layer_alignment_algorithm_test_M_thr;
-
-				two_dim_layer_alignment_algorithm_test_M_thr=
-				new two_dim_layer_alignment_algorithm<long int>(
-				seq1_length,//target length of the sequence #1
-				seq2_length,//target length of the sequence #2
-				&two_dim_layer_alignment_algorithm_test_);
-
-				two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag=false;
-
-				seq1_length_M_thr=seq1_length;
-				seq2_length_M_thr=seq2_length;
-
-			};
-
-
-
-			if(ending_time_>=0)
-			{
-				if(new_calculation_flag)
-				{
-					double time1_current;
-					FSA_utils::get_current_time(time1_current);
-					if(time1_current>=ending_time_)
-					{
-						stop_loop_flag=true;
-						stopped_by_ending_time_flag_=true;
-					};
-				};
-			};
-
-			if(ending_time_to_test_logarithmic_regime_>0)
-			{
-				double time1_current;
-				FSA_utils::get_current_time(time1_current);
-				if(time1_current>=ending_time_to_test_logarithmic_regime_)
-				{
-					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-				};
-			};
-
-		};
-
-		
-		if(flag_tmp3)
-		{
-			not_all_ALP_are_sampled++;
-		};
-
-		if(screen_output_k_flag_)
-		{
-			if((k+1)%100==0)
-			{
-				cout<<k+1<<endl;
-			};
-		};
-
-
-
-		//expanding
-
-		if(M_thr_flag)
-		{
-			if(!M_thr_var_are_saved)
-			{
-				throw error("Unexpected error in test::collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states\n",1);
-			};
-
-			two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag=true;
-
-			seq1_length=seq1_length_M_thr;
-			seq2_length=seq2_length_M_thr;
-
-			tmp_w=tmp_w_M_thr;
-			tmp_w2=tmp_w2_M_thr;
-
-
-
-			test::restore_arrays(
-			two_dim_layer_alignment_algorithm_test_M_thr,
-			IS1_general_simulation_M_thr,
-			two_dim_layer_alignment_algorithm_test_,
-			IS1_general_simulation_test_);
-
-			two_dim_layer_alignment_algorithm_test_.d_M=two_dim_layer_alignment_algorithm_test_M_thr->d_M;
-
-		};
-
-		
-		long int seq1_length_before_expanding=seq1_length;
-		long int seq2_length_before_expanding=seq2_length;
-		
-		if(futher_expanding_)
-		{
-			bool expanding_new_flag=true;
-			//restore state
-
-			if(states_old_)
-			{
-				if(k<number_of_realizations_old)
-				{
-					if(current_ALP_number==states_old_->d_states[k].d_ALP_number&&(!restored_flag||states_old_->d_states[k].d_expanding_finished_flag))
-					{
-						if(states_old_->d_states[k].d_expanding_finished_flag)
-						{
-							expanding_new_flag=false;
-							two_dim_layer_alignment_algorithm_test_.d_M=states_old_->d_states[k].d_M_after_expanding;
-							array_v<double>::copy_x2_into_x1(
-								two_dim_layer_alignment_algorithm_test_.d_scores_counts,
-								states_old_->d_states[k].d_scores_counts_after_expanding);
-
-							seq1_length=states_old_->d_states[k].d_seq1_length_after_expanding;
-							seq2_length=states_old_->d_states[k].d_seq2_length_after_expanding;
-
-						}
-						else
-						{
-							restore_arrays(
-							k,
-							states_old_,
-							two_dim_layer_alignment_algorithm_test_,
-							IS1_general_simulation_test_);
-						};
-					};
-				};
-			};
-
-			if(expanding_new_flag)
-			{
-				bool tmp_bool=two_dim_layer_alignment_algorithm_test_.d_E_flag;
-				two_dim_layer_alignment_algorithm_test_.d_E_flag=true;
-
-				long int current_state=0;//the current state
-				long int new_state;
-
-				bool success_flag=false;
-
-				long int j;
-				for(j=1;j<=*number_of_cs_steps_for_expanding_;j++)
-				{
-					IS1_general_cs_->one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
-					current_state,//the current state
-					IS1_general_simulation_test_.d_seq1+seq1_length,//letters for the sequence #1; the array must be allocated
-					IS1_general_simulation_test_.d_seq2+seq2_length,//letters for the sequence #2; the array must be allocated
-					new_state);//a new state
-
-					seq1_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;
-					seq2_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;
-
-
-					two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-					//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-					seq1_length,//target length of the sequence #1
-					seq2_length);//target length of the sequence #2
-
-					long int &M=two_dim_layer_alignment_algorithm_test_.d_M;
-					long int &E=two_dim_layer_alignment_algorithm_test_.d_E;
-
-
-					if(E-M<M_threshold)
-					{
-						success_flag=true;
-						break;
-					};
-
-
-					if(ending_time_to_test_logarithmic_regime_>0)
-					{
-						double time1_current;
-						FSA_utils::get_current_time(time1_current);
-						if(time1_current>=ending_time_to_test_logarithmic_regime_)
-						{
-							throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-						};
-					};
-
-
-				};
-
-
-				if(!success_flag)
-				{
-					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-				};
-
-				two_dim_layer_alignment_algorithm_test_.d_E_flag=tmp_bool;
-
-			};
-
-				
-
-			IS1_general_simulation_test_.d_seq1_current_length=seq1_length;
-			IS1_general_simulation_test_.d_seq2_current_length=seq2_length;
-
-			if(save_states_flag_)
-			{
-				states_new_->d_average_expanding_length1+=seq1_length-seq1_length_before_expanding;
-				states_new_->d_average_expanding_length2+=seq2_length-seq2_length_before_expanding;
-				states_new_->d_average_expanding_length1_mult_expanding_length2+=
-					(seq1_length-seq1_length_before_expanding)*(seq2_length-seq2_length_before_expanding);
-
-				states_new_->d_total_number_of_exp_cells+=
-					seq1_length*seq2_length-seq1_length_before_expanding*seq2_length_before_expanding;
-
-				states_new_->d_states[k].d_expanding_finished_flag=true;
-				states_new_->d_states[k].d_M_after_expanding=two_dim_layer_alignment_algorithm_test_.d_M;
-				states_new_->d_states[k].d_seq1_length_after_expanding=seq1_length;
-				states_new_->d_states[k].d_seq2_length_after_expanding=seq2_length;
-
-				array_v<double>::copy_x2_into_x1(
-				states_new_->d_states[k].d_scores_counts_after_expanding,
-				two_dim_layer_alignment_algorithm_test_.d_scores_counts);
-
-
-
-			};
-
-			
-
-		};
-		
-
-
-		//collect differences
-		if(two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag&&futher_expanding_)
-		{
-			//sum of weigths
-			sum_of_weights[0]+=tmp_w;
-			sum_of_weights[sn]+=tmp_w;
-			sum_of_weights_error[0]+=tmp_w2;
-			sum_of_weights_error[sn]+=tmp_w2;
-
-			long int &M=two_dim_layer_alignment_algorithm_test_.d_M;
-			long int ii;
-			
-			for(ii=FSA_utils::Tmax(M_threshold,two_dim_layer_alignment_algorithm_test_.d_scores_counts.d_ind0);ii<=FSA_utils::Tmin(M,two_dim_layer_alignment_algorithm_test_.d_scores_counts.d_dim_plus_d_ind0);ii++)
-			{
-				long int diff_tmp=(M-ii);
-				double diff_tmp_weight=two_dim_layer_alignment_algorithm_test_.d_scores_counts.get_elem(ii)*tmp_w;
-				double diff_tmp_weight2=diff_tmp_weight*diff_tmp_weight;
-
-				diff[0].increase_elem_by_x(diff_tmp,diff_tmp_weight);
-				diff[sn].increase_elem_by_x(diff_tmp,diff_tmp_weight);
-
-				diff_errors[0].increase_elem_by_x(diff_tmp,diff_tmp_weight2);
-				diff_errors[sn].increase_elem_by_x(diff_tmp,diff_tmp_weight2);
-			};
-
-		};
-
-
-	
-		if(ending_time_>=0)
-		{
-			if(stop_loop_flag)
-			{
-				//the loop is stopped due to time limitations
-				number_of_realizations_with_ending_time_=k+1;
-				if(number_of_realizations_with_ending_time_%number_of_realizations_set==0)
-				{
-					number_of_sets_=sn;
-				}
-				else
-				{
-					number_of_sets_=sn-1;
-				};
-
-				number_of_realizations_=number_of_realizations_with_ending_time_;
-
-				break;
-			};
-		};
-	};
-
-
-	
-	
-	//cout<<"Number of real when not all ALP are sampled\t"<<not_all_ALP_are_sampled<<"\t"<<number_of_realizations_<<endl;
-
-	delete IS1_general_simulation_M_thr;
-	delete two_dim_layer_alignment_algorithm_test_M_thr;
-
-	if(stop_loop_flag)
-	{
-		//the loop is stopped due to time limitations
-		//number of realizations and number of subsets is different
-		if(save_states_flag_)
-		{
-			mult_states_type *states_new_loop=new mult_states_type;
-			*states_new_loop=*states_new_;
-
-			states_new_loop->d_number_of_realizations=number_of_realizations_with_ending_time_;
-
-			if(states_old_)
-			{
-				states_new_loop->d_number_of_realizations=
-					FSA_utils::Tmax(number_of_realizations_with_ending_time_,states_old_->d_number_of_realizations);
-			};
-
-			states_new_loop->d_states=new state_type[states_new_loop->d_number_of_realizations];
-			long int ii;
-			for(ii=0;ii<states_new_loop->d_number_of_realizations;ii++)
-			{
-
-
-				states_new_loop->d_states[ii].d_ALP_number=states_new_->d_states[ii].d_ALP_number;
-				states_new_loop->d_states[ii].d_ALP_weights_array=states_new_->d_states[ii].d_ALP_weights_array;
-				states_new_loop->d_states[ii].d_M_array=states_new_->d_states[ii].d_M_array;
-				states_new_loop->d_states[ii].d_seq1_length_array=states_new_->d_states[ii].d_seq1_length_array;
-				states_new_loop->d_states[ii].d_seq2_length_array=states_new_->d_states[ii].d_seq2_length_array;
-				states_new_loop->d_states[ii].d_distance_along_direction_1_array=states_new_->d_states[ii].d_distance_along_direction_1_array;
-				states_new_loop->d_states[ii].d_distance_along_direction_2_array=states_new_->d_states[ii].d_distance_along_direction_2_array;
-
-				states_new_loop->d_states[ii].d_IS1_general_simulation=
-					states_new_->d_states[ii].d_IS1_general_simulation;
-				states_new_loop->d_states[ii].d_two_dim_layer_alignment_algorithm=
-					states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm;
-
-				states_new_loop->d_states[ii].d_expanding_finished_flag=
-					states_new_->d_states[ii].d_expanding_finished_flag;
-				if(states_new_->d_states[ii].d_expanding_finished_flag)
-				{
-					states_new_loop->d_states[ii].d_M_after_expanding=
-						states_new_->d_states[ii].d_M_after_expanding;
-					states_new_loop->d_states[ii].d_seq1_length_after_expanding=
-						states_new_->d_states[ii].d_seq1_length_after_expanding;
-					states_new_loop->d_states[ii].d_seq2_length_after_expanding=
-						states_new_->d_states[ii].d_seq2_length_after_expanding;
-
-					array_v<double>::copy_x2_into_x1(
-					states_new_loop->d_states[ii].d_scores_counts_after_expanding,
-						states_new_->d_states[ii].d_scores_counts_after_expanding);
-				};
-			};
-
-
-
-
-			if(states_old_)
-			{
-				for(ii=number_of_realizations_with_ending_time_;ii<FSA_utils::Tmin(states_old_->d_number_of_realizations,number_of_realizations_before_loop);ii++)
-				{
-
-
-					states_new_loop->d_states[ii].d_IS1_general_simulation=
-					new IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
-					states_old_->d_states[ii].d_IS1_general_simulation);//maximum sequence length
-
-					states_new_loop->d_states[ii].d_two_dim_layer_alignment_algorithm=
-					new two_dim_layer_alignment_algorithm<long int>(
-					//states_old_->d_states[ii].d_seq1_length[states_old_->d_states[ii].d_ALP_number],//target length of the sequence #1
-					states_old_->d_states[ii].d_seq1_length_array->get_elem(states_old_->d_states[ii].d_ALP_number),//target length of the sequence #1
-					//states_old_->d_states[ii].d_seq2_length[states_old_->d_states[ii].d_ALP_number],//target length of the sequence #2
-					states_old_->d_states[ii].d_seq2_length_array->get_elem(states_old_->d_states[ii].d_ALP_number),//target length of the sequence #2
-					states_old_->d_states[ii].d_two_dim_layer_alignment_algorithm);
-
-
-					states_new_loop->d_states[ii].d_ALP_number=states_old_->d_states[ii].d_ALP_number;
-
-					states_new_loop->d_states[ii].d_expanding_finished_flag=
-						states_old_->d_states[ii].d_expanding_finished_flag;
-
-					if(states_old_->d_states[ii].d_expanding_finished_flag)
-					{
-						states_new_loop->d_states[ii].d_M_after_expanding=
-							states_old_->d_states[ii].d_M_after_expanding;
-						states_new_loop->d_states[ii].d_seq1_length_after_expanding=
-							states_old_->d_states[ii].d_seq1_length_after_expanding;
-						states_new_loop->d_states[ii].d_seq2_length_after_expanding=
-							states_old_->d_states[ii].d_seq2_length_after_expanding;
-
-						array_v<double>::copy_x2_into_x1(
-						states_new_loop->d_states[ii].d_scores_counts_after_expanding,
-							states_old_->d_states[ii].d_scores_counts_after_expanding);
-					};
-
-				};
-			};
-
-
-			for(ii=states_new_loop->d_number_of_realizations;ii<states_new_->d_number_of_realizations;ii++)
-			{
-				delete states_new_->d_states[ii].d_ALP_weights_array;
-				delete states_new_->d_states[ii].d_M_array;
-				delete states_new_->d_states[ii].d_seq1_length_array;
-				delete states_new_->d_states[ii].d_seq2_length_array;
-				delete states_new_->d_states[ii].d_distance_along_direction_1_array;
-				delete states_new_->d_states[ii].d_distance_along_direction_2_array;
-
-				delete states_new_->d_states[ii].d_IS1_general_simulation;
-				delete states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm;
-			};
-
-			delete []states_new_->d_states;
-			delete states_new_;
-			states_new_=states_new_loop;
-		};
-	};
-
-
-	
-	double time2;
-	if(save_states_flag_)
-	{
-		FSA_utils::get_current_time(time2);
-		double total_time_tmp=time2-time1;
-		if(states_old_&&!futher_expanding_)
-		{
-			total_time_tmp+=states_old_->d_total_calculation_time;
-		};
-		states_new_->d_total_calculation_time=total_time_tmp;
-		states_new_->d_number_of_ALP=target_ALP_;
-
-		states_new_->d_average_ALP_pos1/=(double)(states_new_->d_number_of_realizations);
-		states_new_->d_average_ALP_pos2/=(double)(states_new_->d_number_of_realizations);
-		states_new_->d_average_ALP_pos1_mult_ALP_pos2/=(double)(states_new_->d_number_of_realizations);
-
-		states_new_->d_average_expanding_length1/=(double)(states_new_->d_number_of_realizations);
-		states_new_->d_average_expanding_length2/=(double)(states_new_->d_number_of_realizations);
-		states_new_->d_average_expanding_length1_mult_expanding_length2/=(double)(states_new_->d_number_of_realizations);
-
-	};
-
-	//calculation of parameters
-	for(k1=0;k1<=number_of_sets_;k1++)
-	{
-		long int number_of_realizations_tmp=number_of_realizations_set;
-		if(k1==0)
-		{
-			number_of_realizations_tmp=number_of_realizations_;
-		};
-
-		for(k=0;k<=target_ALP_;k++)
-		{
-			long int j;
-			for(j=distrE[k1][k]->d_ind0;j<=score_max[k1][k];j++)
-			{
-				distrE[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
-				distrE_errors[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
-				distrE_errors[k1][k]->increase_elem_by_x(j,-distrE[k1][k]->get_elem(j)*distrE[k1][k]->get_elem(j));
-				distrE_errors[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
-			};
-		};
-	};
-
-
-	//calculate M_thr_estimation_
-
-	{
-		double M_thr_estimation_tmp=0;
-		double sum_of_weigths_tmp=0;
-
-		long int j;
-		for(j=distrE[0][target_ALP_]->d_ind0;j<=score_max[0][target_ALP_];j++)
-		{
-			M_thr_estimation_tmp+=distrE[0][target_ALP_]->get_elem(j)*j;
-			sum_of_weigths_tmp+=distrE[0][target_ALP_]->get_elem(j);
-		};
-
-		if(sum_of_weigths_tmp>=0)
-		{
-			M_thr_estimation_tmp/=sum_of_weigths_tmp;
-			M_thr_estimation_=(long int)FSA_utils::round(M_thr_estimation_tmp);
-		}
-		else
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-	};
-
-	if(compute_allocated_memory_flag_)
-	{
-		double states_static_size=(sizeof(IS1_general_simulation)+sizeof(array_positive<double>)+5*sizeof(array_positive<long int>));
-		allocated_memory_+=states_new_->d_number_of_realizations*states_static_size;
-
-		double double_dim=0;
-		double long_dim=0;
-		long int ii;
-		for(ii=0;ii<states_new_->d_number_of_realizations;ii++)
-		{
-			double_dim+=states_new_->d_states[ii].d_ALP_weights_array->d_dim;
-			long_dim+=states_new_->d_states[ii].d_M_array->d_dim;
-			long_dim+=states_new_->d_states[ii].d_seq1_length_array->d_dim;
-			long_dim+=states_new_->d_states[ii].d_seq2_length_array->d_dim;
-			long_dim+=states_new_->d_states[ii].d_distance_along_direction_1_array->d_dim;
-			long_dim+=states_new_->d_states[ii].d_distance_along_direction_2_array->d_dim;
-
-
-			long int n_states=states_new_->d_states[ii].d_IS1_general_simulation->d_IS1_general_obj->d_number_of_states;
-			allocated_memory_+=sizeof(two_dim_layer<double>)*(double)n_states;
-			for(k=0;k<n_states;k++)
-			{
-				two_dim_layer<double> *&tmp1=states_new_->d_states[ii].d_IS1_general_simulation->d_W1[k];
-
-				double_dim+=
-				tmp1->d_layers_number1 *
-					tmp1->d_max_ind2+
-				tmp1->d_layers_number2 *
-					tmp1->d_max_ind1;
-
-			};
-
-			long_dim+=states_new_->d_states[ii].d_IS1_general_simulation->d_max_seq1_length+
-				states_new_->d_states[ii].d_IS1_general_simulation->d_max_seq2_length;
-
-			long int var_n=states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm->d_number_of_variables;
-			allocated_memory_+=sizeof(two_dim_layer<long int>)*(double)var_n;
-
-			for(k=0;k<var_n;k++)
-			{
-				two_dim_layer<long int> *&tmp1=states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm->d_vars[k];
-				
-					long_dim+=
-					tmp1->d_layers_number1 *
-						tmp1->d_max_ind2+
-					tmp1->d_layers_number2 *
-						tmp1->d_max_ind1;
-			};
-		};
-
-
-		allocated_memory_+=double_dim*sizeof(double);
-		allocated_memory_+=long_dim*sizeof(long);
-
-		if(states_new_->d_number_of_realizations>0)
-		{
-			allocated_memory_/=(double)states_new_->d_number_of_realizations;
-		};
-
-
-	};
-
-	if(parameters_are_not_calculated_)
-	{
-		if(score_max)
-		{
-			for(k1=0;k1<=number_of_sets_;k1++)
-			{
-				delete[]score_max[k1];
-			};
-			delete []score_max;
-		};
-
-		if(distrE)
-		{
-			for(k1=0;k1<=number_of_sets_;k1++)
-			{
-				for(k=0;k<=target_ALP_;k++)
-				{
-					delete distrE[k1][k];
-				};
-				delete []distrE[k1];
-			};
-			delete []distrE;
-			distrE=NULL;
-		};
-
-		if(distrE_errors)
-		{
-			for(k1=0;k1<=number_of_sets_;k1++)
-			{
-				for(k=0;k<=target_ALP_;k++)
-				{
-					delete distrE_errors[k1][k];
-				};
-				delete []distrE_errors[k1];
-			};
-			delete []distrE_errors;
-			distrE_errors=NULL;
-		};
-
-		delete[]diff;
-		delete[]diff_errors;
-
-		delete[]distance_along_direction_1;
-		delete[]distance_along_direction_2;
-
-		delete[]ALP_weight;
-		delete[]ALP_edge_max;
-
-		delete[]sum_of_weights;
-		delete[]sum_of_weights_error;
-
-		return;
-	};
-
-
-	
-
-	par_.realizations_number=number_of_realizations_;
-
-	double *lambda_out_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(lambda_out_vect);
-
-	double *lambda_out_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(lambda_out_error_vect);
-
-
-	double *C_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(C_vect);
-
-	double *C_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(C_error_vect);
-
-
-
-	{
-
-		long int nalp=target_ALP_;
-
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-			bool check_the_criteria=false;
-			long int nalp_thr;
-			bool inside_simulation_flag;
-			void **alp_distr=(void**)distrE[k1];
-			void **alp_distr_errors=(void**)distrE_errors[k1];
-			double ungapped_lambda=ungapped_lambda_;
-			double lambda;
-			double lambda_error;
-
-			fsa_par::calculate_lambda(
-			check_the_criteria,
-			nalp,
-			nalp_thr,
-			inside_simulation_flag,
-			alp_distr,
-			alp_distr_errors,
-			ungapped_lambda,
-			lambda,
-			lambda_error);
-
-
-			if(inside_simulation_flag)
-			{
-				lambda_out_vect[k1]=lambda;
-				lambda_out_error_vect[k1]=lambda_error;
-
-				if(k1==0)
-				{
-					struct_for_lambda_calculation tmp_struct;
-					tmp_struct.d_alp_distr=alp_distr;
-					tmp_struct.d_alp_distr_errors=alp_distr_errors;
-					tmp_struct.d_nalp=nalp;
-					tmp_struct.d_calculate_alp_number=false;
-
-					void * data_tmp=(void*)(&tmp_struct);
-					fsa_par::function_for_lambda_calculation(
-					lambda,
-					data_tmp);
-
-					double error2=FSA_utils::Tmax(fabs(tmp_struct.d_last_sum-tmp_struct.d_before_last_sum),fabs(tmp_struct.d_last_sum_error));
-					double fabs_tmp=fabs(FSA_utils::Tmin(tmp_struct.d_last_sum,tmp_struct.d_before_last_sum));
-
-
-					if(fabs_tmp<=0)
-					{
-						throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-					};
-
-					error2/=fabs_tmp;
-
-					par_.lambda_last_ALP_relative_error=error2;
-
-				};
-			}
-			else
-			{
-				inside_simulation_flag_=false;
-				lambda_out_vect[k1]=-1;
-				lambda_out_error_vect[k1]=-1;
-			};
-		};
-
-		
-		lambda_out_=lambda_out_vect[0];
-		lambda_out_error_=lambda_out_error_vect[0];
-
-		if(screen_output_flag_)
-		{
-			//cout<<endl;
-			cout<<"Parameter\tvalue\terror\n";
-		};
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"Lambda\t"<<lambda_out_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			lambda_out_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			lambda_out_vect+1);
-
-			if(average_set_results_flag)
-			{
-				lambda_out_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				lambda_out_vect+1);
-
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<lambda_out_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<lambda_out_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_LambdaSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_LambdaSbs.push_back(lambda_out_vect[k1]);
-		};
-
-
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-
-			void **alp_distr=(void**)distrE[k1];
-			void **alp_distr_errors=(void**)distrE_errors[k1];
-
-			long int starting_point=0;
-
-			bool inside_simulation_flag;
-
-			fsa_par::calculate_C(
-			starting_point,
-			nalp,
-			alp_distr,
-			alp_distr_errors,
-			lambda_out_vect[k1],
-			lambda_out_error_vect[k1],
-			C_vect[k1],
-			C_error_vect[k1],
-			inside_simulation_flag);
-
-
-			if(!inside_simulation_flag)
-			{
-				inside_simulation_flag_=false;
-				C_vect[k1]=-1;
-				C_error_vect[k1]=-1;
-			};
-		};
-
-		C_=C_vect[0];
-		C_error_=C_error_vect[0];
-
-		if(screen_output_flag_)
-		{
-			cout<<"C\t"<<C_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			C_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			C_vect+1);
-
-			if(average_set_results_flag)
-			{
-				C_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				C_vect+1);
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<C_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<C_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_CSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_CSbs.push_back(C_vect[k1]);
-		};
-
-	};
-
-
-
-	for(k=0;k<=target_ALP_;k++)
-	{
-
-		if(output_flag)
-		{
-			long int s;
-
-			double sum_tmp=0;
-			double sum_tmp_error=0;
-
-			fE<<k<<endl;
-			fE<<score_max[0][k]+1<<endl;
-
-			for(s=0;s<=score_max[0][k];s++)
-			{
-				fE<<s<<"\t"<<distrE[0][k]->d_elem[s-distrE[0][k]->d_ind0]<<"\t"<<FSA_utils::sqrt_plus(distrE_errors[0][k]->d_elem[s-distrE_errors[0][k]->d_ind0])<<endl;
-				sum_tmp+=distrE[0][k]->d_elem[s-distrE[0][k]->d_ind0]*exp((double)s*ungapped_lambda_);
-				sum_tmp_error+=FSA_utils::sqrt_plus(distrE_errors[0][k]->d_elem[s-distrE_errors[0][k]->d_ind0])*exp((double)s*ungapped_lambda_);
-			};
-			fE<<endl;
-
-			fE_summary<<k<<"\t"<<sum_tmp<<"\t"<<sum_tmp_error<<endl;
-		};
-	};
-
-
-	double *K_C_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(K_C_vect);
-
-	double *K_C_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(K_C_error_vect);
-
-
-	//calculation of the ratio K/C
-	if(two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag&&futher_expanding_)
-	{
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-			long int number_of_realizations_tmp=number_of_realizations_set;
-			if(k1==0)
-			{
-				number_of_realizations_tmp=number_of_realizations_;
-			};
-
-			long int ii;
-			for(ii=0;ii<=diff[k1].d_dim;ii++)
-			{
-				diff[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
-				diff_errors[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
-				diff_errors[k1].increase_elem_by_x(ii,-diff[k1].get_elem(ii)*diff[k1].get_elem(ii));
-				diff_errors[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
-				double tmp=FSA_utils::sqrt_plus(diff_errors[k1].get_elem(ii));
-				diff_errors[k1].set_elem(ii,tmp);
-			};
-
-			
-
-			sum_of_weights[k1]/=(double)number_of_realizations_tmp;
-			sum_of_weights_error[k1]/=(double)number_of_realizations_tmp;
-			sum_of_weights_error[k1]-=sum_of_weights[k1]*sum_of_weights[k1];
-			sum_of_weights_error[k1]/=(double)number_of_realizations_tmp;
-			sum_of_weights_error[k1]=FSA_utils::sqrt_plus(sum_of_weights_error[k1]);
-			
-
-			double den=0;
-			double den_error=0;
-			for(ii=0;ii<=diff[k1].d_dim;ii++)
-			{
-				double tmp=exp(-lambda_out_vect[k1]*(double)ii);
-				den+=tmp*diff[k1].get_elem(ii);
-				den_error+=tmp*tmp*diff_errors[k1].get_elem(ii)*diff_errors[k1].get_elem(ii);
-
-			};
-
-
-			den_error=FSA_utils::sqrt_plus(den_error);
-
-			if(den!=0)
-			{
-				K_C_vect[k1]=sum_of_weights[k1]/den;
-				K_C_error_vect[k1]=FSA_utils::error_of_the_ratio(sum_of_weights[k1],sum_of_weights_error[k1],den,den_error);
-			}
-			else
-			{
-				inside_simulation_flag_=false;
-				K_C_vect[k1]=-1;
-				K_C_error_vect[k1]=-1;
-			};
-
-		};
-
-		K_C_=K_C_vect[0];
-		K_C_error_=K_C_error_vect[0];
-
-
-		if(output_flag)
-		{
-			fE<<endl;
-			fE<<"K/C distributions\n";
-			fE<<diff[0].d_dim+1<<endl;
-			long int ii;
-			for(ii=0;ii<=diff[0].d_dim;ii++)
-			{
-				//double tmp=exp(-lambda_out_*(double)ii);
-				fE<<ii<<"\t"<<diff[0].get_elem(ii)/sum_of_weights[0]<<"\t"<<diff_errors[0].get_elem(ii)/sum_of_weights[0]<<endl;
-			};
-
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<"K/C\t"<<K_C_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			K_C_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			K_C_vect+1);
-
-			if(average_set_results_flag)
-			{
-				K_C_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				K_C_vect+1);
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<K_C_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<K_C_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_K_CSbs.clear();
-		par_.m_KSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_K_CSbs.push_back(K_C_vect[k1]);
-			par_.m_KSbs.push_back(K_C_vect[k1]*C_vect[k1]);
-		};
-
-
-
-
-	};
-
-
-	double *a_I_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(a_I_vect);
-	double *a_I_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(a_I_error_vect);
-	double *a_J_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(a_J_vect);
-	double *a_J_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(a_J_error_vect);
-	double *sigma_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(sigma_vect);
-	double *sigma_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(sigma_error_vect);
-	double *alpha_I_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(alpha_I_vect);
-	double *alpha_I_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(alpha_I_error_vect);
-	double *alpha_J_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(alpha_J_vect);
-	double *alpha_J_error_vect=new double[number_of_sets_+1];
-	FSA_utils::assert_mem(alpha_J_error_vect);
-
-
-	//FSC
-	{
-		long int k1;
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-
-			pair<long int,long int> boundaries;
-			if(k1==0)
-			{
-				boundaries.first=0;
-				boundaries.second=number_of_realizations_-1;
-			}
-			else
-			{
-				boundaries=set_number_boundaries(//boundaries of realization order numbers for the set; numeration of realizations starts from 0
-				k1,//set order number; the numeration starts from 1
-				number_of_realizations_set);//total number of sets
-			};
-
-			
-			bool test_FSC_flag=false;
-			double *test_FSC_vect=NULL;
-			if(test_FSC_flag)
-			{
-				test_FSC_vect=new double[target_ALP_+1];
-			};
-
-			bool inside_simulation_flag;
-
-			fsa_par::calculate_FSC(
-			target_ALP_,
-			boundaries.first,
-			boundaries.second,
-			
-
-			lambda_out_vect[k1],
-
-			M_max,
-
-			distance_along_direction_1,
-			distance_along_direction_2,
-
-			ALP_weight,
-			ALP_edge_max,
-
-			a_I_vect[k1],
-			a_I_error_vect[k1],
-			a_J_vect[k1],
-			a_J_error_vect[k1],
-			sigma_vect[k1],
-			sigma_error_vect[k1],
-			alpha_I_vect[k1],
-			alpha_I_error_vect[k1],
-			alpha_J_vect[k1],
-			alpha_J_error_vect[k1],
-			inside_simulation_flag,
-			test_FSC_vect);
-
-
-			if(test_FSC_flag)
-			{
-
-				string E_distr_file_name_summary=E_distr_file_name_+"_summary_II";
-				fE_summary.open(E_distr_file_name_summary.data());
-				if(!fE_summary)
-				{
-					throw error("Error - the file "+E_distr_file_name_summary+" is not found\n",3);
-				};
-
-				fE_summary<<target_ALP_<<endl;
-				long int j;
-				for(j=0;j<=target_ALP_;j++)
-				{
-					fE_summary<<j<<"\t"<<test_FSC_vect[j]<<"\t0.0\n";
-				};
-
-
-				fE_summary.close();
-				exit(1);
-			};
-
-			if(!inside_simulation_flag)
-			{
-				a_I_vect[k1]=-1;
-				a_I_error_vect[k1]=-1;
-				a_J_vect[k1]=-1;
-				a_J_error_vect[k1]=-1;
-				sigma_vect[k1]=-1;
-				sigma_error_vect[k1]=-1;
-				alpha_I_vect[k1]=-1;
-				alpha_I_error_vect[k1]=-1;
-				alpha_J_vect[k1]=-1;
-				alpha_J_error_vect[k1]=-1;
-
-				inside_simulation_flag_=false;
-			};
-		};
-
-		a_I_=a_I_vect[0];
-		a_I_error_=a_I_error_vect[0];
-		a_J_=a_J_vect[0];
-		a_J_error_=a_J_error_vect[0];
-		sigma_=sigma_vect[0];
-		sigma_error_=sigma_error_vect[0];
-		alpha_I_=alpha_I_vect[0];
-		alpha_I_error_=alpha_I_error_vect[0];
-		alpha_J_=alpha_J_vect[0];
-		alpha_J_error_=alpha_J_error_vect[0];
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"a_I\t"<<a_I_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			a_I_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			a_I_vect+1);
-
-			if(average_set_results_flag)
-			{
-				a_I_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				a_I_vect+1);
-
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<a_I_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<a_I_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_AISbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_AISbs.push_back(a_I_vect[k1]);
-		};
-
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"a_J\t"<<a_J_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			a_J_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			a_J_vect+1);
-
-			if(average_set_results_flag)
-			{
-				a_J_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				a_J_vect+1);
-
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<a_J_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<a_J_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_AJSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_AJSbs.push_back(a_J_vect[k1]);
-		};
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"sigma\t"<<sigma_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			sigma_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			sigma_vect+1);
-
-			if(average_set_results_flag)
-			{
-				sigma_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				sigma_vect+1);
-
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<sigma_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<sigma_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_SigmaSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_SigmaSbs.push_back(sigma_vect[k1]);
-		};
-
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"alpha_I\t"<<alpha_I_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			alpha_I_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			alpha_I_vect+1);
-
-			if(average_set_results_flag)
-			{
-				alpha_I_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				alpha_I_vect+1);
-
-				if(screen_output_flag_)
-				{
-					cout<<"\t"<<alpha_I_;
-				};
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<alpha_I_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_AlphaISbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_AlphaISbs.push_back(alpha_I_vect[k1]);
-		};
-
-
-		if(screen_output_flag_)
-		{
-			cout<<"alpha_J\t"<<alpha_J_;
-		};
-
-		if(number_of_sets_>1)
-		{
-			alpha_J_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-			number_of_sets_,
-			alpha_J_vect+1);
-
-			if(average_set_results_flag)
-			{
-				alpha_J_=FSA_utils::average(//average of elements of vect_
-				number_of_sets_,
-				alpha_J_vect+1);
-
-				cout<<"\t"<<alpha_J_;
-			};
-
-			if(screen_output_flag_)
-			{
-				cout<<"\t"<<alpha_J_error_;
-			};
-		};
-
-		if(screen_output_flag_)
-		{
-			cout<<endl;
-		};
-
-		par_.m_AlphaJSbs.clear();
-		for(k1=1;k1<=number_of_sets_;k1++)
-		{
-			par_.m_AlphaJSbs.push_back(alpha_J_vect[k1]);
-		};
-
-	};
-
-
-
-	if(output_flag)
-	{
-		fE.close();
-		fE_summary.close();
-	};
-
-
-	if(score_max)
-	{
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-			delete[]score_max[k1];
-		};
-		delete []score_max;
-	};
-
-	if(distrE)
-	{
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-			for(k=0;k<=target_ALP_;k++)
-			{
-				delete distrE[k1][k];
-			};
-			delete []distrE[k1];
-		};
-		delete []distrE;
-		distrE=NULL;
-	};
-
-	if(distrE_errors)
-	{
-		for(k1=0;k1<=number_of_sets_;k1++)
-		{
-			for(k=0;k<=target_ALP_;k++)
-			{
-				delete distrE_errors[k1][k];
-			};
-			delete []distrE_errors[k1];
-		};
-		delete []distrE_errors;
-		distrE_errors=NULL;
-	};
-	
-
-
-	delete[]distance_along_direction_1;
-	delete[]distance_along_direction_2;
-	delete[]ALP_weight;
-	delete[]ALP_edge_max;
-
-	delete[]diff;
-	delete[]diff_errors;
-
-	delete[]sum_of_weights;
-	delete[]sum_of_weights_error;
-
-
-
-	delete[]lambda_out_vect;
-	delete[]lambda_out_error_vect;
-	delete[]C_vect;
-	delete[]C_error_vect;
-	delete[]K_C_vect;
-	delete[]K_C_error_vect;
-	delete[]a_I_vect;
-	delete[]a_I_error_vect;
-	delete[]a_J_vect;
-	delete[]a_J_error_vect;
-	delete[]sigma_vect;
-	delete[]sigma_error_vect;
-	delete[]alpha_I_vect;
-	delete[]alpha_I_error_vect;
-	delete[]alpha_J_vect;
-	delete[]alpha_J_error_vect;
-
-	//end4
-
-}
-
-//tests
-void test::classical_IS(
-
-unsigned rand_,//randomization number
-long int open1_,//gap opening penalty for the nucleotide sequence #1
-long int open2_,//gap opening penalty for the amino acid sequence #2
-
-long int epen1_,//gap extension penalty for the nucleotide sequence #1
-long int epen2_,//gap extension penalty for the amino acid sequence #2
-
-
-string smatr_file_name_,//scoring matrix file name
-string RR1_file_name_,//background frequencies file name for the sequence #1
-string RR2_file_name_)//background frequencies file name for the sequence #2
-
-//long int seq1_length_,//length of sequence #1
-//long int seq2_length_,//length of sequence #2
-
-//long int seq_number_)//number of tested alignments
-{
-	FSA_utils::srand2(rand_);
-
-	long int alphabet_letters_number1;//number of letters in the sequence #1
-	long int alphabet_letters_number2;//number of letters in the sequence #2
-	double *RR1=NULL;//background probability for the sequence #1
-	double *RR2=NULL;//background probability for the sequence #2
-	long int number_of_states=3;//number of states
-	double **transition_probabilities=NULL;//transition probabilities between states; matrix d_number_of_states x d_number_of_states
-	pair<long int, long int> *states_description=NULL;//description of the states; the index is a state number
-	double ***states_distr=NULL;//distributions of the states; the index is a state number
-								//the second and the third indexes correspond to an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-
-	double *RR1_sum=NULL;
-	long int *RR1_sum_elements=NULL;
-	double *RR2_sum=NULL;
-	long int *RR2_sum_elements=NULL;
-
-	long int **smatr=NULL;
-
-	double ungapped_lambda;
-
-	d_IS1=NULL;
-	d_IS1_general_simulation=NULL;
-
-	long int *seq1=NULL;
-	long int *seq2=NULL;
-
-	{
-		long int number_of_AA_smatr;
-		long int smatr_min;
-
-		FSA_utils::read_smatr(
-		smatr_file_name_,
-		smatr,
-		number_of_AA_smatr,
-		smatr_min);
-
-		
-
-		FSA_utils::read_RR(
-		RR1_file_name_,
-		RR1,
-		RR1_sum,
-		RR1_sum_elements,
-		alphabet_letters_number1);
-
-
-		FSA_utils::read_RR(
-		RR2_file_name_,
-		RR2,
-		RR2_sum,
-		RR2_sum_elements,
-		alphabet_letters_number2);
-
-		if(number_of_AA_smatr!=alphabet_letters_number1||number_of_AA_smatr!=alphabet_letters_number2)
-		{
-			throw error("Error - different numbers of letters in the files "+smatr_file_name_+", "+RR1_file_name_+", "+RR2_file_name_+"\n",1);
-		};
-
-		calculate_ungapped_lambda(
-		alphabet_letters_number1,
-		RR1,
-		RR2,
-		smatr,
-		ungapped_lambda);
-
-	};
-
-	map<string, long int> state_name_into_number;
-
-	state_name_into_number["S"]=0;
-	state_name_into_number["D"]=1;
-	state_name_into_number["I"]=2;
-
-	map<long int,string> state_number_into_name;
-
-	state_number_into_name[0]="S";
-	state_number_into_name[1]="D";
-	state_number_into_name[2]="I";
-
-
-	FSA_utils::get_memory_for_matrix(number_of_states,number_of_states,transition_probabilities);
-
-	long int min_open=FSA_utils::Tmin(open1_,open2_);
-	long int min_epen=FSA_utils::Tmin(epen1_,epen2_);
-
-	double mu=exp(-ungapped_lambda*(min_open+min_epen));
-	double v=exp(-ungapped_lambda*min_epen);
-
-
-
-	transition_probabilities[state_name_into_number["S"]][state_name_into_number["S"]]=
-		((1-v)*(1-v))/((1+mu-v)*(1+mu-v));
-
-	transition_probabilities[state_name_into_number["S"]][state_name_into_number["D"]]=
-		mu/(1+mu-v);
-
-	transition_probabilities[state_name_into_number["S"]][state_name_into_number["I"]]=
-		(mu*(1-v))/((1+mu-v)*(1+mu-v));
-
-
-
-
-	transition_probabilities[state_name_into_number["D"]][state_name_into_number["S"]]=
-		((1-v)*(1-v))/(1+mu-v);
-
-	transition_probabilities[state_name_into_number["D"]][state_name_into_number["D"]]=
-		v;
-
-	transition_probabilities[state_name_into_number["D"]][state_name_into_number["I"]]=
-		(mu*(1-v))/(1+mu-v);
-
-
-
-
-	transition_probabilities[state_name_into_number["I"]][state_name_into_number["S"]]=
-		1-v;
-
-	transition_probabilities[state_name_into_number["I"]][state_name_into_number["D"]]=
-		0;
-
-	transition_probabilities[state_name_into_number["I"]][state_name_into_number["I"]]=
-		v;
-
-	//FSA_utils::print_matrix("mtp.out",3,3,transition_probabilities);
-
-//--------------------
-	states_description=new pair<long int, long int>[number_of_states];
-	FSA_utils::assert_mem(states_description);
-
-	states_description[state_name_into_number["S"]]=make_pair(1,1);
-	states_description[state_name_into_number["D"]]=make_pair(1,0);
-	states_description[state_name_into_number["I"]]=make_pair(0,1);
-
-//--------------------
-
-	states_distr=new double **[number_of_states];
-
-	long int s;
-	for(s=0;s<number_of_states;s++)
-	{
-		states_distr[s]=IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-			alphabet_letters_number1,//number of letters in the sequence #1
-			alphabet_letters_number2,//number of letters in the sequence #2
-			states_description[s]);//state description
-
-	};
-
-	double tmp_sum=0;
-	long int i,j;
-	for(i=0;i<alphabet_letters_number1;i++)
-	{
-		for(j=0;j<alphabet_letters_number2;j++)
-		{
-			states_distr[state_name_into_number["S"]][i][j]=RR1[i]*RR2[j]*exp(ungapped_lambda*smatr[i][j]);
-			tmp_sum+=states_distr[state_name_into_number["S"]][i][j];
-		};
-	};
-
-	//cout<<"Total sum of joint distribution of (S_A,S_B) is "<<tmp_sum<<endl;
-
-	for(i=0;i<alphabet_letters_number1;i++)
-	{
-		states_distr[state_name_into_number["D"]][i][0]=RR1[i];
-	};
-
-	for(j=0;j<alphabet_letters_number2;j++)
-	{
-		states_distr[state_name_into_number["I"]][0][j]=RR2[j];
-	};
-	
-
-
-	d_IS1=new IS1_general(
-	alphabet_letters_number1,//number of letters in the sequence #1
-	alphabet_letters_number2,//number of letters in the sequence #2
-	RR1,//background probability for the sequence #1
-	RR2,//background probability for the sequence #2
-	number_of_states,//number of states
-	transition_probabilities,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
-	states_description,//description of the states; the index is a state number
-	states_distr);//distributions of the states; the index is a state number
-
-//-----------------------------------
-//crude sampling object
-
-	long int number_of_states_cs=1;
-	double **transition_probabilities_cs=NULL;//transition probabilities between states; matrix d_number_of_states x d_number_of_states
-	pair<long int, long int> *states_description_cs=NULL;//description of the states; the index is a state number
-	double ***states_distr_cs=NULL;//distributions of the states; the index is a state number
-
-	FSA_utils::get_memory_for_matrix(number_of_states_cs,number_of_states_cs,transition_probabilities_cs);
-	transition_probabilities_cs[state_name_into_number["S"]][state_name_into_number["S"]]=1;
-
-	states_description_cs=new pair<long int, long int>[number_of_states_cs];
-	FSA_utils::assert_mem(states_description_cs);
-
-	states_description_cs[state_name_into_number["S"]]=make_pair(1,1);
-
-
-	states_distr_cs=new double **[number_of_states_cs];
-
-	for(s=0;s<number_of_states_cs;s++)
-	{
-		states_distr_cs[s]=IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-			alphabet_letters_number1,//number of letters in the sequence #1
-			alphabet_letters_number2,//number of letters in the sequence #2
-			states_description_cs[s]);//state description
-
-	};
-
-
-	double tmp_sum_cs=0;
-	for(i=0;i<alphabet_letters_number1;i++)
-	{
-		for(j=0;j<alphabet_letters_number2;j++)
-		{
-			states_distr_cs[state_name_into_number["S"]][i][j]=RR1[i]*RR2[j];
-			tmp_sum_cs+=states_distr_cs[state_name_into_number["S"]][i][j];
-		};
-	};
-
-
-	IS1_general* IS1_cs=new IS1_general(
-	alphabet_letters_number1,//number of letters in the sequence #1
-	alphabet_letters_number2,//number of letters in the sequence #2
-	RR1,//background probability for the sequence #1
-	RR2,//background probability for the sequence #2
-	number_of_states_cs,//number of states
-	transition_probabilities_cs,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
-	states_description_cs,//description of the states; the index is a state number
-	states_distr_cs);//distributions of the states; the index is a state number
-
-
-//-----------------------------------------------------------
-//test for the layers object
-	{
-
-		long int max_ind1=100;//max of the index #1
-		long int max_ind2=200;//max of the index #2
-
-
-
-		long int layers_number1=6;//number of layers for the index #1
-		long int layers_number2=20;//number of layers for the index #2
-
-		two_dim_layer<long int> two_dim_layer_test(
-		max_ind1,//max of the index #1
-		max_ind2,//max of the index #2
-		layers_number1,//number of layers for the index #1
-		layers_number2,//number of layers for the index #2
-		0);
-
-	
-	};
-	//------------------------------------------------------
-	//test for the two_dim_layer_alignment_algorithm object
-	{
-		long int depth1=1;//the maximum difference of the first index in the dynamic equations
-		long int depth2=1;//the maximum difference of the second index in the dynamic equations
-
-		long int max_ind1=100;//max of the index #1
-		long int max_ind2=200;//max of the index #2
-
-		long int var_num_dim=1000;
-		long int *var_num=new long int[var_num_dim];
-		long int i;
-		for(i=0;i<var_num_dim;i++)
-		{
-			var_num[i]=-1;
-		};
-
-		var_num['S']=0;
-		var_num['D']=1;
-		var_num['I']=2;
-
-		data_for_classical_alignment data_test;
-
-		data_test.d_open1=open1_;
-		data_test.d_open2=open2_;
-
-		data_test.d_epen1=epen1_;
-		data_test.d_epen2=epen2_;
-
-		data_test.d_smatr=smatr;
-
-
-
-		long int initial_state=state_name_into_number["S"];
-
-		d_IS1_general_simulation=new IS1_general_simulation(
-		d_IS1,
-		initial_state,//initial state for the IS
-		max_ind1*5,//maximum sequence length
-		max_ind2*5);//maximum sequence length
-
-
-		data_test.d_seq1=d_IS1_general_simulation->d_seq1;//sequence #1
-		data_test.d_seq2=d_IS1_general_simulation->d_seq2;//sequence #2
-
-
-		
-
-
-
-		two_dim_layer_alignment_algorithm<long int> two_dim_layer_alignment_algorithm_test(
-		number_of_states,//total number of variables in dynamic equations
-		depth1,//the maximum difference of the first index in the dynamic equations
-		depth2,//the maximum difference of the second index in the dynamic equations
-		max_ind1,//max of the index #1 (minimum index is 0 by default)
-		max_ind2,//max of the index #2 (minimum index is 0 by default)
-		0,//null element of T
-		var_num);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
-
-		two_dim_layer_alignment_algorithm_test.d_two_dim_layer_alignment_function=test::two_dim_layer_alignment_function_classical_global;
-		two_dim_layer_alignment_algorithm_test.d_two_dim_layer_boundary_function=test::two_dim_layer_alignment_function_classical_global;
-		two_dim_layer_alignment_algorithm_test.d_par=&data_test;
-
-		long int target_seq1_length=100;
-		long int target_seq2_length=200;
-
-		d_IS1_general_simulation->simulate_upto_target_lengths(
-			target_seq1_length,
-			target_seq2_length);
-
-
-
-		two_dim_layer_alignment_algorithm_test.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-		//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-		target_seq1_length,//target length of the sequence #1
-		target_seq2_length);//target length of the sequence #2
-
-
-		delete[]var_num;
-	};
-
-
-
-	//test for the two_dim_layer_alignment_algorithm object
-	//crude sampling
-	{
-		long int number_of_realizations=100;
-
-		long int depth1=1;//the maximum difference of the first index in the dynamic equations
-		long int depth2=1;//the maximum difference of the second index in the dynamic equations
-
-		long int max_ind1=100;//max of the index #1
-		long int max_ind2=100;//max of the index #2
-
-		long int var_num_dim=1000;
-		long int *var_num=new long int[var_num_dim];
-		long int i;
-		for(i=0;i<var_num_dim;i++)
-		{
-			var_num[i]=-1;
-		};
-
-		var_num['S']=0;
-		var_num['D']=1;
-		var_num['I']=2;
-
-		data_for_classical_alignment data_test;
-
-		data_test.d_open1=open1_;
-		data_test.d_open2=open2_;
-
-		data_test.d_epen1=epen1_;
-		data_test.d_epen2=epen2_;
-
-		data_test.d_smatr=smatr;
-
-
-
-		long int initial_state=state_name_into_number["S"];
-
-		IS1_general_simulation *IS1_general_simulation_cs=new IS1_general_simulation(
-		IS1_cs,
-		initial_state,//initial state for the IS
-		max_ind1,//maximum sequence length
-		max_ind2);//maximum sequence length
-
-
-		data_test.d_seq1=IS1_general_simulation_cs->d_seq1;//sequence #1
-		data_test.d_seq2=IS1_general_simulation_cs->d_seq2;//sequence #2
-
-
-		
-
-
-
-		two_dim_layer_alignment_algorithm<long int> two_dim_layer_alignment_algorithm_test_cs(
-		number_of_states,//total number of variables in dynamic equations
-		depth1,//the maximum difference of the first index in the dynamic equations
-		depth2,//the maximum difference of the second index in the dynamic equations
-		max_ind1,//max of the index #1 (minimum index is 0 by default)
-		max_ind2,//max of the index #2 (minimum index is 0 by default)
-		0,//null element of T
-		var_num);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
-
-		two_dim_layer_alignment_algorithm_test_cs.d_two_dim_layer_alignment_function=test::two_dim_layer_alignment_function_classical_global;
-		two_dim_layer_alignment_algorithm_test_cs.d_two_dim_layer_boundary_function=test::two_dim_layer_alignment_function_classical_global;
-		two_dim_layer_alignment_algorithm_test_cs.d_par=&data_test;
-
-		two_dim_layer_alignment_algorithm_test_cs.d_M_flag=true;
-
-		long int target_seq1_length=max_ind1;
-		long int target_seq2_length=max_ind2;
-
-		ofstream fM;
-
-		array_v<double> *distrM=NULL;
-		long int score_max=-inf;
-
-		if(two_dim_layer_alignment_algorithm_test_cs.d_M_flag)
-		{
-			//distribution of M
-			string M_distr_file_name="distr_M_tmp.out";
-
-			fM.open(M_distr_file_name.data());
-			if(!fM)
-			{
-				throw error("Error - the file "+M_distr_file_name+" is not found\n",3);
-			};
-
-
-			distrM=new array_v<double>(NULL);
-
-			
-
-		};
-
-		//--------------------
-
-		long int k;
-		for(k=1;k<=number_of_realizations;k++)
-		{
-
-			IS1_general_simulation_cs->init();
-			IS1_general_simulation_cs->simulate_upto_target_lengths(
-			target_seq1_length,
-			target_seq2_length);
-
-			two_dim_layer_alignment_algorithm_test_cs.init();
-			two_dim_layer_alignment_algorithm_test_cs.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-			//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-			target_seq1_length,//target length of the sequence #1
-			target_seq2_length);//target length of the sequence #2
-
-			if(two_dim_layer_alignment_algorithm_test_cs.d_M_flag)
-			{
-				score_max=FSA_utils::Tmax(score_max,two_dim_layer_alignment_algorithm_test_cs.d_M);
-				distrM->increase_elem_by_1(two_dim_layer_alignment_algorithm_test_cs.d_M);
-			};
-
-			if(k%1000==0)
-			{
-				cout<<k<<endl;
-			};
-
-		};
-
-		if(two_dim_layer_alignment_algorithm_test_cs.d_M_flag)
-		{
-			long int s;
-
-			double sum_tmp=0;
-			for(s=0;s<=score_max;s++)
-			{
-				sum_tmp+=distrM->d_elem[s-distrM->d_ind0];
-			};
-
-			if(sum_tmp<=0)
-			{
-				throw error("Unexpected error - sum_tmp<=0\n",1);
-			};
-			
-
-			fM<<score_max+1<<endl;
-			for(s=0;s<=score_max;s++)
-			{
-				distrM->d_elem[s-distrM->d_ind0]/=sum_tmp;
-				fM<<s<<"\t"<<distrM->d_elem[s-distrM->d_ind0]<<endl;
-			};
-
-			fM.close();
-		};
-
-
-
-		delete[]var_num;
-		delete IS1_general_simulation_cs;
-		delete distrM;
-	};
-
-
-	delete[]RR1;
-	delete[]RR2;
-
-	delete[]RR1_sum;
-	delete[]RR2_sum;
-
-	delete[]RR1_sum_elements;
-	delete[]RR2_sum_elements;
-
-	FSA_utils::delete_memory_for_matrix(alphabet_letters_number1,smatr);
-	FSA_utils::delete_memory_for_matrix(number_of_states,transition_probabilities);
-	FSA_utils::delete_memory_for_matrix(number_of_states_cs,transition_probabilities_cs);
-
-	for(s=0;s<number_of_states;s++)
-	{
-		IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-			states_distr[s],
-			alphabet_letters_number1,//number of letters in the sequence #1
-			states_description[s]);//state description
-	};
-
-	for(s=0;s<number_of_states_cs;s++)
-	{
-		IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-			states_distr_cs[s],
-			alphabet_letters_number1,//number of letters in the sequence #1
-			states_description_cs[s]);//state description
-	};
-
-
-	delete[]states_description;
-
-	delete[]states_description_cs;
-	
-
-	delete[]seq1;
-	delete[]seq2;
-
-	delete d_IS1;
-
-	delete IS1_cs;
-
-	delete d_IS1_general_simulation;
-	
-}
-
-double test::lambda_equation(double x_,void* func_number_)
-{
-	data_for_lambda_equation *data=(data_for_lambda_equation*)func_number_;
-	long int d_number_of_AA=data->d_number_of_AA;
-	long int** d_smatr=data->d_smatr;
-	double *d_RR1=data->d_RR1;
-	double *d_RR2=data->d_RR2;
-
-	double res=0;
-	long int i,j;
-
-	for(i=0;i<d_number_of_AA;i++)
-	{
-		for(j=0;j<d_number_of_AA;j++)
-		{
-			res+=d_RR1[i]*d_RR2[j]*exp(x_*d_smatr[i][j]);
-		};
-	};
-
-	return res-1.0;
-}
-
-double test::lambda_equation_FSA(double x_,void* func_number_)
-{
-	data_for_lambda_equation_FSA *data=(data_for_lambda_equation_FSA*)func_number_;
-	long int number_of_letters1=data->d_number_of_letters1;
-	long int number_of_letters2=data->d_number_of_letters2;
-
-	long int** d_smatr=data->d_smatr;
-	double *d_RR1=data->d_RR1;
-	double *d_RR2=data->d_RR2;
-
-	long int codon_length=data->d_codon_length;//codon length 
-	long int *codon_AA=data->d_codon_AA;//<codon code,AA number>
-
-	long int *codon=new long int [codon_length];
-	FSA_utils::assert_mem(codon);
-
-	long int i,j;
-
-	long int code_n=1;
-	for(i=1;i<=codon_length;i++)
-	{
-		code_n*=number_of_letters1;
-	};
-
-	double res=0;
-	
-
-	for(i=0;i<code_n;i++)
-	{
-		FSA_utils::convert_code_into_codon(
-		i,//the input code
-		codon_length,//codon length 
-		number_of_letters1,//number of letters for the sequence 1
-		codon);//must be allocated
-
-		long int AA1=codon_AA[i];
-
-		double RR1_mult=1;
-		
-		for(j=0;j<codon_length;j++)
-		{
-			RR1_mult*=d_RR1[codon[j]];
-		};
-
-		for(j=0;j<number_of_letters2;j++)
-		{
-			res+=RR1_mult*d_RR2[j]*exp(x_*d_smatr[AA1][j]);
-		};
-	};
-
-	delete[]codon;
-	return res-1.0;
-}
-
-
-void test::calculate_ungapped_lambda(
-long int number_of_AA_,
-double *RR1_,
-double *RR2_,
-long int**smatr_,
-double &ungapped_lambda_)
-{
-	//calculation of the importance sampling theta
-
-	data_for_lambda_equation tmp_ptr;
-	tmp_ptr.d_number_of_AA=number_of_AA_;
-	tmp_ptr.d_RR1=RR1_;
-	tmp_ptr.d_RR2=RR2_;
-	tmp_ptr.d_smatr=smatr_;
-
-	//calculate maximum of smatr_ elements
-	long int smatr_max=smatr_[0][0];
-	long int smatr_max_i=0;
-	long int smatr_max_j=0;
-	long int smatr_min=smatr_[0][0];
-
-	long int smatr_pos_max=LONG_MIN;
-	long int smatr_neg_min=LONG_MAX;
-
-	double eps=0.0000001;
-	double threshold=DBL_MIN*10.0;
-
-	double aver_score=0;
-	long int i,j;
-	for(i=0;i<number_of_AA_;i++)
-	{
-		for(j=0;j<number_of_AA_;j++)
-		{
-			if(RR1_[i]*RR2_[j]<=threshold)
-			{
-				continue;
-			};
-								
-
-
-			aver_score+=RR1_[i]*RR2_[j]*smatr_[i][j];
-
-			if(smatr_max<smatr_[i][j])
-			{
-				smatr_max=smatr_[i][j];
-				smatr_max_i=i;
-				smatr_max_j=j;
-			};
-			smatr_min=FSA_utils::Tmin(smatr_min,smatr_[i][j]);
-			
-
-			if(smatr_[i][j]>0)
-			{
-				smatr_pos_max=FSA_utils::Tmax(smatr_pos_max,smatr_[i][j]);
-			};
-
-			if(smatr_[i][j]<0)
-			{
-				smatr_neg_min=FSA_utils::Tmin(smatr_neg_min,smatr_[i][j]);
-			};
-
-		};
-	};
-
-	if(aver_score>=-threshold)
-	{
-		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-	};
-
-	if(smatr_max<=0)
-	{
-		throw error("Error - at least one element of the scoring matrix must be positive\n",3);
-	};
-
-	
-
-	double a=eps;
-
-	while(test::lambda_equation(a,(void*)(&tmp_ptr))>0)
-	{
-		a/=2.0;
-
-		if(a<threshold*100.0)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-	};
-
-	if(a<threshold*100.0)
-	{
-		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-	};
-
-	eps=a/10.0;
-
-
-	double tmp_pr=RR1_[smatr_max_i]*RR2_[smatr_max_j];
-	double b=(log(1+10*eps)-log(tmp_pr))/(double)smatr_max;
-
-	
-	long int n_partition=2;
-	std::vector<double> res_lambda;
-	
-	
-	alp_reg::find_tetta_general(
-	test::lambda_equation,
-	(void*)(&tmp_ptr),
-	a,
-	b,
-	n_partition,
-	eps,
-	res_lambda);
-
-	sort(res_lambda.begin(),res_lambda.end());
-
-	if(res_lambda.size()==0)
-	{
-		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-	};
-
-	
-	ungapped_lambda_=res_lambda[res_lambda.size()-1];
-
-	cout<<"Ungapped lambda is "<<ungapped_lambda_<<endl;
-
-
-}
-
-void test::calculate_ungapped_lambda_general(
-function_type *func_,
-void* func_pointer_,
-double &ungapped_lambda_)
-{
-
-	double eps=1e-7;
-	double threshold=DBL_MIN*10.0;
-
-	double threshold2=DBL_MAX/4;
-
-
-	double a=eps;
-	while(func_(a,func_pointer_)>0)
-	{
-		a/=2.0;
-
-		if(a<threshold*100.0)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-	};
-
-	if(a<threshold*100.0)
-	{
-		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-	};
-
-	eps=a/10.0;
-
-
-	double b=a;
-
-
-	while(func_(b,func_pointer_)<=0)
-	{
-		b*=2.0;
-
-		if(b>threshold2)
-		{
-			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-		};
-	};
-
-
-	
-	long int n_partition=2;
-	std::vector<double> res_lambda;
-	
-	
-	alp_reg::find_tetta_general(
-	func_,
-	func_pointer_,
-	a,
-	b,
-	n_partition,
-	eps,
-	res_lambda);
-
-	sort(res_lambda.begin(),res_lambda.end());
-
-	if(res_lambda.size()==0)
-	{
-		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
-	};
-
-	
-	ungapped_lambda_=res_lambda[res_lambda.size()-1];
-
-	//cout<<setprecision(12)<<"Ungapped lambda is "<<ungapped_lambda_<<endl;
-	//cout<<"Ungapped lambda is "<<ungapped_lambda_<<endl;
-
-
-}
-
-//======================================================
-
-void test::two_dim_layer_alignment_function_FSA(
-long int i1_,
-long int i2_,
-two_dim_layer_alignment_algorithm<long int> *obj_,
-void*par_)
-{
-	data_for_FSA_alignment &data=*(data_for_FSA_alignment*)par_;
-
-	long int &alphabet_letters_number1=data.d_alphabet_letters_number1;//number of letters in the sequence #1
-
-	long int &open1=data.d_open1;//gap opening penalty for the nucleotide sequence #1
-	long int &open2=data.d_open2;//gap opening penalty for the amino acid sequence #2
-
-	long int &epen1=data.d_epen1;//gap extension penalty for the nucleotide sequence #1
-	long int &epen2=data.d_epen2;//gap extension penalty for the amino acid sequence #2
-
-	long int &gamma=data.d_gamma;//frame shift penalty
-
-	long int**&smatr=data.d_smatr;//the scoring matrix
-	long int *&seq1=data.d_seq1;//element of sequence #1
-	long int *&seq2=data.d_seq2;//element of sequence #2
-
-	long int *&codon_AA=data.d_codon_AA;//<codon code,AA number>
-
-	bool &insertions_after_deletions=data.d_insertions_after_deletions;//if true, then insertions after deletions are allowed
-
-	string &alignment_type=data.d_alignment_type;//possible values are "global" or "local"
-
-	if(obj_->d_number_of_variables!=3)
-	{
-		throw error("Error - obj_->d_number_of_variables!=3 in two_dim_layer_alignment_function_FSA\n",1);
-	};
-
-	long int *d_var_num=obj_->d_var_num;
-
-	two_dim_layer<long int> **vars=obj_->d_vars;
-
-	long int Sn=d_var_num['S'];
-	long int Dn=d_var_num['D'];
-	long int In=d_var_num['I'];
-
-	long int codon_length=3;//codon length 
-
-//----------------------------------------
-
-	bool local_flag=(alignment_type=="local");
-
-	long int init_for_S=-inf;
-	if(local_flag)
-	{
-		init_for_S=0;
-	};
-
-
-	long int i=i1_;
-	long int j=i2_;
-
-	if(j==0)
-	{
-		if(local_flag)
-		{
-			vars[Dn]->set_element(i,0,-inf);
-		}
-		else
-		{
-			vars[Dn]->set_element(i,0,-inf);
-			
-		};
-
-
-		
-		vars[In]->set_element(i,0,-inf);
-
-		//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-		//if(i<=2)
-		if(i<=0)
-		{
-			vars[Sn]->set_element(i,0,0);
-		}
-		else
-		{
-			vars[Sn]->set_element(i,0,init_for_S);
-		};
-
-
-		return;
-
-	};
-
-	if(i==0)
-	{
-
-		vars[Sn]->set_element(0,j,init_for_S);
-		vars[Dn]->set_element(0,j,-inf);
-		if(local_flag)
-		{
-			vars[In]->set_element(0,j,-inf);
-		}
-		else
-		{
-			vars[In]->set_element(0,j,-inf);
-		};
-
-		return;
-	};
-
-	if(i==1)
-	{
-		//check these conditions
-		vars[Sn]->set_element(1,j,init_for_S);
-		vars[Dn]->set_element(1,j,-inf);
-		if(local_flag)
-		{
-			vars[In]->set_element(1,j,-inf);
-		}
-		else
-		{
-			vars[In]->set_element(1,j,-inf);
-		};
-
-		return;
-	};
-
-	if(i==2)
-	{
-		vars[Sn]->set_element(2,j,init_for_S);
-		vars[Dn]->set_element(2,j,-inf);
-		if(local_flag)
-		{
-			vars[In]->set_element(2,j,-inf);
-		}
-		else
-		{
-			vars[In]->set_element(2,j,-inf);
-		};
-
-		return;
-	};
-
-
-	{
-
-		{
-
-			if(insertions_after_deletions)
-			{
-				vars[In]->set_element(i,j,
-					FSA_utils::Tmax(
-					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-					vars[Dn]->get_element(i,j-1)-open2-epen2,
-					vars[Sn]->get_element(i,j-1)-open2-epen2,vars[In]->get_element(i,j-1)-epen2));
-			}
-			else
-			{
-				vars[In]->set_element(i,j,
-					FSA_utils::Tmax(
-					vars[Sn]->get_element(i,j-1)-open2-epen2,vars[In]->get_element(i,j-1)-epen2));
-
-			};
-			
-			if(i==3)
-			{
-
-				long int AA1=FSA_utils::convert_codon_into_AA(
-				codon_length,//codon length 
-				codon_AA,//<codon code,AA number>
-				alphabet_letters_number1,//number of letters for the sequence 1
-				seq1+i-3);
-
-
-				long int smart_score=smatr[AA1][seq2[j-1]];
-				vars[Sn]->set_element(i,j,FSA_utils::Tmax(
-
-					//for local alignment
-					init_for_S,
-					
-					FSA_utils::Tmax(vars[Sn]->get_element(i-3,j-1),vars[Dn]->get_element(i-3,j-1),vars[In]->get_element(i-3,j-1))+smart_score,
-					FSA_utils::Tmax(vars[Sn]->get_element(i-2,j-1),vars[Dn]->get_element(i-2,j-1),vars[In]->get_element(i-2,j-1))+smart_score-gamma
-					
-					)
-				);
-
-				vars[Dn]->set_element(i,j,FSA_utils::Tmax(
-					
-					FSA_utils::Tmax(vars[Sn]->get_element(i-3,j)-open1-epen1,vars[Dn]->get_element(i-3,j)-epen1),
-					FSA_utils::Tmax(vars[Sn]->get_element(i-2,j)-open1-epen1,vars[Dn]->get_element(i-2,j)-epen1)-gamma
-
-					)
-					);
-				return;
-				
-			};
-			if(i>=4)
-			{
-
-				long int AA1=FSA_utils::convert_codon_into_AA(
-				codon_length,//codon length 
-				codon_AA,//<codon code,AA number>
-				alphabet_letters_number1,//number of letters for the sequence 1
-				seq1+i-3);
-
-				long int smart_score=smatr[AA1][seq2[j-1]];
-				vars[Sn]->set_element(i,j,FSA_utils::Tmax(
-					
-					//for local alignment
-					init_for_S,
-					
-					FSA_utils::Tmax(vars[Sn]->get_element(i-3,j-1),vars[Dn]->get_element(i-3,j-1),vars[In]->get_element(i-3,j-1))+smart_score,
-					
-					FSA_utils::Tmax(
-					FSA_utils::Tmax(vars[Sn]->get_element(i-2,j-1),vars[Dn]->get_element(i-2,j-1),vars[In]->get_element(i-2,j-1)),
-					FSA_utils::Tmax(vars[Sn]->get_element(i-4,j-1),vars[Dn]->get_element(i-4,j-1),vars[In]->get_element(i-4,j-1))
-					)+smart_score-gamma
-					
-					)
-					);
-
-
-
-				vars[Dn]->set_element(i,j,FSA_utils::Tmax(
-					
-					FSA_utils::Tmax(vars[Sn]->get_element(i-3,j)-open1-epen1,vars[Dn]->get_element(i-3,j)-epen1),
-					FSA_utils::Tmax(vars[Sn]->get_element(i-2,j)-open1-epen1,vars[Dn]->get_element(i-2,j)-epen1)-gamma,
-					FSA_utils::Tmax(vars[Sn]->get_element(i-4,j)-open1-epen1,vars[Dn]->get_element(i-4,j)-epen1)-gamma
-
-					)
-					);
-
-			};
-
-
-
-		};
-	};
-
-
-}
-
-//======================================================
-
-
-void test::two_dim_layer_alignment_function_classical_global(
-long int i1_,
-long int i2_,
-two_dim_layer_alignment_algorithm<long int> *obj_,
-void*par_)
-{
-	data_for_classical_alignment data=*(data_for_classical_alignment*)par_;
-
-	long int &open1=data.d_open1;//gap opening penalty for the nucleotide sequence #1
-	long int &open2=data.d_open2;//gap opening penalty for the amino acid sequence #2
-
-	long int &epen1=data.d_epen1;//gap extension penalty for the nucleotide sequence #1
-	long int &epen2=data.d_epen2;//gap extension penalty for the amino acid sequence #2
-
-	long int**&smatr=data.d_smatr;//the scoring matrix
-	long int *seq1=data.d_seq1;//element of sequence #1
-	long int *seq2=data.d_seq2;//element of sequence #2
-
-	if(obj_->d_number_of_variables!=3)
-	{
-		throw error("Error - obj_->d_number_of_variables!=3 in two_dim_layer_alignment_function_classical_global\n",1);
-	};
-
-	long int *d_var_num=obj_->d_var_num;
-
-	two_dim_layer<long int> **vars=obj_->d_vars;
-
-	long int Sn=d_var_num['S'];
-	long int Dn=d_var_num['D'];
-	long int In=d_var_num['I'];
-
-	//boundary conditions
-	if(i1_==0)
-	{
-		if(i2_==0)
-		{
-			vars[Sn]->set_element(0,0,0);
-			vars[Dn]->set_element(0,0,-open1);
-		}
-		else
-		{
-			vars[Sn]->set_element(0,i2_,-inf);
-			vars[Dn]->set_element(0,i2_,-inf);
-		};
-
-		vars[In]->set_element(0,i2_,-open2-i2_*epen2);
-		return;
-	};
-
-	if(i2_==0)
-	{
-		if(i1_==0)
-		{
-			vars[Sn]->set_element(0,0,0);
-			vars[In]->set_element(0,0,-open2);
-		}
-		else
-		{
-			vars[Sn]->set_element(i1_,0,-inf);
-			vars[In]->set_element(i1_,0,-inf);
-		};
-
-		vars[Dn]->set_element(i1_,0,-open1-i1_*epen1);
-		return;
-	};
-
-	//here i1_>0, i2_>0
-	long int S_1_1=vars[Sn]->get_element(i1_-1,i2_-1);
-	long int D_1_1=vars[Dn]->get_element(i1_-1,i2_-1);
-	long int I_1_1=vars[In]->get_element(i1_-1,i2_-1);
-
-
-	long int S_1_0=vars[Sn]->get_element(i1_-1,i2_);
-	long int D_1_0=vars[Dn]->get_element(i1_-1,i2_);
-	//long int I_1_0=vars[In]->get_element(i1_-1,i2_);
-
-	long int S_0_1=vars[Sn]->get_element(i1_,i2_-1);
-	long int D_0_1=vars[Dn]->get_element(i1_,i2_-1);
-	long int I_0_1=vars[In]->get_element(i1_,i2_-1);
-
-	long int S_0_0=FSA_utils::Tmax(S_1_1,D_1_1,I_1_1)+smatr[seq1[i1_-1]][seq2[i2_-1]];
-	long int D_0_0=FSA_utils::Tmax(S_1_0-open1-epen1,D_1_0-epen1);
-	long int I_0_0=FSA_utils::Tmax(S_0_1-open2-epen2,I_0_1-epen2,D_0_1-open2-epen2);
-
-	vars[Sn]->set_element(i1_,i2_,S_0_0);
-	vars[Dn]->set_element(i1_,i2_,D_0_0);
-	vars[In]->set_element(i1_,i2_,I_0_0);
-
-
-}
-
-//--------------------------------------
-template<typename T> 
-two_dim_layer_alignment_algorithm<T>::two_dim_layer_alignment_algorithm(
-long int number_of_variables_,//total number of variables in dynamic equations
-long int depth1_,//the maximum difference of the first index in the dynamic equations
-long int depth2_,//the maximum difference of the second index in the dynamic equations
-long int max_ind1_,//max of the index #1 (minimum index is 0 by default)
-long int max_ind2_,//max of the index #2 (minimum index is 0 by default)
-T null_,//null element of T
-long int *var_num_)//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
-{
-
-	d_max_ind1=max_ind1_;
-	d_max_ind2=max_ind2_;
-
-	d_number_of_variables=number_of_variables_;
-	d_depth1=depth1_;
-	d_depth2=depth2_;
-	d_var_num=var_num_;
-	d_null=null_;
-	d_step1=depth1_*2+1;
-	d_step2=depth2_*2+1;
-
-	//d_step1=depth1_;
-	//d_step2=depth2_;
-
-	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-	d_edge_maximum_calculation_depth1=3;
-	d_edge_maximum_calculation_depth2=1;
-
-	long int layers_number1=depth1_+d_step1;//number of layers for the index #1
-	long int layers_number2=depth2_+d_step2;//number of layers for the index #2
-
-	d_vars=new two_dim_layer<T> *[number_of_variables_];
-
-	long int i;
-	for(i=0;i<d_number_of_variables;i++)
-	{
-		d_vars[i]=new two_dim_layer<T>(
-		max_ind1_,//max of the index #1 (minimum index is 0 by default)
-		max_ind2_,//max of the index #2 (minimum index is 0 by default)
-		layers_number1,//number of layers for the index #1
-		layers_number2,//number of layers for the index #2
-		null_);
-	};
-
-	d_current_align_ind1=-1;
-	d_current_align_ind2=-1;
-
-	//statistics 
-	d_M_flag=false;
-	d_M=-inf;
-
-	d_E_flag=false;
-	d_E=-inf;
-
-}
-
-
-template<typename T> 
-two_dim_layer_alignment_algorithm<T>::two_dim_layer_alignment_algorithm(
-long int max_ind1_,//max of the index #1
-long int max_ind2_,//max of the index #2
-two_dim_layer_alignment_algorithm<T> *two_dim_layer_alignment_algorithm_)
-{
-
-	d_max_ind1=two_dim_layer_alignment_algorithm_->d_max_ind1;
-	d_max_ind2=two_dim_layer_alignment_algorithm_->d_max_ind2;
-
-	d_number_of_variables=two_dim_layer_alignment_algorithm_->d_number_of_variables;
-	d_depth1=two_dim_layer_alignment_algorithm_->d_depth1;
-	d_depth2=two_dim_layer_alignment_algorithm_->d_depth2;
-	d_var_num=two_dim_layer_alignment_algorithm_->d_var_num;
-	d_null=two_dim_layer_alignment_algorithm_->d_null;
-	d_step1=two_dim_layer_alignment_algorithm_->d_step1;
-	d_step2=two_dim_layer_alignment_algorithm_->d_step2;
-
-
-	d_edge_maximum_calculation_depth1=two_dim_layer_alignment_algorithm_->d_edge_maximum_calculation_depth1;
-	d_edge_maximum_calculation_depth2=two_dim_layer_alignment_algorithm_->d_edge_maximum_calculation_depth2;
-
-	d_vars=new two_dim_layer<T> *[d_number_of_variables];
-
-	long int i;
-	for(i=0;i<d_number_of_variables;i++)
-	{
-		d_vars[i]=new two_dim_layer<T>(
-		max_ind1_,//max of the index #1 (minimum index is 0 by default)
-		max_ind2_,//max of the index #2 (minimum index is 0 by default)
-		two_dim_layer_alignment_algorithm_->d_vars[i]);
-	};
-
-	d_current_align_ind1=two_dim_layer_alignment_algorithm_->d_current_align_ind1;
-	d_current_align_ind2=two_dim_layer_alignment_algorithm_->d_current_align_ind2;
-
-	//statistics 
-	d_M_flag=two_dim_layer_alignment_algorithm_->d_M_flag;
-	d_M=two_dim_layer_alignment_algorithm_->d_M;
-
-	d_E_flag=two_dim_layer_alignment_algorithm_->d_E_flag;
-	d_E=two_dim_layer_alignment_algorithm_->d_E;
-
-}
-
-
-template<typename T> 
-two_dim_layer_alignment_algorithm<T>::~two_dim_layer_alignment_algorithm()
-{
-	long int i;
-	for(i=0;i<d_number_of_variables;i++)
-	{
-		d_vars[i]->~two_dim_layer<T>();
-	};
-
-	delete[]d_vars;
-}
-
-template<typename T> 
-void two_dim_layer_alignment_algorithm<T>::init()//initialization for a new alignment
-{
-	d_M=-inf;
-	d_E=-inf;
-	d_current_align_ind1=-1;
-	d_current_align_ind2=-1;
-
-	d_scores_counts.clear();
-}
-
-template<typename T> 
-void two_dim_layer_alignment_algorithm<T>::align_upto_target_lengths_step(//aligns the sequences upto the target sequence lengths including 
-//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-long int target_align1_length_,//target length for the sequence #1
-long int target_align2_length_)//target length for the sequence #2
-{
-	long int i;
-	for(i=0;i<d_number_of_variables;i++)
-	{
-		d_vars[i]->set_max_ind(target_align1_length_,target_align2_length_);
-	};
-
-	if(target_align1_length_-d_current_align_ind1>d_step1||target_align2_length_-d_current_align_ind2>d_step2)
-	{
-		throw error("Unexpected error in two_dim_layer_alignment_algorithm<T>::align_upto_target_lengths: target_align1_length_-d_current_align_ind1>d_step1||target_align2_length_-d_current_align_ind2>d_step2\n",1);
-	};
-
-	long int i1,i2;
-	for(i1=0;i1<=d_current_align_ind1;i1++)
-	{
-		for(i2=d_current_align_ind2+1;i2<=target_align2_length_;i2++)
-		{
-			two_dim_layer_alignment_function_type *tmp_func=d_two_dim_layer_alignment_function;
-			if(i1<d_depth1||i2<d_depth2)
-			{
-				tmp_func=d_two_dim_layer_boundary_function;
-			};
-
-			tmp_func(i1,i2,this,d_par);
-		};
-	};
-
-	for(i2=0;i2<=d_current_align_ind2;i2++)
-	{
-		for(i1=d_current_align_ind1+1;i1<=target_align1_length_;i1++)
-		{
-			two_dim_layer_alignment_function_type *tmp_func=d_two_dim_layer_alignment_function;
-			if(i1<d_depth1||i2<d_depth2)
-			{
-				tmp_func=d_two_dim_layer_boundary_function;
-			};
-
-			tmp_func(i1,i2,this,d_par);
-		};
-	};
-
-	for(i1=d_current_align_ind1+1;i1<=target_align1_length_;i1++)
-	{
-		for(i2=d_current_align_ind2+1;i2<=target_align2_length_;i2++)
-		{
-			two_dim_layer_alignment_function_type *tmp_func=d_two_dim_layer_alignment_function;
-			if(i1<d_depth1||i2<d_depth2)
-			{
-				tmp_func=d_two_dim_layer_boundary_function;
-			};
-
-			tmp_func(i1,i2,this,d_par);
-		};
-	};
-
-	d_current_align_ind1=FSA_utils::Tmax(target_align1_length_,d_current_align_ind1);
-	d_current_align_ind2=FSA_utils::Tmax(target_align2_length_,d_current_align_ind2);
-
-}
-
-template<typename T> 
-void two_dim_layer_alignment_algorithm<T>::align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-long int target_align1_length_,//target length for the sequence #1
-long int target_align2_length_)//target length for the sequence #2
-{
-
-	while(d_current_align_ind1<target_align1_length_||d_current_align_ind2<target_align2_length_)
-	{
-		long int current_align_ind1_old=d_current_align_ind1;
-		long int current_align_ind2_old=d_current_align_ind2;
-
-		align_upto_target_lengths_step(
-		FSA_utils::Tmin(target_align1_length_,d_current_align_ind1+d_step1),
-		FSA_utils::Tmin(target_align2_length_,d_current_align_ind2+d_step2));
-
-		long int M_tmp=d_M;
-
-		//statistics
-		if(d_M_flag||d_FSC_flag)
-		{
-			long int i1,i2,j;
-			for(i1=0;i1<=d_current_align_ind1;i1++)
-			{
-				for(i2=current_align_ind2_old+1;i2<=d_current_align_ind2;i2++)
-				{
-					for(j=0;j<d_number_of_variables;j++)
-					{
-						d_M=FSA_utils::Tmax(d_M,d_vars[j]->get_element(i1,i2));
-					};
-				};
-			};
-
-			for(i1=current_align_ind1_old+1;i1<=d_current_align_ind1;i1++)
-			{
-				for(i2=0;i2<=current_align_ind2_old;i2++)
-				{
-					for(j=0;j<d_number_of_variables;j++)
-					{
-						d_M=FSA_utils::Tmax(d_M,d_vars[j]->get_element(i1,i2));
-					};
-				};
-			};
-
-		};
-
-		if(d_scores_counts_flag)
-		{
-			long int i1,i2,j;
-			for(i1=0;i1<=d_current_align_ind1;i1++)
-			{
-				for(i2=current_align_ind2_old+1;i2<=d_current_align_ind2;i2++)
-				{
-					long int M_local=d_vars[0]->get_element(i1,i2);
-					for(j=1;j<d_number_of_variables;j++)
-					{
-						M_local=FSA_utils::Tmax(M_local,d_vars[j]->get_element(i1,i2));
-					};
-
-
-					if(M_local>=d_M_threshold)
-					{
-						d_scores_counts.increase_elem_by_1(M_local);
-					};
-				};
-			};
-
-			for(i1=current_align_ind1_old+1;i1<=d_current_align_ind1;i1++)
-			{
-				for(i2=0;i2<=current_align_ind2_old;i2++)
-				{
-					long int M_local=d_vars[0]->get_element(i1,i2);
-					for(j=1;j<d_number_of_variables;j++)
-					{
-						M_local=FSA_utils::Tmax(M_local,d_vars[j]->get_element(i1,i2));
-					};
-
-					if(M_local>=d_M_threshold)
-					{
-						d_scores_counts.increase_elem_by_1(M_local);
-					};
-				};
-			};
-
-		};
-
-
-
-
-		if(d_FSC_flag&&M_tmp<d_M)
-		{//calculated only along the edge containing the next ALP
-
-			d_distance_along_direction_1=-1;
-
-			d_distance_along_direction_2=-1;
-
-			long int i1,i2,j;
-			for(i1=0;i1<=d_current_align_ind1;i1++)
-			{
-				for(i2=current_align_ind2_old+1;i2<=d_current_align_ind2;i2++)
-				{
-					long int M_local=d_vars[0]->get_element(i1,i2);
-					for(j=1;j<d_number_of_variables;j++)
-					{
-						M_local=FSA_utils::Tmax(M_local,d_vars[j]->get_element(i1,i2));
-					};
-
-					if(M_local==d_M)
-					{
-						if(d_distance_along_direction_1==-1)
-						{
-							d_distance_along_direction_1=i1;
-						}
-						else
-						{
-							d_distance_along_direction_1=FSA_utils::Tmin(d_distance_along_direction_1,i1);
-						};
-
-						if(d_distance_along_direction_2==-1)
-						{
-							d_distance_along_direction_2=i2;
-						}
-						else
-						{
-							d_distance_along_direction_2=FSA_utils::Tmin(d_distance_along_direction_2,i2);
-						};
-					};
-
-				};
-			};
-
-			for(i1=current_align_ind1_old+1;i1<=d_current_align_ind1;i1++)
-			{
-				for(i2=0;i2<=d_current_align_ind2;i2++)
-				{
-					long int M_local=d_vars[0]->get_element(i1,i2);
-					for(j=1;j<d_number_of_variables;j++)
-					{
-						M_local=FSA_utils::Tmax(M_local,d_vars[j]->get_element(i1,i2));
-					};
-
-					if(M_local==d_M)
-					{
-						if(d_distance_along_direction_1==-1)
-						{
-							d_distance_along_direction_1=i1;
-						}
-						else
-						{
-							d_distance_along_direction_1=FSA_utils::Tmin(d_distance_along_direction_1,i1);
-						};
-
-						if(d_distance_along_direction_2==-1)
-						{
-							d_distance_along_direction_2=i2;
-						}
-						else
-						{
-							d_distance_along_direction_2=FSA_utils::Tmin(d_distance_along_direction_2,i2);
-						};
-					};
-				};
-			};
-
-
-			if(d_distance_along_direction_1==-1||d_distance_along_direction_2==-1)
-			{
-				throw error("Unexpected error - d_distance_along_direction_1==-1||d_distance_along_direction_2==-1\n",1);
-			};
-		};
-
-
-
-	};
-
-
-	//statistics
-	if(d_E_flag||d_scores_counts_flag)
-	{
-
-		d_E=-inf;
-		long int i1,i2,j;
-		for(i1=0;i1<=d_current_align_ind1;i1++)
-		{
-			for(i2=d_current_align_ind2-d_edge_maximum_calculation_depth2+1;i2<=d_current_align_ind2;i2++)
-			{
-				for(j=0;j<d_number_of_variables;j++)
-				{
-					d_E=FSA_utils::Tmax(d_E,d_vars[j]->get_element(i1,i2));
-				};
-			};
-		};
-
-		for(i1=d_current_align_ind1-d_edge_maximum_calculation_depth1+1;i1<=d_current_align_ind1;i1++)
-		{
-			for(i2=0;i2<=d_current_align_ind2-d_edge_maximum_calculation_depth2;i2++)
-			{
-				for(j=0;j<d_number_of_variables;j++)
-				{
-					d_E=FSA_utils::Tmax(d_E,d_vars[j]->get_element(i1,i2));
-				};
-			};
-		};
-
-
-
-
-	};
-
-
-}
-//---------------------------------------------------------
-
+/* $Id: $
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's offical duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_repwords.cpp
+
+Author: Sergey Sheetlin
+
+Contents: Frameshift alignment algorithms 
+
+******************************************************************************/
+
+#include "sls_fsa1.hpp"
+
+using namespace Sls;
+using namespace std;
+
+static bool test_mode=true;//of true, then the test mode is activated
+
+static long int small_long=(long int)((double)LONG_MIN/2.0);
+static long int length_max=1000;
+
+FSA::FSA(//constructor
+
+bool reversed_seq_,//whether the sequences are reversed or not
+string alignment_type_,//type of alignment; possible values "local", "global"
+
+long int rand_,//randomization number
+long int open1_,//gap opening penalty for the nucleotide sequence #1
+long int open2_,//gap opening penalty for the amino acid sequence #2
+
+long int epen1_,//gap extension penalty for the nucleotide sequence #1
+long int epen2_,//gap extension penalty for the amino acid sequence #2
+
+long int gamma_,//frameshift penalty gamma
+
+string smatr_file_name_,//scoring matrix file name
+string RR1_file_name_,//background frequencies file name for the sequence #1
+string RR2_file_name_,//background frequencies file name for the sequence #2
+string DNA_codon_table_file_name_,//a name of a file with DNA codon table
+long int seq1_length_,//length of sequence #1
+long int seq2_length_,//length of sequence #2
+long int seq_number_)//number of tested alignments
+{
+
+	d_alphabet1=NULL;
+	d_alphabet2=NULL;
+
+	d_alphabet1_to_long=NULL;
+	d_alphabet2_to_long=NULL;
+
+	d_smatr=NULL;
+	d_RR1=NULL;
+	d_RR1_sum=NULL;
+	d_RR1_sum_elements=NULL;
+
+	d_RR2=NULL;
+	d_RR2_sum=NULL;
+	d_RR2_sum_elements=NULL;
+
+	d_S_a1=NULL;
+	d_I_a1=NULL;
+	d_D_a1=NULL;
+
+	d_codon_AA=NULL;
+
+	d_seq1=NULL;
+	d_seq2=NULL;
+
+
+	try
+	{
+
+		d_reversed_seq=reversed_seq_;
+		d_alignment_type=alignment_type_;
+
+		long int number_of_AA_RR2;
+		long int number_of_AA_smatr;
+		long int smatr_min;
+
+		FSA_utils::read_smatr(
+		smatr_file_name_,
+		d_smatr,
+		number_of_AA_smatr,
+		smatr_min);
+
+		
+
+		FSA_utils::read_RR(
+		RR1_file_name_,
+		d_RR1,
+		d_RR1_sum,
+		d_RR1_sum_elements,
+		d_number_of_letters1);
+
+
+		FSA_utils::read_RR(
+		RR2_file_name_,
+		d_RR2,
+		d_RR2_sum,
+		d_RR2_sum_elements,
+		number_of_AA_RR2);
+
+
+		if(number_of_AA_RR2==number_of_AA_smatr)
+		{
+			d_number_of_letters2=number_of_AA_smatr;
+		}
+		else
+		{
+			throw error("The number of letters is different in the files "+smatr_file_name_+" and "+RR2_file_name_+"\n",3);
+		};
+
+		long int number_of_letters1_tmp;//number of letters for the sequence 1
+		long int number_of_letters2_tmp;//number of letters for the sequence 2
+
+		FSA_utils::read_codon_AA_file(
+		DNA_codon_table_file_name_,
+		number_of_letters1_tmp,//number of letters for the sequence 1
+		number_of_letters2_tmp,//number of letters for the sequence 2
+
+		d_alphabet1,//alphabet letters for the sequence #1
+		d_alphabet2,//alphabet letters for the sequence #2
+
+		d_alphabet1_to_long,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+		d_alphabet2_to_long,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+		d_codon_length,//codon length 
+		d_codon_AA);//<codon code,AA number>
+
+
+		if(d_number_of_letters1!=number_of_letters1_tmp)
+		{
+			throw error("The number of letters is different in the files "+DNA_codon_table_file_name_+" and "+RR1_file_name_+"\n",3);
+		};
+		if(d_number_of_letters2!=number_of_letters2_tmp)
+		{
+			throw error("The number of letters is different in the files "+DNA_codon_table_file_name_+" and "+RR2_file_name_+"\n",3);
+		};
+
+		d_open1=open1_;
+		d_open2=open2_;
+
+		d_epen1=epen1_;
+		d_epen2=epen2_;
+
+		d_gamma=gamma_;
+
+		d_seq1_length=seq1_length_;//length of sequence #1
+		d_seq2_length=seq2_length_;//length of sequence #2
+		d_seq_number=seq_number_;//number of tested alignments
+
+
+
+		//randomization
+		long int random_factor=rand_;
+
+
+		if(random_factor<0)
+		{
+			random_factor=(long int)time(NULL);
+			#ifndef _MSC_VER //UNIX program
+				struct timeval tv;
+				struct timezone tz;
+				gettimeofday(&tv, &tz);
+				random_factor+=tv.tv_usec*10000000;
+			#else
+				struct _timeb timebuffer;
+				char *timeline;
+				_ftime( &timebuffer );
+				timeline = ctime( & ( timebuffer.time ) );
+				rand_+=timebuffer.millitm*10000000;
+			#endif
+
+			random_factor=abs(random_factor);
+
+			d_rand_flag=false;
+
+		};
+
+		d_random_factor=random_factor;
+		cout<<"Random seed "<<d_random_factor<<endl;
+
+		FSA_utils::srand2(d_random_factor);
+
+		FSA_utils::get_memory_for_matrix(d_seq1_length+1,d_seq2_length+1,d_S_a1);
+		FSA_utils::get_memory_for_matrix(d_seq1_length+1,d_seq2_length+1,d_I_a1);
+		FSA_utils::get_memory_for_matrix(d_seq1_length+1,d_seq2_length+1,d_D_a1);
+
+		d_seq1=new long int[d_seq1_length];
+		d_seq2=new long int[d_seq2_length];
+
+	}
+	catch (...)
+	{
+		this->~FSA();
+		throw;
+	};
+
+}
+
+FSA::~FSA()
+{
+	if(d_smatr)
+	{
+		FSA_utils::delete_memory_for_matrix(d_number_of_letters2,d_smatr);
+	};
+
+	delete[]d_RR1;
+	delete[]d_RR2;
+	delete[]d_RR1_sum;
+	delete[]d_RR2_sum;
+	delete[]d_RR1_sum_elements;
+	delete[]d_RR2_sum_elements;
+	delete[]d_alphabet1;
+	delete[]d_alphabet2;
+
+	delete[]d_alphabet1_to_long;
+	delete[]d_alphabet2_to_long;
+	delete[]d_codon_AA;
+
+	if(d_S_a1)
+	{
+		FSA_utils::delete_memory_for_matrix(d_seq1_length+1,d_S_a1);
+	};
+	if(d_I_a1)
+	{
+		FSA_utils::delete_memory_for_matrix(d_seq1_length+1,d_I_a1);
+	};
+	if(d_D_a1)
+	{
+		FSA_utils::delete_memory_for_matrix(d_seq1_length+1,d_D_a1);
+	};
+
+
+}
+
+long int FSA::random_AA1()
+{
+	return FSA_utils::random_long(
+		FSA_utils::ran2(),
+			d_number_of_letters1,
+			d_RR1_sum,
+			d_RR1_sum_elements);
+}
+
+long int FSA::random_AA2()
+{
+	return FSA_utils::random_long(
+		FSA_utils::ran2(),
+			d_number_of_letters2,
+			d_RR2_sum,
+			d_RR2_sum_elements);
+}
+
+
+
+long int FSA::convert_codon_into_AA(
+long int *codon_)
+{
+	return FSA_utils::convert_codon_into_AA(
+			d_codon_length,//codon length 
+			d_codon_AA,//<codon code,AA number>
+			d_number_of_letters1,//number of letters for the sequence 1
+			codon_);
+}
+
+void FSA::classical_global_alignment(
+long int *seq1_,//sequence #1
+long int *seq2_,//sequence #2
+FSA *FAS_object_,//a pointer to FSA object
+void*par_)//additonal parameters
+{
+
+	bool local_flag=(FAS_object_->d_alignment_type=="local");
+
+	long int init_for_S=-inf;
+	if(local_flag)
+	{
+		init_for_S=0;
+	};
+
+	long int i,j;
+	//initial conditions
+	for(i=0;i<=FAS_object_->d_seq1_length;i++)
+	{
+		if(local_flag)
+		{
+			FAS_object_->d_D_a1[i][0]=-inf;
+		}
+		else
+		{
+			FAS_object_->d_D_a1[i][0]=-FAS_object_->d_open1-FAS_object_->d_epen1*i;
+		};
+
+		FAS_object_->d_S_a1[i][0]=init_for_S;
+		FAS_object_->d_I_a1[i][0]=-inf;
+	};
+
+	for(j=0;j<=FAS_object_->d_seq2_length;j++)
+	{
+		FAS_object_->d_S_a1[0][j]=init_for_S;
+		FAS_object_->d_D_a1[0][j]=-inf;
+		if(local_flag)
+		{
+			FAS_object_->d_I_a1[0][j]=-inf;
+		}
+		else
+		{
+			FAS_object_->d_I_a1[0][j]=-FAS_object_->d_open2-FAS_object_->d_epen2*j;
+		};
+
+	};
+
+	FAS_object_->d_S_a1[0][0]=0;
+
+	for(i=1;i<=FAS_object_->d_seq1_length;i++)
+	{
+		for(j=1;j<=FAS_object_->d_seq2_length;j++)
+		{
+
+			FAS_object_->d_I_a1[i][j]=FSA_utils::Tmax(FAS_object_->d_S_a1[i][j-1]-FAS_object_->d_open2-FAS_object_->d_epen2,FAS_object_->d_I_a1[i][j-1]-FAS_object_->d_epen2);
+			FAS_object_->d_D_a1[i][j]=FSA_utils::Tmax(FAS_object_->d_S_a1[i-1][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-1][j]-FAS_object_->d_epen1);
+
+			long int smart_score=FAS_object_->d_smatr[seq1_[i-1]][seq2_[j-1]];
+			FAS_object_->d_S_a1[i][j]=
+				FSA_utils::Tmax(
+					init_for_S,
+					FSA_utils::Tmax(FAS_object_->d_S_a1[i-1][j-1],FAS_object_->d_D_a1[i-1][j-1],FAS_object_->d_I_a1[i-1][j-1])+smart_score
+					);
+			
+		};
+	};
+
+	long int score=FAS_object_->d_S_a1[0][0];
+	for(i=0;i<=FAS_object_->d_seq1_length;i++)
+	{
+		for(j=0;j<=FAS_object_->d_seq2_length;j++)
+		{
+			score=FSA_utils::Tmax(score,
+				FSA_utils::Tmax(FAS_object_->d_S_a1[i][j],FAS_object_->d_D_a1[i][j],FAS_object_->d_I_a1[i][j])
+				);
+		};
+	};
+
+	struct_for_alignment &tmp_obj=*((struct_for_alignment*)par_);
+	tmp_obj.d_score=score;
+
+}
+
+
+void FSA::a1_global_alignment(
+long int *seq1_,//sequence #1
+long int *seq2_,//sequence #2
+FSA *FAS_object_,//a pointer to FSA object
+void*par_)//additonal parameters
+{
+	bool local_flag=(FAS_object_->d_alignment_type=="local");
+
+	long int init_for_S=-inf;
+	if(local_flag)
+	{
+		init_for_S=0;
+	};
+
+
+	long int i,j;
+	//initial conditions
+	for(i=0;i<=FAS_object_->d_seq1_length;i++)
+	{
+		long int i_div_3;
+
+		if(local_flag)
+		{
+			FAS_object_->d_D_a1[i][0]=-inf;
+		}
+		else
+		{
+			if(i%3==0)
+			{
+				i_div_3=i/3;
+				FAS_object_->d_D_a1[i][0]=-FAS_object_->d_open1-FAS_object_->d_epen1*i_div_3;
+			};
+
+			if(i%3==1)
+			{
+				i_div_3=(i-1)/3;
+				FAS_object_->d_D_a1[i][0]=-FAS_object_->d_open1-FAS_object_->d_epen1*i_div_3-FAS_object_->d_gamma;
+			};
+
+			if(i%3==2)
+			{
+				i_div_3=(i+1)/3;
+				FAS_object_->d_D_a1[i][0]=-FAS_object_->d_open1-FAS_object_->d_epen1*i_div_3-FAS_object_->d_gamma;
+			};
+
+			i_div_3=(long int)floor((double)i/3.0);
+			FAS_object_->d_D_a1[i][0]=-FAS_object_->d_open1-FAS_object_->d_epen1*i_div_3;
+			
+		};
+
+
+		FAS_object_->d_S_a1[i][0]=init_for_S;
+		FAS_object_->d_I_a1[i][0]=-inf;
+	};
+
+	for(j=0;j<=FAS_object_->d_seq2_length;j++)
+	{
+		FAS_object_->d_S_a1[0][j]=init_for_S;
+		FAS_object_->d_D_a1[0][j]=-inf;
+		if(local_flag)
+		{
+			FAS_object_->d_I_a1[0][j]=-inf;
+		}
+		else
+		{
+			FAS_object_->d_I_a1[0][j]=-FAS_object_->d_open2-FAS_object_->d_epen2*j;
+		};
+
+		FAS_object_->d_S_a1[1][j]=init_for_S;
+		FAS_object_->d_D_a1[1][j]=-inf;
+		if(local_flag)
+		{
+			FAS_object_->d_I_a1[1][j]=-inf;
+		}
+		else
+		{
+			FAS_object_->d_I_a1[1][j]=-FAS_object_->d_open2-FAS_object_->d_epen2*j;
+		};
+
+		FAS_object_->d_S_a1[2][j]=init_for_S;
+		FAS_object_->d_D_a1[2][j]=-inf;
+		if(local_flag)
+		{
+			FAS_object_->d_I_a1[2][j]=-inf;
+		}
+		else
+		{
+			FAS_object_->d_I_a1[2][j]=-FAS_object_->d_open2-FAS_object_->d_epen2*j;
+		};
+	};
+
+	FAS_object_->d_S_a1[0][0]=0;
+	FAS_object_->d_S_a1[1][0]=0;
+	FAS_object_->d_S_a1[2][0]=0;
+
+	for(i=3;i<=FAS_object_->d_seq1_length;i++)
+	{
+		for(j=1;j<=FAS_object_->d_seq2_length;j++)
+		{
+
+			FAS_object_->d_I_a1[i][j]=FSA_utils::Tmax(FAS_object_->d_S_a1[i][j-1]-FAS_object_->d_open2-FAS_object_->d_epen2,FAS_object_->d_I_a1[i][j-1]-FAS_object_->d_epen2);
+			
+			if(i==2)
+			{
+				FAS_object_->d_S_a1[i][j]=init_for_S;
+
+				FAS_object_->d_D_a1[i][j]=FAS_object_->d_D_a1[i-1][j];
+
+				//FAS_object_->d_D_a1[i][j]=
+				//	Tmax(FAS_object_->d_S_a1[i-2][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-2][j]-FAS_object_->d_epen1)-FAS_object_->d_gamma;
+
+				continue;
+			};
+			if(i==3)
+			{
+				long int smart_score=FAS_object_->d_smatr[FAS_object_->convert_codon_into_AA(seq1_+i-3)][seq2_[j-1]];
+				FAS_object_->d_S_a1[i][j]=FSA_utils::Tmax(
+
+					//for local alignment
+					init_for_S,
+					
+					FSA_utils::Tmax(FAS_object_->d_S_a1[i-3][j-1],FAS_object_->d_D_a1[i-3][j-1],FAS_object_->d_I_a1[i-3][j-1])+smart_score,
+					FSA_utils::Tmax(FAS_object_->d_S_a1[i-2][j-1],FAS_object_->d_D_a1[i-2][j-1],FAS_object_->d_I_a1[i-2][j-1])+smart_score-FAS_object_->d_gamma
+					
+					);
+
+				FAS_object_->d_D_a1[i][j]=FSA_utils::Tmax(
+					
+					FSA_utils::Tmax(FAS_object_->d_S_a1[i-3][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-3][j]-FAS_object_->d_epen1),
+					FSA_utils::Tmax(FAS_object_->d_S_a1[i-2][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-2][j]-FAS_object_->d_epen1)-FAS_object_->d_gamma
+
+					);
+				continue;
+				
+			};
+			if(i>=4)
+			{
+
+				long int smart_score=FAS_object_->d_smatr[FAS_object_->convert_codon_into_AA(seq1_+i-3)][seq2_[j-1]];
+				FAS_object_->d_S_a1[i][j]=FSA_utils::Tmax(
+					
+					//for local alignment
+					init_for_S,
+					
+					FSA_utils::Tmax(FAS_object_->d_S_a1[i-3][j-1],FAS_object_->d_D_a1[i-3][j-1],FAS_object_->d_I_a1[i-3][j-1])+smart_score,
+					
+					FSA_utils::Tmax(
+					FSA_utils::Tmax(FAS_object_->d_S_a1[i-2][j-1],FAS_object_->d_D_a1[i-2][j-1],FAS_object_->d_I_a1[i-2][j-1]),
+					FSA_utils::Tmax(FAS_object_->d_S_a1[i-4][j-1],FAS_object_->d_D_a1[i-4][j-1],FAS_object_->d_I_a1[i-4][j-1])
+					)+smart_score-FAS_object_->d_gamma
+					
+					);
+
+				FAS_object_->d_D_a1[i][j]=FSA_utils::Tmax(
+					
+					FSA_utils::Tmax(FAS_object_->d_S_a1[i-3][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-3][j]-FAS_object_->d_epen1),
+					FSA_utils::Tmax(FAS_object_->d_S_a1[i-2][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-2][j]-FAS_object_->d_epen1)-FAS_object_->d_gamma,
+					FSA_utils::Tmax(FAS_object_->d_S_a1[i-4][j]-FAS_object_->d_open1-FAS_object_->d_epen1,FAS_object_->d_D_a1[i-4][j]-FAS_object_->d_epen1)-FAS_object_->d_gamma
+
+					);
+
+			};
+
+
+
+		};
+	};
+
+	long int score=FAS_object_->d_S_a1[0][0];
+	for(i=0;i<=FAS_object_->d_seq1_length;i++)
+	{
+		for(j=0;j<=FAS_object_->d_seq2_length;j++)
+		{
+			score=FSA_utils::Tmax(score,
+				FSA_utils::Tmax(FAS_object_->d_S_a1[i][j],FAS_object_->d_D_a1[i][j],FAS_object_->d_I_a1[i][j])
+				);
+		};
+	};
+
+	struct_for_alignment &tmp_obj=*((struct_for_alignment*)par_);
+	tmp_obj.d_score=score;
+
+	bool test_flag=false;
+	if(test_flag)
+	{
+		FSA_utils::print_matrix(
+		"d_S_a1.out",
+		FAS_object_->d_seq1_length+1,
+		FAS_object_->d_seq2_length+1,
+		FAS_object_->d_S_a1);
+
+		FSA_utils::print_matrix(
+		"d_I_a1.out",
+		FAS_object_->d_seq1_length+1,
+		FAS_object_->d_seq2_length+1,
+		FAS_object_->d_I_a1);
+
+		FSA_utils::print_matrix(
+		"d_D_a1.out",
+		FAS_object_->d_seq1_length+1,
+		FAS_object_->d_seq2_length+1,
+		FAS_object_->d_D_a1);
+
+
+	};
+}
+
+void FSA::DNA_AA_global(
+string distr_file_name_,
+alignment_function_type *alignment_function_)
+{
+	bool test_out=false;
+
+	ofstream ftest;
+	if(test_out)
+	{
+		string test_out_st="sss.out";
+		ftest.open(test_out_st.data());
+		if(!ftest)
+		{
+			throw error("Error - the file "+test_out_st+" is not found\n",1);
+		};
+
+		
+	};
+
+	ofstream f(distr_file_name_.data());
+	if(!f)
+	{
+		throw error("Error - the file "+distr_file_name_+" is not found\n",3);
+	};
+
+
+	array_v<double> distr(this);
+
+
+	long int s;
+	long int score_max=small_long,score_min=-small_long;
+
+	for(s=0;s<d_seq_number;s++)
+	{
+
+		if(test_out)
+		{
+			ftest<<">seq"<<s<<"\n";
+		};
+
+		long int i,j;
+		//generate sequence #1
+		for(i=0;i<d_seq1_length;i++)
+		{
+			d_seq1[i]=random_AA1();
+			if(test_out)
+			{
+				ftest<<this->d_alphabet1[d_seq1[i]];
+			};
+		};
+		if(test_out)
+		{
+			ftest<<"\n";
+		};
+
+		//generate sequence #2
+		for(j=0;j<d_seq2_length;j++)
+		{
+			d_seq2[j]=random_AA2();
+			if(test_out)
+			{
+				ftest<<this->d_alphabet2[d_seq2[j]];
+			};
+
+		};
+		if(test_out)
+		{
+			ftest<<"\n";
+		};
+
+		if(d_reversed_seq)
+		{
+			FSA_utils::reverse_sequence(//reverse the letters of the sequence
+			d_seq1,
+			d_seq1_length);
+
+			FSA_utils::reverse_sequence(//reverse the letters of the sequence
+			d_seq2,
+			d_seq2_length);
+		};
+
+		struct_for_alignment tmp_str;
+
+		alignment_function_(
+		d_seq1,//sequence #1
+		d_seq2,//sequence #2
+		this,
+		(void*)(&tmp_str));
+
+		long int score=tmp_str.d_score;
+		if(s==0)
+		{
+			score_max=score;
+			score_min=score;
+		}
+		else
+		{
+			score_max=FSA_utils::Tmax(score_max,score);
+			score_min=FSA_utils::Tmin(score_min,score);
+		};
+
+		distr.increase_elem_by_1(score);
+
+		if(test_out)
+		{
+			cout<<score<<endl;
+		};
+
+		if((s+1)%1000==0)
+		{
+			cout<<s+1<<endl;
+		};
+	};
+
+	f<<score_max+1<<endl;
+	for(s=0;s<=score_max;s++)
+	{
+		f<<s<<"\t"<<distr.d_elem[s-distr.d_ind0]<<endl;
+	};
+
+	f.close();
+}
+
+void FSA::AA_AA_global(
+string distr_file_name_,
+alignment_function_type *alignment_function_)
+{
+	ofstream f(distr_file_name_.data());
+	if(!f)
+	{
+		throw error("Error - the file "+distr_file_name_+" is not found\n",3);
+	};
+
+	array_v<double> distr(this);
+
+
+	long int s;
+	long int score_max=small_long,score_min=-small_long;
+
+	for(s=0;s<d_seq_number;s++)
+	{
+		long int i,j;
+		//generate sequence #1
+
+		for(i=0;i<d_seq1_length;i++)
+		{
+			d_seq1[i]=random_AA2();
+		};
+		//generate sequence #2
+		for(j=0;j<d_seq2_length;j++)
+		{
+			d_seq2[j]=random_AA2();
+		};
+
+		if(d_reversed_seq)
+		{
+			FSA_utils::reverse_sequence(//reverse the letters of the sequence
+			d_seq1,
+			d_seq1_length);
+
+			FSA_utils::reverse_sequence(//reverse the letters of the sequence
+			d_seq2,
+			d_seq2_length);
+		};
+
+		struct_for_alignment tmp_str;
+
+		alignment_function_(
+		d_seq1,//sequence #1
+		d_seq2,//sequence #2
+		this,
+		(void*)(&tmp_str));
+
+		long int score=tmp_str.d_score;
+		if(s==0)
+		{
+			score_max=score;
+			score_min=score;
+		}
+		else
+		{
+			score_max=FSA_utils::Tmax(score_max,score);
+			score_min=FSA_utils::Tmin(score_min,score);
+		};
+
+		distr.increase_elem_by_1(score);
+
+		if((s+1)%1000==0)
+		{
+			cout<<s+1<<endl;
+		};
+	};
+
+	f<<score_max+1<<endl;
+	for(s=0;s<=score_max;s++)
+	{
+		f<<s<<"\t"<<distr.d_elem[s-distr.d_ind0]<<endl;
+	};
+
+	f.close();
+}
+
+void FSA::DNA_to_3_frames_AA_global(
+string distr_file_name_,
+alignment_function_type *alignment_function_)
+{
+	bool frame_output_flag=false;
+	long int s;
+	double *freqs_from_frames=new double [d_number_of_letters2];
+	for(s=0;s<d_number_of_letters2;s++)
+	{
+		freqs_from_frames[s]=0;
+	};
+
+	ofstream f(distr_file_name_.data());
+	if(!f)
+	{
+		throw error("Error - the file "+distr_file_name_+" is not found\n",3);
+	};
+
+	array_v<double> distr(this);
+
+
+	
+	long int score_max=small_long,score_min=-small_long;
+
+	for(s=0;s<d_seq_number;s++)
+	{
+		long int i,j;
+		//generate sequence #1
+		for(i=0;i<d_seq1_length;i++)
+		{
+			d_seq1[i]=random_AA1();
+		};
+		//generate sequence #2
+		for(j=0;j<d_seq2_length;j++)
+		{
+			d_seq2[j]=random_AA2();
+		};
+
+		if(d_reversed_seq)
+		{
+			FSA_utils::reverse_sequence(//reverse the letters of the sequence
+			d_seq1,
+			d_seq1_length);
+
+			FSA_utils::reverse_sequence(//reverse the letters of the sequence
+			d_seq2,
+			d_seq2_length);
+		};
+
+		struct_for_alignment tmp_str;
+
+		long int score=0;
+
+		long int v;
+		for(v=0;v<d_codon_length;v++)
+		{
+			long int length1_tmp=this->d_seq1_length;
+
+			long int length1_v_div_3=(long int)floor((double)(length1_tmp-v)/3.0);
+
+			long int *seq1_AA=new long int[length1_v_div_3];
+
+			long int j;
+			for(j=0;j<length1_v_div_3;j++)
+			{
+				long int ind=v+j*3;
+				seq1_AA[j]=convert_codon_into_AA(d_seq1+ind);
+				freqs_from_frames[seq1_AA[j]]++;
+			};
+
+
+			this->d_seq1_length=length1_v_div_3;
+
+			alignment_function_(
+			seq1_AA,//sequence #1
+			d_seq2,//sequence #2
+			this,
+			(void*)(&tmp_str));
+
+			this->d_seq1_length=length1_tmp;
+
+			if(v==0)
+			{
+				score=tmp_str.d_score;
+			}
+			else
+			{
+				score=FSA_utils::Tmax(score,tmp_str.d_score);
+			};
+
+			delete[]seq1_AA;
+		};
+
+		if(s==0)
+		{
+			score_max=score;
+			score_min=score;
+		}
+		else
+		{
+			score_max=FSA_utils::Tmax(score_max,score);
+			score_min=FSA_utils::Tmin(score_min,score);
+		};
+
+		distr.increase_elem_by_1(score);
+
+		if((s+1)%1000==0)
+		{
+			cout<<s+1<<endl;
+		};
+	};
+
+	f<<score_max+1<<endl;
+	for(s=0;s<=score_max;s++)
+	{
+		f<<s<<"\t"<<distr.d_elem[s-distr.d_ind0]<<endl;
+	};
+
+	f.close();
+
+	string frames_file_name="RR25_from_frames.in";
+	ofstream freqf;
+	
+	if(frame_output_flag)
+	{
+		freqf.open(frames_file_name.data());
+		if(!freqf)
+		{
+			throw error("Error - the file "+frames_file_name+" is not found\n",3);
+		};
+	};
+
+	double sum=0;
+	for(s=0;s<d_number_of_letters2;s++)
+	{
+		sum+=freqs_from_frames[s];
+	};
+
+	if(frame_output_flag)
+	{
+		freqf<<d_number_of_letters2<<endl;
+		for(s=0;s<d_number_of_letters2;s++)
+		{
+			freqf<<freqs_from_frames[s]/sum<<endl;
+		};
+
+		freqf.close();
+	};
+
+	delete[]freqs_from_frames;
+
+	
+}
+
+
+//general important sampling
+
+IS1_general::IS1_general(
+long int alphabet_letters_number1_,//number of letters in the sequence #1
+long int alphabet_letters_number2_,//number of letters in the sequence #2
+double *RR1_,//background probability for the sequence #1
+double *RR2_,//background probability for the sequence #2
+long int number_of_states_,//number of states
+double **transition_probabilities_,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
+pair<long int, long int> *states_description_,//description of the states; the index is a state number
+double ***states_distr_)//distributions of the states; the index is a state number
+{
+	d_alphabet_letters_number1=alphabet_letters_number1_;
+	d_alphabet_letters_number2=alphabet_letters_number2_;
+	d_RR1=RR1_;
+	d_RR2=RR2_;
+	d_number_of_states=number_of_states_;
+	d_states_description=states_description_;
+	d_states_distr=states_distr_;
+
+	if(d_number_of_states<=0)
+	{
+		throw error("Error - incorrect parameter number_of_states_ in IS1_general::IS1_general\n",1);
+	};
+
+	d_states_distr_dimensions=new pair<long int, long int>[d_number_of_states];
+	FSA_utils::assert_mem(d_states_distr_dimensions);
+
+	d_states_sum_distr=new double*[d_number_of_states];
+	FSA_utils::assert_mem(d_states_sum_distr);
+
+	long int max_dim=d_number_of_states;
+
+	d_max_dim1=-1;
+	d_max_dim2=-1;
+
+	long int s;
+	for(s=0;s<d_number_of_states;s++)
+	{
+		d_max_dim1=FSA_utils::Tmax(d_max_dim1,d_states_description[s].first);
+		d_max_dim2=FSA_utils::Tmax(d_max_dim2,d_states_description[s].second);
+
+		long int dim1=FSA_utils::power_long(alphabet_letters_number1_,d_states_description[s].first);
+		long int dim2=FSA_utils::power_long(alphabet_letters_number2_,d_states_description[s].second);
+
+
+		d_states_distr_dimensions[s]=make_pair(dim1,dim2);
+
+		max_dim=FSA_utils::Tmax(max_dim,dim1*dim2);
+
+		IS1_general::generate_one_state_sum_distr(//calculates sum-distributions corresponded to the input parameters
+		d_states_distr_dimensions[s],//dimensions of the matrix state_distr_
+		d_states_distr[s],//state distribution in the same format as in d_states_distr[s]
+		d_states_sum_distr[s]);//the result; the dimention is state_distr__dim1 x state_distr__dim2
+
+	};
+
+
+	d_states_sum_distr_elements_for_all_states=new long int[max_dim];
+	FSA_utils::assert_mem(d_states_sum_distr_elements_for_all_states);
+
+	
+
+	long int i;
+	for(i=0;i<max_dim;i++)
+	{
+		d_states_sum_distr_elements_for_all_states[i]=i;
+	};
+
+	FSA_utils::get_memory_for_matrix(d_number_of_states,d_number_of_states,d_transition_probabilities_sum);
+	FSA_utils::get_memory_for_matrix(d_number_of_states,d_number_of_states,d_transition_probabilities);
+
+	double eps=1e-5;
+
+	for(s=0;s<d_number_of_states;s++)
+	{
+		double sum_tmp=0;
+		long int s2;
+		for(s2=0;s2<d_number_of_states;s2++)
+		{
+			d_transition_probabilities[s][s2]=transition_probabilities_[s][s2];
+			d_transition_probabilities_sum[s][s2]=transition_probabilities_[s][s2];
+			sum_tmp+=transition_probabilities_[s][s2];
+		};
+		if(fabs(sum_tmp-1.0)>eps)
+		{
+			throw error("Unexpected error in the parameter transition_probabilities_ of the function IS1_general::IS1_general\n",1);
+		};
+
+		for(s2=0;s2<d_number_of_states;s2++)
+		{
+			d_transition_probabilities[s][s2]/=sum_tmp;
+		};
+
+		FSA_utils::convert_distr_into_sum(//calculates and allocates sum-distribution
+		d_number_of_states,//dimension
+		d_transition_probabilities_sum[s]);//the result; the dimention is state_distr__dim1 x state_distr__dim2
+
+	};
+
+
+	d_tmp_letters=new pair<long int*, long int*>[d_number_of_states];
+	FSA_utils::assert_mem(d_tmp_letters);
+
+	for(s=0;s<d_number_of_states;s++)
+	{
+		d_tmp_letters[s].first=new long int[d_states_description[s].first];
+		FSA_utils::assert_mem(d_tmp_letters[s].first);
+		d_tmp_letters[s].second=new long int[d_states_description[s].second];
+		FSA_utils::assert_mem(d_tmp_letters[s].second);
+	};
+
+	allocate_states_distr_sums();
+
+}
+
+IS1_general::~IS1_general()
+{
+	deallocate_states_distr_sums();
+
+	delete[]d_states_distr_dimensions;
+
+	long int s;
+	for(s=0;s<d_number_of_states;s++)
+	{
+		delete[]d_states_sum_distr[s];
+	};
+
+	delete[]d_states_sum_distr_elements_for_all_states;
+	
+	FSA_utils::delete_memory_for_matrix(d_number_of_states,d_transition_probabilities_sum);
+	FSA_utils::delete_memory_for_matrix(d_number_of_states,d_transition_probabilities);
+
+
+	for(s=0;s<d_number_of_states;s++)
+	{
+		delete[]d_tmp_letters[s].first;
+		delete[]d_tmp_letters[s].second;
+	};
+	delete[]d_tmp_letters;
+
+}
+
+void IS1_general::allocate_states_distr_sums()//allocates d_states_distr_sums
+{
+	long int*letters1=new long int[d_max_dim1];
+	FSA_utils::assert_mem(letters1);
+
+	long int*letters2=new long int[d_max_dim2];
+	FSA_utils::assert_mem(letters2);
+
+
+	long int s,x1,x2;
+
+	d_states_distr_sums=new double ****[d_number_of_states];
+	FSA_utils::assert_mem(d_states_distr_sums);
+
+	for(s=0;s<d_number_of_states;s++)
+	{
+		d_states_distr_sums[s]=new double ***[d_states_description[s].first+1];
+		FSA_utils::assert_mem(d_states_distr_sums[s]);
+
+		long int dim1;
+		long int dim2;
+
+		for(x1=0;x1<=d_states_description[s].first;x1++)
+		{
+			dim1=FSA_utils::power_long(d_alphabet_letters_number1,x1);
+
+			d_states_distr_sums[s][x1]=new double **[d_states_description[s].second+1];
+			FSA_utils::assert_mem(d_states_distr_sums[s][x1]);
+
+			for(x2=0;x2<=d_states_description[s].second;x2++)
+			{
+				dim2=FSA_utils::power_long(d_alphabet_letters_number2,x2);
+
+				FSA_utils::get_memory_for_matrix(
+				dim1,
+				dim2,
+				d_states_distr_sums[s][x1][x2]);
+
+				long int i1,i2;
+				for(i1=0;i1<dim1;i1++)
+				{
+
+					long int v;
+
+					code_to_letters(//returns a unique code for the array of letters
+					i1,//input code
+					d_alphabet_letters_number1,//total number of letters
+					x1,//dimension of the array with letters
+					letters1);//array of letters; the result
+
+					for(v=x1;v<d_states_description[s].first;v++)
+					{
+						letters1[v]=0;
+					};
+
+					long int code1=letters_to_code(//returns a unique code for the array of letters
+					d_alphabet_letters_number1,//total number of letters
+					d_states_description[s].first,//dimension of the array with letters
+					letters1);//array of letters
+
+					long int len1=FSA_utils::power_long(d_alphabet_letters_number1,d_states_description[s].first-x1)-1;
+
+					double mult1=1.0;
+					for(v=0;v<x1;v++)
+					{
+						mult1*=d_RR1[letters1[v]];
+					};
+
+
+					for(i2=0;i2<dim2;i2++)
+					{
+
+						code_to_letters(//returns a unique code for the array of letters
+						i2,//input code
+						d_alphabet_letters_number2,//total number of letters
+						x2,//dimension of the array with letters
+						letters2);//array of letters; the result
+
+						for(v=x2;v<d_states_description[s].second;v++)
+						{
+							letters2[v]=0;
+						};
+
+						long int code2=letters_to_code(//returns a unique code for the array of letters
+						d_alphabet_letters_number2,//total number of letters
+						d_states_description[s].second,//dimension of the array with letters
+						letters2);//array of letters
+
+						long int len2=FSA_utils::power_long(d_alphabet_letters_number2,d_states_description[s].second-x2)-1;
+
+						double mult2=1.0;
+						for(v=0;v<x2;v++)
+						{
+							mult2*=d_RR2[letters2[v]];
+						};
+
+						double sum_tmp=0;
+						long int v1,v2;
+						for(v1=code1;v1<=code1+len1;v1++)
+						{
+							for(v2=code2;v2<=code2+len2;v2++)
+							{
+								sum_tmp+=d_states_distr[s][v1][v2];
+							};
+						};
+
+						if(sum_tmp!=0&&(mult1==0||mult2==0))
+						{
+							throw error("The parameters d_states_distr and d_RR1 and d_RR2 are contradictory in IS1_general::allocate_states_distr_sums()\n",1);
+						};
+
+						if(mult1==0||mult2==0)
+						{
+							d_states_distr_sums[s][x1][x2][i1][i2]=0;
+						}
+						else
+						{
+							d_states_distr_sums[s][x1][x2][i1][i2]=sum_tmp/(mult1*mult2);
+						};
+
+
+
+
+
+					};
+				};
+			};
+		};
+	};
+
+	delete[]letters1;
+	delete[]letters2;
+
+	//calculate matrices for infinite sums
+
+	
+	{
+		long int code1=0;
+		long int code2=0;
+		long int x1=0;
+		long int x2=0;
+
+		calculate_inverse_matrices_for_the_infinite_sums(
+			code1,
+			code2,
+			&d_A1_inv,
+			&d_A2_inv,
+			x1,
+			x2);
+	};
+
+}
+
+void IS1_general::deallocate_states_distr_sums()//deallocates d_states_distr_sums
+{
+	long int s,x1,x2;
+
+	for(s=0;s<d_number_of_states;s++)
+	{
+
+		long int dim1;
+
+		for(x1=0;x1<=d_states_description[s].first;x1++)
+		{
+			dim1=FSA_utils::power_long(d_alphabet_letters_number1,x1);
+
+
+			for(x2=0;x2<=d_states_description[s].second;x2++)
+			{
+
+				FSA_utils::delete_memory_for_matrix(
+				dim1,
+				d_states_distr_sums[s][x1][x2]);
+			};
+
+			delete[]d_states_distr_sums[s][x1];
+		};
+
+		delete[] d_states_distr_sums[s];
+	};
+
+	delete[]d_states_distr_sums;
+}
+
+
+long int IS1_general::letters_to_code(//returns a unique code for the array of letters
+long int letters_number_,//total number of letters
+long int letters_dim_,//dimension of the array with letters
+long int* letters_)//array of letters
+{
+	if(test_mode)
+	{
+		if(letters_dim_<=0)
+		{
+			if(letters_dim_<0)
+			{
+				throw error("Unexpected error\n",1);
+			};
+			return 0;
+		};
+
+		if(letters_number_<=0)
+		{
+			throw error("Unexpected error\n",1);
+		};
+
+		long int i;
+		for(i=0;i<letters_dim_;i++)
+		{
+			if(letters_[i]<0||letters_[i]>=letters_number_)
+			{
+				throw error("Unexpected error\n",1);
+			};
+		};
+	};
+
+	long int res=letters_[0];
+	long int i;
+	for(i=1;i<letters_dim_;i++)
+	{
+		res=res*letters_number_+letters_[i];
+	};
+
+	return res;
+}
+
+void IS1_general::code_to_letters(//returns a unique code for the array of letters
+long int code_,//input code
+long int letters_number_,//total number of letters
+long int letters_dim_,//dimension of the array with letters
+long int*letters_)//array of letters; the result
+{
+	if(test_mode)
+	{
+		if(letters_dim_<=0)
+		{
+			if(letters_dim_<0)
+			{
+				throw error("Unexpected error\n",1);
+			};
+			return;
+		};
+
+		if(code_<0)
+		{
+			throw error("Unexpected error\n",1);
+		};
+
+		if(letters_number_<=0)
+		{
+			throw error("Unexpected error\n",1);
+		};
+
+	};
+
+	long int i;
+	for(i=letters_dim_-1;i>=0;i--)
+	{
+		letters_[i]=code_%letters_number_;
+		code_=(code_-letters_[i])/letters_number_;
+	};
+
+	if(test_mode)
+	{
+		if(code_!=0)
+		{
+			throw error("Unexpected error\n",1);
+		};
+	};
+
+}
+
+long int IS1_general::matr_indexes_to_code(
+long int code1_,//code #1
+long int code1_number_,//the range of code1_ is [0,code1_number_-1]
+long int code2_,//code #2
+long int code2_number_)//the range of code2_ is [0,code2_number_-1]
+{
+	if(test_mode)
+	{
+		if(code1_number_<=0||code2_number_<=0)
+		{
+			throw error("Unexpected error\n",1);
+		};
+
+		if(code2_<0||code2_>=code2_number_||code1_<0||code1_>=code1_number_)
+		{
+			throw error("Unexpected error\n",1);
+		};
+	};
+
+	return code1_*code2_number_+code2_;
+}
+
+void IS1_general::code_to_matr_indexes(
+long int code_,//input code
+long int &code1_,//code #1; the result
+long int code1_number_,//the range of code1_ is [0,code1_number_-1]
+long int &code2_,//code #2; the result
+long int code2_number_)//the range of code2_ is [0,code2_number_-1]
+{
+	if(test_mode)
+	{
+		if(code1_number_<=0||code2_number_<=0)
+		{
+			throw error("Unexpected error\n",1);
+		};
+	};
+
+	code2_=code_%code2_number_;
+	code1_=(code_-code2_)/code2_number_;
+
+	if(test_mode)
+	{
+
+		if(code2_<0||code2_>=code2_number_||code1_<0||code1_>=code1_number_)
+		{
+			throw error("Unexpected error\n",1);
+		};
+	};
+}
+
+double ** IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+long int alphabet_letters_number1_,//number of letters in the sequence #1
+long int alphabet_letters_number2_,//number of letters in the sequence #2
+pair<long int, long int> state_description_)//state description
+{
+	double ** res=NULL;
+
+	long int dim1=FSA_utils::power_long(alphabet_letters_number1_,state_description_.first);
+	long int dim2=FSA_utils::power_long(alphabet_letters_number2_,state_description_.second);
+
+	FSA_utils::get_memory_for_matrix(dim1,dim2,res);
+
+	return res;
+}
+
+void IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+double **&state_distr_,
+long int alphabet_letters_number1_,//number of letters in the sequence #1
+pair<long int, long int> state_description_)//state description
+{
+	long int dim1=FSA_utils::power_long(alphabet_letters_number1_,state_description_.first);
+
+	FSA_utils::delete_memory_for_matrix(dim1,state_distr_);
+	state_distr_=NULL;
+}
+
+
+void IS1_general::generate_one_state_sum_distr(//calculates sum-distributions corresponded to the input parameters
+pair<long int, long int> state_distr_dims_,//dimensions of the matrix state_distr_
+double **state_distr_,//state distribution in the same format as in d_states_distr[s]
+double *&state_sum_distr_)//the result; the dimention is state_distr__dim1 x state_distr__dim2
+{
+	long int dim1=state_distr_dims_.first;
+	long int dim2=state_distr_dims_.second;
+
+	long int dim=dim1*dim2;
+
+	state_sum_distr_=new double [dim];
+	FSA_utils::assert_mem(state_sum_distr_);
+
+	long int i,j;
+	for(i=0;i<dim1;i++)
+	{
+		for(j=0;j<dim2;j++)
+		{
+			long int code=matr_indexes_to_code(
+			i,//code #1
+			dim1,//the range of code1_ is [0,code1_number_-1]
+			j,//code #2
+			dim2);//the range of code2_ is [0,code2_number_-1]
+
+			state_sum_distr_[code]=state_distr_[i][j];
+
+			if(test_mode)
+			{
+				if(code<0||code>=dim)
+				{
+					throw error("Error - code<0||code>=dim\n",1);
+				};
+			};
+
+		};
+	};
+	
+	FSA_utils::convert_distr_into_sum(//convert distr_[0], distr_[1], distr_[2],... into distr_[0], distr_[0]+distr_[1], distr_[0]+distr_[1]+distr_[2],...
+	dim,
+	state_sum_distr_);
+}
+
+void IS1_general::generate_random_letters_in_a_given_state(
+long int state_number_,//state number
+long int *letters1_,//the resulted letters for the sequence 1; the array must be allocated
+long int *letters2_)//the resulted letters for the sequence 2; the array must be allocated
+{
+	long int dim1=d_states_distr_dimensions[state_number_].first;
+	long int dim2=d_states_distr_dimensions[state_number_].second;
+
+	long int dim=dim1*dim2;
+
+	long int code=FSA_utils::random_long(
+		FSA_utils::ran2(),
+		dim,
+		d_states_sum_distr[state_number_],
+		d_states_sum_distr_elements_for_all_states);
+
+		long int code1;
+		long int code2;
+
+		code_to_matr_indexes(
+		code,
+		code1,
+		dim1,
+		code2,
+		dim2);
+
+		code_to_letters(//returns a unique code for the array of letters
+		code1,//input code
+		//dim1,//total number of letters
+		d_alphabet_letters_number1,
+		d_states_description[state_number_].first,//dimension of the array with letters
+		letters1_);//array of letters; the result
+
+		code_to_letters(//returns a unique code for the array of letters
+		code2,//input code
+		//dim2,//total number of letters
+		d_alphabet_letters_number2,
+		d_states_description[state_number_].second,//dimension of the array with letters
+		letters2_);//array of letters; the result
+
+
+}
+
+void IS1_general::one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
+long int current_state_,//the current state
+long int *seq1_add_letters_,//letters for the sequence #1; the array must be allocated
+long int *seq2_add_letters_,//letters for the sequence #2; the array must be allocated
+long int &new_state_)//a new state
+{
+	//generate a new state
+	new_state_=FSA_utils::random_long(
+		FSA_utils::ran2(),
+		d_number_of_states,
+		d_transition_probabilities_sum[current_state_],
+		d_states_sum_distr_elements_for_all_states);
+
+	generate_random_letters_in_a_given_state(
+		new_state_,//state number
+		seq1_add_letters_,//the resulted letters for the sequence 1; the array must be allocated
+		seq2_add_letters_);//the resulted letters for the sequence 2; the array must be allocated
+
+
+}
+
+//-------------------------------------------------------------------
+//the importance sampling simulation object
+
+IS1_general_simulation::IS1_general_simulation(
+IS1_general *IS1_general_obj_,
+long int initial_state_,//initial state for the IS
+long int max_seq1_length_,//maximum sequence length
+long int max_seq2_length_,//maximum sequence length
+double *initial_distr_)//initial distribution of states; initial_state_ is ignored if d_initial_distr_ is defined
+{
+	d_IS1_general_obj=IS1_general_obj_;
+	d_max_seq1_length=max_seq1_length_;
+	d_max_seq2_length=max_seq2_length_;
+
+	d_seq1=new long int [d_max_seq1_length];
+	FSA_utils::assert_mem(d_seq1);
+
+	d_seq2=new long int [d_max_seq2_length];
+	FSA_utils::assert_mem(d_seq2);
+
+	d_seq1_current_length=0;
+	d_seq2_current_length=0;
+
+	d_initial_state=initial_state_;
+	d_current_state=initial_state_;
+
+	d_initial_distr_sum=NULL;
+	if(initial_distr_)
+	{
+		double eps_tmp=1e-10;
+		double sum_tmp=0;
+		d_initial_distr_sum=new double[IS1_general_obj_->d_number_of_states];
+		FSA_utils::assert_mem(d_initial_distr_sum);
+		long int i;
+		for(i=0;i<IS1_general_obj_->d_number_of_states;i++)
+		{
+			d_initial_distr_sum[i]=initial_distr_[i];
+			sum_tmp+=initial_distr_[i];
+		};
+		if(fabs(sum_tmp-1.0)>=eps_tmp)
+		{
+			throw error("Unexpected error - the sum of probablities in initial_distr_ is not 1.0 in IS1_general_simulation::IS1_general_simulation\n",1);
+		};
+
+		FSA_utils::convert_distr_into_sum(//convert distr_[0], distr_[1], distr_[2],... into distr_[0], distr_[0]+distr_[1], distr_[0]+distr_[1]+distr_[2],...
+			IS1_general_obj_->d_number_of_states,
+			d_initial_distr_sum);
+
+		d_current_state=FSA_utils::random_long<long int>(
+		FSA_utils::ran2(),
+		d_IS1_general_obj->d_number_of_states,
+		d_initial_distr_sum);
+
+
+	};
+
+
+	//weights calculation
+	long int depth1=-1;
+	long int depth2=-1;
+
+	long int s;
+	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+	{
+		depth1=FSA_utils::Tmax(depth1,d_IS1_general_obj->d_states_description[s].first);
+		depth2=FSA_utils::Tmax(depth2,d_IS1_general_obj->d_states_description[s].second);
+	};
+
+	d_W1_step1=depth1+1;
+	d_W1_step2=depth2+1;
+
+	depth1+=d_W1_step1;
+	depth2+=d_W1_step2;
+
+	d_W1=new two_dim_layer<double>* [d_IS1_general_obj->d_number_of_states];
+	FSA_utils::assert_mem(d_W1);
+
+	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+	{
+		d_W1[s]=new two_dim_layer<double> (
+			max_seq1_length_,
+			max_seq2_length_,
+			depth1,
+			depth2,
+			0);
+
+	};
+
+}
+
+
+IS1_general_simulation::IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
+IS1_general_simulation *IS1_general_simulation_)//maximum sequence length
+{
+	d_IS1_general_obj=IS1_general_simulation_->d_IS1_general_obj;
+	d_max_seq1_length=IS1_general_simulation_->d_W1_seq1_current_length;
+	d_max_seq2_length=IS1_general_simulation_->d_W1_seq2_current_length;
+
+	d_seq1_current_length=IS1_general_simulation_->d_seq1_current_length;
+	d_seq2_current_length=IS1_general_simulation_->d_seq2_current_length;
+
+	d_seq1=new long int [d_seq1_current_length];
+	FSA_utils::assert_mem(d_seq1);
+
+	d_seq2=new long int [d_seq2_current_length];
+	FSA_utils::assert_mem(d_seq2);
+
+
+	d_initial_state=IS1_general_simulation_->d_initial_state;
+	d_current_state=IS1_general_simulation_->d_current_state;
+
+	d_initial_distr_sum=NULL;
+	if(IS1_general_simulation_->d_initial_distr_sum)
+	{
+		d_initial_distr_sum=new double[IS1_general_simulation_->d_IS1_general_obj->d_number_of_states];
+		FSA_utils::assert_mem(d_initial_distr_sum);
+		long int i;
+		for(i=0;i<IS1_general_simulation_->d_IS1_general_obj->d_number_of_states;i++)
+		{
+			d_initial_distr_sum[i]=IS1_general_simulation_->d_initial_distr_sum[i];
+		};
+	};
+
+	//weights calculation
+	long int depth1=-1;
+	long int depth2=-1;
+
+	long int s;
+	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+	{
+		depth1=FSA_utils::Tmax(depth1,d_IS1_general_obj->d_states_description[s].first);
+		depth2=FSA_utils::Tmax(depth2,d_IS1_general_obj->d_states_description[s].second);
+	};
+
+	d_W1_step1=depth1+1;
+	d_W1_step2=depth2+1;
+
+	depth1+=d_W1_step1;
+	depth2+=d_W1_step2;
+
+	d_W1=new two_dim_layer<double>* [d_IS1_general_obj->d_number_of_states];
+	FSA_utils::assert_mem(d_W1);
+
+	d_W1_seq1_current_length=IS1_general_simulation_->d_W1_seq1_current_length;;
+	d_W1_seq2_current_length=IS1_general_simulation_->d_W1_seq2_current_length;;
+
+
+	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+	{
+		d_W1[s]=new two_dim_layer<double> (//constructor; copies data from two_dim_layer_ with minimally allocated memory
+		d_W1_seq1_current_length,
+		d_W1_seq2_current_length,
+		IS1_general_simulation_->d_W1[s]);
+	};
+
+
+	//copy sequences
+	for(s=0;s<d_seq1_current_length;s++)
+	{
+		d_seq1[s]=IS1_general_simulation_->d_seq1[s];
+	};
+
+	for(s=0;s<d_seq2_current_length;s++)
+	{
+		d_seq2[s]=IS1_general_simulation_->d_seq2[s];
+	};
+
+
+}
+
+
+IS1_general_simulation::~IS1_general_simulation()
+{
+	delete[]d_seq1;
+	delete[]d_seq2;
+	delete[]d_initial_distr_sum;
+
+	//weights calculation
+	long int s;
+	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+	{
+		delete d_W1[s];
+	};
+}
+
+void IS1_general_simulation::init()//initialization for a new sequence generation
+{
+	d_seq1_current_length=0;
+	d_seq2_current_length=0;
+
+	d_current_state=d_initial_state;
+
+	if(d_initial_distr_sum)
+	{
+		d_current_state=FSA_utils::random_long<long int>(
+		FSA_utils::ran2(),
+		d_IS1_general_obj->d_number_of_states,
+		d_initial_distr_sum);
+	};
+
+	//weights calculation
+	d_W1_seq1_current_length=-1;
+	d_W1_seq2_current_length=-1;
+
+}
+
+void IS1_general_simulation::simulate_upto_target_lengths(
+long int target_seq1_length_,//target length of the sequence #1
+long int target_seq2_length_)//target length of the sequence #2
+{
+	
+	long int new_state;
+
+	while((d_seq1_current_length<target_seq1_length_)||(d_seq2_current_length<target_seq2_length_))
+	{
+		long int expected_len1=d_seq1_current_length+d_IS1_general_obj->d_max_dim1;
+		long int expected_len2=d_seq2_current_length+d_IS1_general_obj->d_max_dim2;
+
+
+		if(expected_len1>d_max_seq1_length||expected_len2>d_max_seq2_length)
+		{
+			throw error("Error - please increase maximum allowed sequence length in IS1_general_simulation::simulate_upto_target_lengths\n",1);
+		};
+
+		d_IS1_general_obj->one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
+		d_current_state,//the current state
+		d_seq1+d_seq1_current_length,//letters for the sequence #1; the array must be allocated
+		d_seq2+d_seq2_current_length,//letters for the sequence #2; the array must be allocated
+		new_state);//a new state
+
+
+		d_current_state=new_state;
+
+		d_seq1_current_length+=d_IS1_general_obj->d_states_description[d_current_state].first;
+		d_seq2_current_length+=d_IS1_general_obj->d_states_description[d_current_state].second;
+
+	};
+	
+}
+
+//weights calculation
+void IS1_general_simulation::calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
+long int target_length1_,//target length for sequence #1
+long int target_length2_,//target length for sequence #2
+long int i1_,//the first index (corresponded to the sequence #1)
+long int i2_)//the second index (corresponded to the sequence #2)
+{
+	if(i1_>d_max_seq1_length||i2_>d_max_seq2_length)
+	{
+		throw error("Unexpected error - i1_>d_max_seq1_length||i2_>d_max_seq2_length in IS1_general_simulation::calculate_weight_W1_one_step\n",1);
+	};
+
+	if(i1_==0&&i2_==0)
+	{
+
+		long int s;
+		for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+		{
+			d_W1[s]->set_element(i1_,i2_,0);
+		};
+
+		d_W1[d_initial_state]->set_element(i1_,i2_,1.0);
+
+		if(d_initial_distr_sum)
+		{
+			s=0;
+			d_W1[s]->set_element(i1_,i2_,d_initial_distr_sum[s]);
+
+			for(s=1;s<d_IS1_general_obj->d_number_of_states;s++)
+			{
+				d_W1[s]->set_element(i1_,i2_,d_initial_distr_sum[s]-d_initial_distr_sum[s-1]);
+			};
+		};
+
+		return;
+	};
+	
+
+	long int s;
+	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+	{
+
+		long int dim1_tmp=d_IS1_general_obj->d_states_description[s].first;
+		long int diff1=-dim1_tmp+i1_;
+
+		long int dim2_tmp=d_IS1_general_obj->d_states_description[s].second;
+		long int diff2=-dim2_tmp+i2_;
+
+		long int code1=-1;
+		long int code2=-1;
+
+
+		double w_tmp=0;
+
+		if(diff1>=0&&diff2>=0)
+		{
+
+			
+			long int x1;
+			long int tmp_d=i1_-target_length1_;
+			if(-tmp_d>=0)
+			{
+				x1=dim1_tmp;
+			}
+			else
+			{
+				if(tmp_d>=dim1_tmp)
+				{
+					x1=0;
+				}
+				else
+				{
+					x1=dim1_tmp-tmp_d;
+				};
+			};
+
+			long int x2;
+			tmp_d=i2_-target_length2_;
+			if(-tmp_d>=0)
+			{
+				x2=dim2_tmp;
+			}
+			else
+			{
+				if(tmp_d>=dim2_tmp)
+				{
+					x2=0;
+				}
+				else
+				{
+					x2=dim2_tmp-tmp_d;
+				};
+			};
+
+		code1=d_IS1_general_obj->letters_to_code(//returns a unique code for the array of letters
+			d_IS1_general_obj->d_alphabet_letters_number1,//total number of letters
+			x1,//dimension of the array with letters
+			d_seq1+diff1);//array of letters
+
+		code2=d_IS1_general_obj->letters_to_code(//returns a unique code for the array of letters
+			d_IS1_general_obj->d_alphabet_letters_number2,//total number of letters
+			x2,//dimension of the array with letters
+			d_seq2+diff2);//array of letters
+
+
+			double q2=d_IS1_general_obj->d_states_distr_sums[s][x1][x2][code1][code2];
+
+
+
+
+			long int x;
+			for(x=0;x<d_IS1_general_obj->d_number_of_states;x++)
+			{
+				w_tmp+=d_IS1_general_obj->d_transition_probabilities[x][s]*d_W1[x]->get_element(i1_-dim1_tmp,i2_-dim2_tmp);
+			};
+			w_tmp*=q2;
+		};
+
+
+		d_W1[s]->set_element(i1_,i2_,w_tmp);
+
+
+	};
+
+}
+
+void IS1_general_simulation::calculate_weight_W1_upto_target_lengths(
+long int target_seq1_length_,//target length of the sequence #1
+long int target_seq2_length_,//target length of the sequence #2
+long int seq1_length_tmp_,//the weights are calculated upto this length for the sequence #1
+long int seq2_length_tmp_)//the weights are calculated upto this length for the sequence #2
+{
+	if(d_W1_seq1_current_length==-1&&d_W1_seq2_current_length==-1)
+	{
+		calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
+		target_seq1_length_,
+		target_seq2_length_,
+		0,//the first index (corresponded to the sequence #1)
+		0);//the second index (corresponded to the sequence #2)
+
+		d_W1_seq1_current_length=0;
+		d_W1_seq2_current_length=0;
+	};
+
+
+	long int ind1,ind2;
+
+	for(ind1=d_W1_seq1_current_length+1;ind1<=seq1_length_tmp_;ind1++)
+	{
+
+
+		long int s;
+		for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+		{
+			d_W1[s]->set_max_ind(ind1,d_W1_seq2_current_length);
+		};
+
+		long int i2;
+		for(i2=0;i2<=d_W1_seq2_current_length;i2++)
+		{
+			calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
+			target_seq1_length_,
+			target_seq2_length_,
+			ind1,//the first index (corresponded to the sequence #1)
+			i2);//the second index (corresponded to the sequence #2)
+		};
+
+	};
+
+	d_W1_seq1_current_length=target_seq1_length_;
+
+	for(ind2=d_W1_seq2_current_length+1;ind2<=seq2_length_tmp_;ind2++)
+	{
+
+		long int s;
+		for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+		{
+			d_W1[s]->set_max_ind(seq1_length_tmp_,ind2);
+		};
+
+		long int i1;
+		for(i1=0;i1<=seq1_length_tmp_;i1++)
+		{
+			calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
+			target_seq1_length_,
+			target_seq2_length_,
+			i1,//the first index (corresponded to the sequence #1)
+			ind2);//the second index (corresponded to the sequence #2)
+		};
+
+	};
+	
+	d_W1_seq2_current_length=target_seq2_length_;
+
+}
+
+void IS1_general_simulation::calculate_weight_W1_for_fixed_lengths_using_recursions(
+long int target_seq1_length_,//target length of the sequence #1
+long int target_seq2_length_,//target length of the sequence #2
+double &weight_,//the resulted weight
+bool save_matrices_,
+std::vector<std::vector<double> > *A1_,
+std::vector<std::vector<double> > *A2_)
+{
+	map<long int,bool> ind1_flag;
+	map<long int,bool> ind2_flag;
+	if(save_matrices_)
+	{
+		long int dimA1=0;
+		long int dimA2=0;
+
+		long int s;
+		for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+		{
+			long int dim1_tmp=d_IS1_general_obj->d_states_description[s].first;
+			long int dim2_tmp=d_IS1_general_obj->d_states_description[s].second;
+
+			if(dim1_tmp==0)
+			{
+				dimA2++;
+				ind2_flag[s]=true;
+			};
+
+			if(dim2_tmp==0)
+			{
+				dimA1++;
+				ind1_flag[s]=true;
+			};
+
+		};
+
+		if(save_matrices_)
+		{
+			A1_->clear();
+			A2_->clear();
+
+			if(dimA1>0)
+			{
+				A1_->resize(dimA1,std::vector<double> (dimA1+1,1));
+			};
+
+			if(dimA2>0)
+			{
+				A2_->resize(dimA2,std::vector<double> (dimA2+1,1));
+			};
+		};
+
+	};
+	
+	long int i1_ind_max=target_seq1_length_+d_IS1_general_obj->d_max_dim1-1;
+	long int i2_ind_max=target_seq2_length_+d_IS1_general_obj->d_max_dim2-1;
+
+	long int s;
+	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+	{
+		d_W1[s]->set_max_ind(i1_ind_max,i2_ind_max);
+	};
+
+	long int seq1_length_tmp=target_seq1_length_+d_IS1_general_obj->d_max_dim1-1;
+	long int seq2_length_tmp=target_seq2_length_+d_IS1_general_obj->d_max_dim2-1;
+
+	calculate_weight_W1_upto_target_lengths(
+		target_seq1_length_,//target length of the sequence #1
+		target_seq2_length_,//target length of the sequence #2
+		seq1_length_tmp,
+		seq2_length_tmp);
+
+
+	array_v<double> *sum_over_ind1=new array_v<double>[d_IS1_general_obj->d_number_of_states];
+	array_v<double> *sum_over_ind2=new array_v<double>[d_IS1_general_obj->d_number_of_states];
+
+	
+	{
+		
+		//index #1
+		long int s;
+
+		long int i1;
+		for(i1=-d_IS1_general_obj->d_max_dim1;i1<0;i1++)
+		{
+			for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+			{
+				sum_over_ind2[s].set_elem(i1,0);
+			};
+		};
+
+
+		
+		for(i1=0;i1<=i1_ind_max;i1++)
+		{
+
+			if(save_matrices_)
+			{
+				if(i1!=target_seq1_length_)
+				{
+					continue;
+				};
+			};
+
+			bool explicit_dependency_flag=true;
+
+			loop1:;
+
+			vector<double> x2_vect;
+
+			long int ind_count=-1;
+			
+			
+
+			for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+			{
+
+				long int dim1_tmp=d_IS1_general_obj->d_states_description[s].first;
+				long int dim2_tmp=d_IS1_general_obj->d_states_description[s].second;
+
+				
+
+				if(explicit_dependency_flag)
+				{
+					if(dim1_tmp==0)
+					{
+						continue;
+					};
+				}
+				else
+				{
+					if(dim1_tmp!=0)
+					{
+						continue;
+					};
+					
+				};
+
+				double x2_vect_elem=0;
+
+
+	//------------------------------------------
+				long int diff1=-dim1_tmp+i1;
+
+
+				double w_tmp=0;
+				double q2=0;
+
+				if(diff1>=0)
+				{
+					long int code1=-1;
+					long int code2=0;
+
+					
+					long int x1;
+					long int tmp_d=i1-target_seq1_length_;
+					if(-tmp_d>=0)
+					{
+						x1=dim1_tmp;
+					}
+					else
+					{
+						if(tmp_d>=dim1_tmp)
+						{
+							x1=0;
+						}
+						else
+						{
+							x1=dim1_tmp-tmp_d;
+						};
+					};
+
+					
+
+					long int x2=0;
+
+				code1=d_IS1_general_obj->letters_to_code(//returns a unique code for the array of letters
+					d_IS1_general_obj->d_alphabet_letters_number1,//total number of letters
+					x1,//dimension of the array with letters
+					d_seq1+diff1);//array of letters
+
+
+					q2=d_IS1_general_obj->d_states_distr_sums[s][x1][x2][code1][code2];
+					
+
+
+					if(save_matrices_)
+					{
+						if(i1==target_seq1_length_)
+						{
+							if(!explicit_dependency_flag)
+							{
+								if(dim1_tmp==0)
+								{
+									ind_count++;
+
+									long int ind_count2=-1;
+									long int s1;
+									for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
+									{
+										if(ind2_flag[s1])
+										{
+											ind_count2++;
+
+											(*A2_)[ind_count][ind_count2]=d_IS1_general_obj->d_transition_probabilities[s1][s]*q2;
+
+											if(s==s1)
+											{
+												(*A2_)[ind_count][ind_count2]-=1.0;
+											};
+
+										};
+									};
+								};
+							};
+						};
+						continue;
+					};
+
+
+		//------------------------------------------
+
+
+					long int s1;
+					if(explicit_dependency_flag)
+					{
+						for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
+						{
+							w_tmp+=d_IS1_general_obj->d_transition_probabilities[s1][s]*sum_over_ind2[s1].get_elem(i1-dim1_tmp);
+						};
+
+						w_tmp*=q2;
+					}
+					else
+					{
+						long int s1;
+						for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
+						{
+							if(!(d_IS1_general_obj->d_states_description[s1].first==0))
+							{
+								x2_vect_elem-=d_IS1_general_obj->d_transition_probabilities[s1][s]*sum_over_ind2[s1].get_elem(i1-dim1_tmp);
+							};
+
+						};
+
+						x2_vect_elem*=q2;
+
+					};
+
+
+
+
+					
+					
+
+				};
+
+				long int ii2;
+				for(ii2=0;ii2<dim2_tmp;ii2++)
+				{
+					double ww=d_W1[s]->get_element(i1,target_seq2_length_+ii2);
+					if(explicit_dependency_flag)
+					{
+						w_tmp+=ww;
+					}
+					else
+					{
+						x2_vect_elem-=ww;
+					};
+				};
+
+
+
+
+				if(explicit_dependency_flag)
+				{
+					sum_over_ind2[s].set_elem(i1,w_tmp);
+				}
+				else
+				{
+					x2_vect.push_back(x2_vect_elem);
+				};
+
+			};
+
+			if(explicit_dependency_flag)
+			{
+				explicit_dependency_flag=false;
+				goto loop1;
+			};
+
+			if(!explicit_dependency_flag)
+			{
+				if(d_IS1_general_obj->d_A2_inv.size()>0)
+				{
+					
+					std::vector<double> res2;
+					
+					FSA_utils::multiply_matrix_and_vector(
+						d_IS1_general_obj->d_A2_inv,
+						x2_vect,
+						res2);
+						
+
+
+					long int dimA2=0;
+
+					long int s;
+					for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+					{
+
+						long int dim1_t=d_IS1_general_obj->d_states_description[s].first;
+
+
+						if(dim1_t==0)
+						{
+							sum_over_ind2[s].set_elem(i1,res2[dimA2]);
+							dimA2++;
+						};
+
+
+					};
+
+				};
+
+			};
+
+		};
+	};
+
+
+//============================================================================================
+
+	{
+		//index #2
+		long int s;
+
+		long int i2;
+		for(i2=-d_IS1_general_obj->d_max_dim2;i2<0;i2++)
+		{
+			for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+			{
+				sum_over_ind1[s].set_elem(i2,0);
+			};
+		};
+
+
+		
+		for(i2=0;i2<=i2_ind_max;i2++)
+		{
+
+			if(save_matrices_)
+			{
+				if(i2!=target_seq2_length_)
+				{
+					continue;
+				};
+			};
+
+			bool explicit_dependency_flag=true;
+
+			loop2:;
+
+			vector<double> x1_vect;
+
+			long int ind_count=-1;
+			
+
+			for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+			{
+
+
+				long int dim1_tmp=d_IS1_general_obj->d_states_description[s].first;
+				long int dim2_tmp=d_IS1_general_obj->d_states_description[s].second;
+
+				if(explicit_dependency_flag)
+				{
+					if(dim2_tmp==0)
+					{
+						continue;
+					};
+				}
+				else
+				{
+					if(dim2_tmp!=0)
+					{
+						continue;
+					};
+				};
+
+				double x1_vect_elem=0;
+
+
+	//------------------------------------------
+				long int diff2=-dim2_tmp+i2;
+
+
+				double w_tmp=0;
+
+				double q2=0;
+
+				if(diff2>=0)
+				{
+					long int code1=0;
+					long int code2=-1;
+
+					
+					long int x2;
+					long int tmp_d=i2-target_seq2_length_;
+					if(-tmp_d>=0)
+					{
+						x2=dim2_tmp;
+					}
+					else
+					{
+						if(tmp_d>=dim2_tmp)
+						{
+							x2=0;
+						}
+						else
+						{
+							x2=dim2_tmp-tmp_d;
+						};
+					};
+
+					
+
+					long int x1=0;
+
+
+				code2=d_IS1_general_obj->letters_to_code(//returns a unique code for the array of letters
+					d_IS1_general_obj->d_alphabet_letters_number2,//total number of letters
+					x2,//dimension of the array with letters
+					d_seq2+diff2);//array of letters
+
+
+					q2=d_IS1_general_obj->d_states_distr_sums[s][x1][x2][code1][code2];
+
+					if(save_matrices_)
+					{
+						if(i2==target_seq2_length_)
+						{
+							if(!explicit_dependency_flag)
+							{
+								if(dim2_tmp==0)
+								{
+									ind_count++;
+
+									long int ind_count2=-1;
+									long int s1;
+									for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
+									{
+										if(ind1_flag[s1])
+										{
+											ind_count2++;
+
+											(*A1_)[ind_count][ind_count2]=d_IS1_general_obj->d_transition_probabilities[s1][s]*q2;
+
+											if(s==s1)
+											{
+												(*A1_)[ind_count][ind_count2]-=1.0;
+											};
+
+										};
+									};
+								};
+							};
+						};
+						continue;
+					};
+
+
+		//------------------------------------------
+
+
+					long int s1;
+					if(explicit_dependency_flag)
+					{
+						for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
+						{
+							w_tmp+=d_IS1_general_obj->d_transition_probabilities[s1][s]*sum_over_ind1[s1].get_elem(i2-dim2_tmp);
+						};
+
+						w_tmp*=q2;
+					}
+					else
+					{
+						long int s1;
+						for(s1=0;s1<d_IS1_general_obj->d_number_of_states;s1++)
+						{
+							if(!(d_IS1_general_obj->d_states_description[s1].second==0))
+							{
+								x1_vect_elem-=d_IS1_general_obj->d_transition_probabilities[s1][s]*sum_over_ind1[s1].get_elem(i2-dim2_tmp);
+							};
+
+						};
+
+						x1_vect_elem*=q2;
+
+					};
+
+
+
+				};
+
+				long int ii1;
+				for(ii1=0;ii1<dim1_tmp;ii1++)
+				{
+					double ww=d_W1[s]->get_element(target_seq1_length_+ii1,i2);
+					if(explicit_dependency_flag)
+					{
+						w_tmp+=ww;
+					}
+					else
+					{
+						x1_vect_elem-=ww;
+					};
+
+				};
+
+				if(explicit_dependency_flag)
+				{
+					sum_over_ind1[s].set_elem(i2,w_tmp);
+				}
+				if(!explicit_dependency_flag)
+				{
+					x1_vect.push_back(x1_vect_elem);
+				};
+
+
+			};
+
+			if(explicit_dependency_flag)
+			{
+				explicit_dependency_flag=false;
+				goto loop2;
+			};
+
+			if(!explicit_dependency_flag)
+			{
+				if(d_IS1_general_obj->d_A2_inv.size()>0)
+				{
+					
+					std::vector<double> res1;
+					
+					FSA_utils::multiply_matrix_and_vector(
+						d_IS1_general_obj->d_A1_inv,
+						x1_vect,
+						res1);
+						
+
+
+					long int dimA1=0;
+					
+
+					long int s;
+					for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+					{
+						
+						long int dim2_t=d_IS1_general_obj->d_states_description[s].second;
+
+
+						if(dim2_t==0)
+						{
+							sum_over_ind1[s].set_elem(i2,res1[dimA1]);
+							
+							dimA1++;
+						};
+
+					};
+
+				};
+
+			};
+
+
+
+		};
+
+	};
+
+	weight_=0;
+
+	for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+	{
+		long int dim1_tmp=d_IS1_general_obj->d_states_description[s].first;
+		long int dim2_tmp=d_IS1_general_obj->d_states_description[s].second;
+
+		long int i1;
+		for(i1=0;i1<dim1_tmp;i1++)
+		{
+			weight_+=sum_over_ind2[s].get_elem(target_seq1_length_+i1);
+		};
+
+		long int i2;
+		for(i2=0;i2<dim2_tmp;i2++)
+		{
+			weight_+=sum_over_ind1[s].get_elem(target_seq2_length_+i2);
+		};
+
+		for(i1=0;i1<dim1_tmp;i1++)
+		{
+			for(i2=0;i2<dim2_tmp;i2++)
+			{
+				weight_-=d_W1[s]->get_element(target_seq1_length_+i1,target_seq2_length_+i2);
+			};
+		};
+
+		
+	};
+
+
+	delete[]sum_over_ind1;
+	delete[]sum_over_ind2;
+
+
+
+}
+
+//================================
+void IS1_general::calculate_inverse_matrices_for_the_infinite_sums(
+long int code1_,
+long int code2_,
+std::vector<std::vector<double> > *A1_inv_,
+std::vector<std::vector<double> > *A2_inv_,
+long int x1_,
+long int x2_)
+{
+	std::vector<std::vector<double> > A1;
+	std::vector<std::vector<double> > A2;
+
+	map<long int,bool> ind1_flag;
+	map<long int,bool> ind2_flag;
+
+	{
+		long int dimA1=0;
+		long int dimA2=0;
+
+		long int s;
+		for(s=0;s<d_number_of_states;s++)
+		{
+			long int dim1_tmp=d_states_description[s].first;
+			long int dim2_tmp=d_states_description[s].second;
+
+			if(dim1_tmp==0)
+			{
+				dimA2++;
+				ind2_flag[s]=true;
+			};
+
+			if(dim2_tmp==0)
+			{
+				dimA1++;
+				ind1_flag[s]=true;
+			};
+
+		};
+
+		
+		
+
+		if(x1_>=0)
+		{
+			A1.clear();
+			(*A1_inv_).clear();
+			if(dimA1>0)
+			{
+				A1.resize(dimA1,std::vector<double> (dimA1+1,1));
+			};
+			
+		};
+
+
+		if(x2_>=0)
+		{
+			A2.clear();
+			(*A2_inv_).clear();
+			if(dimA2>0)
+			{
+				A2.resize(dimA2,std::vector<double> (dimA2+1,1));
+			};
+		};
+
+
+	};
+	
+
+	if(x1_>=0)
+	{
+		
+		//index #1
+		long int s;
+		long int ind_count=-1;
+
+		for(s=0;s<d_number_of_states;s++)
+		{
+			long int dim1_tmp=d_states_description[s].first;
+
+			if(dim1_tmp!=0)
+			{
+				continue;
+			};
+
+
+			double q2=0;
+
+			long int code1=code1_;
+			long int code2=0;
+
+			
+			long int x1=x1_;
+			long int x2=0;
+
+			q2=d_states_distr_sums[s][x1][x2][code1][code2];
+			
+
+
+			ind_count++;
+
+			long int ind_count2=-1;
+			long int s1;
+			for(s1=0;s1<d_number_of_states;s1++)
+			{
+				if(ind2_flag[s1])
+				{
+					ind_count2++;
+
+					A2[ind_count][ind_count2]=d_transition_probabilities[s1][s]*q2;
+
+					if(s==s1)
+					{
+						A2[ind_count][ind_count2]-=1.0;
+					};
+
+				};
+			};
+
+		};
+
+
+
+
+		if(A2.size()>0)
+		{
+			double inside_eps=1e-12;
+			std::vector<double> x2;
+			FSA_utils::Gauss(
+				A2,//matrix n*(n+1)
+				x2,//solution
+				inside_eps,
+				A2_inv_);
+		};
+
+		
+
+	};
+
+//============================================================================================
+
+	if(x2_>=0)
+	{
+		//index #2
+		long int s;
+
+		
+
+		long int ind_count=-1;
+
+		for(s=0;s<d_number_of_states;s++)
+		{
+			long int dim2_tmp=d_states_description[s].second;
+
+			if(dim2_tmp!=0)
+			{
+				continue;
+			};
+
+
+
+			double q2=0;
+
+			long int code1=0;
+			long int code2=code2_;
+
+			
+			long int x2=x2_;
+			long int x1=0;
+
+
+
+			q2=d_states_distr_sums[s][x1][x2][code1][code2];
+
+			ind_count++;
+
+			long int ind_count2=-1;
+			long int s1;
+			for(s1=0;s1<d_number_of_states;s1++)
+			{
+				if(ind1_flag[s1])
+				{
+					ind_count2++;
+
+					A1[ind_count][ind_count2]=d_transition_probabilities[s1][s]*q2;
+
+					if(s==s1)
+					{
+						A1[ind_count][ind_count2]-=1.0;
+					};
+
+				};
+			};
+
+
+
+		};
+
+
+
+		if(A1.size()>0)
+		{
+			double inside_eps=1e-12;
+			std::vector<double> x1;
+			FSA_utils::Gauss(
+				A1,//matrix n*(n+1)
+				x1,//solution
+				inside_eps,
+				A1_inv_);
+		};
+
+	};
+
+
+}
+
+//================================
+void IS1_general_simulation::calculate_weight_W1_for_fixed_lengths_using_infinite_sums(
+long int target_seq1_length_,//target length of the sequence #1
+long int target_seq2_length_,//target length of the sequence #2
+double &weight_)//the resulted weight
+{
+	weight_=0;
+
+	long int margin2=FSA_utils::Tmax(d_IS1_general_obj->d_max_dim2,(long int)200);
+	long int margin1=FSA_utils::Tmax(d_IS1_general_obj->d_max_dim1,3*margin2);
+
+	margin1=FSA_utils::Tmin(margin1,d_W1[0]->d_max_ind1-target_seq1_length_);
+	margin2=FSA_utils::Tmin(margin2,d_W1[0]->d_max_ind2-target_seq2_length_);
+
+	//if(d_W1_seq1_current_length==0&&d_W1_seq2_current_length==0)
+	{
+		calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
+		target_seq1_length_,
+		target_seq2_length_,
+		0,//the first index (corresponded to the sequence #1)
+		0);//the second index (corresponded to the sequence #2)
+	};
+
+	d_W1_seq1_current_length=-1;
+	d_W1_seq2_current_length=-1;
+
+	while(d_W1_seq1_current_length<target_seq1_length_+margin1)
+	{
+
+		d_W1_seq1_current_length++;
+
+		long int i1_ind_max=d_W1_seq1_current_length;
+
+		long int i2_ind_max=FSA_utils::Tmax(target_seq2_length_+d_IS1_general_obj->d_max_dim2-1,d_W1_seq2_current_length);
+
+		if(d_W1_seq1_current_length>=target_seq1_length_||
+			d_W1_seq1_current_length<=target_seq1_length_+d_IS1_general_obj->d_max_dim1-1)
+		{
+			i2_ind_max=FSA_utils::Tmax(target_seq2_length_+margin2,d_W1_seq2_current_length);
+		};
+
+		long int s;
+		for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+		{
+			d_W1[s]->set_max_ind(i1_ind_max,i2_ind_max);
+		};
+
+		long int i2;
+		for(i2=0;i2<=i2_ind_max;i2++)
+		{
+
+
+			calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
+			target_seq1_length_,
+			target_seq2_length_,
+			d_W1_seq1_current_length,//the first index (corresponded to the sequence #1)
+			i2);//the second index (corresponded to the sequence #2)
+
+			{
+				
+
+				long int i1=d_W1_seq1_current_length;
+
+				long int i1_diff=i1-target_seq1_length_;
+				long int i2_diff=i2-target_seq2_length_;
+
+				for(s=0;s<d_IS1_general_obj->d_number_of_states;s++)
+				{
+
+					if(i1_diff>=0&&i2_diff>=0&&
+						(i1_diff<d_IS1_general_obj->d_states_description[s].first||
+						i2_diff<d_IS1_general_obj->d_states_description[s].second)
+						)
+					{
+						weight_+=d_W1[s]->get_element(i1,i2);
+					};
+
+				};
+			};
+
+		};
+	};
+
+}
+
+void test::normalize_state_distributions(
+long int alphabet_letters_number1_,//number of letters in the sequence #1
+long int alphabet_letters_number2_,//number of letters in the sequence #2
+
+long int number_of_states_,//number of states
+
+pair<long int, long int> *states_description_,//description of the states; the index is a state number
+double ***states_distr_)//distributions of the states; the index is a state number
+{
+	long int s;
+	for(s=0;s<number_of_states_;s++)
+	{
+		long int dim1=FSA_utils::power_long(alphabet_letters_number1_,states_description_[s].first);
+		long int dim2=FSA_utils::power_long(alphabet_letters_number2_,states_description_[s].second);
+
+		double sum_tmp=0;
+		long int i1,i2;
+		for(i1=0;i1<dim1;i1++)
+		{
+			for(i2=0;i2<dim2;i2++)
+			{
+				sum_tmp+=states_distr_[s][i1][i2];
+			};
+		};
+
+		if(sum_tmp<=0)
+		{
+			throw error("Error: the distribution defined by states_distr_ in test::normalize_state_distributions is incorrect\n",1);
+		};
+
+		for(i1=0;i1<dim1;i1++)
+		{
+			for(i2=0;i2<dim2;i2++)
+			{
+				states_distr_[s][i1][i2]/=sum_tmp;
+			};
+		};
+
+	};
+}
+
+//=============================
+void test::FSA_IS_transition_probabilities_calculation(
+bool &FSA_flag,
+double ***&states_distr,
+
+bool &cs_flag,
+double ***&states_distr_cs,
+
+bool &sim_flag,
+double ***&states_distr_sim,
+
+long int &number_of_states,
+long int &alphabet_letters_number1,
+long int &alphabet_letters_number2,
+pair<long int, long int> *&states_description,
+long int &codon_length,
+long int *&codon_AA,
+double *&RR1,
+double *&RR2,
+map<string, long int> &state_name_into_number,
+long int **&smatr,
+double &ungappedlambda)
+{
+	long int *letters1=new long int[4];
+	long int *letters2=new long int[1];
+	long int *codon_tmp=new long int[3];
+
+	long int s;
+	for(s=0;s<number_of_states;s++)
+	{
+
+		long int i1,i2;
+
+		long int max_ind1=FSA_utils::power_long(alphabet_letters_number1,states_description[s].first);
+		long int max_ind2=FSA_utils::power_long(alphabet_letters_number2,states_description[s].second);
+
+		for(i1=0;i1<max_ind1;i1++)
+		{
+			IS1_general::code_to_letters(//returns a unique code for the array of letters
+			i1,//input code
+			alphabet_letters_number1,//total number of letters
+			states_description[s].first,//dimension of the array with letters
+			letters1);//array of letters; the result
+
+			double tmp1=1;
+			long int t1;
+			for(t1=0;t1<states_description[s].first;t1++)
+			{
+				tmp1*=RR1[letters1[t1]];
+			};
+
+			long int AA1=0;
+
+			if(s==state_name_into_number["S1"])
+			{
+				AA1=FSA_utils::convert_codon_into_AA(
+				codon_length,//codon length 
+				codon_AA,//<codon code,AA number>
+				alphabet_letters_number1,//number of letters for the sequence 1
+				letters1);
+			};
+
+			if(s==state_name_into_number["S3"])
+			{
+				AA1=FSA_utils::convert_codon_into_AA(
+				codon_length,//codon length 
+				codon_AA,//<codon code,AA number>
+				alphabet_letters_number1,//number of letters for the sequence 1
+				letters1+1);
+			};
+
+			//simplified sampling
+			if(sim_flag)
+			{
+				if(s==0)
+				{
+					states_distr_sim[1][i1][0]=tmp1;
+				};
+			};
+			//simplified sampling - end
+
+
+
+			for(i2=0;i2<max_ind2;i2++)
+			{
+				IS1_general::code_to_letters(//returns a unique code for the array of letters
+				i2,//input code
+				alphabet_letters_number2,//total number of letters
+				states_description[s].second,//dimension of the array with letters
+				letters2);//array of letters; the result
+
+				double tmp2=1;
+				long int t2;
+				for(t2=0;t2<states_description[s].second;t2++)
+				{
+					tmp2*=RR2[letters2[t2]];
+				};
+
+					if(s==state_name_into_number["D1"]||s==state_name_into_number["D2"]||
+						s==state_name_into_number["D3"]||s==state_name_into_number["I"]||
+					s==state_name_into_number["F"])
+					{
+						if(FSA_flag)
+						{
+							states_distr[s][i1][i2]=tmp1*tmp2;
+						};
+						continue;
+					};
+
+				//crude sampling
+				if(cs_flag)
+				{
+					if(s==0)
+					{
+						states_distr_cs[0][i1][i2]=tmp1*tmp2;
+					};
+				};
+				//crude sampling - end
+
+				//simplified sampling
+				if(sim_flag)
+				{
+					if(s==0)
+					{
+						states_distr_sim[0][i1][i2]=tmp1*tmp2*exp(ungappedlambda*smatr[AA1][letters2[0]]);
+
+						if(i1==0)
+						{
+							states_distr_sim[2][0][i2]=tmp2;
+						};
+
+					};
+				};
+				//simplified sampling - end
+
+
+
+				if(s==state_name_into_number["S1"]||s==state_name_into_number["S3"])
+				{
+					if(FSA_flag)
+					{
+						states_distr[s][i1][i2]=tmp1*tmp2*exp(ungappedlambda*smatr[AA1][letters2[0]]);
+					};
+					continue;
+				};
+
+				if(s==state_name_into_number["S2"])
+				{
+					double tmp3=0;
+
+					long int a1;
+					for(a1=0;a1<alphabet_letters_number1;a1++)
+					{
+						codon_tmp[0]=a1;
+						codon_tmp[1]=letters1[0];
+						codon_tmp[2]=letters1[1];
+
+
+						AA1=FSA_utils::convert_codon_into_AA(
+						codon_length,//codon length 
+						codon_AA,//<codon code,AA number>
+						alphabet_letters_number1,//number of letters for the sequence 1
+						codon_tmp);
+
+						tmp3+=RR1[a1]*exp(ungappedlambda*smatr[AA1][letters2[0]]);
+
+
+					};
+
+					if(FSA_flag)
+					{
+						states_distr[s][i1][i2]=tmp1*tmp2*tmp3;
+					};
+					continue;
+				};
+
+
+
+			};
+
+		};
+
+
+	};
+
+	delete[]letters1;
+	delete[]letters2;
+	delete[]codon_tmp;
+}
+
+void test::combine_parameters_from_forward_and_reversed_calculations_generalized(
+Sls::FALP_set_of_parameters &par_,//parameters from forward calculation
+Sls::FALP_set_of_parameters &par_reversed_,//parameters from reversed calculation
+Sls::FALP_set_of_parameters &par_result_)//the result
+{
+
+	long int c12=par_.realizations_number+par_reversed_.realizations_number;
+	if(c12<=0)
+	{
+		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+	};
+	double c1=(double)par_.realizations_number/(double)c12;
+	double c2=(double)par_reversed_.realizations_number/(double)c12;
+
+	par_result_.lambda=c1*par_.lambda+c2*par_reversed_.lambda;
+	par_result_.lambda_error=FSA_utils::error_of_the_sum(//v1_+v2_
+								c1*par_.lambda_error,
+								c2*par_reversed_.lambda_error);
+
+		
+
+	par_result_.C=par_.C;
+	par_result_.C_error=par_.C_error;
+
+	par_result_.K_C=par_reversed_.K_C;
+	par_result_.K_C_error=par_reversed_.K_C_error;
+
+	par_result_.K=par_.C*par_reversed_.K_C;
+	par_result_.K_error=FSA_utils::error_of_the_product(//v1_*v2_
+								par_.C,
+								par_.C_error,
+								par_reversed_.K_C,
+								par_reversed_.K_C_error);
+
+	par_result_.a_I=c1*par_.a_I+c2*par_reversed_.a_I;
+	par_result_.a_I=FSA_utils::Tmax(par_result_.a_I,0.0);
+	par_result_.a_I_error=FSA_utils::error_of_the_sum(//v1_+v2_
+								c1*par_.a_I_error,
+								c2*par_reversed_.a_I_error);
+
+	par_result_.a_J=c1*par_.a_J+c2*par_reversed_.a_J;
+	par_result_.a_J=FSA_utils::Tmax(par_result_.a_J,0.0);
+	par_result_.a_J_error=FSA_utils::error_of_the_sum(//v1_+v2_
+								c1*par_.a_J_error,
+								c2*par_reversed_.a_J_error);
+
+	par_result_.sigma=c1*par_.sigma+c2*par_reversed_.sigma;
+	par_result_.sigma=FSA_utils::Tmax(par_result_.sigma,0.0);
+	par_result_.sigma_error=FSA_utils::error_of_the_sum(//v1_+v2_
+								c1*par_.sigma_error,
+								c2*par_reversed_.sigma_error);
+
+	par_result_.alpha_I=c1*par_.alpha_I+c2*par_reversed_.alpha_I;
+	par_result_.alpha_I=FSA_utils::Tmax(par_result_.alpha_I,0.0);
+	par_result_.alpha_I_error=FSA_utils::error_of_the_sum(//v1_+v2_
+								c1*par_.alpha_I_error,
+								c2*par_reversed_.alpha_I_error);
+
+	par_result_.alpha_J=c1*par_.alpha_J+c2*par_reversed_.alpha_J;
+	par_result_.alpha_J=FSA_utils::Tmax(par_result_.alpha_J,0.0);
+	par_result_.alpha_J_error=FSA_utils::error_of_the_sum(//v1_+v2_
+								c1*par_.alpha_J_error,
+								c2*par_reversed_.alpha_J_error);
+
+
+
+	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	par_result_.G=0;
+	par_result_.G1=0;
+	par_result_.G2=0;
+
+	/*
+	par_result_.G=par_.G;
+	par_result_.G1=par_.G1;
+	par_result_.G2=par_.G2;
+	*/
+
+
+	size_t size_tmp=par_.m_LambdaSbs.size();
+
+	if(size_tmp!=par_reversed_.m_LambdaSbs.size()||
+		size_tmp!=par_reversed_.m_KSbs.size()||
+		size_tmp!=par_reversed_.m_K_CSbs.size()||
+		size_tmp!=par_.m_CSbs.size()||
+		size_tmp!=par_reversed_.m_CSbs.size()||
+		size_tmp!=par_.m_SigmaSbs.size()||
+		size_tmp!=par_reversed_.m_SigmaSbs.size()||
+		size_tmp!=par_.m_AlphaISbs.size()||
+		size_tmp!=par_reversed_.m_AlphaISbs.size()||
+		size_tmp!=par_.m_AlphaJSbs.size()||
+		size_tmp!=par_reversed_.m_AlphaJSbs.size()||
+		size_tmp!=par_.m_AISbs.size()||
+		size_tmp!=par_reversed_.m_AISbs.size()||
+		size_tmp!=par_.m_AJSbs.size()||
+		size_tmp!=par_reversed_.m_AJSbs.size()
+		)
+	{
+		throw error("Unexpected error in combine_parameters_from_forward_and_reversed_calculations_generalized\n",1);
+	};
+
+	par_result_.m_LambdaSbs.resize(size_tmp);
+	par_result_.m_KSbs.resize(size_tmp);
+	
+	par_result_.m_K_CSbs.resize(size_tmp);
+
+	par_result_.m_CSbs.resize(size_tmp);
+
+	par_result_.m_SigmaSbs.resize(size_tmp);
+	par_result_.m_AlphaISbs.resize(size_tmp);
+	par_result_.m_AlphaJSbs.resize(size_tmp);
+
+	par_result_.m_AISbs.resize(size_tmp);
+	par_result_.m_AJSbs.resize(size_tmp);
+
+
+	long int k;
+	for(k=0;k<(long int)size_tmp;k++)
+	{
+		par_result_.m_LambdaSbs[k]=c1*par_.m_LambdaSbs[k]+c2*par_reversed_.m_LambdaSbs[k];
+		par_result_.m_KSbs[k]=par_.m_CSbs[k]*par_reversed_.m_K_CSbs[k];
+		
+		par_result_.m_K_CSbs[k]=par_reversed_.m_K_CSbs[k];
+
+		par_result_.m_CSbs[k]=par_.m_CSbs[k];
+
+		par_result_.m_SigmaSbs[k]=c1*par_.m_SigmaSbs[k]+c2*par_reversed_.m_SigmaSbs[k];
+		par_result_.m_SigmaSbs[k]=FSA_utils::Tmax(par_result_.m_SigmaSbs[k],0.0);
+
+		par_result_.m_AlphaISbs[k]=c1*par_.m_AlphaISbs[k]+c2*par_reversed_.m_AlphaISbs[k];
+		par_result_.m_AlphaISbs[k]=FSA_utils::Tmax(par_result_.m_AlphaISbs[k],0.0);
+
+		par_result_.m_AlphaJSbs[k]=c1*par_.m_AlphaJSbs[k]+c2*par_reversed_.m_AlphaJSbs[k];
+		par_result_.m_AlphaJSbs[k]=FSA_utils::Tmax(par_result_.m_AlphaJSbs[k],0.0);
+
+		par_result_.m_AISbs[k]=c1*par_.m_AISbs[k]+c2*par_reversed_.m_AISbs[k];
+		par_result_.m_AISbs[k]=FSA_utils::Tmax(par_result_.m_AISbs[k],0.0);
+
+		par_result_.m_AJSbs[k]=c1*par_.m_AJSbs[k]+c2*par_reversed_.m_AJSbs[k];
+		par_result_.m_AJSbs[k]=FSA_utils::Tmax(par_result_.m_AJSbs[k],0.0);
+	};
+
+
+}
+
+void test::delete_mult_states_type(
+mult_states_type *&states_old1)
+{
+	if(states_old1)
+	{
+		long int kk1;
+		for(kk1=0;kk1<states_old1->d_number_of_realizations;kk1++)
+		{
+			
+
+			delete states_old1->d_states[kk1].d_M_array;
+			delete states_old1->d_states[kk1].d_seq1_length_array;
+			delete states_old1->d_states[kk1].d_seq2_length_array;
+			delete states_old1->d_states[kk1].d_distance_along_direction_1_array;
+			delete states_old1->d_states[kk1].d_distance_along_direction_2_array;
+			delete states_old1->d_states[kk1].d_ALP_weights_array;
+
+			delete states_old1->d_states[kk1].d_IS1_general_simulation;
+			delete states_old1->d_states[kk1].d_two_dim_layer_alignment_algorithm;
+
+		};
+
+		delete[]states_old1->d_states;
+
+		delete states_old1;states_old1=NULL;
+	};
+}
+
+//for test
+void test::compare_mult_states(
+mult_states_type *states_old_,
+mult_states_type *states_new_)
+{
+	if(states_old_->d_average_ALP_pos1!=states_new_->d_average_ALP_pos1)
+	{
+		cout<<"states_old_->d_average_ALP_pos1!=states_new_->d_average_ALP_pos1\n";
+	};
+
+	if(states_old_->d_average_ALP_pos2!=states_new_->d_average_ALP_pos2)
+	{
+		cout<<"states_old_->d_average_ALP_pos2!=states_new_->d_average_ALP_pos2\n";
+	};
+	if(states_old_->d_average_ALP_pos1_mult_ALP_pos2!=states_new_->d_average_ALP_pos1_mult_ALP_pos2)
+	{
+		cout<<"states_old_->d_average_ALP_pos1_mult_ALP_pos2!=states_new_->d_average_ALP_pos1_mult_ALP_pos2\n";
+	};
+	if(states_old_->d_average_expanding_length1!=states_new_->d_average_expanding_length1)
+	{
+		cout<<"states_old_->d_average_expanding_length1!=states_new_->d_average_expanding_length1\n";
+	};
+	if(states_old_->d_average_expanding_length1_mult_expanding_length2!=states_new_->d_average_expanding_length1_mult_expanding_length2)
+	{
+		cout<<"states_old_->d_average_expanding_length1_mult_expanding_length2!=states_new_->d_average_expanding_length1_mult_expanding_length2\n";
+	};
+	if(states_old_->d_average_expanding_length2!=states_new_->d_average_expanding_length2)
+	{
+		cout<<"states_old_->d_average_expanding_length2!=states_new_->d_average_expanding_length2\n";
+	};
+	if(states_old_->d_number_of_ALP!=states_new_->d_number_of_ALP)
+	{
+		cout<<"states_old_->d_number_of_ALP!=states_new_->d_number_of_ALP\n";
+	};
+	if(states_old_->d_number_of_realizations!=states_new_->d_number_of_realizations)
+	{
+		cout<<"states_old_->d_number_of_realizations!=states_new_->d_number_of_realizations\n";
+	};
+	if(states_old_->d_total_calculation_time!=states_new_->d_total_calculation_time)
+	{
+		//cout<<"states_old_->d_total_calculation_time!=states_new_->d_total_calculation_time\n";
+	};
+	if(states_old_->d_states!=states_new_->d_states)
+	{
+		//cout<<"states_old_->d_states!=states_new_->d_states\n";
+	};
+
+	long int k;
+
+	for(k=0;
+		k<FSA_utils::Tmin(states_old_->d_number_of_realizations,states_new_->d_number_of_realizations);
+		//k<1;
+		k++)
+	{
+		if(states_old_->d_states[k].d_ALP_number!=states_new_->d_states[k].d_ALP_number)
+		{
+			//cout<<k<<"\tstates_old_->d_states[k].d_ALP_number!=states_new_->d_states[k].d_ALP_number\n";
+		};
+
+		if(states_old_->d_states[k].d_two_dim_layer_alignment_algorithm!=states_new_->d_states[k].d_two_dim_layer_alignment_algorithm)
+		{
+			//cout<<k<<"\tstates_old_->d_states[k].d_two_dim_layer_alignment_algorithm!=states_new_->d_states[k].d_two_dim_layer_alignment_algorithm\n";
+		};
+
+		if(states_old_->d_states[k].d_IS1_general_simulation!=states_new_->d_states[k].d_IS1_general_simulation)
+		{
+			//cout<<k<<"\tstates_old_->d_states[k].d_IS1_general_simulation!=states_new_->d_states[k].d_IS1_general_simulation\n";
+		};
+
+
+		long int i;
+		for(i=0;i<=FSA_utils::Tmin(states_old_->d_states[k].d_ALP_number,states_new_->d_states[k].d_ALP_number);i++)
+		{
+			if(states_old_->d_states[k].d_ALP_weights_array->get_elem(i)!=states_new_->d_states[k].d_ALP_weights_array->get_elem(i))
+			{
+				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_ALP_weights_array->get_elem(i)!=states_new_->d_states[k].d_ALP_weights_array->get_elem(i)\n";
+			};
+
+			if(states_old_->d_states[k].d_distance_along_direction_1_array->get_elem(i)!=states_new_->d_states[k].d_distance_along_direction_1_array->get_elem(i))
+			{
+				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_distance_along_direction_1_array->get_elem(i)!=states_new_->d_states[k].d_distance_along_direction_1_array->get_elem(i)\n";
+			};
+			if(states_old_->d_states[k].d_distance_along_direction_2_array->get_elem(i)!=states_new_->d_states[k].d_distance_along_direction_2_array->get_elem(i))
+			{
+				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_distance_along_direction_2_array->get_elem(i)!=states_new_->d_states[k].d_distance_along_direction_2_array->get_elem(i)\n";
+			};
+			if(states_old_->d_states[k].d_M_array->get_elem(i)!=states_new_->d_states[k].d_M_array->get_elem(i))
+			{
+				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_M_array->get_elem(i)!=states_new_->d_states[k].d_M_array->get_elem(i)\n";
+			};
+			if(states_old_->d_states[k].d_seq1_length_array->get_elem(i)!=states_new_->d_states[k].d_seq1_length_array->get_elem(i))
+			{
+				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_seq1_length_array->get_elem(i)!=states_new_->d_states[k].d_seq1_length_array->get_elem(i)\n";
+			};
+			if(states_old_->d_states[k].d_seq2_length_array->get_elem(i)!=states_new_->d_states[k].d_seq2_length_array->get_elem(i))
+			{
+				cout<<k<<"\t"<<i<<"\tstates_old_->d_states[k].d_seq2_length_array->get_elem(i)!=states_new_->d_states[k].d_seq2_length_array->get_elem(i)\n";
+			};
+
+		};
+
+
+
+	};
+
+}
+
+//*****************************
+
+void test::FSA_Align(
+
+long int open1_,//gap opening penalty for the nucleotide sequence #1
+long int open2_,//gap opening penalty for the amino acid sequence #2
+
+long int epen1_,//gap extension penalty for the nucleotide sequence #1
+long int epen2_,//gap extension penalty for the amino acid sequence #2
+
+long int gamma_,//frameshift penalty gamma
+
+string smatr_file_name_,//scoring matrix file name
+string DNA_codon_table_file_name_,//a name of a file with DNA codon table
+
+bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
+
+string input_sequences_,//name of file with sequences for alignment (align mode)
+string output_sequences_,//name of output file with alignment scores (align mode)
+string gumbelparin_file_name_)//Gumbel parameters input file name
+{
+
+	double time0_start;
+	FSA_utils::get_current_time(time0_start);
+
+	Sls::FALP_set_of_parameters gumbelparin;//the resulted parameters
+
+	if(gumbelparin_file_name_!="")
+	{
+		fsa_par::Read_Params(
+		gumbelparin,
+		gumbelparin_file_name_);
+
+		FALP_pvalues::compute_intercepts(gumbelparin);
+	};
+
+	static Sls::FALP_pvalues pvalues_obj;
+
+	long int **smatr=NULL;
+
+
+	char *alphabet1=NULL;//alphabet letters for the sequence #1
+	char *alphabet2=NULL;//alphabet letters for the sequence #2
+
+	long int *alphabet1_to_long=NULL;//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+	long int *alphabet2_to_long=NULL;//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+	long int codon_length;//codon length 
+	long int *codon_AA=NULL;//<codon code,AA number>
+
+
+//====================================================
+
+
+	long int number_of_AA_smatr;
+	long int smatr_min;
+
+	FSA_utils::read_smatr(
+	smatr_file_name_,
+	smatr,
+	number_of_AA_smatr,
+	smatr_min);
+
+//====================================================================================
+
+	long int number_of_letters1_tmp;//number of letters for the sequence 1
+	long int number_of_letters2_tmp;//number of letters for the sequence 2
+
+	FSA_utils::read_codon_AA_file(
+	DNA_codon_table_file_name_,
+	number_of_letters1_tmp,//number of letters for the sequence 1
+	number_of_letters2_tmp,//number of letters for the sequence 2
+
+	alphabet1,//alphabet letters for the sequence #1
+	alphabet2,//alphabet letters for the sequence #2
+
+	alphabet1_to_long,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+	alphabet2_to_long,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+	codon_length,//codon length 
+	codon_AA);//<codon code,AA number>
+
+	if(number_of_AA_smatr!=number_of_letters2_tmp)
+	{
+		throw error("Error - different numbers of amino acids in the files "+smatr_file_name_+", "+DNA_codon_table_file_name_+"\n",1);
+	};
+
+
+
+	long int number_of_sequences;
+	string *headers;
+	long int *lengths1;//lengths of the sequences #1
+	long int *lengths2;//lengths of the sequences #2
+	long int **sequences1;
+	long int **sequences2;
+
+	FSA_utils::read_sequences_for_alingment(
+
+	input_sequences_,
+
+	number_of_letters1_tmp,//number of letters for the sequence 1
+	number_of_letters2_tmp,//number of letters for the sequence 2
+
+	alphabet1,//alphabet letters for the sequence #1
+	alphabet2,//alphabet letters for the sequence #2
+
+	number_of_sequences,
+
+	headers,
+	lengths1,
+	lengths2,
+	sequences1,//the first index numerates sequences; the second - sequence letters
+	sequences2);
+
+	long int k;
+
+	long int max_ind1=-1;
+	long int max_ind2=-1;
+	for(k=0;k<number_of_sequences;k++)
+	{
+		max_ind1=FSA_utils::Tmax(max_ind1,lengths1[k]);
+		max_ind2=FSA_utils::Tmax(max_ind2,lengths2[k]);
+	};
+
+	if(max_ind1==0||max_ind2==0)
+	{
+		throw error("Error in the file "+input_sequences_+"\n",1);
+	};
+
+
+//---------two dim alignment algorithm---------------
+
+	long int var_num_dim=1000;
+	long int *var_num=new long int[var_num_dim];
+	long int i;
+	for(i=0;i<var_num_dim;i++)
+	{
+		var_num[i]=-1;
+	};
+
+	var_num['S']=0;
+	var_num['D']=1;
+	var_num['I']=2;
+
+
+	data_for_FSA_alignment data_test;
+
+	data_test.d_alphabet_letters_number1=number_of_letters1_tmp;
+
+	data_test.d_open1=open1_;
+	data_test.d_open2=open2_;
+
+	data_test.d_epen1=epen1_;
+	data_test.d_epen2=epen2_;
+
+	data_test.d_gamma=gamma_;
+
+	data_test.d_smatr=smatr;
+
+	data_test.d_codon_AA=codon_AA;
+
+	data_test.d_insertions_after_deletions=insertions_after_deletions_;
+
+	//data_test.d_alignment_type="global";
+	data_test.d_alignment_type="local";
+
+	long int depth1=4;//the maximum difference of the first index in the dynamic equations
+	long int depth2=1;//the maximum difference of the second index in the dynamic equations
+
+
+
+	long int number_of_variables_for_the_alignment=3;
+
+	two_dim_layer_alignment_algorithm<long int>* two_dim_layer_alignment_algorithm_test=NULL;
+
+
+
+	two_dim_layer_alignment_algorithm_test=
+	new two_dim_layer_alignment_algorithm<long int>(
+	number_of_variables_for_the_alignment,//total number of variables in dynamic equations
+	depth1,//the maximum difference of the first index in the dynamic equations
+	depth2,//the maximum difference of the second index in the dynamic equations
+	max_ind1,//max of the index #1 (minimum index is 0 by default)
+	max_ind2,//max of the index #2 (minimum index is 0 by default)
+	0,//null element of T
+	var_num);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
+
+	two_dim_layer_alignment_algorithm_test->d_two_dim_layer_alignment_function=test::two_dim_layer_alignment_function_FSA;
+	two_dim_layer_alignment_algorithm_test->d_two_dim_layer_boundary_function=test::two_dim_layer_alignment_function_FSA;
+	two_dim_layer_alignment_algorithm_test->d_par=&data_test;
+
+
+	two_dim_layer_alignment_algorithm_test->d_M_flag=true;
+	two_dim_layer_alignment_algorithm_test->d_E_flag=false;
+
+	two_dim_layer_alignment_algorithm_test->d_scores_counts_flag=false;
+
+	ofstream fout(output_sequences_.data());
+	if(!fout)
+	{
+		throw error("Error - the file "+output_sequences_+" is not found\n",1);
+	};
+
+	//calculate alingment scores and P-values
+	for(k=0;k<number_of_sequences;k++)
+	{
+		two_dim_layer_alignment_algorithm_test->init();
+
+		data_test.d_seq1=sequences1[k];
+		data_test.d_seq2=sequences2[k];
+
+		two_dim_layer_alignment_algorithm_test->align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+		//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+		lengths1[k],//target length of the sequence #1
+		lengths2[k]);//target length of the sequence #2
+		fout<<headers[k]<<endl;
+		fout<<two_dim_layer_alignment_algorithm_test->d_M;
+
+		if(gumbelparin_file_name_!="")
+		{
+				vector<double> P_values;
+				vector<double> P_values_errors;
+
+				vector<double> E_values;
+				vector<double> E_values_errors;
+
+
+				pvalues_obj.calculate_P_values(
+				two_dim_layer_alignment_algorithm_test->d_M,
+				two_dim_layer_alignment_algorithm_test->d_M,
+				lengths1[k],
+				lengths2[k],
+				gumbelparin,
+				P_values,
+				P_values_errors,
+				E_values,
+				E_values_errors);
+
+
+				if(P_values.size()==1&&P_values_errors.size()==1)
+				{
+					fout<<"\t"<<P_values[0]<<"\t"<<P_values_errors[0];
+				};
+
+				if(E_values.size()==1&&E_values_errors.size()==1)
+				{
+					fout<<"\t"<<E_values[0]<<"\t"<<E_values_errors[0];
+				};
+
+		};
+		fout<<endl;
+	};
+
+	fout.close();
+
+	delete[]headers;
+	delete[]lengths1;
+	delete[]lengths2;
+
+	
+	for(k=0;k<number_of_sequences;k++)
+	{
+		delete[]sequences1[k];
+		delete[]sequences2[k];
+	};
+
+	delete[]sequences1;
+	delete[]sequences2;
+	delete[]var_num;
+
+	delete two_dim_layer_alignment_algorithm_test;
+
+	double time0_end;
+	FSA_utils::get_current_time(time0_end);
+
+	cout<<"Total calculation time\t"<<time0_end-time0_start<<endl;
+
+}
+
+//*****************************
+void test::input_data_for_the_constructor(
+
+string DNA_codon_table_file_name_,//a name of a file with DNA codon table
+string smatr_file_name_,//scoring matrix file name
+string RR1_file_name_,//probabilities1 file name
+string RR2_file_name_,//probabilities2 file name
+
+long int &alphabetSize1_,
+long int &alphabetSize2_,
+long int **&substitutionScoreMatrix_,
+double *&letterFreqs1_,
+double *&letterFreqs2_,
+
+char *&alphabet1_,//alphabet letters for the sequence #1
+char *&alphabet2_,//alphabet letters for the sequence #2
+
+long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+long int &codon_length_,//codon length 
+long int *&codon_AA_)//<codon code,AA number>
+{
+
+	long int number_of_AA_smatr;
+	long int smatr_min;
+
+
+	FSA_utils::read_smatr(
+	smatr_file_name_,
+	substitutionScoreMatrix_,
+	number_of_AA_smatr,
+	smatr_min);
+
+
+	FSA_utils::read_RR(
+	RR1_file_name_,
+	letterFreqs1_,
+	alphabetSize1_,
+	4);
+
+
+	FSA_utils::read_RR(
+	RR2_file_name_,
+	letterFreqs2_,
+	alphabetSize2_,
+	25);
+
+
+
+	if(number_of_AA_smatr!=alphabetSize2_)
+	{
+		throw error("Error - different number of letters in the files "+smatr_file_name_+", "+RR2_file_name_+"\n",1);
+	};
+
+//====================================================================================
+
+	long int number_of_letters1_tmp;//number of letters for the sequence 1
+	long int number_of_letters2_tmp;//number of letters for the sequence 2
+
+
+	FSA_utils::read_codon_AA_file(
+	DNA_codon_table_file_name_,
+	number_of_letters1_tmp,//number of letters for the sequence 1
+	number_of_letters2_tmp,//number of letters for the sequence 2
+
+	alphabet1_,//alphabet letters for the sequence #1
+	alphabet2_,//alphabet letters for the sequence #2
+
+	alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+	alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+	codon_length_,//codon length 
+	codon_AA_);//<codon code,AA number>
+
+
+
+	if(alphabetSize1_!=number_of_letters1_tmp)
+	{
+		throw error("The numbers of letters is different in the files "+DNA_codon_table_file_name_+" and "+RR1_file_name_+"\n",3);
+	};
+	if(alphabetSize2_!=number_of_letters2_tmp)
+	{
+		throw error("The numbers of letters is different in the files "+DNA_codon_table_file_name_+" and "+RR2_file_name_+"\n",3);
+	};
+
+}
+
+void test::FSA_IS(
+//additional parameters for the library code
+bool library_call_flag_,//if true, then the additional parameters are used
+long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
+long aaAlphabetSize_,//a number of letters in the amino acid alphabet; usually 4
+const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
+const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
+const double *ntFreqs_,//background frequencies of letters in DNA sequences
+const double *aaFreqs_,//background frequencies of letters in amino acid sequences
+//additional parameters for the library code - end
+
+long int rand_,//randomization number
+long int open1_,//gap opening penalty for the nucleotide sequence #1
+long int open2_,//gap opening penalty for the amino acid sequence #2
+
+long int epen1_,//gap extension penalty for the nucleotide sequence #1
+long int epen2_,//gap extension penalty for the amino acid sequence #2
+
+long int gamma_,//frameshift penalty gamma
+
+string smatr_file_name_,//scoring matrix file name
+string RR1_file_name_,//background frequencies file name for the sequence #1
+string RR2_file_name_,//background frequencies file name for the sequence #2
+string DNA_codon_table_file_name_,//a name of a file with DNA codon table
+
+double eps_lambda_,//relative error for lambda calculation
+double eps_K_,//relative error for K calculation
+
+bool gapped_flag_,//if true, then the gapped alingment is performed
+double max_time_,//maximum allowed calculation time in seconds
+double max_mem_,//maximum allowed memory usage in MB
+
+//additional parameters
+long int seq_number_,//number of tested alignments
+long int nalp_,//number of ALPs for the calculation
+long int number_of_subsets_for_errors_calculation_,//number of subsets used for the splitting method
+bool forward_and_reverse_screen_output_flag_,//determines whether the parameters are outputted for forward and reverse calculations
+bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
+
+//for test
+double mult_for_is_lambda_,//multiplier for lambda in the IS
+
+//the result
+Sls::FALP_set_of_parameters &par_result_,//the resulted parameters
+Sls::par_test1_type *par_test1_)//for tests
+{
+	double seconds1;
+	FSA_utils::get_current_time(seconds1);
+
+	FSA_utils::process_random_factor(
+	rand_);
+
+	double empirical_mem_coeff=2.5;
+
+	double max_mem_for_states_alloc=max_mem_*1048576/empirical_mem_coeff;//maximum allocatin size for states in bytes
+	double max_number_of_states=FSA_utils::Tmin((double)inf,max_mem_for_states_alloc/sizeof(state_type));
+
+	//the parameters
+
+	bool FSA_flag=true;//if true, then FSA IS is performed
+	bool cs_flag=true;//if true, then crude sampling simulation is also performed
+	bool sim_flag=false;//flag for the simplified IS technique
+
+	double eps_K=eps_K_;//relative error for K
+
+	long int depth1=4;//the maximum difference of the first index in the dynamic equations
+	long int depth2=1;//the maximum difference of the second index in the dynamic equations
+
+	long int max_ind2=10000;//max of the index #2
+	long int max_ind1=max_ind2*3;//max of the index #1
+
+
+	long int target_ALP=nalp_;
+	
+
+	long int number_of_realizations=seq_number_;
+	long int number_of_sets=number_of_subsets_for_errors_calculation_;//number of sets for error calculation
+
+	bool futher_expanding=true;
+	long int number_of_cs_steps_for_expanding=max_ind2;
+
+	long int mult_margin=5;
+	long int add_margin=100;
+
+	bool lambda_output_flag=false;
+
+#ifdef _MSDOS_
+	string lambda_file_name="lambda_"+FSA_utils::long_to_string(rand_)+".out";
+#else
+	string lambda_file_name="/net/frosty/vol/export1/sls/ff1/res1/lambda_"+FSA_utils::long_to_string(rand_)+".out";
+#endif
+
+//-------------------------------------------------
+
+	//bool add_fake_state_flag=true;
+	bool add_fake_state_flag=false;
+
+	FSA_utils::srand2(rand_);
+	if(!library_call_flag_)
+	{
+		cout<<"Randomization factor\t"<<rand_<<endl;
+	};
+
+	long int alphabet_letters_number1;//number of letters in the sequence #1
+	long int alphabet_letters_number2;//number of letters in the sequence #2
+	double *RR1=NULL;//background probability for the sequence #1
+	double *RR2=NULL;//background probability for the sequence #2
+	long int number_of_states=7;//number of states
+	if(add_fake_state_flag)
+	{
+		number_of_states++;
+	};
+	double **transition_probabilities=NULL;//transition probabilities between states; matrix d_number_of_states x d_number_of_states
+	pair<long int, long int> *states_description=NULL;//description of the states; the index is a state number
+	double ***states_distr=NULL;//distributions of the states; the index is a state number
+								//the second and the third indexes correspond to an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+
+	double ***states_distr_reversed=NULL;
+
+//crude sampling
+	pair<long int, long int> *states_description_cs=NULL;
+	double ***states_distr_cs=NULL;
+	double **transition_probabilities_cs=NULL;
+//crude sampling - end
+
+//simplified sampling
+	double ***states_distr_sim=NULL;
+//simplified sampling - end
+
+	double *RR1_sum=NULL;
+	long int *RR1_sum_elements=NULL;
+	double *RR2_sum=NULL;
+	long int *RR2_sum_elements=NULL;
+
+	long int **smatr=NULL;
+
+	double ungappedlambda;
+
+	d_IS1=NULL;
+	d_IS1_general_simulation=NULL;
+
+	double *RR1_AA=NULL;
+
+
+//===============================================
+
+	char *alphabet1=NULL;//alphabet letters for the sequence #1
+	char *alphabet2=NULL;//alphabet letters for the sequence #2
+
+	long int *alphabet1_to_long=NULL;//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+	long int *alphabet2_to_long=NULL;//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+	long int codon_length;//codon length 
+	long int *codon_AA=NULL;//<codon code,AA number>
+	long int *codon_reversed_AA=NULL;//<codon code,AA number>
+
+
+//====================================================
+
+	{
+		
+		if(!library_call_flag_)
+		{
+			input_data_for_the_constructor(
+
+			DNA_codon_table_file_name_,//a name of a file with DNA codon table
+			smatr_file_name_,//scoring matrix file name
+			RR1_file_name_,//probabilities1 file name
+			RR2_file_name_,//probabilities2 file name
+
+			alphabet_letters_number1,
+			alphabet_letters_number2,
+			smatr,
+			RR1,
+			RR2,
+
+			alphabet1,//alphabet letters for the sequence #1
+			alphabet2,//alphabet letters for the sequence #2
+
+			alphabet1_to_long,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+			alphabet2_to_long,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+			codon_length,//codon length 
+			codon_AA);//<codon code,AA number>
+		}
+		else
+		{
+			alphabet_letters_number1=ntAlphabetSize_;
+			alphabet_letters_number2=aaAlphabetSize_;
+
+			RR1=new double[ntAlphabetSize_];
+			RR2=new double[aaAlphabetSize_];
+
+			alphabet1=new char[ntAlphabetSize_];//alphabet letters for the sequence #1
+			alphabet2=new char[aaAlphabetSize_];//alphabet letters for the sequence #2
+
+
+			long int i,j;
+			for(i=0;i<ntAlphabetSize_;i++)
+			{
+				RR1[i]=ntFreqs_[i];
+				alphabet1[i]=(char)(i+1);
+			};
+
+			for(i=0;i<aaAlphabetSize_;i++)
+			{
+				RR2[i]=aaFreqs_[i];
+				alphabet2[i]=(char)(i+1);
+			};
+
+			FSA_utils::get_memory_for_matrix(aaAlphabetSize_,aaAlphabetSize_,smatr);
+			for(i=0;i<aaAlphabetSize_;i++)
+			{
+				for(j=0;j<aaAlphabetSize_;j++)
+				{
+					smatr[i][j]=substitutionScoreMatrix_[i][j];
+				};
+			};
+			
+
+			alphabet1_to_long=new long int [length_max];
+			FSA_utils::assert_mem(alphabet1_to_long);
+			alphabet2_to_long=new long int [length_max];
+			FSA_utils::assert_mem(alphabet2_to_long);
+
+			long int k;
+			for(k=0;k<length_max;k++)
+			{
+				alphabet1_to_long[k]=-1;
+				alphabet2_to_long[k]=-1;
+			};
+
+			for(k=0;k<alphabet_letters_number1;k++)
+			{
+				alphabet1_to_long[(size_t)alphabet1[k]]=k;
+			};
+			for(k=0;k<alphabet_letters_number2;k++)
+			{
+				alphabet2_to_long[(size_t)alphabet2[k]]=k;
+			};
+
+
+			codon_length=3;//codon length 
+
+			long int number_of_codons=1;
+			for(k=0;k<codon_length;k++)
+			{
+				number_of_codons*=alphabet_letters_number1;
+			};
+
+			codon_AA=new long int [number_of_codons];
+			FSA_utils::assert_mem(codon_AA);
+
+			for(k=0;k<number_of_codons;k++)
+			{
+				codon_AA[k]=codonTable_[k];//<codon code,AA number>
+			};
+
+
+		};
+
+		long int number_of_AA_smatr=alphabet_letters_number2;
+		long int smatr_min;
+
+		long int number_of_letters1_tmp=alphabet_letters_number1;
+		long int number_of_letters2_tmp=alphabet_letters_number2;
+
+		FSA_utils::calculate_RR_sum(
+		RR1,
+		number_of_letters1_tmp,
+		RR1_sum,
+		RR1_sum_elements);
+
+		FSA_utils::calculate_RR_sum(
+		RR2,
+		number_of_letters2_tmp,
+		RR2_sum,
+		RR2_sum_elements);
+
+		FSA_utils::smatr_min(
+		smatr,
+		number_of_AA_smatr,
+		smatr_min);
+
+		{
+			FSA_utils::remove_zero_probabilities(
+			RR1,
+			RR1_sum,
+			RR1_sum_elements,
+			alphabet_letters_number1,
+			RR2,
+			RR2_sum,
+			RR2_sum_elements,
+			alphabet_letters_number2,
+			smatr,
+			number_of_AA_smatr,
+			smatr_min,
+
+			number_of_letters1_tmp,//number of letters for the sequence 1
+			number_of_letters2_tmp,//number of letters for the sequence 2
+
+			alphabet1,//alphabet letters for the sequence #1
+			alphabet2,//alphabet letters for the sequence #2
+
+			alphabet1_to_long,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+			alphabet2_to_long,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+			codon_length,//codon length 
+			codon_AA);//<codon code,AA number>
+
+		};
+
+
+//====================================================================================
+
+		data_for_lambda_equation_FSA func_pointer;
+
+		func_pointer.d_number_of_letters1=alphabet_letters_number1;
+		func_pointer.d_number_of_letters2=alphabet_letters_number2;
+		func_pointer.d_smatr=smatr;
+		func_pointer.d_RR1=RR1;
+		func_pointer.d_RR2=RR2;
+
+		func_pointer.d_codon_length=codon_length;
+
+
+		if(futher_expanding)
+		{
+			FSA_utils::reverse_codons(
+			codon_AA,//<codon code,AA number>; original codons
+			alphabet_letters_number1,//number of letters for the sequence #1
+			codon_length,//codon length 
+			codon_reversed_AA);//<codon code,AA number>; reversed codons
+
+		};
+
+		func_pointer.d_codon_AA=codon_AA;
+
+		calculate_ungapped_lambda_general(
+		lambda_equation_FSA,
+		(void*) &func_pointer,
+		ungappedlambda);
+
+		ungappedlambda*=mult_for_is_lambda_;
+		//cout<<"Multiplier for IS lambda\t"<<mult_for_is_lambda_<<endl;
+
+		//gapless calculaton begin
+		double GaplessTimePortion=0.5;
+
+		double GaplessCalculationTime=max_time_;
+
+		if(max_time_<=0)
+		{
+			GaplessCalculationTime=120;
+		};
+
+		if(gapped_flag_)
+		{
+			//Gapless calculation may take only a portion of maximum allowed calculation time in the case of gapped calculation 
+			GaplessCalculationTime*=GaplessTimePortion;
+		};
+
+
+
+		
+
+		FSA_utils::extract_AA_frequencies_for_DNA_sequence(
+		codon_AA,//<codon code,AA number>
+		codon_length,//codon length 
+		number_of_letters1_tmp,//number of letters for the sequence 1
+		number_of_letters2_tmp,//number of letters for the sequence 2
+		RR1,//nucleotide probabilities
+		RR1_AA);//the resulted frequencies
+
+		
+		Njn::LocalMaxStatMatrix local_max_stat_matrix(number_of_letters2_tmp,
+							  smatr,
+							  RR1_AA,
+							  RR2,
+							  number_of_letters2_tmp,
+							  GaplessCalculationTime);
+
+		if(local_max_stat_matrix.getTerminated()) 
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+
+		//calculation of a and sigma
+		double calculation_error=1e-6;
+
+		par_result_.gapless_alpha_J = local_max_stat_matrix.getAlpha ();
+		par_result_.gapless_alpha_J=FSA_utils::Tmax(par_result_.gapless_alpha_J,0.0);
+		par_result_.gapless_alpha_J_error = calculation_error;
+
+		par_result_.gapless_alpha_I=par_result_.gapless_alpha_J*9;
+		par_result_.gapless_alpha_I_error = calculation_error*9;
+
+		par_result_.gapless_sigma=par_result_.gapless_alpha_J*3;
+		par_result_.gapless_sigma_error = calculation_error*3;
+
+
+		par_result_.gapless_a_J = local_max_stat_matrix.getA ();
+		par_result_.gapless_a_J=FSA_utils::Tmax(par_result_.gapless_a_J,0.0);
+		par_result_.gapless_a_J_error = calculation_error;
+
+		par_result_.gapless_a_I = par_result_.gapless_a_J*3;
+		par_result_.gapless_a_I_error = calculation_error*3;
+
+
+
+		if(!gapped_flag_) {
+
+
+			//calculation of all required parameters for a gapless case
+			par_result_.G=0;
+			par_result_.G1=0;
+			par_result_.G2=0;
+
+			par_result_.lambda = local_max_stat_matrix.getLambda ();
+			par_result_.lambda_error = calculation_error;
+
+			par_result_.K = local_max_stat_matrix.getK ();
+			par_result_.K_error = calculation_error;
+				
+			par_result_.C = local_max_stat_matrix.getC ();;
+			par_result_.C_error = calculation_error;
+
+			if(par_result_.C!=0)
+			{
+				par_result_.K_C = par_result_.K/par_result_.C;
+			}
+			else
+			{
+				par_result_.K_C = 0;
+			};
+			par_result_.K_C_error = calculation_error;
+
+
+			par_result_.sigma = par_result_.gapless_sigma;
+			par_result_.sigma_error = par_result_.gapless_sigma_error;
+
+			par_result_.alpha_I = par_result_.gapless_alpha_I;
+			par_result_.alpha_I_error = par_result_.gapless_alpha_I_error;
+
+			par_result_.alpha_J = par_result_.gapless_alpha_J;
+			par_result_.alpha_J_error = par_result_.gapless_alpha_J_error;
+
+			par_result_.a_I = par_result_.gapless_a_I;
+			par_result_.a_I_error = par_result_.gapless_a_I_error;
+
+			par_result_.a_J = par_result_.gapless_a_J;
+			par_result_.a_J_error = par_result_.gapless_a_J_error;
+
+
+			std::vector<double > sbs_arrays;
+
+			sbs_arrays.resize(2);
+			sbs_arrays[0]=par_result_.lambda;
+			sbs_arrays[1]=par_result_.lambda + calculation_error;
+
+			par_result_.m_LambdaSbs=sbs_arrays;
+
+
+			sbs_arrays.resize(2);
+			sbs_arrays[0]=par_result_.K;
+			sbs_arrays[1]=par_result_.K+calculation_error;
+
+			par_result_.m_KSbs=sbs_arrays;
+
+
+			sbs_arrays.resize(2);
+			sbs_arrays[0]=par_result_.C;
+			sbs_arrays[1]=par_result_.C+calculation_error;
+
+			par_result_.m_CSbs=sbs_arrays;
+
+
+			sbs_arrays.resize(2);
+			sbs_arrays[0]=par_result_.sigma;
+			sbs_arrays[1]=par_result_.sigma + calculation_error;
+
+			par_result_.m_SigmaSbs=sbs_arrays;
+
+
+			sbs_arrays.resize(2);
+			sbs_arrays[0]=par_result_.alpha_I;
+			sbs_arrays[1]=par_result_.alpha_I + calculation_error;
+
+			par_result_.m_AlphaISbs=sbs_arrays;
+
+
+			sbs_arrays.resize(2);
+			sbs_arrays[0]=par_result_.alpha_J;
+			sbs_arrays[1]=par_result_.alpha_J + calculation_error;
+
+			par_result_.m_AlphaJSbs=sbs_arrays;
+
+
+			sbs_arrays.resize(2);
+			sbs_arrays[0]=par_result_.a_I;
+			sbs_arrays[1]=par_result_.a_I + calculation_error;
+
+			par_result_.m_AISbs=sbs_arrays;
+
+
+			sbs_arrays.resize(2);
+			sbs_arrays[0]=par_result_.a_J;
+			sbs_arrays[1]=par_result_.a_J + calculation_error;
+
+			par_result_.m_AJSbs=sbs_arrays;
+
+
+			FSA_flag=false;//if true, then FSA IS is performed
+			cs_flag=false;//if true, then crude sampling simulation is also performed
+			sim_flag=false;//flag for the simplified IS technique
+			futher_expanding=false;
+
+		};
+
+
+		//gapless calculation end
+
+	};
+
+	//possible choice #1
+	//long int minopen=FSA_utils::Tmin(open1_,open2_);
+	//long int minepen=FSA_utils::Tmin(epen1_,epen2_);
+
+	//possible choice #2
+	//long int minopen=FSA_utils::Tmax(open1_,open2_);
+	//long int minepen=FSA_utils::Tmax(epen1_,epen2_);
+
+	//possible choice #3
+	long int minopen=(long int)FSA_utils::round((double)(open1_+open2_)*0.5);
+	long int minepen=(long int)FSA_utils::round((double)(epen1_+epen2_)*0.5);
+
+	long int choice_of_IS_weights=1;
+
+
+	long int gamma=gamma_;
+
+
+	map<string, long int> state_name_into_number;
+	map<long int,string> state_number_into_name;
+
+	
+	
+	state_name_into_number["S1"]=0;
+	state_name_into_number["S2"]=1;
+	state_name_into_number["S3"]=2;
+	state_name_into_number["D1"]=3;
+	state_name_into_number["D2"]=4;
+	state_name_into_number["D3"]=5;
+	state_name_into_number["I"]=6;
+	if(add_fake_state_flag)
+	{
+		state_name_into_number["F"]=7;
+	}
+	else
+	{
+		state_name_into_number["F"]=-1;
+	};
+
+
+
+	state_number_into_name[0]="S1";
+	state_number_into_name[1]="S2";
+	state_number_into_name[2]="S3";
+	state_number_into_name[3]="D1";
+	state_number_into_name[4]="D2";
+	state_number_into_name[5]="D3";
+	state_number_into_name[6]="I";
+	if(add_fake_state_flag)
+	{
+		state_number_into_name[7]="F";
+	};
+
+	states_description=new pair<long int, long int>[number_of_states];
+	FSA_utils::assert_mem(states_description);
+
+	states_description[state_name_into_number["S1"]]=make_pair(3,1);
+	states_description[state_name_into_number["S2"]]=make_pair(2,1);
+	states_description[state_name_into_number["S3"]]=make_pair(4,1);
+	states_description[state_name_into_number["D1"]]=make_pair(3,0);
+	states_description[state_name_into_number["D2"]]=make_pair(2,0);
+	states_description[state_name_into_number["D3"]]=make_pair(4,0);
+	states_description[state_name_into_number["I"]]=make_pair(0,1);
+	if(add_fake_state_flag)
+	{
+		states_description[state_name_into_number["F"]]=make_pair(0,0);
+	};
+
+	if(FSA_flag)
+	{
+		FSA_utils::get_memory_for_matrix(number_of_states,number_of_states,transition_probabilities);
+
+		if(choice_of_IS_weights==1)
+		{
+			transition_probabilities[0][0]=((-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda)))/(1 - exp(gamma*ungappedlambda) + exp(minepen*ungappedlambda) + exp((gamma + minepen)*ungappedlambda) + 4*exp((minepen - minopen)*ungappedlambda) + 2*exp((gamma + minepen - minopen)*ungappedlambda));
+			transition_probabilities[0][1]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[0][2]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[0][3]=exp((gamma + minepen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[0][4]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[0][5]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[0][6]=((2 + exp(gamma*ungappedlambda))*exp(minepen*ungappedlambda))/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[1][0]=((-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda)))/(1 - exp(gamma*ungappedlambda) + exp(minepen*ungappedlambda) + exp((gamma + minepen)*ungappedlambda) + 4*exp((minepen - minopen)*ungappedlambda) + 2*exp((gamma + minepen - minopen)*ungappedlambda));
+			transition_probabilities[1][1]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[1][2]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[1][3]=exp((gamma + minepen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[1][4]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[1][5]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[1][6]=((2 + exp(gamma*ungappedlambda))*exp(minepen*ungappedlambda))/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[2][0]=((-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda)))/(1 - exp(gamma*ungappedlambda) + exp(minepen*ungappedlambda) + exp((gamma + minepen)*ungappedlambda) + 4*exp((minepen - minopen)*ungappedlambda) + 2*exp((gamma + minepen - minopen)*ungappedlambda));
+			transition_probabilities[2][1]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[2][2]=exp((minepen + minopen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[2][3]=exp((gamma + minepen)*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[2][4]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[2][5]=exp(minepen*ungappedlambda)/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[2][6]=((2 + exp(gamma*ungappedlambda))*exp(minepen*ungappedlambda))/(4*exp(minepen*ungappedlambda) + 2*exp((gamma + minepen)*ungappedlambda) + exp(minopen*ungappedlambda) - exp((gamma + minopen)*ungappedlambda) + exp((minepen + minopen)*ungappedlambda) + exp((gamma + minepen + minopen)*ungappedlambda));
+			transition_probabilities[3][0]=(-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
+			transition_probabilities[3][1]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
+			transition_probabilities[3][2]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
+			transition_probabilities[3][3]=(-1 + exp(gamma*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
+			transition_probabilities[3][4]=exp(-((gamma + minepen)*ungappedlambda))/2.;
+			transition_probabilities[3][5]=exp(-((gamma + minepen)*ungappedlambda))/2.;
+			transition_probabilities[3][6]=0;
+			transition_probabilities[4][0]=(-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
+			transition_probabilities[4][1]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
+			transition_probabilities[4][2]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
+			transition_probabilities[4][3]=(-1 + exp(gamma*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
+			transition_probabilities[4][4]=exp(-((gamma + minepen)*ungappedlambda))/2.;
+			transition_probabilities[4][5]=exp(-((gamma + minepen)*ungappedlambda))/2.;
+			transition_probabilities[4][6]=0;
+			transition_probabilities[5][0]=(-1 + exp(gamma*ungappedlambda))*(-1 + exp(minepen*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
+			transition_probabilities[5][1]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
+			transition_probabilities[5][2]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
+			transition_probabilities[5][3]=(-1 + exp(gamma*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda));
+			transition_probabilities[5][4]=exp(-((gamma + minepen)*ungappedlambda))/2.;
+			transition_probabilities[5][5]=exp(-((gamma + minepen)*ungappedlambda))/2.;
+			transition_probabilities[5][6]=0;
+			transition_probabilities[6][0]=1 - exp(-(gamma*ungappedlambda)) - exp(-(minepen*ungappedlambda)) + 2*exp(-((gamma + minepen)*ungappedlambda));
+			transition_probabilities[6][1]=((-1 + exp(minepen*ungappedlambda))*exp(-((gamma + minepen)*ungappedlambda)))/2.;
+			transition_probabilities[6][2]=(exp(-(gamma*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda)))/2.;
+			transition_probabilities[6][3]=0;
+			transition_probabilities[6][4]=0;
+			transition_probabilities[6][5]=0;
+			transition_probabilities[6][6]=exp(-(minepen*ungappedlambda)) - exp(-((gamma + minepen)*ungappedlambda));
+		};
+
+		//for test
+		if(choice_of_IS_weights==2)
+		{
+			transition_probabilities[0][0]=1/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[0][1]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[0][2]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[0][3]=exp((-epen1_ - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[0][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[0][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[0][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[1][0]=1/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[1][1]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[1][2]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[1][3]=exp((-epen1_ - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[1][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[1][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[1][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[2][0]=1/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[2][1]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[2][2]=exp(-(gamma*ungappedlambda))/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[2][3]=exp((-epen1_ - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[2][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[2][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[2][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + 2*exp(-(gamma*ungappedlambda)) + exp((-epen1_ - open1_)*ungappedlambda) + 2*exp((-epen1_ - gamma - open1_)*ungappedlambda) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[3][0]=1/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[3][1]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[3][2]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[3][3]=exp(-(epen1_*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[3][4]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[3][5]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[3][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[4][0]=1/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[4][1]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[4][2]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[4][3]=exp(-(epen1_*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[4][4]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[4][5]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[4][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[5][0]=1/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[5][1]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[5][2]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[5][3]=exp(-(epen1_*ungappedlambda))/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[5][4]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[5][5]=exp((-epen1_ - gamma)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[5][6]=exp((-epen2_ - open2_)*ungappedlambda)/(1 + exp(-(epen1_*ungappedlambda)) + 2*exp((-epen1_ - gamma)*ungappedlambda) + 2*exp(-(gamma*ungappedlambda)) + exp((-epen2_ - open2_)*ungappedlambda));
+			transition_probabilities[6][0]=1/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
+			transition_probabilities[6][1]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
+			transition_probabilities[6][2]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
+			transition_probabilities[6][3]=0;
+			transition_probabilities[6][4]=0;
+			transition_probabilities[6][5]=0;
+			transition_probabilities[6][6]=exp(-(epen2_*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
+		};
+
+		if(choice_of_IS_weights==3)
+		{
+			transition_probabilities[0][0]=1/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[0][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[0][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[0][3]=exp((-epen1_ - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[0][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[0][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[0][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[1][0]=1/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[1][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[1][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[1][3]=exp((-epen1_ - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[1][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[1][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[1][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[2][0]=1/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[2][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[2][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[2][3]=exp((-epen1_ - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[2][4]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[2][5]=exp((-epen1_ - gamma - open1_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[2][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen1_ - open1_)*ungappedlambda)/3. + (2*exp((-epen1_ - gamma - open1_)*ungappedlambda))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[3][0]=1/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[3][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[3][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[3][3]=exp(-(epen1_*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[3][4]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[3][5]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[3][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[4][0]=1/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[4][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[4][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[4][3]=exp(-(epen1_*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[4][4]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[4][5]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[4][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[5][0]=1/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[5][1]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[5][2]=exp(-(gamma*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[5][3]=exp(-(epen1_*ungappedlambda))/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[5][4]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[5][5]=exp((-epen1_ - gamma)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[5][6]=exp((-epen2_ - open2_)*ungappedlambda)/(3.*(0.3333333333333333 + exp(-(epen1_*ungappedlambda))/3. + (2*exp((-epen1_ - gamma)*ungappedlambda))/3. + (2*exp(-(gamma*ungappedlambda)))/3. + exp((-epen2_ - open2_)*ungappedlambda)/3.));
+			transition_probabilities[6][0]=1/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
+			transition_probabilities[6][1]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
+			transition_probabilities[6][2]=exp(-(gamma*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
+			transition_probabilities[6][3]=0;
+			transition_probabilities[6][4]=0;
+			transition_probabilities[6][5]=0;
+			transition_probabilities[6][6]=exp(-(epen2_*ungappedlambda))/(1 + exp(-(epen2_*ungappedlambda)) + 2*exp(-(gamma*ungappedlambda)));
+		};
+		//for test
+
+		//introducing a fake state
+		if(add_fake_state_flag)
+		{
+			long int i;
+			for(i=0;i<number_of_states;i++)
+			{
+				transition_probabilities[i][state_name_into_number["F"]]=0;
+				transition_probabilities[state_name_into_number["F"]][i]=0;
+			};
+
+			transition_probabilities[state_name_into_number["F"]][state_name_into_number["S1"]]=1.0/3.0;
+			transition_probabilities[state_name_into_number["F"]][state_name_into_number["S2"]]=1.0/3.0;
+			transition_probabilities[state_name_into_number["F"]][state_name_into_number["S3"]]=1.0-1.0/3.0-1.0/3.0;
+
+		};
+
+
+		//test transition probablities
+		long int i,j;
+		for(i=0;i<number_of_states;i++)
+		{
+			for(j=0;j<number_of_states;j++)
+			{
+				if(transition_probabilities[i][j]<0)
+				{
+					throw error("Error - transition probablities of the importance sampling are negative;\nthe method is not applicable for the input scoring scheme\n",1);
+				};
+			};
+		};
+	
+	};
+
+//crude sampling
+
+	long int number_of_states_cs=1;
+
+	if(cs_flag)
+	{
+		states_description_cs=new pair<long int, long int>[number_of_states_cs];
+		FSA_utils::assert_mem(states_description_cs);
+
+		states_description_cs[0]=make_pair(3,1);
+
+		FSA_utils::get_memory_for_matrix(number_of_states_cs,number_of_states_cs,transition_probabilities_cs);
+		transition_probabilities_cs[0][0]=1;
+	};
+
+//crude sampling - end
+
+
+//=========================
+
+	long int s;
+
+	if(FSA_flag)
+	{
+		states_distr=new double **[number_of_states];
+
+		long int s;
+		for(s=0;s<number_of_states;s++)
+		{
+			states_distr[s]=IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+				alphabet_letters_number1,//number of letters in the sequence #1
+				alphabet_letters_number2,//number of letters in the sequence #2
+				states_description[s]);//state description
+
+		};
+	};
+
+	if(futher_expanding&&FSA_flag)
+	{
+		states_distr_reversed=new double **[number_of_states];
+
+		long int s;
+		for(s=0;s<number_of_states;s++)
+		{
+			states_distr_reversed[s]=IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+				alphabet_letters_number1,//number of letters in the sequence #1
+				alphabet_letters_number2,//number of letters in the sequence #2
+				states_description[s]);//state description
+
+		};
+
+	};
+
+
+	if(cs_flag)
+	{
+		states_distr_cs=new double **[number_of_states_cs];
+
+		long int s;
+		for(s=0;s<number_of_states_cs;s++)
+		{
+			states_distr_cs[s]=IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+				alphabet_letters_number1,//number of letters in the sequence #1
+				alphabet_letters_number2,//number of letters in the sequence #2
+				states_description_cs[s]);//state description
+
+		};
+
+	};
+
+//=========================
+	FSA_IS_transition_probabilities_calculation(
+	FSA_flag,
+	states_distr,
+
+	cs_flag,
+	states_distr_cs,
+
+	sim_flag,
+	states_distr_sim,
+
+	number_of_states,
+	alphabet_letters_number1,
+	alphabet_letters_number2,
+	states_description,
+	codon_length,
+	codon_AA,
+	RR1,
+	RR2,
+	state_name_into_number,
+	smatr,
+	ungappedlambda);
+
+	if(futher_expanding&&FSA_flag)
+	{
+		bool cs_flag_tmp=false;
+		bool sim_flag_tmp=false;
+
+		FSA_IS_transition_probabilities_calculation(
+		FSA_flag,
+		states_distr_reversed,
+
+		cs_flag_tmp,
+		states_distr_cs,
+
+		sim_flag_tmp,
+		states_distr_sim,
+
+		number_of_states,
+		alphabet_letters_number1,
+		alphabet_letters_number2,
+		states_description,
+		codon_length,
+		codon_reversed_AA,
+		RR1,
+		RR2,
+		state_name_into_number,
+		smatr,
+		ungappedlambda);
+
+	};
+
+//=========================
+
+	if(futher_expanding&&FSA_flag)
+	{
+		normalize_state_distributions(
+		alphabet_letters_number1,//number of letters in the sequence #1
+		alphabet_letters_number2,//number of letters in the sequence #2
+		number_of_states,//number of states
+		states_description,//description of the states; the index is a state number
+		states_distr_reversed);//distributions of the states; the index is a state number
+
+	};
+
+	if(FSA_flag)
+	{
+		normalize_state_distributions(
+		alphabet_letters_number1,//number of letters in the sequence #1
+		alphabet_letters_number2,//number of letters in the sequence #2
+		number_of_states,//number of states
+		states_description,//description of the states; the index is a state number
+		states_distr);//distributions of the states; the index is a state number
+
+	};
+
+	if(cs_flag)
+	{
+		normalize_state_distributions(
+		alphabet_letters_number1,//number of letters in the sequence #1
+		alphabet_letters_number2,//number of letters in the sequence #2
+		number_of_states_cs,//number of states
+		states_description_cs,//description of the states; the index is a state number
+		states_distr_cs);//distributions of the states; the index is a state number
+
+	};
+
+//=========================
+
+	IS1_general* IS1_reversed=NULL;
+	if(FSA_flag&&futher_expanding)
+	{
+		IS1_reversed=new IS1_general(
+		alphabet_letters_number1,//number of letters in the sequence #1
+		alphabet_letters_number2,//number of letters in the sequence #2
+		RR1,//background probability for the sequence #1
+		RR2,//background probability for the sequence #2
+		number_of_states,//number of states
+		transition_probabilities,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
+		states_description,//description of the states; the index is a state number
+		states_distr_reversed);//distributions of the states; the index is a state number
+
+	};
+
+
+	if(FSA_flag)
+	{
+		d_IS1=new IS1_general(
+		alphabet_letters_number1,//number of letters in the sequence #1
+		alphabet_letters_number2,//number of letters in the sequence #2
+		RR1,//background probability for the sequence #1
+		RR2,//background probability for the sequence #2
+		number_of_states,//number of states
+		transition_probabilities,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
+		states_description,//description of the states; the index is a state number
+		states_distr);//distributions of the states; the index is a state number
+
+	};
+
+
+	//crude sampling 
+
+
+	IS1_general* IS1_cs=NULL;
+	if(cs_flag)
+	{
+		IS1_cs=new IS1_general(
+		alphabet_letters_number1,//number of letters in the sequence #1
+		alphabet_letters_number2,//number of letters in the sequence #2
+		RR1,//background probability for the sequence #1
+		RR2,//background probability for the sequence #2
+		number_of_states_cs,//number of states
+		transition_probabilities_cs,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
+		states_description_cs,//description of the states; the index is a state number
+		states_distr_cs);//distributions of the states; the index is a state number
+	};
+	//crude sampling - end
+
+
+	ofstream lambda_out;
+
+	if(lambda_output_flag)
+	{
+		lambda_out.open(lambda_file_name.data());
+		if(!lambda_out)
+		{
+			throw error("Error - the file "+lambda_file_name+" is not found\n",1);
+		};
+	};
+
+
+	long int var_num_dim=1000;
+	long int *var_num=new long int[var_num_dim];
+	long int i;
+	for(i=0;i<var_num_dim;i++)
+	{
+		var_num[i]=-1;
+	};
+
+	var_num['S']=0;
+	var_num['D']=1;
+	var_num['I']=2;
+
+
+	data_for_FSA_alignment data_test;
+	
+
+	data_test.d_alphabet_letters_number1=alphabet_letters_number1;
+
+	data_test.d_open1=open1_;
+	data_test.d_open2=open2_;
+
+	data_test.d_epen1=epen1_;
+	data_test.d_epen2=epen2_;
+
+	data_test.d_gamma=gamma_;
+
+	data_test.d_smatr=smatr;
+
+	data_test.d_codon_AA=codon_AA;
+
+	data_test.d_insertions_after_deletions=insertions_after_deletions_;
+
+	data_test.d_alignment_type="global";
+	//data_test.d_alignment_type="local";
+
+	if(lambda_output_flag)
+	{
+		lambda_out<<open1_<<"\t"<<epen1_<<"\t"<<open2_<<"\t"<<epen2_<<"\t"<<gamma_<<"\t"<<number_of_realizations<<"\t"<<target_ALP<<endl;
+		lambda_out<<"lambda\t";
+		lambda_out<<"C\t";
+		lambda_out<<"a_I\t";
+		lambda_out<<"a_J\t";
+		lambda_out<<"sigma\t";
+		lambda_out<<"alpha_I\t";
+		lambda_out<<"alpha_J\t";
+		lambda_out<<"K_C\t";
+		lambda_out<<endl;
+
+	};
+
+
+	long int number_of_variables_for_the_alignment=3;
+
+
+	two_dim_layer_alignment_algorithm<long int>* two_dim_layer_alignment_algorithm_test=NULL;
+
+	Sls::FALP_set_of_parameters par;
+
+	double time0_start;
+	FSA_utils::get_current_time(time0_start);
+
+	bool accuracy_is_achieved_flag=false;
+
+//--------------------------
+		//crude sampling
+		string M_distr_file_name_cs=lambda_file_name+"_M_cs.out";
+		data_for_FSA_alignment data_test_cs;
+
+		IS1_general_simulation *IS1_general_simulation_cs=NULL;
+		two_dim_layer_alignment_algorithm<long int> *two_dim_layer_alignment_algorithm_test_cs=NULL;
+
+		//crude sampling - end
+//--------------------------
+
+	long int M_thr_estimation_direct=0;//average score threshold corresponded to target_ALP_
+
+
+	if(FSA_flag)
+	{
+		long int initial_state=state_name_into_number["S1"];
+
+		if(add_fake_state_flag)
+		{
+			initial_state=state_name_into_number["F"];
+		};
+
+
+
+		d_IS1_general_simulation=new IS1_general_simulation(
+		d_IS1,
+		initial_state,//initial state for the IS
+		max_ind1*mult_margin+add_margin,//maximum sequence length
+		max_ind2*mult_margin+3*add_margin);//maximum sequence length
+
+
+		data_test.d_seq1=d_IS1_general_simulation->d_seq1;//sequence #1
+		data_test.d_seq2=d_IS1_general_simulation->d_seq2;//sequence #2
+	
+
+		two_dim_layer_alignment_algorithm_test=
+		new two_dim_layer_alignment_algorithm<long int>(
+		number_of_variables_for_the_alignment,//total number of variables in dynamic equations
+		depth1,//the maximum difference of the first index in the dynamic equations
+		depth2,//the maximum difference of the second index in the dynamic equations
+		max_ind1,//max of the index #1 (minimum index is 0 by default)
+		max_ind2,//max of the index #2 (minimum index is 0 by default)
+		0,//null element of T
+		var_num);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
+
+
+
+
+		//string M_distr_file_name="M_distr_FSA.out";
+		string M_distr_file_name=lambda_file_name+"_M.out";
+
+		if(par_test1_)
+		{
+			M_distr_file_name=par_test1_->d_gumbelparout_file_name;
+		};
+
+		
+		two_dim_layer_alignment_algorithm_test->d_two_dim_layer_alignment_function=test::two_dim_layer_alignment_function_FSA;
+		two_dim_layer_alignment_algorithm_test->d_two_dim_layer_boundary_function=test::two_dim_layer_alignment_function_FSA;
+		two_dim_layer_alignment_algorithm_test->d_par=&data_test;
+
+
+		two_dim_layer_alignment_algorithm_test->d_M_flag=true;
+		two_dim_layer_alignment_algorithm_test->d_E_flag=false;
+
+		two_dim_layer_alignment_algorithm_test->d_scores_counts_flag=false;
+
+
+		double fraction_of_ALP_opt=0.5;
+
+
+		{
+
+			//bool futher_expanding_tmp=true;
+			bool futher_expanding_tmp=false;
+			
+
+			long int limit2=max_ind2;
+
+			two_dim_layer_alignment_algorithm_test->d_scores_counts_flag=futher_expanding_tmp;
+			two_dim_layer_alignment_algorithm_test->d_FSC_flag=true;
+
+
+
+			//additional test whether the scoring scheme is logarithmic
+
+			double time_for_one_realization_without_killing=0;
+			double time_for_one_realization_with_killing=0;
+			long int M_thr_estimation_direct_from_the_minimal_test;
+
+			{
+				double time_tmp00;
+				double time_tmp11;
+				
+
+				double ending_time_tmp2=-1;
+				bool stopped_by_ending_time_flag_tmp2;
+				long int number_of_realizations_with_ending_time_tmp2;
+				double ending_time_to_test_logarithmic_regime2=-1;
+
+				bool inside_simulation_flag=true;
+				bool save_states_flag=false;
+				mult_states_type *states_old1=NULL;
+				mult_states_type *states_new1=NULL;
+				bool futher_expanding_test=true;
+				long int M_thr=-inf;
+
+				//number of test realizations for the test
+				long int number_of_realizations_test=1;
+				long int number_of_sets_test=1;
+				
+
+
+				try
+				{
+
+					two_dim_layer_alignment_algorithm_test->d_scores_counts_flag=true;
+					bool parameters_are_not_calculated=true;
+
+					
+
+					FSA_utils::get_current_time(time_tmp00);
+
+					bool compute_allocated_memory_flag_tmp=false;
+					double allocated_memory_tmp;
+
+
+					//without expanding with calculation of M-threshold
+					collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+					compute_allocated_memory_flag_tmp,
+					allocated_memory_tmp,
+
+					number_of_realizations_test,
+					M_distr_file_name,
+					*two_dim_layer_alignment_algorithm_test,
+					*d_IS1_general_simulation,
+					target_ALP,//target ALP number
+					ungappedlambda,
+					limit2,
+
+					number_of_sets_test,
+					par,
+					inside_simulation_flag,
+					false,
+					false,
+
+					ending_time_tmp2,
+					stopped_by_ending_time_flag_tmp2,
+					number_of_realizations_with_ending_time_tmp2,
+
+					ending_time_to_test_logarithmic_regime2,
+
+					save_states_flag,
+					states_old1,
+					states_new1,
+					M_thr_estimation_direct,
+
+					//futher_expanding_test,
+					false,
+					M_thr,
+					IS1_cs,
+					&eps_K,
+					&number_of_cs_steps_for_expanding,
+					parameters_are_not_calculated);
+
+					FSA_utils::get_current_time(time_tmp11);
+
+					time_for_one_realization_without_killing=(time_tmp11-time_tmp00)/(double)number_of_realizations_test;
+					if(time_for_one_realization_without_killing<0)
+					{
+						time_for_one_realization_without_killing=0;
+					};
+
+					{
+						
+
+						bool compute_allocated_memory_flag_tmp=false;
+						double allocated_memory_tmp;
+
+						//test with expanding
+						collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+						compute_allocated_memory_flag_tmp,
+						allocated_memory_tmp,
+
+
+						number_of_realizations_test,
+						M_distr_file_name,
+						*two_dim_layer_alignment_algorithm_test,
+						*d_IS1_general_simulation,
+						target_ALP,//target ALP number
+						ungappedlambda,
+						limit2,
+
+						number_of_sets_test,
+						par,
+						inside_simulation_flag,
+						false,
+						false,
+
+						ending_time_tmp2,
+						stopped_by_ending_time_flag_tmp2,
+						number_of_realizations_with_ending_time_tmp2,
+
+						ending_time_to_test_logarithmic_regime2,
+
+						save_states_flag,
+						states_old1,
+						states_new1,
+						M_thr_estimation_direct_from_the_minimal_test,
+
+						futher_expanding_test,
+						M_thr_estimation_direct,
+						IS1_cs,
+						&eps_K,
+						&number_of_cs_steps_for_expanding,
+						parameters_are_not_calculated);
+
+						M_thr_estimation_direct_from_the_minimal_test=(long int)FSA_utils::round(0.5*(M_thr_estimation_direct_from_the_minimal_test+
+							M_thr_estimation_direct));
+					};
+
+
+					two_dim_layer_alignment_algorithm_test->d_scores_counts_flag=false;
+
+
+				}
+				catch (error er)
+				{ 
+					if(er.error_code==10)
+					{
+						throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+					}
+					else
+					{
+						throw error(er.st,er.error_code);
+					};
+
+				};
+
+				double time_tmp22;
+				FSA_utils::get_current_time(time_tmp22);
+
+				time_for_one_realization_with_killing=(time_tmp22-time_tmp11)/(double)number_of_realizations_test;
+				if(time_for_one_realization_with_killing<0)
+				{
+					time_for_one_realization_with_killing=0;
+				};
+
+
+			};
+
+
+
+
+			//automatic adjusment of ALP number
+			if(max_time_>0)
+			{
+				if(!library_call_flag_)
+				{
+					cout<<"\nPreliminary stage...\n";
+				};
+
+				double mult_for_prediction=1.0;
+
+				double mult0=0.5;
+				double mult1=0.5*mult0;
+
+				long int max_number_of_realizations0=100;
+				
+
+
+
+				long int number_of_realizations0=max_number_of_realizations0;
+
+				//long int number_of_realizations1_without_extending=number_of_realizations0;
+				long int number_of_realizations1_with_extending=100;
+
+				long int number_of_sets1_without_extending=5;
+				long int number_of_sets1_with_extending=1;
+				
+
+				//double max_calculation_time_for_preliminary_stage=60;//in seconds
+				double max_calculation_time_for_preliminary_stage=inf;//in seconds
+
+				double time_preliminary_stage_expected=
+					//time_for_one_realization_with_killing*number_of_realizations1_with_extending+
+					//number_of_realizations1_without_extending*time_for_one_realization_without_killing;
+					time_for_one_realization_with_killing*number_of_realizations1_with_extending;
+
+				if(max_calculation_time_for_preliminary_stage<time_preliminary_stage_expected)
+				{
+					max_calculation_time_for_preliminary_stage=1.5*time_preliminary_stage_expected;
+				};
+
+				if(max_calculation_time_for_preliminary_stage>max_time_*mult0)
+				{
+					max_calculation_time_for_preliminary_stage=max_time_*mult0;
+				};
+
+				if(!library_call_flag_)
+				{
+					cout<<"Maximum time for the preliminary stage: "<<max_calculation_time_for_preliminary_stage<<" sec\n\n";
+				};
+
+
+
+				bool test_output1=false;
+
+				
+				ofstream ff;
+
+				if(test_output1)
+				{
+					string fn="ALP_stat_test1.out";
+
+					ff.open(fn.data());
+					if(!ff)
+					{
+						throw error("Error - file "+fn+" is not found\n",1);
+					};
+
+
+					ff<<"number of realizations\t\
+number of ALP\t\
+time per one cell (ALP)\t\
+ALP position for seq #1\t\
+ALP position for seq #2\t\
+product of positions\t\
+expected relative error of lambda\t\
+time per one cell (expanding)\t\
+expanding length for seq #1\t\
+expanding length for seq #2\t\
+product of lengths\n";
+				};
+
+
+				bool save_states_flag=true;
+				mult_states_type *states_old1=NULL;
+				mult_states_type *states_new1=new mult_states_type;
+				Sls::FALP_set_of_parameters par1;
+
+				bool further_expanding_tmp1=true;
+
+				long int ALP_max_number=10;
+
+				long int ALP1_start=3;
+
+				vector<bool> ALP_flag(ALP_max_number+1,false);
+
+
+				long int ALP1=ALP1_start;
+				
+				
+
+				long int count_tmp1=0;
+				vector<double> lambda_relative_errors;
+				
+				long int number_of_ALP_for_errors=1;
+
+				double L1=0;
+				double L2=0;
+				double L1_L2=0;
+
+				double X1;
+				double X2;
+				double X1_X2;
+
+				double time_cell_ALP=0;
+				double time_cell_exp=0;
+				double time_exp=0;
+
+				long int ALP_opt=3;
+				double error_opt=inf;
+				mult_states_type *states_opt=NULL;
+				long int expected_number_of_realizations1_opt=0;
+				
+
+				long int delete_old_object_flag=0;
+
+				bool inside_simulation_flag;
+
+				long int count_of_failed_relative_errors_max=3;
+				long int count_of_failed_relative_errors=0;
+				bool flag1=true;
+				double total_time_without_extending=0;
+				double total_time_without_extending_opt=0;
+
+				long int number_of_realizations1=0;
+				long int number_of_sets1=0;
+
+				while(flag1)
+				{
+					
+					Sls::FALP_set_of_parameters par1_old;
+
+					if(states_old1)
+					{
+						par1_old=par1;
+					};
+
+					
+					double ending_time_tmp1=-1.0;
+					bool stopped_by_ending_time_flag_tmp1;
+					long int number_of_realizations_with_ending_time_tmp1;
+					double ending_time_to_test_logarithmic_regime1;
+					long int M_thr=-inf;
+
+						bool compute_allocated_memory_flag_tmp;
+						double allocated_memory_tmp;
+
+					
+					if(count_tmp1==0)
+					{
+						compute_allocated_memory_flag_tmp=true;
+						allocated_memory_tmp=0;
+
+						number_of_realizations1=number_of_realizations1_with_extending;
+						number_of_sets1=number_of_sets1_with_extending;
+						ending_time_to_test_logarithmic_regime1=time0_start+FSA_utils::Tmin(max_calculation_time_for_preliminary_stage,mult1*max_time_);
+						M_thr=M_thr_estimation_direct_from_the_minimal_test;
+					}
+					else
+					{
+						compute_allocated_memory_flag_tmp=false;
+
+						//number_of_realizations1=number_of_realizations1_without_extending;
+						number_of_sets1=number_of_sets1_without_extending;
+						ending_time_to_test_logarithmic_regime1=-1;
+					};
+
+					double time_without_extending_tmp1;
+					FSA_utils::get_current_time(time_without_extending_tmp1);
+
+					collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+					compute_allocated_memory_flag_tmp,
+					allocated_memory_tmp,
+
+					number_of_realizations1,
+					M_distr_file_name,
+					*two_dim_layer_alignment_algorithm_test,
+					*d_IS1_general_simulation,
+					ALP1,//target ALP number
+					ungappedlambda,
+					limit2,
+					number_of_sets1,
+					par1,
+					inside_simulation_flag,
+					false,
+					false,
+
+					ending_time_tmp1,
+					stopped_by_ending_time_flag_tmp1,
+					number_of_realizations_with_ending_time_tmp1,
+
+					ending_time_to_test_logarithmic_regime1,
+
+					save_states_flag,
+					states_old1,
+					states_new1,
+					M_thr_estimation_direct,
+
+					false,
+					M_thr,
+					IS1_cs,
+					&eps_K,
+					&number_of_cs_steps_for_expanding);
+
+					if(compute_allocated_memory_flag_tmp)
+					{
+						if(allocated_memory_tmp>0)
+						{
+							max_number_of_states=FSA_utils::round(FSA_utils::Tmin((double)inf,max_mem_for_states_alloc/allocated_memory_tmp/((double)((ALP1+1)*(ALP1+1))/(double)(ALP1*ALP1))/2.0));
+						};
+					}
+					else
+					{
+						max_number_of_states/=(double)((ALP1+1)*(ALP1+1))/(double)(ALP1*ALP1);
+					};
+
+
+
+					double time_without_extending_tmp2;
+					FSA_utils::get_current_time(time_without_extending_tmp2);
+
+
+					total_time_without_extending+=time_without_extending_tmp2-time_without_extending_tmp1;
+
+
+					if(further_expanding_tmp1)
+					{
+						delete_mult_states_type(states_old1);
+						
+						states_old1=states_new1;
+						states_new1=new mult_states_type;
+
+						bool compute_allocated_memory_flag_tmp=false;
+						double allocated_memory_tmp;
+
+
+						collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+						compute_allocated_memory_flag_tmp,
+						allocated_memory_tmp,
+
+						number_of_realizations1,
+						M_distr_file_name,
+						*two_dim_layer_alignment_algorithm_test,
+						*d_IS1_general_simulation,
+						ALP1,//target ALP number
+						ungappedlambda,
+						limit2,
+						number_of_sets1,
+						par1,
+						inside_simulation_flag,
+						false,
+						false,
+
+						ending_time_tmp1,
+						stopped_by_ending_time_flag_tmp1,
+						number_of_realizations_with_ending_time_tmp1,
+
+						ending_time_to_test_logarithmic_regime1,
+
+						save_states_flag,
+						states_old1,
+						states_new1,
+						M_thr_estimation_direct,
+
+						further_expanding_tmp1,
+						M_thr,
+						IS1_cs,
+						&eps_K,
+						&number_of_cs_steps_for_expanding);
+
+
+						time_cell_exp=states_new1->d_total_calculation_time;
+						time_exp=time_cell_exp;
+
+						states_new1->d_total_calculation_time=states_old1->d_total_calculation_time;
+
+
+						delete_mult_states_type(states_old1);
+						states_old1=NULL;
+
+
+					};
+
+					count_tmp1++;
+
+					if(inside_simulation_flag)
+					{
+						if(!library_call_flag_)
+						{
+							cout<<"ALP#="<<ALP1<<"; realizations#="<<number_of_realizations1<<"; time="<<states_new1->d_total_calculation_time<<"\n";
+						};
+						ALP_flag[ALP1]=true;
+					}
+					else
+					{
+						if(!library_call_flag_)
+						{
+							cout<<"ALP#="<<ALP1<<"; realizations#="<<number_of_realizations1<<"; time="<<states_new1->d_total_calculation_time<<": the calculation is not successful\n";
+						};
+					};
+
+					X1=states_new1->d_average_ALP_pos1/(double)states_new1->d_number_of_ALP;
+					X2=states_new1->d_average_ALP_pos2/(double)states_new1->d_number_of_ALP;
+					X1_X2=states_new1->d_average_ALP_pos1_mult_ALP_pos2/((double)(states_new1->d_number_of_ALP*states_new1->d_number_of_ALP));
+
+					if(further_expanding_tmp1)
+					{
+						L1=states_new1->d_average_expanding_length1;
+						L2=states_new1->d_average_expanding_length2;
+						L1_L2=states_new1->d_average_expanding_length1_mult_expanding_length2;
+
+
+						if(states_new1->d_total_number_of_exp_cells>0)
+						{
+							time_cell_exp=time_exp/(double)states_new1->d_total_number_of_exp_cells;
+						}
+						else
+						{
+							throw error("Unexpected error\n",1);
+						};
+					};
+
+					double time_cell_ALP_tmp=states_new1->d_total_calculation_time/((double)states_new1->d_total_number_of_ALP_cells);
+
+					time_cell_ALP=time_cell_ALP_tmp;
+
+					if(test_output1)
+					{
+						ff<<number_of_realizations1<<"\t"<<states_new1->d_number_of_ALP<<"\t"
+							<<time_cell_ALP<<"\t"
+							<<X1<<"\t"
+							<<X2<<"\t"
+							<<X1_X2;
+
+					};
+
+
+
+
+
+
+					//check relative errors
+					if(ALP_flag[ALP1]&&ALP_flag[ALP1-1])
+					{
+
+
+						
+						double T_per_realization=(2*ALP1*ALP1*X1_X2*time_cell_ALP+(ALP1*(X1*L2+X2*L1)+L1_L2)*time_cell_exp);
+
+						if(T_per_realization<=0)
+						{
+							throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+						};
+
+						long int expected_number_of_realizations1=(long int)FSA_utils::round(
+							FSA_utils::Tmin(max_number_of_states,
+							mult_for_prediction*(max_time_-time_exp)
+							/T_per_realization)
+							);
+
+						expected_number_of_realizations1=FSA_utils::Tmax(expected_number_of_realizations1,(long int)1);
+
+
+						double lambda_error1=par1.lambda_last_ALP_relative_error;
+
+
+						lambda_error1*=sqrt((double)number_of_realizations1/(2.0*(double)expected_number_of_realizations1));
+
+						lambda_relative_errors.push_back(lambda_error1);
+						if(!library_call_flag_)
+						{
+							cout<<"Expected lambda relative error for ALP#="<<ALP1<<" is "<<lambda_error1<<endl<<endl;
+						};
+
+						if(test_output1)
+						{
+							ff<<"\t"<<lambda_error1;
+						};
+
+						long int vect_size=(long int)lambda_relative_errors.size();
+						if(vect_size>=number_of_ALP_for_errors)
+						{
+							double average_relative_error=0;
+
+							long int j;
+							for(j=0;j<number_of_ALP_for_errors;j++)
+							{
+								average_relative_error+=lambda_relative_errors[vect_size-1-j];
+							};
+
+							average_relative_error/=(double)number_of_ALP_for_errors;
+
+
+							if(average_relative_error<eps_lambda_)
+							{
+								flag1=false;
+							};
+
+							delete_old_object_flag++;
+
+
+							if(average_relative_error<error_opt)
+							{
+								total_time_without_extending_opt=total_time_without_extending;
+
+								count_of_failed_relative_errors=0;
+								ALP_opt=ALP1;
+								error_opt=average_relative_error;
+
+								expected_number_of_realizations1_opt=expected_number_of_realizations1;
+
+								//calculaton of the fraction of ALP
+								double nom=ALP1*ALP1*X1_X2*time_cell_ALP;
+								fraction_of_ALP_opt=nom/T_per_realization;
+
+
+								if(states_opt==states_old1)
+								{
+									states_old1=NULL;
+								};
+
+								delete_mult_states_type(states_opt);
+								states_opt=states_new1;
+
+								delete_old_object_flag=-2;
+
+							}
+							else
+							{
+								if(count_of_failed_relative_errors_max>0)
+								{
+									count_of_failed_relative_errors++;
+									if(count_of_failed_relative_errors>count_of_failed_relative_errors_max)
+									{
+										flag1=false;
+									};
+								};
+							};
+						};
+					}
+					else
+					{
+						if(test_output1)
+						{
+							ff<<"\t#N/A";
+						};
+						if(!library_call_flag_)
+						{
+							cout<<endl;
+						};
+					};
+
+
+					if(test_output1)
+					{
+
+						if(further_expanding_tmp1)
+						{
+							ff<<"\t"<<time_cell_exp<<"\t"
+							<<L1<<"\t"
+							<<L2<<"\t"
+							<<L1_L2;
+						}
+						else
+						{
+							ff<<"\t#N/A\t"
+							<<"#N/A\t"
+							<<"#N/A\t"
+							<<"#N/A";
+
+						};
+
+						
+					};
+
+
+
+					if(ALP1>=ALP_max_number)
+					{
+						flag1=false;
+					};
+					//cout<<ALP1<<endl;
+
+
+					double time0_current;
+					FSA_utils::get_current_time(time0_current);
+
+					//time limits
+					if(time0_current-time0_start>=max_time_*mult1||time0_current-time0_start>=max_calculation_time_for_preliminary_stage)
+					{
+						flag1=false;
+					};
+
+					if(test_output1)
+					{
+						ff<<"\t"<<time0_current-time0_start-time_exp<<"\t"<<states_new1->d_total_calculation_time;
+						ff<<"\n";
+					};
+
+					//deallocate and allocate memory
+					if(states_opt!=states_old1)
+					{
+						delete_mult_states_type(states_old1);
+					};
+
+
+					states_old1=states_new1;
+					states_new1=new mult_states_type;
+
+
+					if(!flag1)
+					{
+						break;
+					};
+
+					//increase number of ALP
+					ALP1++;
+
+					//prediction of the time required for the calculation with the new number of ALP=ALP1
+					long int ALP1_corrected=FSA_utils::Tmax(ALP1,ALP1_start+number_of_ALP_for_errors+1);
+					double T_per_realization=(2*ALP1_corrected*ALP1_corrected*X1_X2*time_cell_ALP+(ALP1_corrected*(X1*L2+X2*L1)+L1_L2)*time_cell_exp);
+
+					if(T_per_realization<=0)
+					{
+						throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+					};
+
+					
+					number_of_realizations1=(long int)FSA_utils::round(
+						FSA_utils::Tmin(max_number_of_states,
+						FSA_utils::Tmin(mult0*max_calculation_time_for_preliminary_stage,mult1*(max_time_-time_exp))
+						/T_per_realization)
+						);
+
+					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+					//number_of_realizations1=FSA_utils::Tmin(max_number_of_realizations0,number_of_realizations1);
+
+
+					if(further_expanding_tmp1)
+					{
+						further_expanding_tmp1=false;
+					};					
+				};
+
+
+				if(test_output1)
+				{
+					ff.close();
+				};
+
+				if(states_opt!=states_old1)
+				{
+					delete_mult_states_type(states_old1);
+				};
+				if(states_opt!=states_new1)
+				{
+					delete_mult_states_type(states_new1);
+				};
+
+				if(!states_opt)
+				{
+					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+				};
+
+
+				if(eps_lambda_>0)
+				{
+					if(error_opt<eps_lambda_)
+					{
+						accuracy_is_achieved_flag=true;
+						//number of realizations is too large for the requested accuracy
+						//decreasing number of realizations
+						double coeff=error_opt/eps_lambda_;
+						coeff=coeff*coeff;
+						expected_number_of_realizations1_opt=(long int)FSA_utils::round(
+							FSA_utils::Tmin(max_number_of_states,
+							coeff*expected_number_of_realizations1_opt));
+						expected_number_of_realizations1_opt=FSA_utils::Tmax(number_of_realizations0,expected_number_of_realizations1_opt);
+					}
+					else
+					{
+						expected_number_of_realizations1_opt*=8;
+					};
+				}
+				else
+				{
+					expected_number_of_realizations1_opt*=8;
+				};
+
+				expected_number_of_realizations1_opt=(long int)FSA_utils::round(
+					FSA_utils::Tmin((double)max_number_of_states,
+					(double)expected_number_of_realizations1_opt));
+
+				if(!library_call_flag_)
+				{
+					cout<<"\n--------------\n";
+					cout<<"\nOptimal ALP# for the forward and reverse stages is\t"<<ALP_opt<<endl;
+					cout<<"\n--------------\n";
+
+					if(accuracy_is_achieved_flag)
+					{
+						cout<<"The input relative error for lambda can be acheived with this number of realizations\n";
+					};
+					cout<<endl;
+
+				};
+
+
+				double time_tmp2;
+				FSA_utils::get_current_time(time_tmp2);
+
+				double tmp2=(max_time_-(time_tmp2-time0_start)+states_opt->d_total_calculation_time)*fraction_of_ALP_opt
+				//-states_opt->d_total_calculation_time;
+				-total_time_without_extending_opt;
+
+				if(tmp2<0)
+				{
+					tmp2=0;
+				};
+
+				double ending_time_tmp2=time_tmp2+tmp2;
+
+				bool stopped_by_ending_time_flag_tmp2;
+				long int number_of_realizations_with_ending_time_tmp2;
+				double ending_time_to_test_logarithmic_regime2=-1;
+				long int M_thr=-inf;
+
+				//final calculation
+				if(!library_call_flag_)
+				{
+					cout<<"Forward stage...\n\n";
+				};
+				save_states_flag=true;
+				states_new1=NULL;
+				states_new1=new mult_states_type;
+				
+				bool compute_allocated_memory_flag_tmp=false;
+				double allocated_memory_tmp;
+
+				collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+				compute_allocated_memory_flag_tmp,
+				allocated_memory_tmp,
+
+
+				expected_number_of_realizations1_opt,
+				M_distr_file_name,
+				*two_dim_layer_alignment_algorithm_test,
+				*d_IS1_general_simulation,
+				ALP_opt,//target ALP number
+				ungappedlambda,
+				limit2,
+				number_of_sets,
+				par,
+				inside_simulation_flag,
+				false,
+				true&&forward_and_reverse_screen_output_flag_,
+
+				ending_time_tmp2,
+				stopped_by_ending_time_flag_tmp2,
+				number_of_realizations_with_ending_time_tmp2,
+
+				ending_time_to_test_logarithmic_regime2,
+
+				save_states_flag,
+				states_opt,
+				states_new1,
+				M_thr_estimation_direct,
+
+				false,
+				M_thr,
+				IS1_cs,
+				&eps_K,
+				&number_of_cs_steps_for_expanding);
+
+				number_of_realizations=expected_number_of_realizations1_opt;
+				target_ALP=ALP_opt;
+
+				if(stopped_by_ending_time_flag_tmp2)
+				{
+					if(!library_call_flag_)
+					{
+						cout<<"Number of realizations of the forward stage is\t"<<number_of_realizations_with_ending_time_tmp2<<endl<<endl;
+						cout<<"Parameters estimation from the forward stage\n";
+					};
+					number_of_realizations=number_of_realizations_with_ending_time_tmp2;
+
+
+					save_states_flag=false;
+					ending_time_tmp2=-1;
+					mult_states_type *states_new1_tmp=NULL;
+
+					bool compute_allocated_memory_flag_tmp=false;
+					double allocated_memory_tmp;
+
+
+					collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+					compute_allocated_memory_flag_tmp,
+					allocated_memory_tmp,
+
+					number_of_realizations,
+					M_distr_file_name,
+					*two_dim_layer_alignment_algorithm_test,
+					*d_IS1_general_simulation,
+					ALP_opt,//target ALP number
+					ungappedlambda,
+					limit2,
+
+					number_of_sets,
+					par,
+					inside_simulation_flag,
+					forward_and_reverse_screen_output_flag_,
+					false,
+
+					ending_time_tmp2,
+					stopped_by_ending_time_flag_tmp2,
+					number_of_realizations_with_ending_time_tmp2,
+
+					ending_time_to_test_logarithmic_regime2,
+
+					save_states_flag,
+					states_new1,
+					states_new1_tmp,
+					M_thr_estimation_direct,
+
+					false,
+					M_thr,
+					IS1_cs,
+					&eps_K,
+					&number_of_cs_steps_for_expanding);
+				};
+
+				if(!inside_simulation_flag)
+				{
+					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+				};
+
+
+				delete_mult_states_type(states_new1);
+				delete_mult_states_type(states_opt);
+
+
+
+			};
+
+
+			if(max_time_<=0)
+			{
+				if(!library_call_flag_)
+				{
+					cout<<"\nForward stage...\n\n";
+				};
+
+				double ending_time_tmp2=-1;
+				bool stopped_by_ending_time_flag_tmp2;
+				long int number_of_realizations_with_ending_time_tmp2;
+				double ending_time_to_test_logarithmic_regime2=-1;
+				long int M_thr=-inf;
+
+				bool inside_simulation_flag=true;
+				bool save_states_flag=false;
+				mult_states_type *states_old1=NULL;
+				mult_states_type *states_new1=NULL;
+
+				bool compute_allocated_memory_flag_tmp=false;
+				double allocated_memory_tmp;
+
+				collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+				compute_allocated_memory_flag_tmp,
+				allocated_memory_tmp,
+
+				number_of_realizations,
+				M_distr_file_name,
+				*two_dim_layer_alignment_algorithm_test,
+				*d_IS1_general_simulation,
+				target_ALP,//target ALP number
+				ungappedlambda,
+				limit2,
+
+				number_of_sets,
+				par,
+				inside_simulation_flag,
+				forward_and_reverse_screen_output_flag_,
+				true&&forward_and_reverse_screen_output_flag_,
+
+				ending_time_tmp2,
+				stopped_by_ending_time_flag_tmp2,
+				number_of_realizations_with_ending_time_tmp2,
+
+				ending_time_to_test_logarithmic_regime2,
+
+				save_states_flag,
+				states_old1,
+				states_new1,
+				M_thr_estimation_direct,
+
+				futher_expanding_tmp,
+				M_thr,
+				IS1_cs,
+				&eps_K,
+				&number_of_cs_steps_for_expanding);
+
+
+				if(!inside_simulation_flag)
+				{
+					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+				};
+
+
+			};
+
+			double time0_end;
+			FSA_utils::get_current_time(time0_end);
+
+			if(!library_call_flag_)
+			{
+				cout<<"Time of the forward stage\t"<<time0_end-time0_start<<endl;
+			};
+
+
+			
+
+			if(lambda_output_flag)
+			{
+				lambda_out<<par.lambda<<"\t";lambda_out<<par.lambda_error<<"\t";
+				lambda_out<<par.C<<"\t";lambda_out<<par.C_error<<"\t";
+				lambda_out<<par.a_I<<"\t";lambda_out<<par.a_I_error<<"\t";
+				lambda_out<<par.a_J<<"\t";lambda_out<<par.a_J_error<<"\t";
+				lambda_out<<par.sigma<<"\t";lambda_out<<par.sigma_error<<"\t";
+				lambda_out<<par.alpha_I<<"\t";lambda_out<<par.alpha_I_error<<"\t";
+				lambda_out<<par.alpha_J<<"\t";lambda_out<<par.alpha_J_error<<"\t";
+
+				if(futher_expanding_tmp)
+				{
+					lambda_out<<par.K_C<<"\t";lambda_out<<par.K_C_error<<"\t";
+				}
+				else
+				{
+					lambda_out<<"#N/A\t";
+				};
+
+			};
+
+
+
+		};
+	};
+
+
+
+
+//reversed FSA sampling
+	string M_distr_file_name_reversed=lambda_file_name+"_M_reversed.out";
+	data_for_FSA_alignment data_test_reversed;
+
+	IS1_general_simulation *IS1_general_simulation_reversed=NULL;
+	two_dim_layer_alignment_algorithm<long int> *two_dim_layer_alignment_algorithm_test_reversed=NULL;
+
+	Sls::FALP_set_of_parameters par_reversed;
+
+
+	if(FSA_flag&&futher_expanding)
+	{
+		long int initial_state=state_name_into_number["S1"];
+
+		if(add_fake_state_flag)
+		{
+			initial_state=state_name_into_number["F"];
+		};
+
+
+		IS1_general_simulation_reversed=new IS1_general_simulation(
+		IS1_reversed,
+		initial_state,//initial state for the IS
+		max_ind1*mult_margin+add_margin,//maximum sequence length
+		max_ind2*mult_margin+3*add_margin);//maximum sequence length
+
+
+
+
+		data_test_reversed=data_test;
+		data_test_reversed.d_codon_AA=codon_reversed_AA;
+
+
+		data_test_reversed.d_seq1=IS1_general_simulation_reversed->d_seq1;//sequence #1
+		data_test_reversed.d_seq2=IS1_general_simulation_reversed->d_seq2;//sequence #2
+	
+
+
+		
+
+
+
+		two_dim_layer_alignment_algorithm_test_reversed=
+		new two_dim_layer_alignment_algorithm<long int>(
+		number_of_variables_for_the_alignment,//total number of variables in dynamic equations
+		depth1,//the maximum difference of the first index in the dynamic equations
+		depth2,//the maximum difference of the second index in the dynamic equations
+		max_ind1,//max of the index #1 (minimum index is 0 by default)
+		max_ind2,//max of the index #2 (minimum index is 0 by default)
+		0,//null element of T
+		var_num);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
+
+
+
+
+		
+		two_dim_layer_alignment_algorithm_test_reversed->d_two_dim_layer_alignment_function=test::two_dim_layer_alignment_function_FSA;
+		two_dim_layer_alignment_algorithm_test_reversed->d_two_dim_layer_boundary_function=test::two_dim_layer_alignment_function_FSA;
+		two_dim_layer_alignment_algorithm_test_reversed->d_par=&data_test_reversed;
+
+
+		two_dim_layer_alignment_algorithm_test_reversed->d_M_flag=true;
+		two_dim_layer_alignment_algorithm_test_reversed->d_E_flag=false;
+		two_dim_layer_alignment_algorithm_test_reversed->d_scores_counts_flag=false;
+
+
+
+		
+		{
+			two_dim_layer_alignment_algorithm_test_reversed->d_scores_counts_flag=true;
+			two_dim_layer_alignment_algorithm_test_reversed->d_FSC_flag=true;
+
+			if(!library_call_flag_)
+			{
+				cout<<"\n--------------\n";
+				cout<<"\nReverse stage...\n\n";
+			};
+
+			double time1_start;
+			FSA_utils::get_current_time(time1_start);
+
+			long int limit2=max_ind2;
+			long int M_thr_estimation_reverse;
+
+			
+
+			bool inside_simulation_flag=true;
+			long int M_thr=M_thr_estimation_direct;
+			if(!library_call_flag_)
+			{
+				cout<<"Score threshold for the reverse stage is \t"<<M_thr<<endl;
+			};
+			
+
+			if(max_time_>0)
+			{
+
+
+				if(!accuracy_is_achieved_flag)
+				{
+					number_of_realizations*=8;
+				};
+
+
+
+				double ending_time_tmp3=time0_start+max_time_;
+				bool stopped_by_ending_time_flag_tmp3;
+				long int number_of_realizations_with_ending_time_tmp3;
+				double ending_time_to_test_logarithmic_regime3=-1;
+				
+
+
+				bool save_states_flag=true;
+				mult_states_type *states_old1=NULL;
+				mult_states_type *states_new1=NULL;
+				states_new1=new mult_states_type;
+
+				bool compute_allocated_memory_flag_tmp=false;
+				double allocated_memory_tmp;
+
+				collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+				compute_allocated_memory_flag_tmp,
+				allocated_memory_tmp,
+
+				number_of_realizations,
+				M_distr_file_name_reversed,
+				*two_dim_layer_alignment_algorithm_test_reversed,
+				*IS1_general_simulation_reversed,
+				target_ALP,//target ALP number
+				ungappedlambda,
+				limit2,
+
+				number_of_sets,
+				par_reversed,
+				inside_simulation_flag,
+				//forward_and_reverse_screen_output_flag_,
+				false,
+				true&&forward_and_reverse_screen_output_flag_,
+
+				ending_time_tmp3,
+				stopped_by_ending_time_flag_tmp3,
+				number_of_realizations_with_ending_time_tmp3,
+
+				ending_time_to_test_logarithmic_regime3,
+
+				save_states_flag,
+				states_old1,
+				states_new1,
+				M_thr_estimation_reverse,
+
+				futher_expanding,
+				M_thr,
+				IS1_cs,
+				&eps_K,
+				&number_of_cs_steps_for_expanding);
+
+				
+
+
+				if(stopped_by_ending_time_flag_tmp3)
+				{
+					if(!library_call_flag_)
+					{
+						cout<<"Number of realizations of the reverse stage is\t"<<number_of_realizations_with_ending_time_tmp3<<endl<<endl;
+						cout<<"Parameters estimation from the reverse stage\n";
+					};
+					number_of_realizations=number_of_realizations_with_ending_time_tmp3;
+					//number_of_realizations_reverse_final=number_of_realizations_with_ending_time_tmp3;
+
+					save_states_flag=false;
+					ending_time_tmp3=-1;
+					mult_states_type *states_new1_tmp=NULL;
+
+					bool compute_allocated_memory_flag_tmp=false;
+					double allocated_memory_tmp;
+
+
+					collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+					compute_allocated_memory_flag_tmp,
+					allocated_memory_tmp,
+
+					number_of_realizations,
+					M_distr_file_name_reversed,
+					*two_dim_layer_alignment_algorithm_test_reversed,
+					*IS1_general_simulation_reversed,
+					target_ALP,//target ALP number
+					ungappedlambda,
+					limit2,
+
+					number_of_sets,
+					par_reversed,
+					inside_simulation_flag,
+					forward_and_reverse_screen_output_flag_,
+					false,
+
+					ending_time_tmp3,
+					stopped_by_ending_time_flag_tmp3,
+					number_of_realizations_with_ending_time_tmp3,
+
+					ending_time_to_test_logarithmic_regime3,
+
+					save_states_flag,
+					states_new1,
+					states_new1_tmp,
+					M_thr_estimation_reverse,
+
+					futher_expanding,
+					M_thr,
+					IS1_cs,
+					&eps_K,
+					&number_of_cs_steps_for_expanding);
+				};
+
+				delete_mult_states_type(states_new1);
+
+			}
+			else
+			{
+				double ending_time_tmp3=-1;
+				bool stopped_by_ending_time_flag_tmp3;
+				long int number_of_realizations_with_ending_time_tmp3;
+				double ending_time_to_test_logarithmic_regime3=-1;
+
+				bool save_states_flag=false;
+				mult_states_type *states_old1=NULL;
+				mult_states_type *states_new1=NULL;
+
+				bool compute_allocated_memory_flag_tmp=false;
+				double allocated_memory_tmp;
+
+				collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+				compute_allocated_memory_flag_tmp,
+				allocated_memory_tmp,
+
+				number_of_realizations,
+				M_distr_file_name_reversed,
+				*two_dim_layer_alignment_algorithm_test_reversed,
+				*IS1_general_simulation_reversed,
+				target_ALP,//target ALP number
+				ungappedlambda,
+				limit2,
+
+				number_of_sets,
+				par_reversed,
+				inside_simulation_flag,
+				forward_and_reverse_screen_output_flag_,
+				true&&forward_and_reverse_screen_output_flag_,
+
+				ending_time_tmp3,
+				stopped_by_ending_time_flag_tmp3,
+				number_of_realizations_with_ending_time_tmp3,
+
+				ending_time_to_test_logarithmic_regime3,
+
+				save_states_flag,
+				states_old1,
+				states_new1,
+				M_thr_estimation_reverse,
+
+				futher_expanding,
+				M_thr,
+				IS1_cs,
+				&eps_K,
+				&number_of_cs_steps_for_expanding);
+
+				
+
+			};
+
+			if(!inside_simulation_flag)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+
+			double time1_end;
+			FSA_utils::get_current_time(time1_end);
+
+			if(!library_call_flag_)
+			{
+				cout<<"Time of the reverse stage\t"<<time1_end-time1_start<<endl;
+			};
+
+
+			if(lambda_output_flag)
+			{
+				lambda_out<<par_reversed.lambda<<"\t";lambda_out<<par_reversed.lambda_error<<"\t";
+				lambda_out<<par_reversed.C<<"\t";lambda_out<<par_reversed.C_error<<"\t";
+				lambda_out<<par_reversed.a_I<<"\t";lambda_out<<par_reversed.a_I_error<<"\t";
+				lambda_out<<par_reversed.a_J<<"\t";lambda_out<<par_reversed.a_J_error<<"\t";
+				lambda_out<<par_reversed.sigma<<"\t";lambda_out<<par_reversed.sigma_error<<"\t";
+				lambda_out<<par_reversed.alpha_I<<"\t";lambda_out<<par_reversed.alpha_I_error<<"\t";
+				lambda_out<<par_reversed.alpha_J<<"\t";lambda_out<<par_reversed.alpha_J_error<<"\t";
+
+				if(futher_expanding)
+				{
+					lambda_out<<par_reversed.K_C<<"\t";lambda_out<<par_reversed.K_C_error<<"\t";
+				}
+				else
+				{
+					lambda_out<<"#N/A\t";
+				};
+
+
+			};
+
+
+		};
+	};
+
+
+
+
+
+
+
+
+	if(FSA_flag&&futher_expanding)
+	{
+		combine_parameters_from_forward_and_reversed_calculations_generalized(
+		par,//parameters from forward calculation
+		par_reversed,//parameters from reversed calculation
+		par_result_);
+
+		//assign gap penalties for the FSC
+		par_result_.G=FSA_utils::Tmin(data_test.d_open1+data_test.d_epen1,
+			data_test.d_open2+data_test.d_epen2,
+			data_test.d_gamma);
+
+		par_result_.G1=par_result_.G;
+		par_result_.G2=par_result_.G;
+	};
+//reversed FSA sampling - end
+
+
+
+
+
+	delete[]var_num;
+
+
+	delete[]RR1;
+	delete[]RR2;
+
+	delete[]RR1_sum;
+	delete[]RR2_sum;
+
+	delete[]RR1_sum_elements;
+	delete[]RR2_sum_elements;
+
+	FSA_utils::delete_memory_for_matrix(alphabet_letters_number1,smatr);
+	FSA_utils::delete_memory_for_matrix(number_of_states,transition_probabilities);
+
+	if(futher_expanding&&FSA_flag)
+	{
+		
+		delete two_dim_layer_alignment_algorithm_test_reversed;
+		delete IS1_general_simulation_reversed;
+		delete IS1_reversed;
+
+		for(s=0;s<number_of_states;s++)
+		{
+			IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+				states_distr_reversed[s],
+				alphabet_letters_number1,//number of letters in the sequence #1
+				states_description[s]);//state description
+		};
+
+		delete[]states_distr_reversed;
+
+		delete[]codon_reversed_AA;
+
+	};
+
+	delete[]codon_AA;
+
+	//crude sampling
+	if(cs_flag)
+	{
+
+		FSA_utils::delete_memory_for_matrix(number_of_states_cs,transition_probabilities_cs);
+		
+		delete two_dim_layer_alignment_algorithm_test_cs;
+		delete IS1_general_simulation_cs;
+		delete IS1_cs;
+
+		long int s;
+		for(s=0;s<number_of_states_cs;s++)
+		{
+			IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+				states_distr_cs[s],
+				alphabet_letters_number1,//number of letters in the sequence #1
+				states_description_cs[s]);//state description
+		};
+
+		delete[]states_description_cs;
+
+	};
+	//crude sampling - end
+
+
+	if(FSA_flag)
+	{
+		delete two_dim_layer_alignment_algorithm_test;
+		delete d_IS1_general_simulation;
+		delete d_IS1;
+
+
+		long int s;
+		for(s=0;s<number_of_states;s++)
+		{
+			IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+				states_distr[s],
+				alphabet_letters_number1,//number of letters in the sequence #1
+				states_description[s]);//state description
+		};
+
+		delete[]states_description;
+	};
+
+	delete[]RR1_AA;
+
+
+
+	if(lambda_output_flag)
+	{
+		lambda_out<<endl;
+		lambda_out.close();
+	};
+
+	//precompute intercepts
+	par_result_.d_params_flag=true;
+	FALP_pvalues::compute_intercepts(par_result_);
+
+	double seconds2;
+	FSA_utils::get_current_time(seconds2);
+
+	par_result_.m_CalcTime=seconds2-seconds1;
+
+
+}
+
+//-------------------------------------------------------------------
+void test::collect_and_output_M_distr_upto_fixed_lengths(
+long int number_of_realizations_,
+string M_distr_file_name_,
+two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+IS1_general_simulation &IS1_general_simulation_test_,
+long int target_seq1_length_,//target length of the sequence #1
+long int target_seq2_length_)//target length of the sequence #2
+{
+	//for test - begin
+	bool test_flag=false;
+
+		
+	string input_file_name="sss.out";
+
+	long int number_of_letters1;//number of letters for the sequence 1
+	long int number_of_letters2;//number of letters for the sequence 2
+
+	char *alphabet1;//alphabet letters for the sequence #1
+	char *alphabet2;//alphabet letters for the sequence #2
+
+	long int number_of_sequences;
+
+	string *headers;
+	long int *lengths1;//lengths of the sequences #1
+	long int *lengths2;//lengths of the sequences #2
+	long int **sequences1=NULL;//the first index numerates sequences; the second - sequence letters
+	long int **sequences2=NULL;
+
+	if(test_flag)
+	{
+
+		long int *alphabet1_to_long=NULL;//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+		long int *alphabet2_to_long=NULL;//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+		long int codon_length;//codon length 
+		long int *codon_AA=NULL;//<codon code,AA number>
+
+		string DNA_codon_table_file_name="test_input_files/codon_AA.in";//a name of a file with DNA codon table
+
+
+
+
+		FSA_utils::read_codon_AA_file(
+		DNA_codon_table_file_name,
+		number_of_letters1,//number of letters for the sequence 1
+		number_of_letters2,//number of letters for the sequence 2
+
+		alphabet1,//alphabet letters for the sequence #1
+		alphabet2,//alphabet letters for the sequence #2
+
+		alphabet1_to_long,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+		alphabet2_to_long,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+		codon_length,//codon length 
+		codon_AA);//<codon code,AA number>
+
+		FSA_utils::read_sequences_for_alingment(
+
+			input_file_name,
+
+			number_of_letters1,//number of letters for the sequence 1
+			number_of_letters2,//number of letters for the sequence 2
+
+			alphabet1,//alphabet letters for the sequence #1
+			alphabet2,//alphabet letters for the sequence #2
+
+			number_of_sequences,
+
+			headers,
+			lengths1,//lengths of the sequences #1
+			lengths2,//lengths of the sequences #2
+			sequences1,//the first index numerates sequences; the second - sequence letters
+			sequences2);
+	};
+
+	//for test - end
+
+	if(!two_dim_layer_alignment_algorithm_test_.d_M_flag)
+	{
+		throw error("Error - two_dim_layer_alignment_algorithm_test_.d_M_flag must be true in test::collect_and_output_M_distr_upto_fixed_lengths\n",1);
+	};
+
+	ofstream fM;
+
+	array_v<double> *distrM=NULL;
+	array_v<double> *distrM_error=NULL;
+	long int score_max=-inf;
+
+	//distribution of M
+
+	fM.open(M_distr_file_name_.data());
+	if(!fM)
+	{
+		throw error("Error - the file "+M_distr_file_name_+" is not found\n",3);
+	};
+
+
+	distrM=new array_v<double>(NULL);
+	distrM_error=new array_v<double>(NULL);
+
+
+
+	//--------------------
+
+	long int k;
+	for(k=1;k<=number_of_realizations_;k++)
+	{
+
+		IS1_general_simulation_test_.init();
+		IS1_general_simulation_test_.simulate_upto_target_lengths(
+		target_seq1_length_,
+		target_seq2_length_);
+
+
+		/*
+		double weight;
+		if(0)
+		{
+			IS1_general_simulation_test_.calculate_weight_W1_for_fixed_lengths_using_infinite_sums(
+			target_seq1_length_,//target length of the sequence #1
+			target_seq2_length_,//target length of the sequence #2
+			weight);//the resulted weight
+		};
+		*/
+
+		//weights calculation
+		IS1_general_simulation_test_.d_W1_seq1_current_length=-1;
+		IS1_general_simulation_test_.d_W1_seq2_current_length=-1;
+
+		double weight2;
+
+		{
+			IS1_general_simulation_test_.calculate_weight_W1_for_fixed_lengths_using_recursions(
+			target_seq1_length_,//target length of the sequence #1
+			target_seq2_length_,//target length of the sequence #2
+			weight2);//the resulted weight
+		};
+
+
+
+
+		two_dim_layer_alignment_algorithm_test_.init();
+
+		if(test_flag)
+		{
+			data_for_FSA_alignment &data=*(data_for_FSA_alignment*)two_dim_layer_alignment_algorithm_test_.d_par;
+
+			data.d_seq1=sequences1[k-1];
+			data.d_seq2=sequences2[k-1];
+		};
+
+		two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+		//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+		target_seq1_length_,//target length of the sequence #1
+		target_seq2_length_);//target length of the sequence #2
+
+		score_max=FSA_utils::Tmax(score_max,two_dim_layer_alignment_algorithm_test_.d_M);
+		double w_tmp=1/weight2;
+		distrM->increase_elem_by_x(two_dim_layer_alignment_algorithm_test_.d_M,w_tmp);
+		distrM_error->increase_elem_by_x(two_dim_layer_alignment_algorithm_test_.d_M,w_tmp*w_tmp);
+
+		if(test_flag)
+		{
+			cout<<two_dim_layer_alignment_algorithm_test_.d_M<<endl;
+		};
+		
+
+		if(k%100==0)
+		{
+			cout<<k<<endl;
+		};
+
+	};
+
+	long int s;
+
+	//convert into tail
+	for(s=score_max-1;s>=0;s--)
+	{
+		distrM->d_elem[s-distrM->d_ind0]+=distrM->d_elem[s+1-distrM->d_ind0];
+		distrM_error->d_elem[s-distrM->d_ind0]+=distrM_error->d_elem[s+1-distrM->d_ind0];
+	};
+
+	for(s=0;s<=score_max;s++)
+	{
+		distrM->d_elem[s-distrM->d_ind0]/=(double)number_of_realizations_;
+		distrM_error->d_elem[s-distrM->d_ind0]/=(double)number_of_realizations_;
+		distrM_error->d_elem[s-distrM->d_ind0]-=distrM->d_elem[s-distrM->d_ind0]*distrM->d_elem[s-distrM->d_ind0];
+		distrM_error->d_elem[s-distrM->d_ind0]/=(double)number_of_realizations_;
+		distrM_error->d_elem[s-distrM->d_ind0]=FSA_utils::sqrt_plus(distrM_error->d_elem[s-distrM->d_ind0]);
+
+	};
+
+
+
+	fM<<score_max+1<<endl;
+	for(s=0;s<=score_max;s++)
+	{
+		fM<<s<<"\t"<<distrM->d_elem[s-distrM->d_ind0]<<"\t"<<distrM_error->d_elem[s-distrM->d_ind0]<<endl;
+	};
+
+	fM.close();
+
+
+	delete distrM;
+	delete distrM_error;
+
+
+}
+
+//===============================
+void test::compare_direct_and_reverse_sampling(
+long int number_of_realizations_,
+long int seq2_length_,
+two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+IS1_general_simulation &IS1_general_simulation_test_,
+two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_reverse_,
+IS1_general_simulation &IS1_general_simulation_test_reverse_,
+IS1_general *IS1_general_cs_)
+{
+
+	cout<<endl;
+
+	cout<<"Starting...\n";
+
+	long int k;
+	for(k=1;k<=number_of_realizations_;k++)
+	{
+
+		
+		
+
+		IS1_general_simulation_test_.init();
+
+		IS1_general_simulation_test_.d_W1_seq1_current_length=-1;
+		IS1_general_simulation_test_.d_W1_seq2_current_length=-1;
+
+		two_dim_layer_alignment_algorithm_test_.init();
+
+
+
+		long int seq1_length=0;
+		long int seq2_length=0;
+
+		long int current_state=0;//the current state
+		long int new_state;
+
+		long int M_direct;
+		long int M_reverse;
+
+		long int j;
+		for(j=1;j<=seq2_length_;j++)
+		{
+			IS1_general_cs_->one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
+			current_state,//the current state
+			IS1_general_simulation_test_.d_seq1+seq1_length,//letters for the sequence #1; the array must be allocated
+			IS1_general_simulation_test_.d_seq2+seq2_length,//letters for the sequence #2; the array must be allocated
+			new_state);//a new state
+
+			seq1_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;
+			seq2_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;
+
+			two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+			//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+			seq1_length,//target length of the sequence #1
+			seq2_length);//target length of the sequence #2
+		};
+
+		M_direct=two_dim_layer_alignment_algorithm_test_.d_M;
+
+//--------
+		IS1_general_simulation_test_reverse_.init();
+
+		IS1_general_simulation_test_reverse_.d_W1_seq1_current_length=-1;
+		IS1_general_simulation_test_reverse_.d_W1_seq2_current_length=-1;
+
+		two_dim_layer_alignment_algorithm_test_reverse_.init();
+//--------
+
+		long int t1=seq1_length;
+		long int t2=seq2_length;
+
+		for(j=1;j<=seq2_length_;j++)
+		{
+			
+			long int ii;
+			for(ii=0;ii<two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;ii++)
+			{
+				seq1_length--;
+				IS1_general_simulation_test_reverse_.d_seq1[t1-1-seq1_length]=
+					IS1_general_simulation_test_.d_seq1[seq1_length];
+
+			};
+
+
+			for(ii=0;ii<two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;ii++)
+			{
+				seq2_length--;
+				IS1_general_simulation_test_reverse_.d_seq2[t2-1-seq2_length]=
+					IS1_general_simulation_test_.d_seq2[seq2_length];
+
+			};
+			
+
+
+
+			two_dim_layer_alignment_algorithm_test_reverse_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+			//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+			j*two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1,//target length of the sequence #1
+			j*two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2);//target length of the sequence #2
+
+			
+		};
+
+		M_reverse=two_dim_layer_alignment_algorithm_test_reverse_.d_M;
+
+		
+
+		if(M_direct!=M_reverse)
+		{
+			cout<<M_direct<<"\t"<<M_reverse<<endl;
+		};
+
+
+		if(k%100==0)
+		{
+			cout<<k<<endl;
+		};
+
+	};
+
+	cout<<"Finished!\n";
+
+}
+
+//-------------------------------------------------------------------
+
+long int test::realization_number_into_set_number(//numeration of sets starts from 1
+long int &realization_number_,//realization order number; the numeration starts from 0
+long int &number_of_realizations_set_)//total number of sets
+{
+	return (realization_number_/number_of_realizations_set_)+1;
+}
+
+pair<long int,long int> test::set_number_boundaries(//boundaries of realization order numbers for the set; numeration of realizations starts from 0
+long int &set_number_,//set order number; the numeration starts from 1
+long int &number_of_realizations_set_)//total number of realizations per set
+{
+	pair<long int,long int> res;
+	res.first=(set_number_-1)*number_of_realizations_set_;
+	res.second=res.first+number_of_realizations_set_-1;
+	return res;
+}
+
+void test::collect_and_output_E_distr_upto_fixed_ALP(
+long int number_of_realizations_,
+string E_distr_file_name_,
+two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+IS1_general_simulation &IS1_general_simulation_test_,
+long int target_ALP_,//target ALP number
+double ungapped_lambda_,
+long int limit2_,
+long int number_of_sets_,//number of sets for error calculation
+Sls::FALP_set_of_parameters &par_,
+bool screen_output_flag_,
+
+bool futher_expanding_,
+IS1_general *IS1_general_cs_,
+double *eps_K_,//relative error for K
+long int *number_of_cs_steps_for_expanding_)
+{
+
+	
+
+	double &lambda_out_=par_.lambda;
+	double &lambda_out_error_=par_.lambda_error;
+	double &C_=par_.C;
+	double &C_error_=par_.C_error;
+
+	double &a_I_=par_.a_I;
+	double &a_I_error_=par_.a_I_error;
+	double &a_J_=par_.a_J;
+	double &a_J_error_=par_.a_J_error;
+	double &sigma_=par_.sigma;
+	double &sigma_error_=par_.sigma_error;
+	double &alpha_I_=par_.alpha_I;
+	double &alpha_I_error_=par_.alpha_I_error;
+	double &alpha_J_=par_.alpha_J;
+	double &alpha_J_error_=par_.alpha_J_error;
+
+	double &K_C_=par_.K_C;
+	double &K_C_error_=par_.K_C_error;
+
+
+
+	bool average_set_results_flag=false;
+
+	{
+		long int number_of_realizations_tmp=(number_of_realizations_/number_of_sets_)*number_of_sets_;
+		if(number_of_realizations_tmp<number_of_realizations_)
+		{
+			number_of_realizations_=number_of_realizations_tmp+number_of_sets_;
+		};
+	};
+
+	long int number_of_realizations_set=number_of_realizations_/number_of_sets_;
+
+	//------------------------------------------------------
+
+	bool output_flag=false;
+
+	if(!two_dim_layer_alignment_algorithm_test_.d_M_flag)
+	{
+		throw error("Error - two_dim_layer_alignment_algorithm_test_.d_E_flag must be true in test::collect_and_output_E_distr_upto_fixed_ALP\n",1);
+	};
+
+	ofstream fE;
+	ofstream fE_summary;
+
+
+
+	array_v<double> ***distrE=new array_v<double> **[number_of_sets_+1];
+	FSA_utils::assert_mem(distrE);
+	array_v<double> ***distrE_errors=new array_v<double> **[number_of_sets_+1];
+	FSA_utils::assert_mem(distrE_errors);
+
+	long int **score_max=new long int*[number_of_sets_+1];//statistic
+	FSA_utils::assert_mem(score_max);
+
+	long int k1;
+	for(k1=0;k1<=number_of_sets_;k1++)
+	{
+		distrE[k1]=new array_v<double>*[target_ALP_+1];
+		FSA_utils::assert_mem(distrE[k1]);
+		distrE_errors[k1]=new array_v<double>*[target_ALP_+1];
+		FSA_utils::assert_mem(distrE_errors[k1]);
+		score_max[k1]=new long int[target_ALP_+1];
+		FSA_utils::assert_mem(score_max[k1]);
+
+		long int k;
+		for(k=0;k<=target_ALP_;k++)
+		{
+			distrE[k1][k]=new array_v<double>(NULL);
+			FSA_utils::assert_mem(distrE[k1][k]);
+
+			distrE_errors[k1][k]=new array_v<double>(NULL);
+			FSA_utils::assert_mem(distrE_errors[k1][k]);
+
+			score_max[k1][k]=-inf;
+		};
+
+	};
+
+	//distribution of E
+	if(output_flag)
+	{
+		fE.open(E_distr_file_name_.data());
+		if(!fE)
+		{
+			throw error("Error - the file "+E_distr_file_name_+" is not found\n",3);
+		};
+
+		string E_distr_file_name_summary=E_distr_file_name_+"_summary";
+		fE_summary.open(E_distr_file_name_summary.data());
+		if(!fE_summary)
+		{
+			throw error("Error - the file "+E_distr_file_name_summary+" is not found\n",3);
+		};
+	};
+
+
+
+
+	long int k;
+
+
+	array_positive<double> *diff=new array_positive<double>[number_of_sets_+1];//statistic
+	array_positive<double> *diff_errors=new array_positive<double>[number_of_sets_+1];//statistic
+	
+
+
+	array_positive<long int> *distance_along_direction_1=new array_positive<long int>[number_of_realizations_];//statistic
+	array_positive<long int> *distance_along_direction_2=new array_positive<long int>[number_of_realizations_];//statistic
+
+	array_positive<double> *ALP_weight=new array_positive<double>[number_of_realizations_];//statistic
+	array_positive<long int> *ALP_edge_max=new array_positive<long int>[number_of_realizations_];//statistic
+
+	//--------------------
+
+	
+
+	double *sum_of_weights=new double[number_of_sets_+1];//statistic;
+	double *sum_of_weights_error=new double[number_of_sets_+1];//statistic;
+
+	for(k1=0;k1<=number_of_sets_;k1++)
+	{
+		sum_of_weights[k1]=0;//statistic
+		sum_of_weights_error[k1]=0;//statistic
+	};
+
+	long int M_threshold=(long int)ceil(log((*eps_K_)*(1.0-ungapped_lambda_))/ungapped_lambda_);
+	M_threshold*=2;
+
+	if(M_threshold>=0)
+	{
+		M_threshold=-1;
+	};
+
+	two_dim_layer_alignment_algorithm_test_.d_M_threshold=M_threshold;
+	
+	long int M_max=0;
+
+	for(k=0;k<number_of_realizations_;k++)
+	{
+		long int sn=realization_number_into_set_number(k,number_of_realizations_set);
+
+		
+		
+
+		IS1_general_simulation_test_.init();
+
+		IS1_general_simulation_test_.d_W1_seq1_current_length=-1;
+		IS1_general_simulation_test_.d_W1_seq2_current_length=-1;
+
+		two_dim_layer_alignment_algorithm_test_.init();
+
+		long int current_ALP_number=0;
+		long int current_M=0;
+		distrE[0][current_ALP_number]->increase_elem_by_x(current_M,1.0);
+
+		distrE[sn][current_ALP_number]->increase_elem_by_x(current_M,1.0);
+		
+		distance_along_direction_1[k].set_elem(current_ALP_number,0);
+		distance_along_direction_2[k].set_elem(current_ALP_number,0);
+
+		ALP_weight[k].set_elem(current_ALP_number,1.0);
+		ALP_edge_max[k].set_elem(current_ALP_number,0);
+
+		score_max[0][current_ALP_number]=current_M;
+		score_max[sn][current_ALP_number]=current_M;
+
+		long int seq1_length=0;
+		long int seq2_length=0;
+
+
+		//weights calculation
+		double weight2;
+		double tmp_w=1;
+		double tmp_w2=1;
+
+
+		while(current_ALP_number<target_ALP_)
+		{
+
+			seq1_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;
+			seq2_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;
+
+			if(seq1_length>two_dim_layer_alignment_algorithm_test_.d_max_ind1||
+				seq2_length>two_dim_layer_alignment_algorithm_test_.d_max_ind2)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+
+
+			IS1_general_simulation_test_.simulate_upto_target_lengths(
+			seq1_length,
+			seq2_length);
+
+
+			IS1_general_simulation_test_.calculate_weight_W1_upto_target_lengths(
+			seq1_length,//target length of the sequence #1
+			seq2_length,//target length of the sequence #2
+			seq1_length,//the weights are calculated upto this length for the sequence #1
+			seq2_length);//the weights are calculated upto this length for the sequence #2
+
+
+			two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+			//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+			seq1_length,//target length of the sequence #1
+			seq2_length);//target length of the sequence #2
+
+
+			if(two_dim_layer_alignment_algorithm_test_.d_M>current_M)
+			{//new ALP found
+
+				current_M=two_dim_layer_alignment_algorithm_test_.d_M;
+				current_ALP_number++;
+
+
+
+				IS1_general_simulation_test_.calculate_weight_W1_for_fixed_lengths_using_recursions(
+				seq1_length,//target length of the sequence #1
+				seq2_length,//target length of the sequence #2
+				weight2);//the resulted weight
+
+
+
+				score_max[0][current_ALP_number]=FSA_utils::Tmax(score_max[0][current_ALP_number],current_M);
+				score_max[sn][current_ALP_number]=FSA_utils::Tmax(score_max[sn][current_ALP_number],current_M);
+
+				tmp_w=1/weight2;
+				tmp_w2=tmp_w*tmp_w;
+
+				
+
+				distrE[0][current_ALP_number]->increase_elem_by_x(current_M,tmp_w);
+				distrE[sn][current_ALP_number]->increase_elem_by_x(current_M,tmp_w);
+				
+				distrE_errors[0][current_ALP_number]->increase_elem_by_x(current_M,tmp_w2);
+				distrE_errors[sn][current_ALP_number]->increase_elem_by_x(current_M,tmp_w2);
+
+				distance_along_direction_1[k].set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_1);
+				distance_along_direction_2[k].set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_2);
+
+				ALP_weight[k].set_elem(current_ALP_number,tmp_w);
+				ALP_edge_max[k].set_elem(current_ALP_number,current_M);
+
+				M_max=FSA_utils::Tmax(current_M,M_max);
+
+		
+			};
+
+			if(seq2_length>limit2_)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+
+
+
+
+
+		};
+
+	
+
+		if((k+1)%100==0)
+		{
+			cout<<k+1<<endl;
+		};
+
+		//expanding
+		if(futher_expanding_)
+		{
+			long int current_state=0;//the current state
+			long int new_state;
+
+			long int j;
+			for(j=1;j<=*number_of_cs_steps_for_expanding_;j++)
+			{
+				IS1_general_cs_->one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
+				current_state,//the current state
+				IS1_general_simulation_test_.d_seq1+seq1_length,//letters for the sequence #1; the array must be allocated
+				IS1_general_simulation_test_.d_seq2+seq2_length,//letters for the sequence #2; the array must be allocated
+				new_state);//a new state
+
+				seq1_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;
+				seq2_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;
+
+				two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+				//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+				seq1_length,//target length of the sequence #1
+				seq2_length);//target length of the sequence #2
+
+				long int &M=two_dim_layer_alignment_algorithm_test_.d_M;
+				long int &E=two_dim_layer_alignment_algorithm_test_.d_E;
+
+				if(E-M<M_threshold)
+				{
+					break;
+				};
+
+
+			};
+
+			IS1_general_simulation_test_.d_seq1_current_length=seq1_length;
+			IS1_general_simulation_test_.d_seq2_current_length=seq2_length;
+
+
+		};
+		
+
+
+		//collect differences
+		if(two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag&&futher_expanding_)
+		{
+			//sum of weigths
+			sum_of_weights[0]+=tmp_w;
+			sum_of_weights[sn]+=tmp_w;
+			sum_of_weights_error[0]+=tmp_w2;
+			sum_of_weights_error[sn]+=tmp_w2;
+
+			long int &M=two_dim_layer_alignment_algorithm_test_.d_M;
+			long int ii;
+			for(ii=FSA_utils::Tmax(M_threshold,two_dim_layer_alignment_algorithm_test_.d_scores_counts.d_ind0);ii<=FSA_utils::Tmin(M,two_dim_layer_alignment_algorithm_test_.d_scores_counts.d_dim_plus_d_ind0);ii++)
+			{
+				long int diff_tmp=(M-ii);
+				double diff_tmp_weight=two_dim_layer_alignment_algorithm_test_.d_scores_counts.get_elem(ii)*tmp_w;
+				double diff_tmp_weight2=diff_tmp_weight*diff_tmp_weight;
+
+				diff[0].increase_elem_by_x(diff_tmp,diff_tmp_weight);
+				diff[sn].increase_elem_by_x(diff_tmp,diff_tmp_weight);
+
+				diff_errors[0].increase_elem_by_x(diff_tmp,diff_tmp_weight2);
+				diff_errors[sn].increase_elem_by_x(diff_tmp,diff_tmp_weight2);
+			};
+
+		};
+
+
+	};
+
+
+	
+	for(k1=0;k1<=number_of_sets_;k1++)
+	{
+		long int number_of_realizations_tmp=number_of_realizations_set;
+		if(k1==0)
+		{
+			number_of_realizations_tmp=number_of_realizations_;
+		};
+
+		for(k=0;k<=target_ALP_;k++)
+		{
+			long int j;
+			for(j=distrE[k1][k]->d_ind0;j<=score_max[k1][k];j++)
+			{
+				distrE[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
+				distrE_errors[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
+				distrE_errors[k1][k]->increase_elem_by_x(j,-distrE[k1][k]->get_elem(j)*distrE[k1][k]->get_elem(j));
+				distrE_errors[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
+			};
+		};
+	};
+
+	double *lambda_out_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(lambda_out_vect);
+
+	double *lambda_out_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(lambda_out_error_vect);
+
+
+	double *C_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(C_vect);
+
+	double *C_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(C_error_vect);
+
+
+	{
+
+		long int nalp=target_ALP_;
+
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+			bool check_the_criteria=false;
+			long int nalp_thr;
+			bool inside_simulation_flag;
+			void **alp_distr=(void**)distrE[k1];
+			void **alp_distr_errors=(void**)distrE_errors[k1];
+			double ungapped_lambda=ungapped_lambda_;
+			double lambda;
+			double lambda_error;
+
+			fsa_par::calculate_lambda(
+			check_the_criteria,
+			nalp,
+			nalp_thr,
+			inside_simulation_flag,
+			alp_distr,
+			alp_distr_errors,
+			ungapped_lambda,
+			lambda,
+			lambda_error);
+
+			if(!inside_simulation_flag)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+
+
+			lambda_out_vect[k1]=lambda;
+			lambda_out_error_vect[k1]=lambda_error;
+		};
+
+		
+		lambda_out_=lambda_out_vect[0];
+		lambda_out_error_=lambda_out_error_vect[0];
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"Lambda\t"<<lambda_out_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			lambda_out_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			lambda_out_vect+1);
+
+			if(average_set_results_flag)
+			{
+				lambda_out_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				lambda_out_vect+1);
+
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<lambda_out_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<lambda_out_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_LambdaSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_LambdaSbs.push_back(lambda_out_vect[k1]);
+		};
+
+
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+
+			void **alp_distr=(void**)distrE[k1];
+			void **alp_distr_errors=(void**)distrE_errors[k1];
+
+			long int starting_point=0;
+			bool inside_simulation_flag;
+
+			fsa_par::calculate_C(
+			starting_point,
+			nalp,
+			alp_distr,
+			alp_distr_errors,
+			lambda_out_vect[k1],
+			lambda_out_error_vect[k1],
+			C_vect[k1],
+			C_error_vect[k1],
+			inside_simulation_flag);
+
+			if(!inside_simulation_flag)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+		};
+
+		C_=C_vect[0];
+		C_error_=C_error_vect[0];
+
+		if(screen_output_flag_)
+		{
+			cout<<"C\t"<<C_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			C_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			C_vect+1);
+
+			if(average_set_results_flag)
+			{
+				C_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				C_vect+1);
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<C_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<C_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_CSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_CSbs.push_back(C_vect[k1]);
+		};
+
+	};
+
+
+
+	for(k=0;k<=target_ALP_;k++)
+	{
+
+		if(output_flag)
+		{
+			long int s;
+
+			double sum_tmp=0;
+			double sum_tmp_error=0;
+
+			fE<<k<<endl;
+			fE<<score_max[0][k]+1<<endl;
+
+			for(s=0;s<=score_max[0][k];s++)
+			{
+				fE<<s<<"\t"<<distrE[0][k]->d_elem[s-distrE[0][k]->d_ind0]<<"\t"<<FSA_utils::sqrt_plus(distrE_errors[0][k]->d_elem[s-distrE_errors[0][k]->d_ind0])<<endl;
+				sum_tmp+=distrE[0][k]->d_elem[s-distrE[0][k]->d_ind0]*exp((double)s*ungapped_lambda_);
+				sum_tmp_error+=FSA_utils::sqrt_plus(distrE_errors[0][k]->d_elem[s-distrE_errors[0][k]->d_ind0])*exp((double)s*ungapped_lambda_);
+			};
+			fE<<endl;
+
+			fE_summary<<k<<"\t"<<sum_tmp<<"\t"<<sum_tmp_error<<endl;
+		};
+	};
+
+
+	double *K_C_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(K_C_vect);
+
+	double *K_C_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(K_C_error_vect);
+
+
+	//calculation of the ratio K/C
+	if(two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag&&futher_expanding_)
+	{
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+			long int number_of_realizations_tmp=number_of_realizations_set;
+			if(k1==0)
+			{
+				number_of_realizations_tmp=number_of_realizations_;
+			};
+
+			long int ii;
+			for(ii=0;ii<=diff[k1].d_dim;ii++)
+			{
+				diff[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
+				diff_errors[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
+				diff_errors[k1].increase_elem_by_x(ii,-diff[k1].get_elem(ii)*diff[k1].get_elem(ii));
+				diff_errors[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
+				double tmp=FSA_utils::sqrt_plus(diff_errors[k1].get_elem(ii));
+				diff_errors[k1].set_elem(ii,tmp);
+			};
+
+			
+
+			sum_of_weights[k1]/=(double)number_of_realizations_tmp;
+			sum_of_weights_error[k1]/=(double)number_of_realizations_tmp;
+			sum_of_weights_error[k1]-=sum_of_weights[k1]*sum_of_weights[k1];
+			sum_of_weights_error[k1]/=(double)number_of_realizations_tmp;
+			sum_of_weights_error[k1]=FSA_utils::sqrt_plus(sum_of_weights_error[k1]);
+		
+
+			double den=0;
+			double den_error=0;
+			for(ii=0;ii<=diff[k1].d_dim;ii++)
+			{
+				double tmp=exp(-lambda_out_vect[k1]*(double)ii);
+				den+=tmp*diff[k1].get_elem(ii);
+				den_error+=tmp*tmp*diff_errors[k1].get_elem(ii)*diff_errors[k1].get_elem(ii);
+
+			};
+
+
+			den_error=FSA_utils::sqrt_plus(den_error);
+
+			K_C_vect[k1]=sum_of_weights[k1]/den;
+			K_C_error_vect[k1]=FSA_utils::error_of_the_ratio(sum_of_weights[k1],sum_of_weights_error[k1],den,den_error);
+
+		};
+
+		K_C_=K_C_vect[0];
+		K_C_error_=K_C_error_vect[0];
+
+
+		if(output_flag)
+		{
+			fE<<endl;
+			fE<<"K/C distributions\n";
+			fE<<diff[0].d_dim+1<<endl;
+			long int ii;
+			for(ii=0;ii<=diff[0].d_dim;ii++)
+			{
+				//double tmp=exp(-lambda_out_*(double)ii);
+				fE<<ii<<"\t"<<diff[0].get_elem(ii)/sum_of_weights[0]<<"\t"<<diff_errors[0].get_elem(ii)/sum_of_weights[0]<<endl;
+			};
+
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<"K/C\t"<<K_C_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			K_C_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			K_C_vect+1);
+
+			if(average_set_results_flag)
+			{
+				K_C_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				K_C_vect+1);
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<K_C_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<K_C_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_K_CSbs.clear();
+		par_.m_KSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_K_CSbs.push_back(K_C_vect[k1]);
+			par_.m_KSbs.push_back(K_C_vect[k1]*C_vect[k1]);
+		};
+
+
+
+
+	};
+
+
+	double *a_I_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(a_I_vect);
+	double *a_I_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(a_I_error_vect);
+	double *a_J_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(a_J_vect);
+	double *a_J_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(a_J_error_vect);
+	double *sigma_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(sigma_vect);
+	double *sigma_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(sigma_error_vect);
+	double *alpha_I_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(alpha_I_vect);
+	double *alpha_I_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(alpha_I_error_vect);
+	double *alpha_J_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(alpha_J_vect);
+	double *alpha_J_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(alpha_J_error_vect);
+
+
+	//FSC
+	{
+		long int k1;
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+
+			pair<long int,long int> boundaries;
+			if(k1==0)
+			{
+				boundaries.first=0;
+				boundaries.second=number_of_realizations_-1;
+			}
+			else
+			{
+				boundaries=set_number_boundaries(//boundaries of realization order numbers for the set; numeration of realizations starts from 0
+				k1,//set order number; the numeration starts from 1
+				number_of_realizations_set);//total number of sets
+			};
+
+			bool inside_simulation_flag;
+
+			fsa_par::calculate_FSC(
+			target_ALP_,
+			boundaries.first,
+			boundaries.second,
+			
+
+			lambda_out_vect[k1],
+
+			M_max,
+
+			distance_along_direction_1,
+			distance_along_direction_2,
+
+			ALP_weight,
+			ALP_edge_max,
+
+			a_I_vect[k1],
+			a_I_error_vect[k1],
+			a_J_vect[k1],
+			a_J_error_vect[k1],
+			sigma_vect[k1],
+			sigma_error_vect[k1],
+			alpha_I_vect[k1],
+			alpha_I_error_vect[k1],
+			alpha_J_vect[k1],
+			alpha_J_error_vect[k1],
+			inside_simulation_flag);
+
+			if(!inside_simulation_flag)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+		};
+
+		a_I_=a_I_vect[0];
+		a_I_error_=a_I_error_vect[0];
+		a_J_=a_J_vect[0];
+		a_J_error_=a_J_error_vect[0];
+		sigma_=sigma_vect[0];
+		sigma_error_=sigma_error_vect[0];
+		alpha_I_=alpha_I_vect[0];
+		alpha_I_error_=alpha_I_error_vect[0];
+		alpha_J_=alpha_J_vect[0];
+		alpha_J_error_=alpha_J_error_vect[0];
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"a_I\t"<<a_I_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			a_I_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			a_I_vect+1);
+
+			if(average_set_results_flag)
+			{
+				a_I_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				a_I_vect+1);
+
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<a_I_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<a_I_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_AISbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_AISbs.push_back(a_I_vect[k1]);
+		};
+
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"a_J\t"<<a_J_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			a_J_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			a_J_vect+1);
+
+			if(average_set_results_flag)
+			{
+				a_J_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				a_J_vect+1);
+
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<a_J_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<a_J_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_AJSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_AJSbs.push_back(a_J_vect[k1]);
+		};
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"sigma\t"<<sigma_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			sigma_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			sigma_vect+1);
+
+			if(average_set_results_flag)
+			{
+				sigma_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				sigma_vect+1);
+
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<sigma_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<sigma_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_SigmaSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_SigmaSbs.push_back(sigma_vect[k1]);
+		};
+
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"alpha_I\t"<<alpha_I_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			alpha_I_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			alpha_I_vect+1);
+
+			if(average_set_results_flag)
+			{
+				alpha_I_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				alpha_I_vect+1);
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<alpha_I_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<alpha_I_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_AlphaISbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_AlphaISbs.push_back(alpha_I_vect[k1]);
+		};
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"alpha_J\t"<<alpha_J_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			alpha_J_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			alpha_J_vect+1);
+
+			if(average_set_results_flag)
+			{
+				alpha_J_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				alpha_J_vect+1);
+
+				cout<<"\t"<<alpha_J_;
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<alpha_J_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_AlphaJSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_AlphaJSbs.push_back(alpha_J_vect[k1]);
+		};
+
+	};
+
+
+
+	if(output_flag)
+	{
+		fE.close();
+		fE_summary.close();
+	};
+
+
+	if(score_max)
+	{
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+			delete[]score_max[k1];
+		};
+		delete []score_max;
+	};
+
+	if(distrE)
+	{
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+			for(k=0;k<=target_ALP_;k++)
+			{
+				delete distrE[k1][k];
+			};
+			delete []distrE[k1];
+		};
+		delete []distrE;
+	};
+
+	if(distrE_errors)
+	{
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+			for(k=0;k<=target_ALP_;k++)
+			{
+				delete distrE_errors[k1][k];
+			};
+			delete []distrE_errors[k1];
+		};
+		delete []distrE_errors;
+	};
+	
+
+
+	//FSC
+	delete[]distance_along_direction_1;
+	delete[]distance_along_direction_2;
+	delete[]ALP_weight;
+	delete[]ALP_edge_max;
+
+
+
+	delete[]lambda_out_vect;
+	delete[]lambda_out_error_vect;
+	delete[]C_vect;
+	delete[]C_error_vect;
+	delete[]K_C_vect;
+	delete[]K_C_error_vect;
+	delete[]a_I_vect;
+	delete[]a_I_error_vect;
+	delete[]a_J_vect;
+	delete[]a_J_error_vect;
+	delete[]sigma_vect;
+	delete[]sigma_error_vect;
+	delete[]alpha_I_vect;
+	delete[]alpha_I_error_vect;
+	delete[]alpha_J_vect;
+	delete[]alpha_J_error_vect;
+
+}
+
+void test::restore_arrays(
+long int k_,
+mult_states_type *states_old_,
+two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+IS1_general_simulation &IS1_general_simulation_test_)
+{
+
+	if(!states_old_)
+	{
+		throw error("Unexpected error in test::restore_arrays\n",1);
+	};
+
+	test::restore_arrays(
+	states_old_->d_states[k_].d_two_dim_layer_alignment_algorithm,
+	states_old_->d_states[k_].d_IS1_general_simulation,
+	two_dim_layer_alignment_algorithm_test_,
+	IS1_general_simulation_test_);
+	
+}
+
+
+void test::restore_arrays(
+two_dim_layer_alignment_algorithm<long int> *two_dim_layer_alignment_algorithm_test_from_,
+IS1_general_simulation *IS1_general_simulation_test_from_,
+two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+IS1_general_simulation &IS1_general_simulation_test_)
+{
+
+	if(!two_dim_layer_alignment_algorithm_test_from_||!IS1_general_simulation_test_from_)
+	{
+		throw error("Unexpected error in test::restore_arrays\n",1);
+	};
+	
+	//alignment object - begin
+	long int i;
+	for(i=0;i<two_dim_layer_alignment_algorithm_test_.d_number_of_variables;i++)
+	{
+		two_dim_layer<long int>::copy_2_into_1_two_dim_layer(
+		two_dim_layer_alignment_algorithm_test_.d_vars[i],
+		two_dim_layer_alignment_algorithm_test_from_->d_vars[i]);
+	};
+	two_dim_layer_alignment_algorithm_test_.d_current_align_ind1=two_dim_layer_alignment_algorithm_test_from_->d_current_align_ind1;
+	two_dim_layer_alignment_algorithm_test_.d_current_align_ind2=two_dim_layer_alignment_algorithm_test_from_->d_current_align_ind2;
+	//alignment object - end
+
+	//IS1_general_simulation object - begin
+	//restore the sequences
+	IS1_general_simulation_test_.d_seq1_current_length=IS1_general_simulation_test_from_->d_seq1_current_length;
+	IS1_general_simulation_test_.d_seq2_current_length=IS1_general_simulation_test_from_->d_seq2_current_length;
+
+	for(i=0;i<IS1_general_simulation_test_from_->d_seq1_current_length;i++)
+	{
+		IS1_general_simulation_test_.d_seq1[i]=IS1_general_simulation_test_from_->d_seq1[i];
+	};
+
+	for(i=0;i<IS1_general_simulation_test_from_->d_seq2_current_length;i++)
+	{
+		IS1_general_simulation_test_.d_seq2[i]=IS1_general_simulation_test_from_->d_seq2[i];
+	};
+
+	//restore the layers for weights
+	IS1_general_simulation_test_.d_current_state=IS1_general_simulation_test_from_->d_current_state;
+	IS1_general_simulation_test_.d_W1_seq1_current_length=IS1_general_simulation_test_from_->d_W1_seq1_current_length;
+	IS1_general_simulation_test_.d_W1_seq2_current_length=IS1_general_simulation_test_from_->d_W1_seq2_current_length;
+
+	for(i=0;i<IS1_general_simulation_test_.d_IS1_general_obj->d_number_of_states;i++)
+	{
+		two_dim_layer<double>::copy_2_into_1_two_dim_layer(
+		IS1_general_simulation_test_.d_W1[i],
+		IS1_general_simulation_test_from_->d_W1[i]);
+	};
+
+
+
+	//IS1_general_simulation object - end
+
+}
+
+void test::collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+bool compute_allocated_memory_flag_,//if true then total allocated memory is computed in allocated_memory_
+double &allocated_memory_,
+
+long int number_of_realizations_,
+string E_distr_file_name_,
+two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+IS1_general_simulation &IS1_general_simulation_test_,
+long int target_ALP_,//target ALP number
+double ungapped_lambda_,
+long int limit2_,
+long int number_of_sets_,//number of sets for error calculation
+Sls::FALP_set_of_parameters &par_,
+bool &inside_simulation_flag_,
+bool screen_output_flag_,
+bool screen_output_k_flag_,
+
+double ending_time_,
+bool &stopped_by_ending_time_flag_,
+long int &number_of_realizations_with_ending_time_,
+
+double ending_time_to_test_logarithmic_regime_,
+
+bool save_states_flag_,
+mult_states_type *states_old_,//NULL or defined
+mult_states_type *&states_new_,//resulted value
+long int &M_thr_estimation_,//average score threshold corresponded to target_ALP_
+
+bool futher_expanding_,
+long int M_thr_,//the expanding starts from the ALP with the score >=M_thr_; used if >=0
+IS1_general *IS1_general_cs_,
+double *eps_K_,//relative error for K
+long int *number_of_cs_steps_for_expanding_,
+bool parameters_are_not_calculated_)
+{
+
+	if(!save_states_flag_&&ending_time_>=0)
+	{
+		throw error("Error - !save_states_flag_&&ending_time_>=0 in test::collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states\n",1);
+	};
+
+	if(compute_allocated_memory_flag_)
+	{
+		allocated_memory_=sizeof(state_type);
+	};
+
+	stopped_by_ending_time_flag_=false;
+
+	inside_simulation_flag_=true;
+
+	double time1=0;
+	if(save_states_flag_||ending_time_>=0)
+	{
+		FSA_utils::get_current_time(time1);
+	};
+	
+
+	double &lambda_out_=par_.lambda;
+	double &lambda_out_error_=par_.lambda_error;
+	double &C_=par_.C;
+	double &C_error_=par_.C_error;
+
+	double &a_I_=par_.a_I;
+	double &a_I_error_=par_.a_I_error;
+	double &a_J_=par_.a_J;
+	double &a_J_error_=par_.a_J_error;
+	double &sigma_=par_.sigma;
+	double &sigma_error_=par_.sigma_error;
+	double &alpha_I_=par_.alpha_I;
+	double &alpha_I_error_=par_.alpha_I_error;
+	double &alpha_J_=par_.alpha_J;
+	double &alpha_J_error_=par_.alpha_J_error;
+
+	double &K_C_=par_.K_C;
+	double &K_C_error_=par_.K_C_error;
+
+
+
+	bool average_set_results_flag=false;
+
+	if(save_states_flag_)
+	{
+		states_new_->d_total_number_of_exp_cells=0;
+
+		if(!states_old_)
+		{
+			states_new_->d_total_number_of_ALP_cells=0;
+			states_new_->d_total_number_of_ALPs=0;
+		}
+		else
+		{
+			states_new_->d_total_number_of_ALP_cells=states_old_->d_total_number_of_ALP_cells;
+			states_new_->d_total_number_of_ALPs=states_old_->d_total_number_of_ALPs;
+		};
+	};
+
+
+	{
+		long int number_of_realizations_tmp=(number_of_realizations_/number_of_sets_)*number_of_sets_;
+		if(number_of_realizations_tmp<number_of_realizations_)
+		{
+			number_of_realizations_=number_of_realizations_tmp+number_of_sets_;
+		};
+	};
+
+	long int number_of_realizations_set=number_of_realizations_/number_of_sets_;
+
+	long int number_of_realizations_old=0;
+	long int number_of_realizations_max=number_of_realizations_;
+
+	if(states_old_)
+	{
+		//number_of_realizations_min=FSA_utils::Tmin(number_of_realizations_,states_old_->d_number_of_realizations);
+		number_of_realizations_max=FSA_utils::Tmax(number_of_realizations_,states_old_->d_number_of_realizations);
+		number_of_realizations_old=states_old_->d_number_of_realizations;
+
+
+	};
+
+	long int number_of_realizations_before_loop=number_of_realizations_;
+	if(save_states_flag_)
+	{
+		states_new_->d_number_of_realizations=number_of_realizations_max;
+		//allocate states
+		states_new_->d_states=new state_type[states_new_->d_number_of_realizations];
+		if(compute_allocated_memory_flag_)
+		{
+			allocated_memory_+=states_new_->d_number_of_realizations*sizeof(state_type);
+		};
+
+		long int ii;
+		for(ii=0;ii<states_new_->d_number_of_realizations;ii++)
+		{
+			long int target_ALP_tmp;
+			if(number_of_realizations_>number_of_realizations_old)
+			{
+				if(ii<number_of_realizations_old)
+				{
+					target_ALP_tmp=FSA_utils::Tmax(target_ALP_,states_old_->d_states[ii].d_ALP_number);
+				}
+				else
+				{
+					target_ALP_tmp=target_ALP_;
+				};
+			}
+			else
+			{
+				if(ii<number_of_realizations_)
+				{
+					target_ALP_tmp=FSA_utils::Tmax(target_ALP_,states_old_->d_states[ii].d_ALP_number);
+				}
+				else
+				{
+					target_ALP_tmp=states_old_->d_states[ii].d_ALP_number;
+				};
+			};
+
+			states_new_->d_states[ii].d_ALP_number=target_ALP_tmp;
+			
+
+			states_new_->d_states[ii].d_IS1_general_simulation=NULL;
+			states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm=NULL;
+			states_new_->d_states[ii].d_expanding_finished_flag=false;
+
+
+			states_new_->d_states[ii].d_ALP_weights_array=NULL;
+			states_new_->d_states[ii].d_M_array=NULL;
+			states_new_->d_states[ii].d_seq1_length_array=NULL;
+			states_new_->d_states[ii].d_seq2_length_array=NULL;
+			states_new_->d_states[ii].d_distance_along_direction_1_array=NULL;
+			states_new_->d_states[ii].d_distance_along_direction_2_array=NULL;
+
+
+			
+		};
+
+		
+
+		if(states_old_)
+		{
+
+
+			long int ii;
+			for(ii=0;ii<states_old_->d_number_of_realizations;ii++)
+			{
+				//allocate memory
+				
+				states_new_->d_states[ii].d_ALP_weights_array=new array_positive<double>;
+				states_new_->d_states[ii].d_M_array=new array_positive<long int>;
+				states_new_->d_states[ii].d_seq1_length_array=new array_positive<long int>;
+				states_new_->d_states[ii].d_seq2_length_array=new array_positive<long int>;
+				states_new_->d_states[ii].d_distance_along_direction_1_array=new array_positive<long int>;
+				states_new_->d_states[ii].d_distance_along_direction_2_array=new array_positive<long int>;
+
+
+
+				long int k;
+				for(k=0;k<=states_old_->d_states[ii].d_ALP_number;k++)
+				{
+					states_new_->d_states[ii].d_ALP_weights_array->set_elem(k,states_old_->d_states[ii].d_ALP_weights_array->get_elem(k));
+					states_new_->d_states[ii].d_M_array->set_elem(k,states_old_->d_states[ii].d_M_array->get_elem(k));
+					states_new_->d_states[ii].d_seq1_length_array->set_elem(k,states_old_->d_states[ii].d_seq1_length_array->get_elem(k));
+					states_new_->d_states[ii].d_seq2_length_array->set_elem(k,states_old_->d_states[ii].d_seq2_length_array->get_elem(k));
+					states_new_->d_states[ii].d_distance_along_direction_1_array->set_elem(k,states_old_->d_states[ii].d_distance_along_direction_1_array->get_elem(k));
+					states_new_->d_states[ii].d_distance_along_direction_2_array->set_elem(k,states_old_->d_states[ii].d_distance_along_direction_2_array->get_elem(k));
+
+				};
+			};
+
+			for(ii=number_of_realizations_;ii<states_old_->d_number_of_realizations;ii++)
+			{
+
+
+				states_new_->d_states[ii].d_IS1_general_simulation=
+				new IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
+				states_old_->d_states[ii].d_IS1_general_simulation);//maximum sequence length
+
+				states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm=
+				new two_dim_layer_alignment_algorithm<long int>(
+				states_old_->d_states[ii].d_seq1_length_array->get_elem(states_old_->d_states[ii].d_ALP_number),//target length of the sequence #1
+				states_old_->d_states[ii].d_seq2_length_array->get_elem(states_old_->d_states[ii].d_ALP_number),//target length of the sequence #2
+				states_old_->d_states[ii].d_two_dim_layer_alignment_algorithm);
+			};
+		};
+
+
+
+	};
+
+	//------------------------------------------------------
+
+	bool output_flag=false;
+
+	if(!two_dim_layer_alignment_algorithm_test_.d_M_flag)
+	{
+		throw error("Error - two_dim_layer_alignment_algorithm_test_.d_E_flag must be true in test::collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states\n",1);
+	};
+
+	ofstream fE;
+	ofstream fE_summary;
+
+
+
+
+	array_v<double> ***distrE=new array_v<double> **[number_of_sets_+1];
+	FSA_utils::assert_mem(distrE);
+	array_v<double> ***distrE_errors=new array_v<double> **[number_of_sets_+1];
+	FSA_utils::assert_mem(distrE_errors);
+
+	long int **score_max=new long int*[number_of_sets_+1];//statistic
+	FSA_utils::assert_mem(score_max);
+
+	long int k1;
+	for(k1=0;k1<=number_of_sets_;k1++)
+	{
+		distrE[k1]=new array_v<double>*[target_ALP_+1];
+		FSA_utils::assert_mem(distrE[k1]);
+		distrE_errors[k1]=new array_v<double>*[target_ALP_+1];
+		FSA_utils::assert_mem(distrE_errors[k1]);
+		score_max[k1]=new long int[target_ALP_+1];
+		FSA_utils::assert_mem(score_max[k1]);
+
+		long int k;
+		for(k=0;k<=target_ALP_;k++)
+		{
+			distrE[k1][k]=new array_v<double>(NULL);
+			FSA_utils::assert_mem(distrE[k1][k]);
+
+			distrE_errors[k1][k]=new array_v<double>(NULL);
+			FSA_utils::assert_mem(distrE_errors[k1][k]);
+
+			score_max[k1][k]=-inf;
+		};
+
+	};
+
+	//distribution of E
+
+	if(output_flag)
+	{
+		fE.open(E_distr_file_name_.data());
+		if(!fE)
+		{
+			throw error("Error - the file "+E_distr_file_name_+" is not found\n",3);
+		};
+
+		string E_distr_file_name_summary=E_distr_file_name_+"_summary";
+		fE_summary.open(E_distr_file_name_summary.data());
+		if(!fE_summary)
+		{
+			throw error("Error - the file "+E_distr_file_name_summary+" is not found\n",3);
+		};
+	};
+
+
+
+
+	long int k;
+
+
+	array_positive<double> *diff=new array_positive<double>[number_of_sets_+1];//statistic
+	array_positive<double> *diff_errors=new array_positive<double>[number_of_sets_+1];//statistic
+	
+
+
+	array_positive<long int> *distance_along_direction_1=new array_positive<long int>[number_of_realizations_max];//statistic
+	array_positive<long int> *distance_along_direction_2=new array_positive<long int>[number_of_realizations_max];//statistic
+
+	array_positive<double> *ALP_weight=new array_positive<double>[number_of_realizations_max];//statistic
+	array_positive<long int> *ALP_edge_max=new array_positive<long int>[number_of_realizations_max];//statistic
+
+	//--------------------
+
+	
+	double *sum_of_weights=new double[number_of_sets_+1];//statistic;
+	double *sum_of_weights_error=new double[number_of_sets_+1];//statistic;
+
+	for(k1=0;k1<=number_of_sets_;k1++)
+	{
+		sum_of_weights[k1]=0;//statistic
+		sum_of_weights_error[k1]=0;//statistic
+	};
+
+	long int M_threshold=(long int)ceil(log((*eps_K_)*(1.0-ungapped_lambda_))/ungapped_lambda_);
+	M_threshold*=2;
+
+
+	if(M_threshold>=0)
+	{
+		M_threshold=-1;
+	};
+
+	two_dim_layer_alignment_algorithm_test_.d_M_threshold=M_threshold;
+	
+	long int M_max=0;
+
+	if(save_states_flag_)
+	{
+		states_new_->d_average_ALP_pos1=0;
+		states_new_->d_average_ALP_pos2=0;
+		states_new_->d_average_ALP_pos1_mult_ALP_pos2=0;
+
+		states_new_->d_average_expanding_length1=0;
+		states_new_->d_average_expanding_length2=0;
+		states_new_->d_average_expanding_length1_mult_expanding_length2=0;
+	};
+
+
+	//variables for saving the state at the moment when M_thr_ is reached
+
+	two_dim_layer_alignment_algorithm<long int> *two_dim_layer_alignment_algorithm_test_M_thr=NULL;
+	IS1_general_simulation *IS1_general_simulation_M_thr=NULL;
+
+	bool M_thr_flag=(M_thr_>0)&&futher_expanding_;
+
+	long int seq1_length_M_thr=0;
+	long int seq2_length_M_thr=0;
+
+	long int not_all_ALP_are_sampled=0;
+
+	bool stop_loop_flag=false;
+	for(k=0;k<number_of_realizations_;k++)
+	{
+
+		//allocate memory
+		if(save_states_flag_)
+		{
+			if(k>=number_of_realizations_old)
+			{
+				states_new_->d_states[k].d_ALP_weights_array=new array_positive<double>;
+				states_new_->d_states[k].d_M_array=new array_positive<long int>;
+				states_new_->d_states[k].d_seq1_length_array=new array_positive<long int>;
+				states_new_->d_states[k].d_seq2_length_array=new array_positive<long int>;
+				states_new_->d_states[k].d_distance_along_direction_1_array=new array_positive<long int>;
+				states_new_->d_states[k].d_distance_along_direction_2_array=new array_positive<long int>;
+
+				
+			};
+		};
+
+
+		long int sn=realization_number_into_set_number(k,number_of_realizations_set);
+
+
+		IS1_general_simulation_test_.init();
+
+		IS1_general_simulation_test_.d_W1_seq1_current_length=-1;
+		IS1_general_simulation_test_.d_W1_seq2_current_length=-1;
+
+		two_dim_layer_alignment_algorithm_test_.init();
+
+		long int current_ALP_number=0;
+		long int current_M=0;
+		distrE[0][current_ALP_number]->increase_elem_by_x(current_M,1.0);
+
+		distrE[sn][current_ALP_number]->increase_elem_by_x(current_M,1.0);
+		
+		distance_along_direction_1[k].set_elem(current_ALP_number,0);
+		distance_along_direction_2[k].set_elem(current_ALP_number,0);
+
+		ALP_weight[k].set_elem(current_ALP_number,1.0);
+		ALP_edge_max[k].set_elem(current_ALP_number,0);
+
+		score_max[0][current_ALP_number]=current_M;
+		score_max[sn][current_ALP_number]=current_M;
+
+
+		long int seq1_length=0;
+		long int seq2_length=0;
+
+		if(save_states_flag_)
+		{
+			if(!states_old_||k>=number_of_realizations_old)
+			{
+				states_new_->d_states[k].d_ALP_weights_array->set_elem(0,1.0);
+				states_new_->d_states[k].d_M_array->set_elem(0,0);
+				states_new_->d_states[k].d_seq1_length_array->set_elem(0,0);
+				states_new_->d_states[k].d_seq2_length_array->set_elem(0,0);
+				states_new_->d_states[k].d_distance_along_direction_1_array->set_elem(0,0);
+				states_new_->d_states[k].d_distance_along_direction_2_array->set_elem(0,0);
+
+			};
+		};
+
+
+		//weights calculation
+		double weight2=1;
+		double tmp_w=1;
+		double tmp_w2=1;
+
+		double tmp_w_M_thr=0;
+		double tmp_w2_M_thr=0;
+
+
+		bool M_thr_var_are_saved=false;
+
+		bool restored_flag=false;
+		bool flag_tmp3=false;
+
+		
+		while((current_ALP_number<target_ALP_)||(M_thr_flag&&!M_thr_var_are_saved))
+		{
+			bool ALP_stat_flag=(current_ALP_number<target_ALP_);
+
+			
+			if(ALP_stat_flag&&M_thr_var_are_saved)
+			{
+				flag_tmp3=true;
+			};
+
+
+			seq1_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;
+			seq2_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;
+
+
+			if(seq1_length>two_dim_layer_alignment_algorithm_test_.d_max_ind1||
+				seq2_length>two_dim_layer_alignment_algorithm_test_.d_max_ind2)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+
+
+			bool new_calculation_flag=true;
+
+			if(states_old_)
+			{
+				if(k<number_of_realizations_old)
+				{
+					if(current_ALP_number<states_old_->d_states[k].d_ALP_number)
+					{
+						new_calculation_flag=false;
+					};
+
+				};
+			};
+			
+
+			bool ALP_flag=false;
+
+
+			if(new_calculation_flag)
+			{
+				if(states_old_)
+				{
+					if(k<number_of_realizations_old)
+					{
+						if(current_ALP_number==states_old_->d_states[k].d_ALP_number&&!restored_flag)
+						{//restore the state; 				seq1_length, seq2_length was increased, require correction
+
+							restored_flag=true;
+
+							restore_arrays(
+							k,
+							states_old_,
+							two_dim_layer_alignment_algorithm_test_,
+							IS1_general_simulation_test_);
+
+
+						};
+					};
+				};
+
+				if(save_states_flag_)
+				{
+					long int seq1_length_prev=IS1_general_simulation_test_.d_W1_seq1_current_length;
+					long int seq2_length_prev=IS1_general_simulation_test_.d_W1_seq2_current_length;
+
+					states_new_->d_total_number_of_ALP_cells+=
+						seq1_length*seq2_length-seq1_length_prev*seq2_length_prev;
+				};
+
+
+
+
+				IS1_general_simulation_test_.simulate_upto_target_lengths(
+				seq1_length,
+				seq2_length);
+
+
+				IS1_general_simulation_test_.calculate_weight_W1_upto_target_lengths(
+				seq1_length,//target length of the sequence #1
+				seq2_length,//target length of the sequence #2
+				seq1_length,//the weights are calculated upto this length for the sequence #1
+				seq2_length);//the weights are calculated upto this length for the sequence #2
+
+
+
+				two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+				//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+				seq1_length,//target length of the sequence #1
+				seq2_length);//target length of the sequence #2
+
+
+				ALP_flag=(two_dim_layer_alignment_algorithm_test_.d_M>current_M);
+
+				if(save_states_flag_)
+				{
+					if(ALP_flag)
+					{
+						states_new_->d_total_number_of_ALPs++;
+					};
+				};
+			};
+
+
+			if(states_old_)
+			{
+				if(!new_calculation_flag)
+				{
+					ALP_flag=(seq1_length==states_old_->d_states[k].d_seq1_length_array->get_elem(current_ALP_number+1))&&
+						(seq2_length==states_old_->d_states[k].d_seq2_length_array->get_elem(current_ALP_number+1));
+
+					
+
+					if(ALP_flag)
+					{
+						//restore the state
+
+						two_dim_layer_alignment_algorithm_test_.d_M=states_old_->d_states[k].d_M_array->get_elem(current_ALP_number+1);
+
+						weight2=states_old_->d_states[k].d_ALP_weights_array->get_elem(current_ALP_number+1);
+
+						two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_1=
+							states_old_->d_states[k].d_distance_along_direction_1_array->get_elem(current_ALP_number+1);
+
+						two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_2=
+							states_old_->d_states[k].d_distance_along_direction_2_array->get_elem(current_ALP_number+1);
+
+
+					};
+
+				};
+			};
+
+			if(ALP_flag)
+			{//new ALP found
+
+				current_M=two_dim_layer_alignment_algorithm_test_.d_M;
+				current_ALP_number++;
+
+
+
+				if(new_calculation_flag)
+				{
+					IS1_general_simulation_test_.calculate_weight_W1_for_fixed_lengths_using_recursions(
+					seq1_length,//target length of the sequence #1
+					seq2_length,//target length of the sequence #2
+					weight2);//the resulted weight
+
+					if(save_states_flag_)
+					{
+						states_new_->d_states[k].d_ALP_weights_array->set_elem(current_ALP_number,weight2);
+						states_new_->d_states[k].d_distance_along_direction_1_array->set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_1);
+						states_new_->d_states[k].d_distance_along_direction_2_array->set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_2);
+						states_new_->d_states[k].d_M_array->set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_M);
+						states_new_->d_states[k].d_seq1_length_array->set_elem(current_ALP_number,seq1_length);
+						states_new_->d_states[k].d_seq2_length_array->set_elem(current_ALP_number,seq2_length);
+					};
+
+
+
+				};
+
+
+
+
+				if(ALP_stat_flag)
+				{
+					score_max[0][current_ALP_number]=FSA_utils::Tmax(score_max[0][current_ALP_number],current_M);
+					score_max[sn][current_ALP_number]=FSA_utils::Tmax(score_max[sn][current_ALP_number],current_M);
+				};
+
+				if(weight2<=0)
+				{
+					inside_simulation_flag_=false;
+					tmp_w=0;
+				}
+				else
+				{
+					tmp_w=1/weight2;
+				};
+
+				tmp_w2=tmp_w*tmp_w;
+
+			
+
+				if(ALP_stat_flag)
+				{
+					distrE[0][current_ALP_number]->increase_elem_by_x(current_M,tmp_w);
+					distrE[sn][current_ALP_number]->increase_elem_by_x(current_M,tmp_w);
+					
+					distrE_errors[0][current_ALP_number]->increase_elem_by_x(current_M,tmp_w2);
+					distrE_errors[sn][current_ALP_number]->increase_elem_by_x(current_M,tmp_w2);
+
+					distance_along_direction_1[k].set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_1);
+					distance_along_direction_2[k].set_elem(current_ALP_number,two_dim_layer_alignment_algorithm_test_.d_distance_along_direction_2);
+
+					ALP_weight[k].set_elem(current_ALP_number,tmp_w);
+					ALP_edge_max[k].set_elem(current_ALP_number,current_M);
+
+
+					M_max=FSA_utils::Tmax(current_M,M_max);
+				};
+
+				
+
+		
+			};
+
+			if(seq2_length>limit2_)
+			{
+				throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+			};
+
+
+			
+
+			
+			bool save_flag_tmp=((current_ALP_number==target_ALP_)&&!M_thr_flag)||
+			(M_thr_flag&&(two_dim_layer_alignment_algorithm_test_.d_M>=M_thr_)&&(current_ALP_number>=target_ALP_));
+			
+			if(save_flag_tmp)
+			{//save the matrices for weights and alingment matrix
+
+
+				if(states_old_)
+				{
+					if(k<number_of_realizations_old)
+					{
+						if(current_ALP_number==states_old_->d_states[k].d_ALP_number&&!restored_flag)
+						{//restore the state; 				
+
+							restored_flag=true;
+
+							restore_arrays(
+							k,
+							states_old_,
+							two_dim_layer_alignment_algorithm_test_,
+							IS1_general_simulation_test_);
+
+
+						};
+					};
+				};
+
+				//save states
+				if(save_states_flag_)
+				{
+
+					states_new_->d_states[k].d_ALP_number=current_ALP_number;
+
+					states_new_->d_states[k].d_IS1_general_simulation=
+					new IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
+					&IS1_general_simulation_test_);//maximum sequence length
+
+					states_new_->d_states[k].d_two_dim_layer_alignment_algorithm=
+					new two_dim_layer_alignment_algorithm<long int>(
+					seq1_length,//target length of the sequence #1
+					seq2_length,//target length of the sequence #2
+					&two_dim_layer_alignment_algorithm_test_);
+
+					states_new_->d_average_ALP_pos1+=seq1_length;
+					states_new_->d_average_ALP_pos2+=seq2_length;
+					states_new_->d_average_ALP_pos1_mult_ALP_pos2+=seq1_length*seq2_length;
+				};
+
+
+			};
+
+			//check wheter we reached the score threshold M_thr_
+
+			if(M_thr_flag&&(two_dim_layer_alignment_algorithm_test_.d_M>=M_thr_)&&!M_thr_var_are_saved)
+			{
+
+				M_thr_var_are_saved=true;
+				tmp_w_M_thr=tmp_w;
+				tmp_w2_M_thr=tmp_w2;
+
+				delete IS1_general_simulation_M_thr;
+
+				IS1_general_simulation_M_thr=
+				new IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
+				&IS1_general_simulation_test_);//maximum sequence length
+
+				delete two_dim_layer_alignment_algorithm_test_M_thr;
+
+				two_dim_layer_alignment_algorithm_test_M_thr=
+				new two_dim_layer_alignment_algorithm<long int>(
+				seq1_length,//target length of the sequence #1
+				seq2_length,//target length of the sequence #2
+				&two_dim_layer_alignment_algorithm_test_);
+
+				two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag=false;
+
+				seq1_length_M_thr=seq1_length;
+				seq2_length_M_thr=seq2_length;
+
+			};
+
+
+
+			if(ending_time_>=0)
+			{
+				if(new_calculation_flag)
+				{
+					double time1_current;
+					FSA_utils::get_current_time(time1_current);
+					if(time1_current>=ending_time_)
+					{
+						stop_loop_flag=true;
+						stopped_by_ending_time_flag_=true;
+					};
+				};
+			};
+
+			if(ending_time_to_test_logarithmic_regime_>0)
+			{
+				double time1_current;
+				FSA_utils::get_current_time(time1_current);
+				if(time1_current>=ending_time_to_test_logarithmic_regime_)
+				{
+					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+				};
+			};
+
+		};
+
+		
+		if(flag_tmp3)
+		{
+			not_all_ALP_are_sampled++;
+		};
+
+		if(screen_output_k_flag_)
+		{
+			if((k+1)%100==0)
+			{
+				cout<<k+1<<endl;
+			};
+		};
+
+
+
+		//expanding
+
+		if(M_thr_flag)
+		{
+			if(!M_thr_var_are_saved)
+			{
+				throw error("Unexpected error in test::collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states\n",1);
+			};
+
+			two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag=true;
+
+			seq1_length=seq1_length_M_thr;
+			seq2_length=seq2_length_M_thr;
+
+			tmp_w=tmp_w_M_thr;
+			tmp_w2=tmp_w2_M_thr;
+
+
+
+			test::restore_arrays(
+			two_dim_layer_alignment_algorithm_test_M_thr,
+			IS1_general_simulation_M_thr,
+			two_dim_layer_alignment_algorithm_test_,
+			IS1_general_simulation_test_);
+
+			two_dim_layer_alignment_algorithm_test_.d_M=two_dim_layer_alignment_algorithm_test_M_thr->d_M;
+
+		};
+
+		
+		long int seq1_length_before_expanding=seq1_length;
+		long int seq2_length_before_expanding=seq2_length;
+		
+		if(futher_expanding_)
+		{
+			bool expanding_new_flag=true;
+			//restore state
+
+			if(states_old_)
+			{
+				if(k<number_of_realizations_old)
+				{
+					if(current_ALP_number==states_old_->d_states[k].d_ALP_number&&(!restored_flag||states_old_->d_states[k].d_expanding_finished_flag))
+					{
+						if(states_old_->d_states[k].d_expanding_finished_flag)
+						{
+							expanding_new_flag=false;
+							two_dim_layer_alignment_algorithm_test_.d_M=states_old_->d_states[k].d_M_after_expanding;
+							array_v<double>::copy_x2_into_x1(
+								two_dim_layer_alignment_algorithm_test_.d_scores_counts,
+								states_old_->d_states[k].d_scores_counts_after_expanding);
+
+							seq1_length=states_old_->d_states[k].d_seq1_length_after_expanding;
+							seq2_length=states_old_->d_states[k].d_seq2_length_after_expanding;
+
+						}
+						else
+						{
+							restore_arrays(
+							k,
+							states_old_,
+							two_dim_layer_alignment_algorithm_test_,
+							IS1_general_simulation_test_);
+						};
+					};
+				};
+			};
+
+			if(expanding_new_flag)
+			{
+				bool tmp_bool=two_dim_layer_alignment_algorithm_test_.d_E_flag;
+				two_dim_layer_alignment_algorithm_test_.d_E_flag=true;
+
+				long int current_state=0;//the current state
+				long int new_state;
+
+				bool success_flag=false;
+
+				long int j;
+				for(j=1;j<=*number_of_cs_steps_for_expanding_;j++)
+				{
+					IS1_general_cs_->one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
+					current_state,//the current state
+					IS1_general_simulation_test_.d_seq1+seq1_length,//letters for the sequence #1; the array must be allocated
+					IS1_general_simulation_test_.d_seq2+seq2_length,//letters for the sequence #2; the array must be allocated
+					new_state);//a new state
+
+					seq1_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth1;
+					seq2_length+=two_dim_layer_alignment_algorithm_test_.d_edge_maximum_calculation_depth2;
+
+
+					two_dim_layer_alignment_algorithm_test_.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+					//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+					seq1_length,//target length of the sequence #1
+					seq2_length);//target length of the sequence #2
+
+					long int &M=two_dim_layer_alignment_algorithm_test_.d_M;
+					long int &E=two_dim_layer_alignment_algorithm_test_.d_E;
+
+
+					if(E-M<M_threshold)
+					{
+						success_flag=true;
+						break;
+					};
+
+
+					if(ending_time_to_test_logarithmic_regime_>0)
+					{
+						double time1_current;
+						FSA_utils::get_current_time(time1_current);
+						if(time1_current>=ending_time_to_test_logarithmic_regime_)
+						{
+							throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+						};
+					};
+
+
+				};
+
+
+				if(!success_flag)
+				{
+					throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+				};
+
+				two_dim_layer_alignment_algorithm_test_.d_E_flag=tmp_bool;
+
+			};
+
+				
+
+			IS1_general_simulation_test_.d_seq1_current_length=seq1_length;
+			IS1_general_simulation_test_.d_seq2_current_length=seq2_length;
+
+			if(save_states_flag_)
+			{
+				states_new_->d_average_expanding_length1+=seq1_length-seq1_length_before_expanding;
+				states_new_->d_average_expanding_length2+=seq2_length-seq2_length_before_expanding;
+				states_new_->d_average_expanding_length1_mult_expanding_length2+=
+					(seq1_length-seq1_length_before_expanding)*(seq2_length-seq2_length_before_expanding);
+
+				states_new_->d_total_number_of_exp_cells+=
+					seq1_length*seq2_length-seq1_length_before_expanding*seq2_length_before_expanding;
+
+				states_new_->d_states[k].d_expanding_finished_flag=true;
+				states_new_->d_states[k].d_M_after_expanding=two_dim_layer_alignment_algorithm_test_.d_M;
+				states_new_->d_states[k].d_seq1_length_after_expanding=seq1_length;
+				states_new_->d_states[k].d_seq2_length_after_expanding=seq2_length;
+
+				array_v<double>::copy_x2_into_x1(
+				states_new_->d_states[k].d_scores_counts_after_expanding,
+				two_dim_layer_alignment_algorithm_test_.d_scores_counts);
+
+
+
+			};
+
+			
+
+		};
+		
+
+
+		//collect differences
+		if(two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag&&futher_expanding_)
+		{
+			//sum of weigths
+			sum_of_weights[0]+=tmp_w;
+			sum_of_weights[sn]+=tmp_w;
+			sum_of_weights_error[0]+=tmp_w2;
+			sum_of_weights_error[sn]+=tmp_w2;
+
+			long int &M=two_dim_layer_alignment_algorithm_test_.d_M;
+			long int ii;
+			
+			for(ii=FSA_utils::Tmax(M_threshold,two_dim_layer_alignment_algorithm_test_.d_scores_counts.d_ind0);ii<=FSA_utils::Tmin(M,two_dim_layer_alignment_algorithm_test_.d_scores_counts.d_dim_plus_d_ind0);ii++)
+			{
+				long int diff_tmp=(M-ii);
+				double diff_tmp_weight=two_dim_layer_alignment_algorithm_test_.d_scores_counts.get_elem(ii)*tmp_w;
+				double diff_tmp_weight2=diff_tmp_weight*diff_tmp_weight;
+
+				diff[0].increase_elem_by_x(diff_tmp,diff_tmp_weight);
+				diff[sn].increase_elem_by_x(diff_tmp,diff_tmp_weight);
+
+				diff_errors[0].increase_elem_by_x(diff_tmp,diff_tmp_weight2);
+				diff_errors[sn].increase_elem_by_x(diff_tmp,diff_tmp_weight2);
+			};
+
+		};
+
+
+	
+		if(ending_time_>=0)
+		{
+			if(stop_loop_flag)
+			{
+				//the loop is stopped due to time limitations
+				number_of_realizations_with_ending_time_=k+1;
+				if(number_of_realizations_with_ending_time_%number_of_realizations_set==0)
+				{
+					number_of_sets_=sn;
+				}
+				else
+				{
+					number_of_sets_=sn-1;
+				};
+
+				number_of_realizations_=number_of_realizations_with_ending_time_;
+
+				break;
+			};
+		};
+	};
+
+
+	
+	
+	//cout<<"Number of real when not all ALP are sampled\t"<<not_all_ALP_are_sampled<<"\t"<<number_of_realizations_<<endl;
+
+	delete IS1_general_simulation_M_thr;
+	delete two_dim_layer_alignment_algorithm_test_M_thr;
+
+	if(stop_loop_flag)
+	{
+		//the loop is stopped due to time limitations
+		//number of realizations and number of subsets is different
+		if(save_states_flag_)
+		{
+			mult_states_type *states_new_loop=new mult_states_type;
+			*states_new_loop=*states_new_;
+
+			states_new_loop->d_number_of_realizations=number_of_realizations_with_ending_time_;
+
+			if(states_old_)
+			{
+				states_new_loop->d_number_of_realizations=
+					FSA_utils::Tmax(number_of_realizations_with_ending_time_,states_old_->d_number_of_realizations);
+			};
+
+			states_new_loop->d_states=new state_type[states_new_loop->d_number_of_realizations];
+			long int ii;
+			for(ii=0;ii<states_new_loop->d_number_of_realizations;ii++)
+			{
+
+
+				states_new_loop->d_states[ii].d_ALP_number=states_new_->d_states[ii].d_ALP_number;
+				states_new_loop->d_states[ii].d_ALP_weights_array=states_new_->d_states[ii].d_ALP_weights_array;
+				states_new_loop->d_states[ii].d_M_array=states_new_->d_states[ii].d_M_array;
+				states_new_loop->d_states[ii].d_seq1_length_array=states_new_->d_states[ii].d_seq1_length_array;
+				states_new_loop->d_states[ii].d_seq2_length_array=states_new_->d_states[ii].d_seq2_length_array;
+				states_new_loop->d_states[ii].d_distance_along_direction_1_array=states_new_->d_states[ii].d_distance_along_direction_1_array;
+				states_new_loop->d_states[ii].d_distance_along_direction_2_array=states_new_->d_states[ii].d_distance_along_direction_2_array;
+
+				states_new_loop->d_states[ii].d_IS1_general_simulation=
+					states_new_->d_states[ii].d_IS1_general_simulation;
+				states_new_loop->d_states[ii].d_two_dim_layer_alignment_algorithm=
+					states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm;
+
+				states_new_loop->d_states[ii].d_expanding_finished_flag=
+					states_new_->d_states[ii].d_expanding_finished_flag;
+				if(states_new_->d_states[ii].d_expanding_finished_flag)
+				{
+					states_new_loop->d_states[ii].d_M_after_expanding=
+						states_new_->d_states[ii].d_M_after_expanding;
+					states_new_loop->d_states[ii].d_seq1_length_after_expanding=
+						states_new_->d_states[ii].d_seq1_length_after_expanding;
+					states_new_loop->d_states[ii].d_seq2_length_after_expanding=
+						states_new_->d_states[ii].d_seq2_length_after_expanding;
+
+					array_v<double>::copy_x2_into_x1(
+					states_new_loop->d_states[ii].d_scores_counts_after_expanding,
+						states_new_->d_states[ii].d_scores_counts_after_expanding);
+				};
+			};
+
+
+
+
+			if(states_old_)
+			{
+				for(ii=number_of_realizations_with_ending_time_;ii<FSA_utils::Tmin(states_old_->d_number_of_realizations,number_of_realizations_before_loop);ii++)
+				{
+
+
+					states_new_loop->d_states[ii].d_IS1_general_simulation=
+					new IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
+					states_old_->d_states[ii].d_IS1_general_simulation);//maximum sequence length
+
+					states_new_loop->d_states[ii].d_two_dim_layer_alignment_algorithm=
+					new two_dim_layer_alignment_algorithm<long int>(
+					//states_old_->d_states[ii].d_seq1_length[states_old_->d_states[ii].d_ALP_number],//target length of the sequence #1
+					states_old_->d_states[ii].d_seq1_length_array->get_elem(states_old_->d_states[ii].d_ALP_number),//target length of the sequence #1
+					//states_old_->d_states[ii].d_seq2_length[states_old_->d_states[ii].d_ALP_number],//target length of the sequence #2
+					states_old_->d_states[ii].d_seq2_length_array->get_elem(states_old_->d_states[ii].d_ALP_number),//target length of the sequence #2
+					states_old_->d_states[ii].d_two_dim_layer_alignment_algorithm);
+
+
+					states_new_loop->d_states[ii].d_ALP_number=states_old_->d_states[ii].d_ALP_number;
+
+					states_new_loop->d_states[ii].d_expanding_finished_flag=
+						states_old_->d_states[ii].d_expanding_finished_flag;
+
+					if(states_old_->d_states[ii].d_expanding_finished_flag)
+					{
+						states_new_loop->d_states[ii].d_M_after_expanding=
+							states_old_->d_states[ii].d_M_after_expanding;
+						states_new_loop->d_states[ii].d_seq1_length_after_expanding=
+							states_old_->d_states[ii].d_seq1_length_after_expanding;
+						states_new_loop->d_states[ii].d_seq2_length_after_expanding=
+							states_old_->d_states[ii].d_seq2_length_after_expanding;
+
+						array_v<double>::copy_x2_into_x1(
+						states_new_loop->d_states[ii].d_scores_counts_after_expanding,
+							states_old_->d_states[ii].d_scores_counts_after_expanding);
+					};
+
+				};
+			};
+
+
+			for(ii=states_new_loop->d_number_of_realizations;ii<states_new_->d_number_of_realizations;ii++)
+			{
+				delete states_new_->d_states[ii].d_ALP_weights_array;
+				delete states_new_->d_states[ii].d_M_array;
+				delete states_new_->d_states[ii].d_seq1_length_array;
+				delete states_new_->d_states[ii].d_seq2_length_array;
+				delete states_new_->d_states[ii].d_distance_along_direction_1_array;
+				delete states_new_->d_states[ii].d_distance_along_direction_2_array;
+
+				delete states_new_->d_states[ii].d_IS1_general_simulation;
+				delete states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm;
+			};
+
+			delete []states_new_->d_states;
+			delete states_new_;
+			states_new_=states_new_loop;
+		};
+	};
+
+
+	
+	double time2;
+	if(save_states_flag_)
+	{
+		FSA_utils::get_current_time(time2);
+		double total_time_tmp=time2-time1;
+		if(states_old_&&!futher_expanding_)
+		{
+			total_time_tmp+=states_old_->d_total_calculation_time;
+		};
+		states_new_->d_total_calculation_time=total_time_tmp;
+		states_new_->d_number_of_ALP=target_ALP_;
+
+		states_new_->d_average_ALP_pos1/=(double)(states_new_->d_number_of_realizations);
+		states_new_->d_average_ALP_pos2/=(double)(states_new_->d_number_of_realizations);
+		states_new_->d_average_ALP_pos1_mult_ALP_pos2/=(double)(states_new_->d_number_of_realizations);
+
+		states_new_->d_average_expanding_length1/=(double)(states_new_->d_number_of_realizations);
+		states_new_->d_average_expanding_length2/=(double)(states_new_->d_number_of_realizations);
+		states_new_->d_average_expanding_length1_mult_expanding_length2/=(double)(states_new_->d_number_of_realizations);
+
+	};
+
+	//calculation of parameters
+	for(k1=0;k1<=number_of_sets_;k1++)
+	{
+		long int number_of_realizations_tmp=number_of_realizations_set;
+		if(k1==0)
+		{
+			number_of_realizations_tmp=number_of_realizations_;
+		};
+
+		for(k=0;k<=target_ALP_;k++)
+		{
+			long int j;
+			for(j=distrE[k1][k]->d_ind0;j<=score_max[k1][k];j++)
+			{
+				distrE[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
+				distrE_errors[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
+				distrE_errors[k1][k]->increase_elem_by_x(j,-distrE[k1][k]->get_elem(j)*distrE[k1][k]->get_elem(j));
+				distrE_errors[k1][k]->divide_elem_by_x(j,(double)number_of_realizations_tmp);
+			};
+		};
+	};
+
+
+	//calculate M_thr_estimation_
+
+	{
+		double M_thr_estimation_tmp=0;
+		double sum_of_weigths_tmp=0;
+
+		long int j;
+		for(j=distrE[0][target_ALP_]->d_ind0;j<=score_max[0][target_ALP_];j++)
+		{
+			M_thr_estimation_tmp+=distrE[0][target_ALP_]->get_elem(j)*j;
+			sum_of_weigths_tmp+=distrE[0][target_ALP_]->get_elem(j);
+		};
+
+		if(sum_of_weigths_tmp>=0)
+		{
+			M_thr_estimation_tmp/=sum_of_weigths_tmp;
+			M_thr_estimation_=(long int)FSA_utils::round(M_thr_estimation_tmp);
+		}
+		else
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+	};
+
+	if(compute_allocated_memory_flag_)
+	{
+		double states_static_size=(sizeof(IS1_general_simulation)+sizeof(array_positive<double>)+5*sizeof(array_positive<long int>));
+		allocated_memory_+=states_new_->d_number_of_realizations*states_static_size;
+
+		double double_dim=0;
+		double long_dim=0;
+		long int ii;
+		for(ii=0;ii<states_new_->d_number_of_realizations;ii++)
+		{
+			double_dim+=states_new_->d_states[ii].d_ALP_weights_array->d_dim;
+			long_dim+=states_new_->d_states[ii].d_M_array->d_dim;
+			long_dim+=states_new_->d_states[ii].d_seq1_length_array->d_dim;
+			long_dim+=states_new_->d_states[ii].d_seq2_length_array->d_dim;
+			long_dim+=states_new_->d_states[ii].d_distance_along_direction_1_array->d_dim;
+			long_dim+=states_new_->d_states[ii].d_distance_along_direction_2_array->d_dim;
+
+
+			long int n_states=states_new_->d_states[ii].d_IS1_general_simulation->d_IS1_general_obj->d_number_of_states;
+			allocated_memory_+=sizeof(two_dim_layer<double>)*(double)n_states;
+			for(k=0;k<n_states;k++)
+			{
+				two_dim_layer<double> *&tmp1=states_new_->d_states[ii].d_IS1_general_simulation->d_W1[k];
+
+				double_dim+=
+				tmp1->d_layers_number1 *
+					tmp1->d_max_ind2+
+				tmp1->d_layers_number2 *
+					tmp1->d_max_ind1;
+
+			};
+
+			long_dim+=states_new_->d_states[ii].d_IS1_general_simulation->d_max_seq1_length+
+				states_new_->d_states[ii].d_IS1_general_simulation->d_max_seq2_length;
+
+			long int var_n=states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm->d_number_of_variables;
+			allocated_memory_+=sizeof(two_dim_layer<long int>)*(double)var_n;
+
+			for(k=0;k<var_n;k++)
+			{
+				two_dim_layer<long int> *&tmp1=states_new_->d_states[ii].d_two_dim_layer_alignment_algorithm->d_vars[k];
+				
+					long_dim+=
+					tmp1->d_layers_number1 *
+						tmp1->d_max_ind2+
+					tmp1->d_layers_number2 *
+						tmp1->d_max_ind1;
+			};
+		};
+
+
+		allocated_memory_+=double_dim*sizeof(double);
+		allocated_memory_+=long_dim*sizeof(long);
+
+		if(states_new_->d_number_of_realizations>0)
+		{
+			allocated_memory_/=(double)states_new_->d_number_of_realizations;
+		};
+
+
+	};
+
+	if(parameters_are_not_calculated_)
+	{
+		if(score_max)
+		{
+			for(k1=0;k1<=number_of_sets_;k1++)
+			{
+				delete[]score_max[k1];
+			};
+			delete []score_max;
+		};
+
+		if(distrE)
+		{
+			for(k1=0;k1<=number_of_sets_;k1++)
+			{
+				for(k=0;k<=target_ALP_;k++)
+				{
+					delete distrE[k1][k];
+				};
+				delete []distrE[k1];
+			};
+			delete []distrE;
+			distrE=NULL;
+		};
+
+		if(distrE_errors)
+		{
+			for(k1=0;k1<=number_of_sets_;k1++)
+			{
+				for(k=0;k<=target_ALP_;k++)
+				{
+					delete distrE_errors[k1][k];
+				};
+				delete []distrE_errors[k1];
+			};
+			delete []distrE_errors;
+			distrE_errors=NULL;
+		};
+
+		delete[]diff;
+		delete[]diff_errors;
+
+		delete[]distance_along_direction_1;
+		delete[]distance_along_direction_2;
+
+		delete[]ALP_weight;
+		delete[]ALP_edge_max;
+
+		delete[]sum_of_weights;
+		delete[]sum_of_weights_error;
+
+		return;
+	};
+
+
+	
+
+	par_.realizations_number=number_of_realizations_;
+
+	double *lambda_out_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(lambda_out_vect);
+
+	double *lambda_out_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(lambda_out_error_vect);
+
+
+	double *C_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(C_vect);
+
+	double *C_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(C_error_vect);
+
+
+
+	{
+
+		long int nalp=target_ALP_;
+
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+			bool check_the_criteria=false;
+			long int nalp_thr;
+			bool inside_simulation_flag;
+			void **alp_distr=(void**)distrE[k1];
+			void **alp_distr_errors=(void**)distrE_errors[k1];
+			double ungapped_lambda=ungapped_lambda_;
+			double lambda;
+			double lambda_error;
+
+			fsa_par::calculate_lambda(
+			check_the_criteria,
+			nalp,
+			nalp_thr,
+			inside_simulation_flag,
+			alp_distr,
+			alp_distr_errors,
+			ungapped_lambda,
+			lambda,
+			lambda_error);
+
+
+			if(inside_simulation_flag)
+			{
+				lambda_out_vect[k1]=lambda;
+				lambda_out_error_vect[k1]=lambda_error;
+
+				if(k1==0)
+				{
+					struct_for_lambda_calculation tmp_struct;
+					tmp_struct.d_alp_distr=alp_distr;
+					tmp_struct.d_alp_distr_errors=alp_distr_errors;
+					tmp_struct.d_nalp=nalp;
+					tmp_struct.d_calculate_alp_number=false;
+
+					void * data_tmp=(void*)(&tmp_struct);
+					fsa_par::function_for_lambda_calculation(
+					lambda,
+					data_tmp);
+
+					double error2=FSA_utils::Tmax(fabs(tmp_struct.d_last_sum-tmp_struct.d_before_last_sum),fabs(tmp_struct.d_last_sum_error));
+					double fabs_tmp=fabs(FSA_utils::Tmin(tmp_struct.d_last_sum,tmp_struct.d_before_last_sum));
+
+
+					if(fabs_tmp<=0)
+					{
+						throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+					};
+
+					error2/=fabs_tmp;
+
+					par_.lambda_last_ALP_relative_error=error2;
+
+				};
+			}
+			else
+			{
+				inside_simulation_flag_=false;
+				lambda_out_vect[k1]=-1;
+				lambda_out_error_vect[k1]=-1;
+			};
+		};
+
+		
+		lambda_out_=lambda_out_vect[0];
+		lambda_out_error_=lambda_out_error_vect[0];
+
+		if(screen_output_flag_)
+		{
+			//cout<<endl;
+			cout<<"Parameter\tvalue\terror\n";
+		};
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"Lambda\t"<<lambda_out_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			lambda_out_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			lambda_out_vect+1);
+
+			if(average_set_results_flag)
+			{
+				lambda_out_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				lambda_out_vect+1);
+
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<lambda_out_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<lambda_out_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_LambdaSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_LambdaSbs.push_back(lambda_out_vect[k1]);
+		};
+
+
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+
+			void **alp_distr=(void**)distrE[k1];
+			void **alp_distr_errors=(void**)distrE_errors[k1];
+
+			long int starting_point=0;
+
+			bool inside_simulation_flag;
+
+			fsa_par::calculate_C(
+			starting_point,
+			nalp,
+			alp_distr,
+			alp_distr_errors,
+			lambda_out_vect[k1],
+			lambda_out_error_vect[k1],
+			C_vect[k1],
+			C_error_vect[k1],
+			inside_simulation_flag);
+
+
+			if(!inside_simulation_flag)
+			{
+				inside_simulation_flag_=false;
+				C_vect[k1]=-1;
+				C_error_vect[k1]=-1;
+			};
+		};
+
+		C_=C_vect[0];
+		C_error_=C_error_vect[0];
+
+		if(screen_output_flag_)
+		{
+			cout<<"C\t"<<C_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			C_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			C_vect+1);
+
+			if(average_set_results_flag)
+			{
+				C_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				C_vect+1);
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<C_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<C_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_CSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_CSbs.push_back(C_vect[k1]);
+		};
+
+	};
+
+
+
+	for(k=0;k<=target_ALP_;k++)
+	{
+
+		if(output_flag)
+		{
+			long int s;
+
+			double sum_tmp=0;
+			double sum_tmp_error=0;
+
+			fE<<k<<endl;
+			fE<<score_max[0][k]+1<<endl;
+
+			for(s=0;s<=score_max[0][k];s++)
+			{
+				fE<<s<<"\t"<<distrE[0][k]->d_elem[s-distrE[0][k]->d_ind0]<<"\t"<<FSA_utils::sqrt_plus(distrE_errors[0][k]->d_elem[s-distrE_errors[0][k]->d_ind0])<<endl;
+				sum_tmp+=distrE[0][k]->d_elem[s-distrE[0][k]->d_ind0]*exp((double)s*ungapped_lambda_);
+				sum_tmp_error+=FSA_utils::sqrt_plus(distrE_errors[0][k]->d_elem[s-distrE_errors[0][k]->d_ind0])*exp((double)s*ungapped_lambda_);
+			};
+			fE<<endl;
+
+			fE_summary<<k<<"\t"<<sum_tmp<<"\t"<<sum_tmp_error<<endl;
+		};
+	};
+
+
+	double *K_C_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(K_C_vect);
+
+	double *K_C_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(K_C_error_vect);
+
+
+	//calculation of the ratio K/C
+	if(two_dim_layer_alignment_algorithm_test_.d_scores_counts_flag&&futher_expanding_)
+	{
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+			long int number_of_realizations_tmp=number_of_realizations_set;
+			if(k1==0)
+			{
+				number_of_realizations_tmp=number_of_realizations_;
+			};
+
+			long int ii;
+			for(ii=0;ii<=diff[k1].d_dim;ii++)
+			{
+				diff[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
+				diff_errors[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
+				diff_errors[k1].increase_elem_by_x(ii,-diff[k1].get_elem(ii)*diff[k1].get_elem(ii));
+				diff_errors[k1].divide_elem_by_x(ii,(double)number_of_realizations_tmp);
+				double tmp=FSA_utils::sqrt_plus(diff_errors[k1].get_elem(ii));
+				diff_errors[k1].set_elem(ii,tmp);
+			};
+
+			
+
+			sum_of_weights[k1]/=(double)number_of_realizations_tmp;
+			sum_of_weights_error[k1]/=(double)number_of_realizations_tmp;
+			sum_of_weights_error[k1]-=sum_of_weights[k1]*sum_of_weights[k1];
+			sum_of_weights_error[k1]/=(double)number_of_realizations_tmp;
+			sum_of_weights_error[k1]=FSA_utils::sqrt_plus(sum_of_weights_error[k1]);
+			
+
+			double den=0;
+			double den_error=0;
+			for(ii=0;ii<=diff[k1].d_dim;ii++)
+			{
+				double tmp=exp(-lambda_out_vect[k1]*(double)ii);
+				den+=tmp*diff[k1].get_elem(ii);
+				den_error+=tmp*tmp*diff_errors[k1].get_elem(ii)*diff_errors[k1].get_elem(ii);
+
+			};
+
+
+			den_error=FSA_utils::sqrt_plus(den_error);
+
+			if(den!=0)
+			{
+				K_C_vect[k1]=sum_of_weights[k1]/den;
+				K_C_error_vect[k1]=FSA_utils::error_of_the_ratio(sum_of_weights[k1],sum_of_weights_error[k1],den,den_error);
+			}
+			else
+			{
+				inside_simulation_flag_=false;
+				K_C_vect[k1]=-1;
+				K_C_error_vect[k1]=-1;
+			};
+
+		};
+
+		K_C_=K_C_vect[0];
+		K_C_error_=K_C_error_vect[0];
+
+
+		if(output_flag)
+		{
+			fE<<endl;
+			fE<<"K/C distributions\n";
+			fE<<diff[0].d_dim+1<<endl;
+			long int ii;
+			for(ii=0;ii<=diff[0].d_dim;ii++)
+			{
+				//double tmp=exp(-lambda_out_*(double)ii);
+				fE<<ii<<"\t"<<diff[0].get_elem(ii)/sum_of_weights[0]<<"\t"<<diff_errors[0].get_elem(ii)/sum_of_weights[0]<<endl;
+			};
+
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<"K/C\t"<<K_C_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			K_C_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			K_C_vect+1);
+
+			if(average_set_results_flag)
+			{
+				K_C_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				K_C_vect+1);
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<K_C_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<K_C_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_K_CSbs.clear();
+		par_.m_KSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_K_CSbs.push_back(K_C_vect[k1]);
+			par_.m_KSbs.push_back(K_C_vect[k1]*C_vect[k1]);
+		};
+
+
+
+
+	};
+
+
+	double *a_I_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(a_I_vect);
+	double *a_I_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(a_I_error_vect);
+	double *a_J_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(a_J_vect);
+	double *a_J_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(a_J_error_vect);
+	double *sigma_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(sigma_vect);
+	double *sigma_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(sigma_error_vect);
+	double *alpha_I_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(alpha_I_vect);
+	double *alpha_I_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(alpha_I_error_vect);
+	double *alpha_J_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(alpha_J_vect);
+	double *alpha_J_error_vect=new double[number_of_sets_+1];
+	FSA_utils::assert_mem(alpha_J_error_vect);
+
+
+	//FSC
+	{
+		long int k1;
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+
+			pair<long int,long int> boundaries;
+			if(k1==0)
+			{
+				boundaries.first=0;
+				boundaries.second=number_of_realizations_-1;
+			}
+			else
+			{
+				boundaries=set_number_boundaries(//boundaries of realization order numbers for the set; numeration of realizations starts from 0
+				k1,//set order number; the numeration starts from 1
+				number_of_realizations_set);//total number of sets
+			};
+
+			
+			bool test_FSC_flag=false;
+			double *test_FSC_vect=NULL;
+			if(test_FSC_flag)
+			{
+				test_FSC_vect=new double[target_ALP_+1];
+			};
+
+			bool inside_simulation_flag;
+
+			fsa_par::calculate_FSC(
+			target_ALP_,
+			boundaries.first,
+			boundaries.second,
+			
+
+			lambda_out_vect[k1],
+
+			M_max,
+
+			distance_along_direction_1,
+			distance_along_direction_2,
+
+			ALP_weight,
+			ALP_edge_max,
+
+			a_I_vect[k1],
+			a_I_error_vect[k1],
+			a_J_vect[k1],
+			a_J_error_vect[k1],
+			sigma_vect[k1],
+			sigma_error_vect[k1],
+			alpha_I_vect[k1],
+			alpha_I_error_vect[k1],
+			alpha_J_vect[k1],
+			alpha_J_error_vect[k1],
+			inside_simulation_flag,
+			test_FSC_vect);
+
+
+			if(test_FSC_flag)
+			{
+
+				string E_distr_file_name_summary=E_distr_file_name_+"_summary_II";
+				fE_summary.open(E_distr_file_name_summary.data());
+				if(!fE_summary)
+				{
+					throw error("Error - the file "+E_distr_file_name_summary+" is not found\n",3);
+				};
+
+				fE_summary<<target_ALP_<<endl;
+				long int j;
+				for(j=0;j<=target_ALP_;j++)
+				{
+					fE_summary<<j<<"\t"<<test_FSC_vect[j]<<"\t0.0\n";
+				};
+
+
+				fE_summary.close();
+				exit(1);
+			};
+
+			if(!inside_simulation_flag)
+			{
+				a_I_vect[k1]=-1;
+				a_I_error_vect[k1]=-1;
+				a_J_vect[k1]=-1;
+				a_J_error_vect[k1]=-1;
+				sigma_vect[k1]=-1;
+				sigma_error_vect[k1]=-1;
+				alpha_I_vect[k1]=-1;
+				alpha_I_error_vect[k1]=-1;
+				alpha_J_vect[k1]=-1;
+				alpha_J_error_vect[k1]=-1;
+
+				inside_simulation_flag_=false;
+			};
+		};
+
+		a_I_=a_I_vect[0];
+		a_I_error_=a_I_error_vect[0];
+		a_J_=a_J_vect[0];
+		a_J_error_=a_J_error_vect[0];
+		sigma_=sigma_vect[0];
+		sigma_error_=sigma_error_vect[0];
+		alpha_I_=alpha_I_vect[0];
+		alpha_I_error_=alpha_I_error_vect[0];
+		alpha_J_=alpha_J_vect[0];
+		alpha_J_error_=alpha_J_error_vect[0];
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"a_I\t"<<a_I_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			a_I_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			a_I_vect+1);
+
+			if(average_set_results_flag)
+			{
+				a_I_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				a_I_vect+1);
+
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<a_I_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<a_I_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_AISbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_AISbs.push_back(a_I_vect[k1]);
+		};
+
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"a_J\t"<<a_J_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			a_J_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			a_J_vect+1);
+
+			if(average_set_results_flag)
+			{
+				a_J_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				a_J_vect+1);
+
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<a_J_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<a_J_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_AJSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_AJSbs.push_back(a_J_vect[k1]);
+		};
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"sigma\t"<<sigma_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			sigma_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			sigma_vect+1);
+
+			if(average_set_results_flag)
+			{
+				sigma_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				sigma_vect+1);
+
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<sigma_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<sigma_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_SigmaSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_SigmaSbs.push_back(sigma_vect[k1]);
+		};
+
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"alpha_I\t"<<alpha_I_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			alpha_I_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			alpha_I_vect+1);
+
+			if(average_set_results_flag)
+			{
+				alpha_I_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				alpha_I_vect+1);
+
+				if(screen_output_flag_)
+				{
+					cout<<"\t"<<alpha_I_;
+				};
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<alpha_I_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_AlphaISbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_AlphaISbs.push_back(alpha_I_vect[k1]);
+		};
+
+
+		if(screen_output_flag_)
+		{
+			cout<<"alpha_J\t"<<alpha_J_;
+		};
+
+		if(number_of_sets_>1)
+		{
+			alpha_J_error_=FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+			number_of_sets_,
+			alpha_J_vect+1);
+
+			if(average_set_results_flag)
+			{
+				alpha_J_=FSA_utils::average(//average of elements of vect_
+				number_of_sets_,
+				alpha_J_vect+1);
+
+				cout<<"\t"<<alpha_J_;
+			};
+
+			if(screen_output_flag_)
+			{
+				cout<<"\t"<<alpha_J_error_;
+			};
+		};
+
+		if(screen_output_flag_)
+		{
+			cout<<endl;
+		};
+
+		par_.m_AlphaJSbs.clear();
+		for(k1=1;k1<=number_of_sets_;k1++)
+		{
+			par_.m_AlphaJSbs.push_back(alpha_J_vect[k1]);
+		};
+
+	};
+
+
+
+	if(output_flag)
+	{
+		fE.close();
+		fE_summary.close();
+	};
+
+
+	if(score_max)
+	{
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+			delete[]score_max[k1];
+		};
+		delete []score_max;
+	};
+
+	if(distrE)
+	{
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+			for(k=0;k<=target_ALP_;k++)
+			{
+				delete distrE[k1][k];
+			};
+			delete []distrE[k1];
+		};
+		delete []distrE;
+		distrE=NULL;
+	};
+
+	if(distrE_errors)
+	{
+		for(k1=0;k1<=number_of_sets_;k1++)
+		{
+			for(k=0;k<=target_ALP_;k++)
+			{
+				delete distrE_errors[k1][k];
+			};
+			delete []distrE_errors[k1];
+		};
+		delete []distrE_errors;
+		distrE_errors=NULL;
+	};
+	
+
+
+	delete[]distance_along_direction_1;
+	delete[]distance_along_direction_2;
+	delete[]ALP_weight;
+	delete[]ALP_edge_max;
+
+	delete[]diff;
+	delete[]diff_errors;
+
+	delete[]sum_of_weights;
+	delete[]sum_of_weights_error;
+
+
+
+	delete[]lambda_out_vect;
+	delete[]lambda_out_error_vect;
+	delete[]C_vect;
+	delete[]C_error_vect;
+	delete[]K_C_vect;
+	delete[]K_C_error_vect;
+	delete[]a_I_vect;
+	delete[]a_I_error_vect;
+	delete[]a_J_vect;
+	delete[]a_J_error_vect;
+	delete[]sigma_vect;
+	delete[]sigma_error_vect;
+	delete[]alpha_I_vect;
+	delete[]alpha_I_error_vect;
+	delete[]alpha_J_vect;
+	delete[]alpha_J_error_vect;
+
+	//end4
+
+}
+
+//tests
+void test::classical_IS(
+
+unsigned rand_,//randomization number
+long int open1_,//gap opening penalty for the nucleotide sequence #1
+long int open2_,//gap opening penalty for the amino acid sequence #2
+
+long int epen1_,//gap extension penalty for the nucleotide sequence #1
+long int epen2_,//gap extension penalty for the amino acid sequence #2
+
+
+string smatr_file_name_,//scoring matrix file name
+string RR1_file_name_,//background frequencies file name for the sequence #1
+string RR2_file_name_)//background frequencies file name for the sequence #2
+
+//long int seq1_length_,//length of sequence #1
+//long int seq2_length_,//length of sequence #2
+
+//long int seq_number_)//number of tested alignments
+{
+	FSA_utils::srand2(rand_);
+
+	long int alphabet_letters_number1;//number of letters in the sequence #1
+	long int alphabet_letters_number2;//number of letters in the sequence #2
+	double *RR1=NULL;//background probability for the sequence #1
+	double *RR2=NULL;//background probability for the sequence #2
+	long int number_of_states=3;//number of states
+	double **transition_probabilities=NULL;//transition probabilities between states; matrix d_number_of_states x d_number_of_states
+	pair<long int, long int> *states_description=NULL;//description of the states; the index is a state number
+	double ***states_distr=NULL;//distributions of the states; the index is a state number
+								//the second and the third indexes correspond to an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+
+	double *RR1_sum=NULL;
+	long int *RR1_sum_elements=NULL;
+	double *RR2_sum=NULL;
+	long int *RR2_sum_elements=NULL;
+
+	long int **smatr=NULL;
+
+	double ungapped_lambda;
+
+	d_IS1=NULL;
+	d_IS1_general_simulation=NULL;
+
+	long int *seq1=NULL;
+	long int *seq2=NULL;
+
+	{
+		long int number_of_AA_smatr;
+		long int smatr_min;
+
+		FSA_utils::read_smatr(
+		smatr_file_name_,
+		smatr,
+		number_of_AA_smatr,
+		smatr_min);
+
+		
+
+		FSA_utils::read_RR(
+		RR1_file_name_,
+		RR1,
+		RR1_sum,
+		RR1_sum_elements,
+		alphabet_letters_number1);
+
+
+		FSA_utils::read_RR(
+		RR2_file_name_,
+		RR2,
+		RR2_sum,
+		RR2_sum_elements,
+		alphabet_letters_number2);
+
+		if(number_of_AA_smatr!=alphabet_letters_number1||number_of_AA_smatr!=alphabet_letters_number2)
+		{
+			throw error("Error - different numbers of letters in the files "+smatr_file_name_+", "+RR1_file_name_+", "+RR2_file_name_+"\n",1);
+		};
+
+		calculate_ungapped_lambda(
+		alphabet_letters_number1,
+		RR1,
+		RR2,
+		smatr,
+		ungapped_lambda);
+
+	};
+
+	map<string, long int> state_name_into_number;
+
+	state_name_into_number["S"]=0;
+	state_name_into_number["D"]=1;
+	state_name_into_number["I"]=2;
+
+	map<long int,string> state_number_into_name;
+
+	state_number_into_name[0]="S";
+	state_number_into_name[1]="D";
+	state_number_into_name[2]="I";
+
+
+	FSA_utils::get_memory_for_matrix(number_of_states,number_of_states,transition_probabilities);
+
+	long int min_open=FSA_utils::Tmin(open1_,open2_);
+	long int min_epen=FSA_utils::Tmin(epen1_,epen2_);
+
+	double mu=exp(-ungapped_lambda*(min_open+min_epen));
+	double v=exp(-ungapped_lambda*min_epen);
+
+
+
+	transition_probabilities[state_name_into_number["S"]][state_name_into_number["S"]]=
+		((1-v)*(1-v))/((1+mu-v)*(1+mu-v));
+
+	transition_probabilities[state_name_into_number["S"]][state_name_into_number["D"]]=
+		mu/(1+mu-v);
+
+	transition_probabilities[state_name_into_number["S"]][state_name_into_number["I"]]=
+		(mu*(1-v))/((1+mu-v)*(1+mu-v));
+
+
+
+
+	transition_probabilities[state_name_into_number["D"]][state_name_into_number["S"]]=
+		((1-v)*(1-v))/(1+mu-v);
+
+	transition_probabilities[state_name_into_number["D"]][state_name_into_number["D"]]=
+		v;
+
+	transition_probabilities[state_name_into_number["D"]][state_name_into_number["I"]]=
+		(mu*(1-v))/(1+mu-v);
+
+
+
+
+	transition_probabilities[state_name_into_number["I"]][state_name_into_number["S"]]=
+		1-v;
+
+	transition_probabilities[state_name_into_number["I"]][state_name_into_number["D"]]=
+		0;
+
+	transition_probabilities[state_name_into_number["I"]][state_name_into_number["I"]]=
+		v;
+
+	//FSA_utils::print_matrix("mtp.out",3,3,transition_probabilities);
+
+//--------------------
+	states_description=new pair<long int, long int>[number_of_states];
+	FSA_utils::assert_mem(states_description);
+
+	states_description[state_name_into_number["S"]]=make_pair(1,1);
+	states_description[state_name_into_number["D"]]=make_pair(1,0);
+	states_description[state_name_into_number["I"]]=make_pair(0,1);
+
+//--------------------
+
+	states_distr=new double **[number_of_states];
+
+	long int s;
+	for(s=0;s<number_of_states;s++)
+	{
+		states_distr[s]=IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+			alphabet_letters_number1,//number of letters in the sequence #1
+			alphabet_letters_number2,//number of letters in the sequence #2
+			states_description[s]);//state description
+
+	};
+
+	double tmp_sum=0;
+	long int i,j;
+	for(i=0;i<alphabet_letters_number1;i++)
+	{
+		for(j=0;j<alphabet_letters_number2;j++)
+		{
+			states_distr[state_name_into_number["S"]][i][j]=RR1[i]*RR2[j]*exp(ungapped_lambda*smatr[i][j]);
+			tmp_sum+=states_distr[state_name_into_number["S"]][i][j];
+		};
+	};
+
+	//cout<<"Total sum of joint distribution of (S_A,S_B) is "<<tmp_sum<<endl;
+
+	for(i=0;i<alphabet_letters_number1;i++)
+	{
+		states_distr[state_name_into_number["D"]][i][0]=RR1[i];
+	};
+
+	for(j=0;j<alphabet_letters_number2;j++)
+	{
+		states_distr[state_name_into_number["I"]][0][j]=RR2[j];
+	};
+	
+
+
+	d_IS1=new IS1_general(
+	alphabet_letters_number1,//number of letters in the sequence #1
+	alphabet_letters_number2,//number of letters in the sequence #2
+	RR1,//background probability for the sequence #1
+	RR2,//background probability for the sequence #2
+	number_of_states,//number of states
+	transition_probabilities,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
+	states_description,//description of the states; the index is a state number
+	states_distr);//distributions of the states; the index is a state number
+
+//-----------------------------------
+//crude sampling object
+
+	long int number_of_states_cs=1;
+	double **transition_probabilities_cs=NULL;//transition probabilities between states; matrix d_number_of_states x d_number_of_states
+	pair<long int, long int> *states_description_cs=NULL;//description of the states; the index is a state number
+	double ***states_distr_cs=NULL;//distributions of the states; the index is a state number
+
+	FSA_utils::get_memory_for_matrix(number_of_states_cs,number_of_states_cs,transition_probabilities_cs);
+	transition_probabilities_cs[state_name_into_number["S"]][state_name_into_number["S"]]=1;
+
+	states_description_cs=new pair<long int, long int>[number_of_states_cs];
+	FSA_utils::assert_mem(states_description_cs);
+
+	states_description_cs[state_name_into_number["S"]]=make_pair(1,1);
+
+
+	states_distr_cs=new double **[number_of_states_cs];
+
+	for(s=0;s<number_of_states_cs;s++)
+	{
+		states_distr_cs[s]=IS1_general::allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+			alphabet_letters_number1,//number of letters in the sequence #1
+			alphabet_letters_number2,//number of letters in the sequence #2
+			states_description_cs[s]);//state description
+
+	};
+
+
+	double tmp_sum_cs=0;
+	for(i=0;i<alphabet_letters_number1;i++)
+	{
+		for(j=0;j<alphabet_letters_number2;j++)
+		{
+			states_distr_cs[state_name_into_number["S"]][i][j]=RR1[i]*RR2[j];
+			tmp_sum_cs+=states_distr_cs[state_name_into_number["S"]][i][j];
+		};
+	};
+
+
+	IS1_general* IS1_cs=new IS1_general(
+	alphabet_letters_number1,//number of letters in the sequence #1
+	alphabet_letters_number2,//number of letters in the sequence #2
+	RR1,//background probability for the sequence #1
+	RR2,//background probability for the sequence #2
+	number_of_states_cs,//number of states
+	transition_probabilities_cs,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
+	states_description_cs,//description of the states; the index is a state number
+	states_distr_cs);//distributions of the states; the index is a state number
+
+
+//-----------------------------------------------------------
+//test for the layers object
+	{
+
+		long int max_ind1=100;//max of the index #1
+		long int max_ind2=200;//max of the index #2
+
+
+
+		long int layers_number1=6;//number of layers for the index #1
+		long int layers_number2=20;//number of layers for the index #2
+
+		two_dim_layer<long int> two_dim_layer_test(
+		max_ind1,//max of the index #1
+		max_ind2,//max of the index #2
+		layers_number1,//number of layers for the index #1
+		layers_number2,//number of layers for the index #2
+		0);
+
+	
+	};
+	//------------------------------------------------------
+	//test for the two_dim_layer_alignment_algorithm object
+	{
+		long int depth1=1;//the maximum difference of the first index in the dynamic equations
+		long int depth2=1;//the maximum difference of the second index in the dynamic equations
+
+		long int max_ind1=100;//max of the index #1
+		long int max_ind2=200;//max of the index #2
+
+		long int var_num_dim=1000;
+		long int *var_num=new long int[var_num_dim];
+		long int i;
+		for(i=0;i<var_num_dim;i++)
+		{
+			var_num[i]=-1;
+		};
+
+		var_num['S']=0;
+		var_num['D']=1;
+		var_num['I']=2;
+
+		data_for_classical_alignment data_test;
+
+		data_test.d_open1=open1_;
+		data_test.d_open2=open2_;
+
+		data_test.d_epen1=epen1_;
+		data_test.d_epen2=epen2_;
+
+		data_test.d_smatr=smatr;
+
+
+
+		long int initial_state=state_name_into_number["S"];
+
+		d_IS1_general_simulation=new IS1_general_simulation(
+		d_IS1,
+		initial_state,//initial state for the IS
+		max_ind1*5,//maximum sequence length
+		max_ind2*5);//maximum sequence length
+
+
+		data_test.d_seq1=d_IS1_general_simulation->d_seq1;//sequence #1
+		data_test.d_seq2=d_IS1_general_simulation->d_seq2;//sequence #2
+
+
+		
+
+
+
+		two_dim_layer_alignment_algorithm<long int> two_dim_layer_alignment_algorithm_test(
+		number_of_states,//total number of variables in dynamic equations
+		depth1,//the maximum difference of the first index in the dynamic equations
+		depth2,//the maximum difference of the second index in the dynamic equations
+		max_ind1,//max of the index #1 (minimum index is 0 by default)
+		max_ind2,//max of the index #2 (minimum index is 0 by default)
+		0,//null element of T
+		var_num);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
+
+		two_dim_layer_alignment_algorithm_test.d_two_dim_layer_alignment_function=test::two_dim_layer_alignment_function_classical_global;
+		two_dim_layer_alignment_algorithm_test.d_two_dim_layer_boundary_function=test::two_dim_layer_alignment_function_classical_global;
+		two_dim_layer_alignment_algorithm_test.d_par=&data_test;
+
+		long int target_seq1_length=100;
+		long int target_seq2_length=200;
+
+		d_IS1_general_simulation->simulate_upto_target_lengths(
+			target_seq1_length,
+			target_seq2_length);
+
+
+
+		two_dim_layer_alignment_algorithm_test.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+		//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+		target_seq1_length,//target length of the sequence #1
+		target_seq2_length);//target length of the sequence #2
+
+
+		delete[]var_num;
+	};
+
+
+
+	//test for the two_dim_layer_alignment_algorithm object
+	//crude sampling
+	{
+		long int number_of_realizations=100;
+
+		long int depth1=1;//the maximum difference of the first index in the dynamic equations
+		long int depth2=1;//the maximum difference of the second index in the dynamic equations
+
+		long int max_ind1=100;//max of the index #1
+		long int max_ind2=100;//max of the index #2
+
+		long int var_num_dim=1000;
+		long int *var_num=new long int[var_num_dim];
+		long int i;
+		for(i=0;i<var_num_dim;i++)
+		{
+			var_num[i]=-1;
+		};
+
+		var_num['S']=0;
+		var_num['D']=1;
+		var_num['I']=2;
+
+		data_for_classical_alignment data_test;
+
+		data_test.d_open1=open1_;
+		data_test.d_open2=open2_;
+
+		data_test.d_epen1=epen1_;
+		data_test.d_epen2=epen2_;
+
+		data_test.d_smatr=smatr;
+
+
+
+		long int initial_state=state_name_into_number["S"];
+
+		IS1_general_simulation *IS1_general_simulation_cs=new IS1_general_simulation(
+		IS1_cs,
+		initial_state,//initial state for the IS
+		max_ind1,//maximum sequence length
+		max_ind2);//maximum sequence length
+
+
+		data_test.d_seq1=IS1_general_simulation_cs->d_seq1;//sequence #1
+		data_test.d_seq2=IS1_general_simulation_cs->d_seq2;//sequence #2
+
+
+		
+
+
+
+		two_dim_layer_alignment_algorithm<long int> two_dim_layer_alignment_algorithm_test_cs(
+		number_of_states,//total number of variables in dynamic equations
+		depth1,//the maximum difference of the first index in the dynamic equations
+		depth2,//the maximum difference of the second index in the dynamic equations
+		max_ind1,//max of the index #1 (minimum index is 0 by default)
+		max_ind2,//max of the index #2 (minimum index is 0 by default)
+		0,//null element of T
+		var_num);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
+
+		two_dim_layer_alignment_algorithm_test_cs.d_two_dim_layer_alignment_function=test::two_dim_layer_alignment_function_classical_global;
+		two_dim_layer_alignment_algorithm_test_cs.d_two_dim_layer_boundary_function=test::two_dim_layer_alignment_function_classical_global;
+		two_dim_layer_alignment_algorithm_test_cs.d_par=&data_test;
+
+		two_dim_layer_alignment_algorithm_test_cs.d_M_flag=true;
+
+		long int target_seq1_length=max_ind1;
+		long int target_seq2_length=max_ind2;
+
+		ofstream fM;
+
+		array_v<double> *distrM=NULL;
+		long int score_max=-inf;
+
+		if(two_dim_layer_alignment_algorithm_test_cs.d_M_flag)
+		{
+			//distribution of M
+			string M_distr_file_name="distr_M_tmp.out";
+
+			fM.open(M_distr_file_name.data());
+			if(!fM)
+			{
+				throw error("Error - the file "+M_distr_file_name+" is not found\n",3);
+			};
+
+
+			distrM=new array_v<double>(NULL);
+
+			
+
+		};
+
+		//--------------------
+
+		long int k;
+		for(k=1;k<=number_of_realizations;k++)
+		{
+
+			IS1_general_simulation_cs->init();
+			IS1_general_simulation_cs->simulate_upto_target_lengths(
+			target_seq1_length,
+			target_seq2_length);
+
+			two_dim_layer_alignment_algorithm_test_cs.init();
+			two_dim_layer_alignment_algorithm_test_cs.align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+			//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+			target_seq1_length,//target length of the sequence #1
+			target_seq2_length);//target length of the sequence #2
+
+			if(two_dim_layer_alignment_algorithm_test_cs.d_M_flag)
+			{
+				score_max=FSA_utils::Tmax(score_max,two_dim_layer_alignment_algorithm_test_cs.d_M);
+				distrM->increase_elem_by_1(two_dim_layer_alignment_algorithm_test_cs.d_M);
+			};
+
+			if(k%1000==0)
+			{
+				cout<<k<<endl;
+			};
+
+		};
+
+		if(two_dim_layer_alignment_algorithm_test_cs.d_M_flag)
+		{
+			long int s;
+
+			double sum_tmp=0;
+			for(s=0;s<=score_max;s++)
+			{
+				sum_tmp+=distrM->d_elem[s-distrM->d_ind0];
+			};
+
+			if(sum_tmp<=0)
+			{
+				throw error("Unexpected error - sum_tmp<=0\n",1);
+			};
+			
+
+			fM<<score_max+1<<endl;
+			for(s=0;s<=score_max;s++)
+			{
+				distrM->d_elem[s-distrM->d_ind0]/=sum_tmp;
+				fM<<s<<"\t"<<distrM->d_elem[s-distrM->d_ind0]<<endl;
+			};
+
+			fM.close();
+		};
+
+
+
+		delete[]var_num;
+		delete IS1_general_simulation_cs;
+		delete distrM;
+	};
+
+
+	delete[]RR1;
+	delete[]RR2;
+
+	delete[]RR1_sum;
+	delete[]RR2_sum;
+
+	delete[]RR1_sum_elements;
+	delete[]RR2_sum_elements;
+
+	FSA_utils::delete_memory_for_matrix(alphabet_letters_number1,smatr);
+	FSA_utils::delete_memory_for_matrix(number_of_states,transition_probabilities);
+	FSA_utils::delete_memory_for_matrix(number_of_states_cs,transition_probabilities_cs);
+
+	for(s=0;s<number_of_states;s++)
+	{
+		IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+			states_distr[s],
+			alphabet_letters_number1,//number of letters in the sequence #1
+			states_description[s]);//state description
+	};
+
+	for(s=0;s<number_of_states_cs;s++)
+	{
+		IS1_general::deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+			states_distr_cs[s],
+			alphabet_letters_number1,//number of letters in the sequence #1
+			states_description_cs[s]);//state description
+	};
+
+
+	delete[]states_description;
+
+	delete[]states_description_cs;
+	
+
+	delete[]seq1;
+	delete[]seq2;
+
+	delete d_IS1;
+
+	delete IS1_cs;
+
+	delete d_IS1_general_simulation;
+	
+}
+
+double test::lambda_equation(double x_,void* func_number_)
+{
+	data_for_lambda_equation *data=(data_for_lambda_equation*)func_number_;
+	long int d_number_of_AA=data->d_number_of_AA;
+	long int** d_smatr=data->d_smatr;
+	double *d_RR1=data->d_RR1;
+	double *d_RR2=data->d_RR2;
+
+	double res=0;
+	long int i,j;
+
+	for(i=0;i<d_number_of_AA;i++)
+	{
+		for(j=0;j<d_number_of_AA;j++)
+		{
+			res+=d_RR1[i]*d_RR2[j]*exp(x_*d_smatr[i][j]);
+		};
+	};
+
+	return res-1.0;
+}
+
+double test::lambda_equation_FSA(double x_,void* func_number_)
+{
+	data_for_lambda_equation_FSA *data=(data_for_lambda_equation_FSA*)func_number_;
+	long int number_of_letters1=data->d_number_of_letters1;
+	long int number_of_letters2=data->d_number_of_letters2;
+
+	long int** d_smatr=data->d_smatr;
+	double *d_RR1=data->d_RR1;
+	double *d_RR2=data->d_RR2;
+
+	long int codon_length=data->d_codon_length;//codon length 
+	long int *codon_AA=data->d_codon_AA;//<codon code,AA number>
+
+	long int *codon=new long int [codon_length];
+	FSA_utils::assert_mem(codon);
+
+	long int i,j;
+
+	long int code_n=1;
+	for(i=1;i<=codon_length;i++)
+	{
+		code_n*=number_of_letters1;
+	};
+
+	double res=0;
+	
+
+	for(i=0;i<code_n;i++)
+	{
+		FSA_utils::convert_code_into_codon(
+		i,//the input code
+		codon_length,//codon length 
+		number_of_letters1,//number of letters for the sequence 1
+		codon);//must be allocated
+
+		long int AA1=codon_AA[i];
+
+		double RR1_mult=1;
+		
+		for(j=0;j<codon_length;j++)
+		{
+			RR1_mult*=d_RR1[codon[j]];
+		};
+
+		for(j=0;j<number_of_letters2;j++)
+		{
+			res+=RR1_mult*d_RR2[j]*exp(x_*d_smatr[AA1][j]);
+		};
+	};
+
+	delete[]codon;
+	return res-1.0;
+}
+
+
+void test::calculate_ungapped_lambda(
+long int number_of_AA_,
+double *RR1_,
+double *RR2_,
+long int**smatr_,
+double &ungapped_lambda_)
+{
+	//calculation of the importance sampling theta
+
+	data_for_lambda_equation tmp_ptr;
+	tmp_ptr.d_number_of_AA=number_of_AA_;
+	tmp_ptr.d_RR1=RR1_;
+	tmp_ptr.d_RR2=RR2_;
+	tmp_ptr.d_smatr=smatr_;
+
+	//calculate maximum of smatr_ elements
+	long int smatr_max=smatr_[0][0];
+	long int smatr_max_i=0;
+	long int smatr_max_j=0;
+	long int smatr_min=smatr_[0][0];
+
+	long int smatr_pos_max=LONG_MIN;
+	long int smatr_neg_min=LONG_MAX;
+
+	double eps=0.0000001;
+	double threshold=DBL_MIN*10.0;
+
+	double aver_score=0;
+	long int i,j;
+	for(i=0;i<number_of_AA_;i++)
+	{
+		for(j=0;j<number_of_AA_;j++)
+		{
+			if(RR1_[i]*RR2_[j]<=threshold)
+			{
+				continue;
+			};
+								
+
+
+			aver_score+=RR1_[i]*RR2_[j]*smatr_[i][j];
+
+			if(smatr_max<smatr_[i][j])
+			{
+				smatr_max=smatr_[i][j];
+				smatr_max_i=i;
+				smatr_max_j=j;
+			};
+			smatr_min=FSA_utils::Tmin(smatr_min,smatr_[i][j]);
+			
+
+			if(smatr_[i][j]>0)
+			{
+				smatr_pos_max=FSA_utils::Tmax(smatr_pos_max,smatr_[i][j]);
+			};
+
+			if(smatr_[i][j]<0)
+			{
+				smatr_neg_min=FSA_utils::Tmin(smatr_neg_min,smatr_[i][j]);
+			};
+
+		};
+	};
+
+	if(aver_score>=-threshold)
+	{
+		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+	};
+
+	if(smatr_max<=0)
+	{
+		throw error("Error - at least one element of the scoring matrix must be positive\n",3);
+	};
+
+	
+
+	double a=eps;
+
+	while(test::lambda_equation(a,(void*)(&tmp_ptr))>0)
+	{
+		a/=2.0;
+
+		if(a<threshold*100.0)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+	};
+
+	if(a<threshold*100.0)
+	{
+		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+	};
+
+	eps=a/10.0;
+
+
+	double tmp_pr=RR1_[smatr_max_i]*RR2_[smatr_max_j];
+	double b=(log(1+10*eps)-log(tmp_pr))/(double)smatr_max;
+
+	
+	long int n_partition=2;
+	std::vector<double> res_lambda;
+	
+	
+	alp_reg::find_tetta_general(
+	test::lambda_equation,
+	(void*)(&tmp_ptr),
+	a,
+	b,
+	n_partition,
+	eps,
+	res_lambda);
+
+	sort(res_lambda.begin(),res_lambda.end());
+
+	if(res_lambda.size()==0)
+	{
+		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+	};
+
+	
+	ungapped_lambda_=res_lambda[res_lambda.size()-1];
+
+	cout<<"Ungapped lambda is "<<ungapped_lambda_<<endl;
+
+
+}
+
+void test::calculate_ungapped_lambda_general(
+function_type *func_,
+void* func_pointer_,
+double &ungapped_lambda_)
+{
+
+	double eps=1e-7;
+	double threshold=DBL_MIN*10.0;
+
+	double threshold2=DBL_MAX/4;
+
+
+	double a=eps;
+	while(func_(a,func_pointer_)>0)
+	{
+		a/=2.0;
+
+		if(a<threshold*100.0)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+	};
+
+	if(a<threshold*100.0)
+	{
+		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+	};
+
+	eps=a/10.0;
+
+
+	double b=a;
+
+
+	while(func_(b,func_pointer_)<=0)
+	{
+		b*=2.0;
+
+		if(b>threshold2)
+		{
+			throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+		};
+	};
+
+
+	
+	long int n_partition=2;
+	std::vector<double> res_lambda;
+	
+	
+	alp_reg::find_tetta_general(
+	func_,
+	func_pointer_,
+	a,
+	b,
+	n_partition,
+	eps,
+	res_lambda);
+
+	sort(res_lambda.begin(),res_lambda.end());
+
+	if(res_lambda.size()==0)
+	{
+		throw error("Error - you have exceeded the calculation time or memory limit.\nThe error might indicate that the regime is linear or too close to linear to permit efficient computation.\nPossible solutions include changing the randomization seed, or increasing the allowed calculation time and the memory limit.\n",3);
+	};
+
+	
+	ungapped_lambda_=res_lambda[res_lambda.size()-1];
+
+	//cout<<setprecision(12)<<"Ungapped lambda is "<<ungapped_lambda_<<endl;
+	//cout<<"Ungapped lambda is "<<ungapped_lambda_<<endl;
+
+
+}
+
+//======================================================
+
+void test::two_dim_layer_alignment_function_FSA(
+long int i1_,
+long int i2_,
+two_dim_layer_alignment_algorithm<long int> *obj_,
+void*par_)
+{
+	data_for_FSA_alignment &data=*(data_for_FSA_alignment*)par_;
+
+	long int &alphabet_letters_number1=data.d_alphabet_letters_number1;//number of letters in the sequence #1
+
+	long int &open1=data.d_open1;//gap opening penalty for the nucleotide sequence #1
+	long int &open2=data.d_open2;//gap opening penalty for the amino acid sequence #2
+
+	long int &epen1=data.d_epen1;//gap extension penalty for the nucleotide sequence #1
+	long int &epen2=data.d_epen2;//gap extension penalty for the amino acid sequence #2
+
+	long int &gamma=data.d_gamma;//frame shift penalty
+
+	long int**&smatr=data.d_smatr;//the scoring matrix
+	long int *&seq1=data.d_seq1;//element of sequence #1
+	long int *&seq2=data.d_seq2;//element of sequence #2
+
+	long int *&codon_AA=data.d_codon_AA;//<codon code,AA number>
+
+	bool &insertions_after_deletions=data.d_insertions_after_deletions;//if true, then insertions after deletions are allowed
+
+	string &alignment_type=data.d_alignment_type;//possible values are "global" or "local"
+
+	if(obj_->d_number_of_variables!=3)
+	{
+		throw error("Error - obj_->d_number_of_variables!=3 in two_dim_layer_alignment_function_FSA\n",1);
+	};
+
+	long int *d_var_num=obj_->d_var_num;
+
+	two_dim_layer<long int> **vars=obj_->d_vars;
+
+	long int Sn=d_var_num['S'];
+	long int Dn=d_var_num['D'];
+	long int In=d_var_num['I'];
+
+	long int codon_length=3;//codon length 
+
+//----------------------------------------
+
+	bool local_flag=(alignment_type=="local");
+
+	long int init_for_S=-inf;
+	if(local_flag)
+	{
+		init_for_S=0;
+	};
+
+
+	long int i=i1_;
+	long int j=i2_;
+
+	if(j==0)
+	{
+		if(local_flag)
+		{
+			vars[Dn]->set_element(i,0,-inf);
+		}
+		else
+		{
+			vars[Dn]->set_element(i,0,-inf);
+			
+		};
+
+
+		
+		vars[In]->set_element(i,0,-inf);
+
+		//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+		//if(i<=2)
+		if(i<=0)
+		{
+			vars[Sn]->set_element(i,0,0);
+		}
+		else
+		{
+			vars[Sn]->set_element(i,0,init_for_S);
+		};
+
+
+		return;
+
+	};
+
+	if(i==0)
+	{
+
+		vars[Sn]->set_element(0,j,init_for_S);
+		vars[Dn]->set_element(0,j,-inf);
+		if(local_flag)
+		{
+			vars[In]->set_element(0,j,-inf);
+		}
+		else
+		{
+			vars[In]->set_element(0,j,-inf);
+		};
+
+		return;
+	};
+
+	if(i==1)
+	{
+		//check these conditions
+		vars[Sn]->set_element(1,j,init_for_S);
+		vars[Dn]->set_element(1,j,-inf);
+		if(local_flag)
+		{
+			vars[In]->set_element(1,j,-inf);
+		}
+		else
+		{
+			vars[In]->set_element(1,j,-inf);
+		};
+
+		return;
+	};
+
+	if(i==2)
+	{
+		vars[Sn]->set_element(2,j,init_for_S);
+		vars[Dn]->set_element(2,j,-inf);
+		if(local_flag)
+		{
+			vars[In]->set_element(2,j,-inf);
+		}
+		else
+		{
+			vars[In]->set_element(2,j,-inf);
+		};
+
+		return;
+	};
+
+
+	{
+
+		{
+
+			if(insertions_after_deletions)
+			{
+				vars[In]->set_element(i,j,
+					FSA_utils::Tmax(
+					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+					vars[Dn]->get_element(i,j-1)-open2-epen2,
+					vars[Sn]->get_element(i,j-1)-open2-epen2,vars[In]->get_element(i,j-1)-epen2));
+			}
+			else
+			{
+				vars[In]->set_element(i,j,
+					FSA_utils::Tmax(
+					vars[Sn]->get_element(i,j-1)-open2-epen2,vars[In]->get_element(i,j-1)-epen2));
+
+			};
+			
+			if(i==3)
+			{
+
+				long int AA1=FSA_utils::convert_codon_into_AA(
+				codon_length,//codon length 
+				codon_AA,//<codon code,AA number>
+				alphabet_letters_number1,//number of letters for the sequence 1
+				seq1+i-3);
+
+
+				long int smart_score=smatr[AA1][seq2[j-1]];
+				vars[Sn]->set_element(i,j,FSA_utils::Tmax(
+
+					//for local alignment
+					init_for_S,
+					
+					FSA_utils::Tmax(vars[Sn]->get_element(i-3,j-1),vars[Dn]->get_element(i-3,j-1),vars[In]->get_element(i-3,j-1))+smart_score,
+					FSA_utils::Tmax(vars[Sn]->get_element(i-2,j-1),vars[Dn]->get_element(i-2,j-1),vars[In]->get_element(i-2,j-1))+smart_score-gamma
+					
+					)
+				);
+
+				vars[Dn]->set_element(i,j,FSA_utils::Tmax(
+					
+					FSA_utils::Tmax(vars[Sn]->get_element(i-3,j)-open1-epen1,vars[Dn]->get_element(i-3,j)-epen1),
+					FSA_utils::Tmax(vars[Sn]->get_element(i-2,j)-open1-epen1,vars[Dn]->get_element(i-2,j)-epen1)-gamma
+
+					)
+					);
+				return;
+				
+			};
+			if(i>=4)
+			{
+
+				long int AA1=FSA_utils::convert_codon_into_AA(
+				codon_length,//codon length 
+				codon_AA,//<codon code,AA number>
+				alphabet_letters_number1,//number of letters for the sequence 1
+				seq1+i-3);
+
+				long int smart_score=smatr[AA1][seq2[j-1]];
+				vars[Sn]->set_element(i,j,FSA_utils::Tmax(
+					
+					//for local alignment
+					init_for_S,
+					
+					FSA_utils::Tmax(vars[Sn]->get_element(i-3,j-1),vars[Dn]->get_element(i-3,j-1),vars[In]->get_element(i-3,j-1))+smart_score,
+					
+					FSA_utils::Tmax(
+					FSA_utils::Tmax(vars[Sn]->get_element(i-2,j-1),vars[Dn]->get_element(i-2,j-1),vars[In]->get_element(i-2,j-1)),
+					FSA_utils::Tmax(vars[Sn]->get_element(i-4,j-1),vars[Dn]->get_element(i-4,j-1),vars[In]->get_element(i-4,j-1))
+					)+smart_score-gamma
+					
+					)
+					);
+
+
+
+				vars[Dn]->set_element(i,j,FSA_utils::Tmax(
+					
+					FSA_utils::Tmax(vars[Sn]->get_element(i-3,j)-open1-epen1,vars[Dn]->get_element(i-3,j)-epen1),
+					FSA_utils::Tmax(vars[Sn]->get_element(i-2,j)-open1-epen1,vars[Dn]->get_element(i-2,j)-epen1)-gamma,
+					FSA_utils::Tmax(vars[Sn]->get_element(i-4,j)-open1-epen1,vars[Dn]->get_element(i-4,j)-epen1)-gamma
+
+					)
+					);
+
+			};
+
+
+
+		};
+	};
+
+
+}
+
+//======================================================
+
+
+void test::two_dim_layer_alignment_function_classical_global(
+long int i1_,
+long int i2_,
+two_dim_layer_alignment_algorithm<long int> *obj_,
+void*par_)
+{
+	data_for_classical_alignment data=*(data_for_classical_alignment*)par_;
+
+	long int &open1=data.d_open1;//gap opening penalty for the nucleotide sequence #1
+	long int &open2=data.d_open2;//gap opening penalty for the amino acid sequence #2
+
+	long int &epen1=data.d_epen1;//gap extension penalty for the nucleotide sequence #1
+	long int &epen2=data.d_epen2;//gap extension penalty for the amino acid sequence #2
+
+	long int**&smatr=data.d_smatr;//the scoring matrix
+	long int *seq1=data.d_seq1;//element of sequence #1
+	long int *seq2=data.d_seq2;//element of sequence #2
+
+	if(obj_->d_number_of_variables!=3)
+	{
+		throw error("Error - obj_->d_number_of_variables!=3 in two_dim_layer_alignment_function_classical_global\n",1);
+	};
+
+	long int *d_var_num=obj_->d_var_num;
+
+	two_dim_layer<long int> **vars=obj_->d_vars;
+
+	long int Sn=d_var_num['S'];
+	long int Dn=d_var_num['D'];
+	long int In=d_var_num['I'];
+
+	//boundary conditions
+	if(i1_==0)
+	{
+		if(i2_==0)
+		{
+			vars[Sn]->set_element(0,0,0);
+			vars[Dn]->set_element(0,0,-open1);
+		}
+		else
+		{
+			vars[Sn]->set_element(0,i2_,-inf);
+			vars[Dn]->set_element(0,i2_,-inf);
+		};
+
+		vars[In]->set_element(0,i2_,-open2-i2_*epen2);
+		return;
+	};
+
+	if(i2_==0)
+	{
+		if(i1_==0)
+		{
+			vars[Sn]->set_element(0,0,0);
+			vars[In]->set_element(0,0,-open2);
+		}
+		else
+		{
+			vars[Sn]->set_element(i1_,0,-inf);
+			vars[In]->set_element(i1_,0,-inf);
+		};
+
+		vars[Dn]->set_element(i1_,0,-open1-i1_*epen1);
+		return;
+	};
+
+	//here i1_>0, i2_>0
+	long int S_1_1=vars[Sn]->get_element(i1_-1,i2_-1);
+	long int D_1_1=vars[Dn]->get_element(i1_-1,i2_-1);
+	long int I_1_1=vars[In]->get_element(i1_-1,i2_-1);
+
+
+	long int S_1_0=vars[Sn]->get_element(i1_-1,i2_);
+	long int D_1_0=vars[Dn]->get_element(i1_-1,i2_);
+	//long int I_1_0=vars[In]->get_element(i1_-1,i2_);
+
+	long int S_0_1=vars[Sn]->get_element(i1_,i2_-1);
+	long int D_0_1=vars[Dn]->get_element(i1_,i2_-1);
+	long int I_0_1=vars[In]->get_element(i1_,i2_-1);
+
+	long int S_0_0=FSA_utils::Tmax(S_1_1,D_1_1,I_1_1)+smatr[seq1[i1_-1]][seq2[i2_-1]];
+	long int D_0_0=FSA_utils::Tmax(S_1_0-open1-epen1,D_1_0-epen1);
+	long int I_0_0=FSA_utils::Tmax(S_0_1-open2-epen2,I_0_1-epen2,D_0_1-open2-epen2);
+
+	vars[Sn]->set_element(i1_,i2_,S_0_0);
+	vars[Dn]->set_element(i1_,i2_,D_0_0);
+	vars[In]->set_element(i1_,i2_,I_0_0);
+
+
+}
+
+//--------------------------------------
+template<typename T> 
+two_dim_layer_alignment_algorithm<T>::two_dim_layer_alignment_algorithm(
+long int number_of_variables_,//total number of variables in dynamic equations
+long int depth1_,//the maximum difference of the first index in the dynamic equations
+long int depth2_,//the maximum difference of the second index in the dynamic equations
+long int max_ind1_,//max of the index #1 (minimum index is 0 by default)
+long int max_ind2_,//max of the index #2 (minimum index is 0 by default)
+T null_,//null element of T
+long int *var_num_)//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
+{
+
+	d_max_ind1=max_ind1_;
+	d_max_ind2=max_ind2_;
+
+	d_number_of_variables=number_of_variables_;
+	d_depth1=depth1_;
+	d_depth2=depth2_;
+	d_var_num=var_num_;
+	d_null=null_;
+	d_step1=depth1_*2+1;
+	d_step2=depth2_*2+1;
+
+	//d_step1=depth1_;
+	//d_step2=depth2_;
+
+	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	d_edge_maximum_calculation_depth1=3;
+	d_edge_maximum_calculation_depth2=1;
+
+	long int layers_number1=depth1_+d_step1;//number of layers for the index #1
+	long int layers_number2=depth2_+d_step2;//number of layers for the index #2
+
+	d_vars=new two_dim_layer<T> *[number_of_variables_];
+
+	long int i;
+	for(i=0;i<d_number_of_variables;i++)
+	{
+		d_vars[i]=new two_dim_layer<T>(
+		max_ind1_,//max of the index #1 (minimum index is 0 by default)
+		max_ind2_,//max of the index #2 (minimum index is 0 by default)
+		layers_number1,//number of layers for the index #1
+		layers_number2,//number of layers for the index #2
+		null_);
+	};
+
+	d_current_align_ind1=-1;
+	d_current_align_ind2=-1;
+
+	//statistics 
+	d_M_flag=false;
+	d_M=-inf;
+
+	d_E_flag=false;
+	d_E=-inf;
+
+}
+
+
+template<typename T> 
+two_dim_layer_alignment_algorithm<T>::two_dim_layer_alignment_algorithm(
+long int max_ind1_,//max of the index #1
+long int max_ind2_,//max of the index #2
+two_dim_layer_alignment_algorithm<T> *two_dim_layer_alignment_algorithm_)
+{
+
+	d_max_ind1=two_dim_layer_alignment_algorithm_->d_max_ind1;
+	d_max_ind2=two_dim_layer_alignment_algorithm_->d_max_ind2;
+
+	d_number_of_variables=two_dim_layer_alignment_algorithm_->d_number_of_variables;
+	d_depth1=two_dim_layer_alignment_algorithm_->d_depth1;
+	d_depth2=two_dim_layer_alignment_algorithm_->d_depth2;
+	d_var_num=two_dim_layer_alignment_algorithm_->d_var_num;
+	d_null=two_dim_layer_alignment_algorithm_->d_null;
+	d_step1=two_dim_layer_alignment_algorithm_->d_step1;
+	d_step2=two_dim_layer_alignment_algorithm_->d_step2;
+
+
+	d_edge_maximum_calculation_depth1=two_dim_layer_alignment_algorithm_->d_edge_maximum_calculation_depth1;
+	d_edge_maximum_calculation_depth2=two_dim_layer_alignment_algorithm_->d_edge_maximum_calculation_depth2;
+
+	d_vars=new two_dim_layer<T> *[d_number_of_variables];
+
+	long int i;
+	for(i=0;i<d_number_of_variables;i++)
+	{
+		d_vars[i]=new two_dim_layer<T>(
+		max_ind1_,//max of the index #1 (minimum index is 0 by default)
+		max_ind2_,//max of the index #2 (minimum index is 0 by default)
+		two_dim_layer_alignment_algorithm_->d_vars[i]);
+	};
+
+	d_current_align_ind1=two_dim_layer_alignment_algorithm_->d_current_align_ind1;
+	d_current_align_ind2=two_dim_layer_alignment_algorithm_->d_current_align_ind2;
+
+	//statistics 
+	d_M_flag=two_dim_layer_alignment_algorithm_->d_M_flag;
+	d_M=two_dim_layer_alignment_algorithm_->d_M;
+
+	d_E_flag=two_dim_layer_alignment_algorithm_->d_E_flag;
+	d_E=two_dim_layer_alignment_algorithm_->d_E;
+
+}
+
+
+template<typename T> 
+two_dim_layer_alignment_algorithm<T>::~two_dim_layer_alignment_algorithm()
+{
+	long int i;
+	for(i=0;i<d_number_of_variables;i++)
+	{
+		d_vars[i]->~two_dim_layer<T>();
+	};
+
+	delete[]d_vars;
+}
+
+template<typename T> 
+void two_dim_layer_alignment_algorithm<T>::init()//initialization for a new alignment
+{
+	d_M=-inf;
+	d_E=-inf;
+	d_current_align_ind1=-1;
+	d_current_align_ind2=-1;
+
+	d_scores_counts.clear();
+}
+
+template<typename T> 
+void two_dim_layer_alignment_algorithm<T>::align_upto_target_lengths_step(//aligns the sequences upto the target sequence lengths including 
+//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+long int target_align1_length_,//target length for the sequence #1
+long int target_align2_length_)//target length for the sequence #2
+{
+	long int i;
+	for(i=0;i<d_number_of_variables;i++)
+	{
+		d_vars[i]->set_max_ind(target_align1_length_,target_align2_length_);
+	};
+
+	if(target_align1_length_-d_current_align_ind1>d_step1||target_align2_length_-d_current_align_ind2>d_step2)
+	{
+		throw error("Unexpected error in two_dim_layer_alignment_algorithm<T>::align_upto_target_lengths: target_align1_length_-d_current_align_ind1>d_step1||target_align2_length_-d_current_align_ind2>d_step2\n",1);
+	};
+
+	long int i1,i2;
+	for(i1=0;i1<=d_current_align_ind1;i1++)
+	{
+		for(i2=d_current_align_ind2+1;i2<=target_align2_length_;i2++)
+		{
+			two_dim_layer_alignment_function_type *tmp_func=d_two_dim_layer_alignment_function;
+			if(i1<d_depth1||i2<d_depth2)
+			{
+				tmp_func=d_two_dim_layer_boundary_function;
+			};
+
+			tmp_func(i1,i2,this,d_par);
+		};
+	};
+
+	for(i2=0;i2<=d_current_align_ind2;i2++)
+	{
+		for(i1=d_current_align_ind1+1;i1<=target_align1_length_;i1++)
+		{
+			two_dim_layer_alignment_function_type *tmp_func=d_two_dim_layer_alignment_function;
+			if(i1<d_depth1||i2<d_depth2)
+			{
+				tmp_func=d_two_dim_layer_boundary_function;
+			};
+
+			tmp_func(i1,i2,this,d_par);
+		};
+	};
+
+	for(i1=d_current_align_ind1+1;i1<=target_align1_length_;i1++)
+	{
+		for(i2=d_current_align_ind2+1;i2<=target_align2_length_;i2++)
+		{
+			two_dim_layer_alignment_function_type *tmp_func=d_two_dim_layer_alignment_function;
+			if(i1<d_depth1||i2<d_depth2)
+			{
+				tmp_func=d_two_dim_layer_boundary_function;
+			};
+
+			tmp_func(i1,i2,this,d_par);
+		};
+	};
+
+	d_current_align_ind1=FSA_utils::Tmax(target_align1_length_,d_current_align_ind1);
+	d_current_align_ind2=FSA_utils::Tmax(target_align2_length_,d_current_align_ind2);
+
+}
+
+template<typename T> 
+void two_dim_layer_alignment_algorithm<T>::align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+long int target_align1_length_,//target length for the sequence #1
+long int target_align2_length_)//target length for the sequence #2
+{
+
+	while(d_current_align_ind1<target_align1_length_||d_current_align_ind2<target_align2_length_)
+	{
+		long int current_align_ind1_old=d_current_align_ind1;
+		long int current_align_ind2_old=d_current_align_ind2;
+
+		align_upto_target_lengths_step(
+		FSA_utils::Tmin(target_align1_length_,d_current_align_ind1+d_step1),
+		FSA_utils::Tmin(target_align2_length_,d_current_align_ind2+d_step2));
+
+		long int M_tmp=d_M;
+
+		//statistics
+		if(d_M_flag||d_FSC_flag)
+		{
+			long int i1,i2,j;
+			for(i1=0;i1<=d_current_align_ind1;i1++)
+			{
+				for(i2=current_align_ind2_old+1;i2<=d_current_align_ind2;i2++)
+				{
+					for(j=0;j<d_number_of_variables;j++)
+					{
+						d_M=FSA_utils::Tmax(d_M,d_vars[j]->get_element(i1,i2));
+					};
+				};
+			};
+
+			for(i1=current_align_ind1_old+1;i1<=d_current_align_ind1;i1++)
+			{
+				for(i2=0;i2<=current_align_ind2_old;i2++)
+				{
+					for(j=0;j<d_number_of_variables;j++)
+					{
+						d_M=FSA_utils::Tmax(d_M,d_vars[j]->get_element(i1,i2));
+					};
+				};
+			};
+
+		};
+
+		if(d_scores_counts_flag)
+		{
+			long int i1,i2,j;
+			for(i1=0;i1<=d_current_align_ind1;i1++)
+			{
+				for(i2=current_align_ind2_old+1;i2<=d_current_align_ind2;i2++)
+				{
+					long int M_local=d_vars[0]->get_element(i1,i2);
+					for(j=1;j<d_number_of_variables;j++)
+					{
+						M_local=FSA_utils::Tmax(M_local,d_vars[j]->get_element(i1,i2));
+					};
+
+
+					if(M_local>=d_M_threshold)
+					{
+						d_scores_counts.increase_elem_by_1(M_local);
+					};
+				};
+			};
+
+			for(i1=current_align_ind1_old+1;i1<=d_current_align_ind1;i1++)
+			{
+				for(i2=0;i2<=current_align_ind2_old;i2++)
+				{
+					long int M_local=d_vars[0]->get_element(i1,i2);
+					for(j=1;j<d_number_of_variables;j++)
+					{
+						M_local=FSA_utils::Tmax(M_local,d_vars[j]->get_element(i1,i2));
+					};
+
+					if(M_local>=d_M_threshold)
+					{
+						d_scores_counts.increase_elem_by_1(M_local);
+					};
+				};
+			};
+
+		};
+
+
+
+
+		if(d_FSC_flag&&M_tmp<d_M)
+		{//calculated only along the edge containing the next ALP
+
+			d_distance_along_direction_1=-1;
+
+			d_distance_along_direction_2=-1;
+
+			long int i1,i2,j;
+			for(i1=0;i1<=d_current_align_ind1;i1++)
+			{
+				for(i2=current_align_ind2_old+1;i2<=d_current_align_ind2;i2++)
+				{
+					long int M_local=d_vars[0]->get_element(i1,i2);
+					for(j=1;j<d_number_of_variables;j++)
+					{
+						M_local=FSA_utils::Tmax(M_local,d_vars[j]->get_element(i1,i2));
+					};
+
+					if(M_local==d_M)
+					{
+						if(d_distance_along_direction_1==-1)
+						{
+							d_distance_along_direction_1=i1;
+						}
+						else
+						{
+							d_distance_along_direction_1=FSA_utils::Tmin(d_distance_along_direction_1,i1);
+						};
+
+						if(d_distance_along_direction_2==-1)
+						{
+							d_distance_along_direction_2=i2;
+						}
+						else
+						{
+							d_distance_along_direction_2=FSA_utils::Tmin(d_distance_along_direction_2,i2);
+						};
+					};
+
+				};
+			};
+
+			for(i1=current_align_ind1_old+1;i1<=d_current_align_ind1;i1++)
+			{
+				for(i2=0;i2<=d_current_align_ind2;i2++)
+				{
+					long int M_local=d_vars[0]->get_element(i1,i2);
+					for(j=1;j<d_number_of_variables;j++)
+					{
+						M_local=FSA_utils::Tmax(M_local,d_vars[j]->get_element(i1,i2));
+					};
+
+					if(M_local==d_M)
+					{
+						if(d_distance_along_direction_1==-1)
+						{
+							d_distance_along_direction_1=i1;
+						}
+						else
+						{
+							d_distance_along_direction_1=FSA_utils::Tmin(d_distance_along_direction_1,i1);
+						};
+
+						if(d_distance_along_direction_2==-1)
+						{
+							d_distance_along_direction_2=i2;
+						}
+						else
+						{
+							d_distance_along_direction_2=FSA_utils::Tmin(d_distance_along_direction_2,i2);
+						};
+					};
+				};
+			};
+
+
+			if(d_distance_along_direction_1==-1||d_distance_along_direction_2==-1)
+			{
+				throw error("Unexpected error - d_distance_along_direction_1==-1||d_distance_along_direction_2==-1\n",1);
+			};
+		};
+
+
+
+	};
+
+
+	//statistics
+	if(d_E_flag||d_scores_counts_flag)
+	{
+
+		d_E=-inf;
+		long int i1,i2,j;
+		for(i1=0;i1<=d_current_align_ind1;i1++)
+		{
+			for(i2=d_current_align_ind2-d_edge_maximum_calculation_depth2+1;i2<=d_current_align_ind2;i2++)
+			{
+				for(j=0;j<d_number_of_variables;j++)
+				{
+					d_E=FSA_utils::Tmax(d_E,d_vars[j]->get_element(i1,i2));
+				};
+			};
+		};
+
+		for(i1=d_current_align_ind1-d_edge_maximum_calculation_depth1+1;i1<=d_current_align_ind1;i1++)
+		{
+			for(i2=0;i2<=d_current_align_ind2-d_edge_maximum_calculation_depth2;i2++)
+			{
+				for(j=0;j<d_number_of_variables;j++)
+				{
+					d_E=FSA_utils::Tmax(d_E,d_vars[j]->get_element(i1,i2));
+				};
+			};
+		};
+
+
+
+
+	};
+
+
+}
+//---------------------------------------------------------
+
diff --git a/src/alp/sls_fsa1.hpp b/src/alp/sls_fsa1.hpp
index c2bf257..ab7e6dd 100644
--- a/src/alp/sls_fsa1.hpp
+++ b/src/alp/sls_fsa1.hpp
@@ -1,1416 +1,1416 @@
-#ifndef GUMBEL_FSA1
-#define GUMBEL_FSA1
-
-/* $Id: $
-* ===========================================================================
-*
-*							PUBLIC DOMAIN NOTICE
-*			   National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_fsa1.hpp
-
-Author: Sergey Sheetlin
-
-Contents: Frameshift alignment algorithms 
-
-******************************************************************************/
-
-#include "sls_alp_regression.hpp"
-#include "sls_fsa1_utils.hpp"
-#include "sls_fsa1_parameters.hpp"
-#include "sls_fsa1_pvalues.hpp"
-
-#include "njn_localmaxstatmatrix.hpp"
-#include "njn_localmaxstatutil.hpp"
-
-#include "sls_fsa1_utils.hpp"
-
-const double mb_bytes=1048576.0;
-
-namespace Sls 
-{
-	const long int inf=LONG_MAX/10;
-
-	class IS1_general_simulation;
-	template<typename T> class two_dim_layer_alignment_algorithm;
-
-	struct par_test1_type
-	{
-		std::string d_gumbelparout_file_name;
-		long int d_seqlen1;
-		long int d_seqlen2;
-	};
-
-	
-	struct state_type
-	{
-		long int d_ALP_number;//number of ALPs simulated
-
-		array_positive<long int> *d_M_array;//global maximum corresponded to the ALP
-		array_positive<long int> *d_seq1_length_array;//length of sequence #1 corresponded to the ALP
-		array_positive<long int> *d_seq2_length_array;//length of sequence #2 corresponded to the ALP
-		array_positive<long int> *d_distance_along_direction_1_array;
-		array_positive<long int> *d_distance_along_direction_2_array;
-		array_positive<double> *d_ALP_weights_array;//IS weigths for the ALP points; dimension of the array is d_ALP_number+1
-
-
-
-		IS1_general_simulation *d_IS1_general_simulation;
-		two_dim_layer_alignment_algorithm<long int> *d_two_dim_layer_alignment_algorithm;
-
-		//for matrix expanding
-		bool d_expanding_finished_flag;
-		long int d_seq1_length_after_expanding;
-		long int d_seq2_length_after_expanding;
-		long int d_M_after_expanding;
-		array_v<double> d_scores_counts_after_expanding;
-
-
-		state_type()
-		{
-			d_M_array=NULL;
-			d_seq1_length_array=NULL;
-			d_seq2_length_array=NULL;
-			d_distance_along_direction_1_array=NULL;
-			d_distance_along_direction_2_array=NULL;
-			d_ALP_weights_array=NULL;
-
-		}
-	};
-
-	struct mult_states_type
-	{
-		long int d_number_of_realizations;
-		long int d_number_of_ALP;
-
-		double d_total_calculation_time;//time in seconds; includes information from the old object
-
-		double d_average_ALP_pos1_mult_ALP_pos2;//average of d_average_ALP_pos1*d_average_ALP_pos2
-		double d_average_ALP_pos1;//average of ALP position for the sequence #1
-		double d_average_ALP_pos2;//average of ALP position for the sequence #2
-		double d_average_expanding_length1;//average length of crude sampling expansion for the sequence #1
-		double d_average_expanding_length2;//average length of crude sampling expansion for the sequence #2
-		double d_average_expanding_length1_mult_expanding_length2;//average of d_average_expanding_length1*d_average_expanding_length2
-
-		//long long d_total_number_of_ALP_cells;
-		//long long d_total_number_of_exp_cells;
-
-		double d_total_number_of_ALP_cells;
-		double d_total_number_of_exp_cells;
-
-		long int d_total_number_of_ALPs;
-
-
-		
-
-		state_type *d_states;//dimension of the array is d_number_of_realizations
-
-		mult_states_type()
-		{
-			d_states=NULL;
-			d_number_of_realizations=-1;
-		}
-	};
-
-
-	class FSA;
-	class FSA_utils;
-
-
-
-	class FSA
-	{
-		public:
-
-		typedef void alignment_function_type(long int *seq1_,long int *seq2_,FSA *FAS_object_,void*par_);
-		struct struct_for_alignment
-		{
-			long int d_score;//alignment score
-		};
-
-
-
-
-		FSA(//constructor
-
-		bool reversed_seq_,//whether the sequences are reversed or not
-		std::string alignment_type_,//type of alignment; possible values "local", "global"
-
-		long int rand_,//randomization number
-		long int open1_,//gap opening penalty for the nucleotide sequence #1
-		long int open2_,//gap opening penalty for the amino acid sequence #2
-
-		long int epen1_,//gap extension penalty for the nucleotide sequence #1
-		long int epen2_,//gap extension penalty for the amino acid sequence #2
-
-		long int gamma_,//frameshift penalty gamma
-
-		std::string smatr_file_name_,//scoring matrix file name
-		std::string RR1_file_name_,//background frequencies file name for the sequence #1
-		std::string RR2_file_name_,//background frequencies file name for the sequence #2
-		std::string DNA_codon_table_file_name_,//a name of a file with DNA codon table
-		long int seq1_length_,//length of sequence #1
-		long int seq2_length_,//length of sequence #2
-		long int seq_number_);//number of tested alignments
-
-		~FSA();
-
-
-
-		long int random_AA1();
-
-		long int random_AA2();
-
-		long int convert_codon_into_AA(//returns AA corresponded to the codon
-		long int *codon_);
-
-		static void classical_global_alignment(
-		long int *seq1_,//sequence #1
-		long int *seq2_,//sequence #2
-		FSA *FAS_object_,//a pointer to FSA object
-		void*par_);//additonal parameters
-
-		static void a1_global_alignment(
-		long int *seq1_,//sequence #1
-		long int *seq2_,//sequence #2
-		FSA *FAS_object_,//a pointer to FSA object
-		void*par_);//additonal parameters
-
-		void DNA_AA_global(
-		std::string distr_file_name_,
-		alignment_function_type *alignment_function_);
-
-		void AA_AA_global(
-		std::string distr_file_name_,
-		alignment_function_type *alignment_function_);
-
-		void DNA_to_3_frames_AA_global(
-		std::string distr_file_name_,
-		alignment_function_type *alignment_function_);
-
-
-
-
-		public:
-
-		
-		//input parameters
-
-		bool d_reversed_seq;//whether the sequences are reversed or not
-		std::string d_alignment_type;//type of alignment; possible values "local", "global"
-
-		long int d_open1;//gap opening penalty for the nucleotide sequence #1
-		long int d_open2;//gap opening penalty for the amino acid sequence #2
-
-
-		long int d_epen1;//gap extension penalty for the nucleotide sequence #1
-		long int d_epen2;//gap extension penalty for the amino acid sequence #2
-
-		long int d_gamma;//frameshift penalty gamma
-
-
-		double d_max_time;//maximum allowed calculation time in seconds
-		double d_max_mem;//maximum allowed memory usage in MB
-		double d_memory_size_in_MB;//current allocated memory size
-
-
-		
-		//additional parameters
-
-		long int d_number_of_letters1;//number of letters for the sequence 1
-		long int d_number_of_letters2;//number of letters for the sequence 2
-
-		char *d_alphabet1;//alphabet letters for the sequence #1
-		char *d_alphabet2;//alphabet letters for the sequence #2
-
-		long int *d_alphabet1_to_long;//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-		long int *d_alphabet2_to_long;//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-
-		long int** d_smatr;//scoring matrix
-
-		double *d_RR1;//nucleotide probabilities
-		double *d_RR1_sum;//probability distribution function for d_RR1
-		long int *d_RR1_sum_elements;//numbers of nucleotide corresponded to d_RR1
-
-		double *d_RR2;//AA probabilities
-		double *d_RR2_sum;//probability distribution function for d_RR2
-		long int *d_RR2_sum_elements;//numbers of AA corresponded to d_RR2
-
-		long int d_seq1_length;//length of sequence #1
-		long int d_seq2_length;//length of sequence #2
-		long int d_seq_number;//number of tested alignments
-
-		long int d_codon_length;//codon length 
-		long int *d_codon_AA;//<codon code,AA number>
-
-		bool d_rand_flag;
-		long int d_random_factor;
-
-		//temporary arrays for alignments
-		long int **d_S_a1;
-		long int **d_I_a1;
-		long int **d_D_a1;
-
-		long int *d_seq1;
-		long int *d_seq2;
-
-	};
-
-	class IS1_general
-	{
-
-		public:
-
-		IS1_general(
-		long int alphabet_letters_number1_,//number of letters in the sequence #1
-		long int alphabet_letters_number2_,//number of letters in the sequence #2
-		double *RR1_,//background probability for the sequence #1
-		double *RR2_,//background probability for the sequence #2
-		long int number_of_states_,//number of states
-		double **transition_probabilities_,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
-		std::pair<long int, long int> *states_description_,//description of the states; the index is a state number
-		double ***states_distr_);//distributions of the states; the first index is a state number
-								//the second and the third indexes correspond to an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-
-		~IS1_general();
-		
-		static long int letters_to_code(//returns a unique code for the array of letters
-		long int letters_number_,//total number of letters
-		long int letters_dim_,//dimension of the array with letters
-		long int*letters_);//array of letters
-		
-
-		static void code_to_letters(//returns a unique code for the array of letters
-		long int code_,//input code
-		long int letters_number_,//total number of letters
-		long int letters_dim_,//dimension of the array with letters
-		long int*letters_);//array of letters; the result
-		
-		static long int matr_indexes_to_code(
-		long int code1_,//code #1
-		long int code1_number_,//the range of code1_ is [0,code1_number_-1]
-		long int code2_,//code #2
-		long int code2_number_);//the range of code2_ is [0,code2_number_-1]
-
-		static void code_to_matr_indexes(
-		long int code_,//input code
-		long int &code1_,//code #1; the result
-		long int code1_number_,//the range of code1_ is [0,code1_number_-1]
-		long int &code2_,//code #2; the result
-		long int code2_number_);//the range of code2_ is [0,code2_number_-1]
-
-		static double ** allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-			long int alphabet_letters_number1_,//number of letters in the sequence #1
-			long int alphabet_letters_number2_,//number of letters in the sequence #2
-			std::pair<long int, long int> state_description_);//state description
-
-		static void deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-			double **&state_distr_,
-			long int alphabet_letters_number1_,//number of letters in the sequence #1
-			std::pair<long int, long int> state_description_);//state description
-
-		static void generate_one_state_sum_distr(//calculates sum-distributions corresponded to the input parameters
-			std::pair<long int, long int> state_distr_dims_,//dimensions of the matrix state_distr_
-			double **state_distr_,//state distribution in the same format as in d_states_distr[s]
-			double *&state_sum_distr_);//the result; the dimention is state_distr__dim1 x state_distr__dim2
-
-		void generate_random_letters_in_a_given_state(
-			long int state_number_,//state number
-			long int *letters1_,//the resulted letters for the sequence 1; the array must be allocated
-			long int *letters2_);//the resulted letters for the sequence 2; the array must be allocated
-
-		void one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
-		long int current_state_,//the current state
-		long int *seq1_add_letters_,//letters for the sequence #1; the array must be allocated
-		long int *seq2_add_letters_,//letters for the sequence #2; the array must be allocated
-		long int &new_state_);//a new state
-
-		void allocate_states_distr_sums();//allocates d_states_distr_sums
-		void deallocate_states_distr_sums();//deallocates d_states_distr_sums
-
-		void calculate_inverse_matrices_for_the_infinite_sums(
-			long int code1_,
-			long int code2_,
-			std::vector<std::vector<double> > *A1_inv_,
-			std::vector<std::vector<double> > *A2_inv_,
-			long int x1_,
-			long int x2_);
-
-
-			
-		public:
-
-		long int d_alphabet_letters_number1;//number of letters in the sequence #1
-		long int d_alphabet_letters_number2;//number of letters in the sequence #2
-
-		double *d_RR1;//background probability for the sequence #1
-		double *d_RR2;//background probability for the sequence #2
-
-		long int d_number_of_states;//number of states
-		double **d_transition_probabilities;//transition probabilities between states; matrix d_number_of_states x d_number_of_states
-
-		double **d_transition_probabilities_sum;//sum-distributions calculated from d_transition_probabilities[s]
-
-		std::pair<long int, long int> *d_states_description;//description of the states; the index is a state number
-		//.first: number of letters generated for the sequence #1
-		//.second: number of letters generated for the sequence #2
-
-		double ***d_states_distr;//distributions of the states; the first index is a state number
-								//the second and the third indexes correspond to an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
-
-		double *****d_states_distr_sums;//distributions of the sums for d_states_distr; the first index is a state number
-		//the second and the third indexes are number of letters retained for the first (x1) and the second (x2) sequence respectively
-		//x1=0..state_description_type.first; x2=0..state_description_type.second
-		//d_states_distr_sums[s][x1][x2] is the distribution and has the dimension d_A_letters^x1 x d_B_letters^x2
-
-		std::vector<std::vector<double> > d_A1_inv;
-		std::vector<std::vector<double> > d_A2_inv;
-		//the second index is x1 and x2 respectively; the third index is the code; 
-		//x1=0..state_description_type.first; x2=0..state_description_type.second
-		//the dimentions of the array d_A1_inv[s][x1] is d_A_letters^x1
-		//the dimentions of the array d_A2_inv[s][x2] is d_B_letters^x2
-
-
-		//calculated values
-		std::pair<long int, long int> *d_states_distr_dimensions;//contains dimensions of the matrix d_states_distr[s], s=0,...,d_number_of_states
-
-		double **d_states_sum_distr;//sum-distributions calculated from d_states_distr
-		long int *d_states_sum_distr_elements_for_all_states;//an array of with numbers 0,1,2,...
-		//can be used for d_states_sum_distr[s] or d_transition_probabilities_sum
-
-		std::pair<long int*, long int*> *d_tmp_letters;//an auxiliary array of length d_number_of_states; 
-												//element #s contains arrays of dimensions <d_states_description[s].first,d_states_description[s].second>
-
-		long int d_max_dim1;//maximum of d_states_description[s].first
-		long int d_max_dim2;//maximum of d_states_description[s].second
-
-	};
-
-	template<typename T> class two_dim_layer
-	{
-		public:
-
-		two_dim_layer(//constructor
-		long int max_ind1_,//max of the index #1 (minimum index is 0 by default)
-		long int max_ind2_,//max of the index #2 (minimum index is 0 by default)
-
-		long int layers_number1_,//number of layers for the index #1
-		long int layers_number2_,//number of layers for the index #2
-
-		T null_)
-		{
-			if(max_ind1_<=0||max_ind2_<=0||layers_number1_<=0||layers_number2_<=0)
-			{
-				throw error("Error - parameters of two_dim_layer::two_dim_layer must be positive\n",1);
-			};
-
-			if(layers_number1_-1>max_ind2_)
-			{
-				throw error("Error - layers_number1_-1>max_ind2_ in two_dim_layer::two_dim_layer\n",1);
-			};
-
-			if(layers_number2_-1>max_ind1_)
-			{
-				throw error("Error - layers_number2_-1>max_ind1_ in two_dim_layer::two_dim_layer\n",1);
-			};
-
-			d_max_ind1=max_ind1_;//max of the index #1
-			d_max_ind2=max_ind2_;//max of the index #2
-
-			d_layers_number1=layers_number1_;//number of layers for the index #1
-			d_layers_number2=layers_number2_;//number of layers for the index #2
-
-			d_current_max_ind1=layers_number1_-1;
-			d_current_max_ind2=layers_number2_-1;
-
-			d_current_min_ind1=0;
-			d_current_min_ind2=0;
-
-			d_layers1=NULL;
-			d_layers2=NULL;
-
-			d_null=null_;
-
-			d_layers1=new T*[d_layers_number1];
-			FSA_utils::assert_mem(d_layers1);
-
-			long int i;
-			for(i=0;i<d_layers_number1;i++)
-			{
-				d_layers1[i]=NULL;
-				d_layers1[i]=new T[d_max_ind2+1];
-				FSA_utils::assert_mem(d_layers1[i]);
-			};
-
-			d_layers2=new T*[d_layers_number2];
-			FSA_utils::assert_mem(d_layers2);
-
-			for(i=0;i<d_layers_number2;i++)
-			{
-				d_layers2[i]=NULL;
-				d_layers2[i]=new T[d_max_ind1+1];
-				FSA_utils::assert_mem(d_layers2[i]);
-			};
-
-			d_layers1_tmp=NULL;
-			d_layers1_tmp=new T*[d_layers_number1];
-			FSA_utils::assert_mem(d_layers1_tmp);
-
-			d_layers2_tmp=NULL;
-			d_layers2_tmp=new T*[d_layers_number2];
-			FSA_utils::assert_mem(d_layers2_tmp);
-
-		}
-
-		two_dim_layer(//constructor; copies data from two_dim_layer_ with minimally allocated memory
-		long int max_ind1_,
-		long int max_ind2_,
-		two_dim_layer *two_dim_layer_)
-		{
-
-			d_max_ind1=max_ind1_;//max of the index #1
-			d_max_ind2=max_ind2_;//max of the index #2
-
-			d_layers_number1=two_dim_layer_->d_layers_number1;//number of layers for the index #1
-			d_layers_number2=two_dim_layer_->d_layers_number2;//number of layers for the index #2
-
-			d_current_max_ind1=two_dim_layer_->d_current_max_ind1;
-			d_current_max_ind2=two_dim_layer_->d_current_max_ind2;
-
-			d_current_min_ind1=two_dim_layer_->d_current_min_ind1;
-			d_current_min_ind2=two_dim_layer_->d_current_min_ind2;
-
-			d_layers1=NULL;
-			d_layers2=NULL;
-
-			d_null=two_dim_layer_->d_null;
-
-			d_layers1=new T*[d_layers_number1];
-			FSA_utils::assert_mem(d_layers1);
-
-			long int i;
-			for(i=0;i<d_layers_number1;i++)
-			{
-				d_layers1[i]=NULL;
-				d_layers1[i]=new T[d_max_ind2+1];
-				FSA_utils::assert_mem(d_layers1[i]);
-			};
-
-			d_layers2=new T*[d_layers_number2];
-			FSA_utils::assert_mem(d_layers2);
-
-			for(i=0;i<d_layers_number2;i++)
-			{
-				d_layers2[i]=NULL;
-				d_layers2[i]=new T[d_max_ind1+1];
-				FSA_utils::assert_mem(d_layers2[i]);
-			};
-
-			d_layers1_tmp=NULL;
-			d_layers2_tmp=NULL;
-
-			//copying data
-			for(i=0;i<d_layers_number1;i++)
-			{
-				long int j;
-				for(j=0;j<=d_max_ind2;j++)
-				{
-					d_layers1[i][j]=two_dim_layer_->d_layers1[i][j];
-				};
-			};
-
-			for(i=0;i<d_layers_number2;i++)
-			{
-				long int j;
-				for(j=0;j<=d_max_ind1;j++)
-				{
-					d_layers2[i][j]=two_dim_layer_->d_layers2[i][j];
-				};
-			};
-
-		}
-
-		static void copy_2_into_1_two_dim_layer(//copies the layers from the second argument to the first; both objects must be defined and fully functional
-		two_dim_layer *two_dim_layer1_,
-		two_dim_layer *two_dim_layer2_)
-		{
-			if(two_dim_layer1_->d_layers_number1!=two_dim_layer2_->d_layers_number1||
-				two_dim_layer1_->d_layers_number2!=two_dim_layer2_->d_layers_number2)
-			{
-				throw error("Unexpected error - objects have different number of layers in copy_2_into_1_two_dim_layer\n",1);
-			};
-
-			if(two_dim_layer2_->d_max_ind2>two_dim_layer1_->d_max_ind2||
-				two_dim_layer2_->d_max_ind1>two_dim_layer1_->d_max_ind1)
-			{
-				throw error("Unexpected error in copy_2_into_1_two_dim_layer\n",1);
-			};
-
-			two_dim_layer1_->d_current_max_ind1=two_dim_layer2_->d_current_max_ind1;
-			two_dim_layer1_->d_current_max_ind2=two_dim_layer2_->d_current_max_ind2;
-
-			two_dim_layer1_->d_current_min_ind1=two_dim_layer2_->d_current_min_ind1;
-			two_dim_layer1_->d_current_min_ind2=two_dim_layer2_->d_current_min_ind2;
-
-
-			//copying data
-			long int i;
-			for(i=0;i<two_dim_layer2_->d_layers_number1;i++)
-			{
-				long int j;
-				for(j=0;j<=two_dim_layer2_->d_max_ind2;j++)
-				{
-					two_dim_layer1_->d_layers1[i][j]=two_dim_layer2_->d_layers1[i][j];
-				};
-			};
-
-			for(i=0;i<two_dim_layer2_->d_layers_number2;i++)
-			{
-				long int j;
-				for(j=0;j<=two_dim_layer2_->d_max_ind1;j++)
-				{
-					two_dim_layer1_->d_layers2[i][j]=two_dim_layer2_->d_layers2[i][j];
-				};
-			};
-
-		}
-
-
-		~two_dim_layer()
-		{
-			long int i;
-			if(d_layers1)
-			{
-				for(i=0;i<d_layers_number1;i++)
-				{
-					delete[]d_layers1[i];
-				};
-				delete[]d_layers1;
-			};
-
-			if(d_layers2)
-			{
-				for(i=0;i<d_layers_number2;i++)
-				{
-					delete[]d_layers2[i];
-				};
-				delete[]d_layers2;
-			};
-
-			delete[]d_layers1_tmp;
-			delete[]d_layers2_tmp;
-
-		}
-
-		T get_element(
-			long int i1_,
-			long int i2_)
-		{
-			if(d_current_min_ind1<=i1_&&i1_<=d_current_max_ind1&&i2_<=d_current_max_ind2)
-			{
-				long int layer1=i1_-d_current_min_ind1;
-				return d_layers1[layer1][i2_];
-			};
-
-			if(d_current_min_ind2<=i2_&&i2_<=d_current_max_ind2&&i1_<d_current_min_ind1)
-			{
-				long int layer2=i2_-d_current_min_ind2;
-				return d_layers2[layer2][i1_];
-			};
-
-			throw error("Error - element cannot be extracted in two_dim_layer::get_element\n",1);
-
-		}
-
-		void auxiliary_function_for_set_element(
-		long int i1_,
-		long int &current_min_ind1_,
-		long int &current_max_ind1_,
-		long int layers_number1_,
-		T**&layers1_,
-		T**&layers1_tmp_,
-
-		long int current_min_ind2_,
-		long int current_max_ind2_,
-		T**layers2_)
-
-		{
-			if(i1_>current_max_ind1_)
-			{
-				long int current_max_ind1_new=i1_;
-				long int current_min_ind1_new=i1_-layers_number1_+1;
-
-
-				long int i;
-				for(i=current_min_ind1_new;i<=current_max_ind1_;i++)
-				{
-					layers1_tmp_[i-current_min_ind1_new]=layers1_[i-current_min_ind1_];
-				};
-
-				long int ind_st=FSA_utils::Tmax(current_max_ind1_+1,current_min_ind1_new);
-				for(i=ind_st;i<=current_max_ind1_new;i++)
-				{
-					layers1_tmp_[i-current_min_ind1_new]=layers1_[i-ind_st];
-				};
-
-				T**tmp_array=layers1_tmp_;
-				layers1_tmp_=layers1_;
-				layers1_=tmp_array;
-
-				current_min_ind1_=current_min_ind1_new;
-				current_max_ind1_=current_max_ind1_new;
-				
-				return;
-
-			};
-
-			if(i1_<current_min_ind1_)
-			{
-				long int current_min_ind1_new=i1_;
-				long int current_max_ind1_new=i1_+layers_number1_-1;
-
-				long int i;
-				for(i=current_min_ind1_;i<=current_max_ind1_new;i++)
-				{
-					layers1_tmp_[i-current_min_ind1_new]=layers1_[i-current_min_ind1_];
-				};
-
-				long int ind_end=FSA_utils::Tmin(current_max_ind1_new,current_min_ind1_-1);
-				long int ind_tmp=FSA_utils::Tmax(-current_min_ind1_new,layers_number1_-current_min_ind1_);
-
-				for(i=current_min_ind1_new;i<=ind_end;i++)
-				{
-					layers1_tmp_[i-current_min_ind1_new]=layers1_[i+ind_tmp];
-				};
-
-				//transfer values
-				
-				for(i=current_min_ind1_new;i<=ind_end;i++)
-				{
-					long int j;
-					for(j=current_min_ind2_;j<=current_max_ind2_;j++)
-					{
-						layers1_tmp_[i-current_min_ind1_new][j]=layers2_[j-current_min_ind2_][i];
-					};
-				};
-
-
-
-				T**tmp_array=layers1_tmp_;
-				layers1_tmp_=layers1_;
-				layers1_=tmp_array;
-
-				current_min_ind1_=current_min_ind1_new;
-				current_max_ind1_=current_max_ind1_new;
-
-			};
-		}
-
-
-		void set_element(
-			long int i1_,
-			long int i2_,
-			T elem_)
-		{
-			if(i1_>d_max_ind1||i1_<0||i2_>d_max_ind2||i2_<0)
-			{
-				throw error("Error in the parameters i1_, i2_ of two_dim_layer::set_element\n",10);
-			};
-
-			bool success_flag0=false;
-			if(d_current_min_ind1<=i1_&&i1_<=d_current_max_ind1&&i2_<=d_current_max_ind2)
-			{
-				long int layer1=i1_-d_current_min_ind1;
-				d_layers1[layer1][i2_]=elem_;
-				success_flag0=true;
-			};
-
-			if(d_current_min_ind2<=i2_&&i2_<=d_current_max_ind2&&i1_<=d_current_max_ind1)
-			{
-				long int layer2=i2_-d_current_min_ind2;
-				d_layers2[layer2][i1_]=elem_;
-				success_flag0=true;
-			};
-
-			if(success_flag0)
-			{
-				return;
-			};
-
-
-		
-			auxiliary_function_for_set_element(
-			i1_,
-			d_current_min_ind1,
-			d_current_max_ind1,
-			d_layers_number1,
-			d_layers1,
-			d_layers1_tmp,
-			
-			d_current_min_ind2,
-			d_current_max_ind2,
-			d_layers2);
-
-			
-
-			auxiliary_function_for_set_element(
-			i2_,
-			d_current_min_ind2,
-			d_current_max_ind2,
-			d_layers_number2,
-			d_layers2,
-			d_layers2_tmp,
-			
-			d_current_min_ind1,
-			d_current_max_ind1,
-			d_layers1);
-
-
-			
-			bool success_flag=false;
-			if(d_current_min_ind1<=i1_&&i1_<=d_current_max_ind1&&i2_<=d_current_max_ind2)
-			{
-				long int layer1=i1_-d_current_min_ind1;
-				d_layers1[layer1][i2_]=elem_;
-				success_flag=true;
-			};
-
-			if(d_current_min_ind2<=i2_&&i2_<=d_current_max_ind2&&i1_<=d_current_max_ind1)
-			{
-				long int layer2=i2_-d_current_min_ind2;
-				d_layers2[layer2][i1_]=elem_;
-				success_flag=true;
-			};
-
-			if(!success_flag)
-			{
-				throw error("Unexpected error in two_dim_layer::set_element\n",1);
-			};
-			
-
-		}
-
-		void set_max_ind(//if the element (i1_,i2_) is not available, changes the maximum and minimum indexes
-			long int i1_,
-			long int i2_)
-		{
-			bool success_flag=false;
-			if(d_current_min_ind1<=i1_&&i1_<=d_current_max_ind1&&i2_<=d_current_max_ind2)
-			{
-				success_flag=true;
-			};
-
-			if(d_current_min_ind2<=i2_&&i2_<=d_current_max_ind2&&i1_<=d_current_max_ind1)
-			{
-				success_flag=true;
-			};
-
-			if(!success_flag)
-			{
-				set_element(i1_,i2_,d_null);
-			};
-
-
-		}
-
-		public:
-
-		long int d_max_ind1;//max of the index #1
-		long int d_max_ind2;//max of the index #2
-
-		long int d_current_max_ind1;//max of the index #1
-		long int d_current_max_ind2;//max of the index #2
-
-		long int d_current_min_ind1;//max of the index #1
-		long int d_current_min_ind2;//max of the index #2
-
-
-		long int d_layers_number1;//number of layers for the index #1
-		long int d_layers_number2;//number of layers for the index #2
-
-		T **d_layers1;//layers corresponded to the index #1; the dimension is d_layers_number1 x d_max_ind2
-		T **d_layers2;//layers corresponded to the index #2; the dimension is d_layers_number2 x d_max_ind1
-
-		T **d_layers1_tmp;
-		T **d_layers2_tmp;
-
-		T d_null;
-
-
-	};
-
-	template<typename T> class two_dim_layer_alignment_algorithm
-	{//the class is desinged to work with two_dim_layer object
-
-		public:
-
-		typedef void two_dim_layer_alignment_function_type(long int i1_,long int i2_,two_dim_layer_alignment_algorithm<T> *obj_,void*par_);
-			
-		two_dim_layer_alignment_algorithm(
-		long int number_of_variables_,//total number of variables in dynamic equations
-		long int depth1_,//the maximum difference of the first index in the dynamic equations
-		long int depth2_,//the maximum difference of the second index in the dynamic equations
-		long int max_ind1_,//max of the index #1 (minimum index is 0 by default)
-		long int max_ind2_,//max of the index #2 (minimum index is 0 by default)
-		T null_,//null element of T
-		long int *var_num_);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
-
-		two_dim_layer_alignment_algorithm(//used to save data from two_dim_layer_alignment_algorithm_ with minimal memory allocation
-		long int max_ind1_,//max of the index #1
-		long int max_ind2_,//max of the index #2
-		two_dim_layer_alignment_algorithm<T> *two_dim_layer_alignment_algorithm_);
-
-
-		~two_dim_layer_alignment_algorithm();
-
-		void align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
-		//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-		long int target_align1_length_,//target length for the sequence #1
-		long int target_align2_length_);//target length for the sequence #2
-
-		
-		void align_upto_target_lengths_step(//aligns the sequences upto the target sequence lengths including; checks whether the jump exeeds d_step
-		//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
-		long int target_align1_length_,//target length for the sequence #1
-		long int target_align2_length_);//target length for the sequence #2
-
-		void init();//initialization for a new alignment
-
-
-
-
-		public:
-
-		long int d_number_of_variables;//total number of variables in dynamic equations
-		long int d_depth1;//the maximum difference of the first index in the dynamic equations
-		long int d_depth2;//the maximum difference of the second index in the dynamic equations
-		long int *d_var_num;//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
-
-		long int d_max_ind1;//max of the index #1 (minimum index is 0 by default)
-		long int d_max_ind2;//max of the index #2 (minimum index is 0 by default)
-
-		long int d_current_align_ind1;//the alignment is calculated in the rectangle [0,d_current_ind1] x [0,d_current_ind2]
-		long int d_current_align_ind2;
-
-		long int d_step1;//maximum jump in sequence #1 lengths permitted in align_upto_target_lengths_step
-		long int d_step2;//maximum jump in sequence #2 lengths permitted in align_upto_target_lengths_step
-
-		long int d_edge_maximum_calculation_depth1;//the maximum difference of the first index for the edge maximum calculation
-		long int d_edge_maximum_calculation_depth2;//the maximum difference of the second index for the edge maximum calculation
-
-
-		T d_null;//null element
-
-
-		two_dim_layer<T> ** d_vars;//variables; the dimension of the array is d_number_of_variables
-
-		two_dim_layer_alignment_function_type * d_two_dim_layer_alignment_function;//the function used for the alingment
-		two_dim_layer_alignment_function_type * d_two_dim_layer_boundary_function;//the function used for the boundary conditions; must be defined in the rectangle [0,depth1_-1] x [0,depth2_-1]
-
-		void *d_par;//parameters for the last argument void*par_ of functions d_two_dim_layer_boundary_function and d_two_dim_layer_alignment_function
-
-		//statistics
-		//global maximum
-		bool d_M_flag;
-		long int d_M;
-
-		//edge maximum
-		bool d_E_flag;
-		long int d_E;
-
-		bool d_scores_counts_flag;
-		array_v<double> d_scores_counts;
-
-		long int d_M_threshold;
-
-		//FSC parameters
-		bool d_FSC_flag;
-		long int d_distance_along_direction_1;
-		long int d_distance_along_direction_2;
-
-
-
-	};
-
-//-----------------------------------------------------
-
-	class IS1_general_simulation
-	{
-		public:
-		IS1_general_simulation(
-			IS1_general *IS1_general_obj_,
-			long int initial_state_,//initial state for the IS
-			long int max_seq1_length_,//maximum sequence length
-			long int max_seq2_length_,//maximum sequence length
-			double *initial_distr_=NULL);//initial distribution of states; initial_state_ is ignored if d_initial_distr_ is defined
-
-		IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
-		IS1_general_simulation *IS1_general_simulation_);//maximum sequence length
-
-
-		~IS1_general_simulation();
-
-		void init();//initialization for a new sequence generation
-
-		void simulate_upto_target_lengths(
-			long int target_seq1_length_,//target length of the sequence #1
-			long int target_seq2_length_);//target length of the sequence #2
-
-
-		//weights calculation
-		void calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
-			long int target_length1_,//target length for sequence #1
-			long int target_length2_,//target length for sequence #2
-			long int i1_,//the first index (corresponded to the sequence #1)
-			long int i2_);//the second index (corresponded to the sequence #2)
-
-		void calculate_weight_W1_upto_target_lengths(
-			long int target_seq1_length_,//target length of the sequence #1
-			long int target_seq2_length_,//target length of the sequence #2
-			long int seq1_length_tmp_,//the weights are calculated upto this length for the sequence #1
-			long int seq2_length_tmp_);//the weights are calculated upto this length for the sequence #2
-
-
-		void calculate_weight_W1_for_fixed_lengths_using_infinite_sums(
-			long int target_seq1_length_,//target length of the sequence #1
-			long int target_seq2_length_,//target length of the sequence #2
-			double &weight_);//the resulted weight
-
-		void calculate_weight_W1_for_fixed_lengths_using_recursions(
-			long int target_seq1_length_,//target length of the sequence #1
-			long int target_seq2_length_,//target length of the sequence #2
-			double &weight_,//the resulted weight
-			bool save_matrices_=false,
-			std::vector<std::vector<double> > *A1_=NULL,
-			std::vector<std::vector<double> > *A2_=NULL);
-
-
-
-
-
-		public:
-
-		long int d_seq1_current_length;//current length of the sequence #1 simulated using the IS
-		long int d_seq2_current_length;//current length of the sequence #2 simulated using the IS
-
-		long int d_max_seq1_length;//maximum sequence length
-		long int d_max_seq2_length;//maximum sequence length
-
-		long int *d_seq1;
-		long int *d_seq2;
-
-		long int d_initial_state;
-		long int d_current_state;
-		double *d_initial_distr_sum;
-
-		IS1_general *d_IS1_general_obj;
-
-		//weights calculation
-
-		two_dim_layer<double> ** d_W1;//array of pointers to weights; dimention of the array is d_IS1_general_obj->d_number_of_states
-		long int d_W1_seq1_current_length;//current length of the sequence #1 simulated using the IS
-		long int d_W1_seq2_current_length;//current length of the sequence #2 simulated using the IS
-
-		long int d_W1_step1;//increase of number of layers of d_W1 for the index #1
-		long int d_W1_step2;//increase of number of layers of d_W1 for the index #2
-
-
-
-	};
-
-//-------------------------------------------------------------------------------------------
-	//objects for tests
-
-	class test
-	{
-		public:
-
-		struct data_for_lambda_equation//struct for lambda_equation
-		{
-			long int d_number_of_AA;//number of AA
-			long int** d_smatr;//scoring matrix
-			double *d_RR1;//AA probabilities
-			double *d_RR2;//AA probabilities
-		};
-
-		struct data_for_lambda_equation_FSA//struct for lambda_equation_FSA
-		{
-			long int d_number_of_letters1;//number of letters for the sequence #1
-			long int d_number_of_letters2;//number of letters for the sequence #2
-			long int** d_smatr;//scoring matrix
-			double *d_RR1;//nucleotide probabilities
-			double *d_RR2;//AA probabilities
-
-			long int d_codon_length;//codon length 
-			long int *d_codon_AA;//<codon code,AA number>
-
-		};
-
-
-		struct data_for_classical_alignment
-		{
-			long int d_open1;//gap opening penalty for the nucleotide sequence #1
-			long int d_open2;//gap opening penalty for the amino acid sequence #2
-
-			long int d_epen1;//gap extension penalty for the nucleotide sequence #1
-			long int d_epen2;//gap extension penalty for the amino acid sequence #2
-
-			long int**d_smatr;//the scoring matrix
-
-			long int *d_seq1;//sequence #1
-			long int *d_seq2;//sequence #2
-
-		};
-
-		struct data_for_FSA_alignment
-		{
-			long int d_alphabet_letters_number1;//number of letters in the sequence #1
-
-			long int d_open1;//gap opening penalty for the nucleotide sequence #1
-			long int d_open2;//gap opening penalty for the amino acid sequence #2
-
-			long int d_epen1;//gap extension penalty for the nucleotide sequence #1
-			long int d_epen2;//gap extension penalty for the amino acid sequence #2
-
-			long int d_gamma;//frame shift penalty
-
-			long int**d_smatr;//the scoring matrix
-
-			long int *d_seq1;//sequence #1
-			long int *d_seq2;//sequence #2
-
-			long int *d_codon_AA;//<codon code,AA number>
-
-			bool d_insertions_after_deletions;//if true, then insertions after deletions are allowed
-
-			std::string d_alignment_type;//possible values are "global" or "local"
-
-		};
-
-
-		void classical_IS(
-
-		unsigned rand_,//randomization number
-		long int open1_,//gap opening penalty for the nucleotide sequence #1
-		long int open2_,//gap opening penalty for the amino acid sequence #2
-
-		long int epen1_,//gap extension penalty for the nucleotide sequence #1
-		long int epen2_,//gap extension penalty for the amino acid sequence #2
-
-
-		std::string smatr_file_name_,//scoring matrix file name
-		std::string RR1_file_name_,//background frequencies file name for the sequence #1
-		std::string RR2_file_name_);//background frequencies file name for the sequence #2
-
-		//long int seq1_length_,//length of sequence #1
-		//long int seq2_length_,//length of sequence #2
-
-		//long int seq_number_);//number of tested alignments
-
-		static long int realization_number_into_set_number(//numeration of sets starts from 1
-		long int &realization_number_,//realization order number; the numeration starts from 0
-		long int &number_of_realizations_set_);//total number of sets
-
-		static std::pair<long int,long int> set_number_boundaries(//boundaries of realization order numbers for the set; numeration of realizations starts from 0
-		long int &set_number_,//set order number; the numeration starts from 1
-		long int &number_of_realizations_set_);//total number of realizations per set
-
-		static void combine_parameters_from_forward_and_reversed_calculations_generalized(
-		Sls::FALP_set_of_parameters &par_,//parameters from forward calculation
-		Sls::FALP_set_of_parameters &par_reversed_,//parameters from reversed calculation
-		Sls::FALP_set_of_parameters &par_result_);//the result
-
-
-		void input_data_for_the_constructor(
-
-		std::string DNA_codon_table_file_name_,//a name of a file with DNA codon table
-		std::string smatr_file_name_,//scoring matrix file name
-		std::string RR1_file_name_,//probabilities1 file name
-		std::string RR2_file_name_,//probabilities2 file name
-
-		long int &alphabetSize1_,
-		long int &alphabetSize2_,
-		long int **&substitutionScoreMatrix_,
-		double *&letterFreqs1_,
-		double *&letterFreqs2_,
-
-		char *&alphabet1_,//alphabet letters for the sequence #1
-		char *&alphabet2_,//alphabet letters for the sequence #2
-
-		long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-		long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-		long int &codon_length_,//codon length 
-		long int *&codon_AA_);//<codon code,AA number>
-
-		void FSA_IS(
-		//additional parameters for the library code
-		bool library_call_flag_,//if true, then the additional parameters are used
-		long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
-		long aaAlphabetSize_,//a number of letters in the amino acid alphabet; usually 4
-		const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
-		const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
-		const double *ntFreqs_,//background frequencies of letters in DNA sequences
-		const double *aaFreqs_,//background frequencies of letters in amino acid sequences
-		//additional parameters for the library code - end
-
-		long int rand_,//randomization number
-		long int open1_,//gap opening penalty for the nucleotide sequence #1
-		long int open2_,//gap opening penalty for the amino acid sequence #2
-
-		long int epen1_,//gap extension penalty for the nucleotide sequence #1
-		long int epen2_,//gap extension penalty for the amino acid sequence #2
-
-		long int gamma_,//frameshift penalty gamma
-
-
-		std::string smatr_file_name_,//scoring matrix file name
-		std::string RR1_file_name_,//background frequencies file name for the sequence #1
-		std::string RR2_file_name_,//background frequencies file name for the sequence #2
-		std::string DNA_codon_table_file_name_,//a name of a file with DNA codon table
-
-		double eps_lambda_,//relative error for lambda calculation
-		double eps_K_,//relative error for K calculation
-
-		bool gapped_flag_,//if true, then the gapped alingment is performed
-		double max_time_,//maximum allowed calculation time in seconds
-		double max_mem_,//maximum allowed memory usage in MB
-
-		long int seq_number_,//number of tested alignments
-		long int nalp_,//number of ALPs for the calculation
-		long int number_of_subsets_for_errors_calculation_,//number of subsets used for the splitting method
-		bool forward_and_reverse_screen_output_flag_,//determines whether the parameters are outputted for forward and reverse calculations
-		bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
-
-		//for test
-		double mult_for_is_lambda_,//multiplier for lambda in the IS
-
-		//the result
-		Sls::FALP_set_of_parameters &par_result_,//the resulted parameters
-		Sls::par_test1_type *par_test1_=NULL);//for tests
-
-
-
-
-		static void FSA_IS_transition_probabilities_calculation(
-		bool &FSA_flag,
-		double ***&states_distr,
-
-		bool &cs_flag,
-		double ***&states_distr_cs,
-
-		bool &sim_flag,
-		double ***&states_distr_sim,
-
-		long int &number_of_states,
-		long int &alphabet_letters_number1,
-		long int &alphabet_letters_number2,
-		std::pair<long int, long int> *&states_description,
-		long int &codon_length,
-		long int *&codon_AA,
-		double *&RR1,
-		double *&RR2,
-		std::map<std::string, long int> &state_name_into_number,
-		long int **&smatr,
-		double &ungappedlambda);
-
-
-		static void calculate_ungapped_lambda(
-		long int number_of_AA_,
-		double *RR1_,
-		double *RR2_,
-		long int**smatr_,
-		double &ungapped_lambda_);
-
-		static void calculate_ungapped_lambda_general(
-		function_type *func_,
-		void* func_pointer_,
-		double &ungapped_lambda_);
-
-
-
-
-		static double lambda_equation(double x_,void* func_number_);
-		static double lambda_equation_FSA(double x_,void* func_number_);
-
-		static void two_dim_layer_alignment_function_classical_global(
-			//function for global classical alignment
-			long int i1_,
-			long int i2_,
-			two_dim_layer_alignment_algorithm<long int> *obj_,
-			void*par_);
-
-		static void two_dim_layer_alignment_function_FSA(//function for the FSA a1-alignment
-			long int i1_,
-			long int i2_,
-			two_dim_layer_alignment_algorithm<long int> *obj_,
-			void*par_);
-
-		static void collect_and_output_M_distr_upto_fixed_lengths(
-			long int number_of_realizations_,
-			std::string M_distr_file_name_,
-			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-			IS1_general_simulation &IS1_general_simulation_test_,
-			long int target_seq1_length_,//target length of the sequence #1
-			long int target_seq2_length_);//target length of the sequence #2
-
-		static void collect_and_output_E_distr_upto_fixed_ALP(
-			long int number_of_realizations_,
-			std::string E_distr_file_name_,
-			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-			IS1_general_simulation &IS1_general_simulation_test_,
-			long int target_ALP_,//target ALP number
-			double ungapped_lambda_,
-			long int limit2_,
-			long int number_of_sets_,//number of sets for error calculation
-			Sls::FALP_set_of_parameters &par_,
-			bool screen_output_flag_,
-
-			bool futher_expanding_=false,
-			IS1_general *IS1_general_cs_=NULL,
-			double *eps_K_=NULL,//relative error for K
-			long int *number_of_cs_steps_for_expanding_=NULL);
-
-		static void delete_mult_states_type(
-			mult_states_type *&states_old1);
-
-		static void restore_arrays(
-			long int k_,
-			mult_states_type *states_old_,
-			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-			IS1_general_simulation &IS1_general_simulation_test_);
-
-		static void restore_arrays(
-			two_dim_layer_alignment_algorithm<long int> *two_dim_layer_alignment_algorithm_test_from_,
-			IS1_general_simulation *IS1_general_simulation_test_from_,
-			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-			IS1_general_simulation &IS1_general_simulation_test_);
-
-		static void compare_mult_states(
-			mult_states_type *states_old_,
-			mult_states_type *states_new_);
-
-
-
-		static void collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
-			bool compute_allocated_memory_flag_,//if true then total allocated memory is computed in allocated_memory_
-			double &allocated_memory_,
-
-
-			long int number_of_realizations_,
-			std::string E_distr_file_name_,
-			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-			IS1_general_simulation &IS1_general_simulation_test_,
-			long int target_ALP_,//target ALP number
-			double ungapped_lambda_,
-			long int limit2_,
-			long int number_of_sets_,//number of sets for error calculation
-			Sls::FALP_set_of_parameters &par_,
-			bool &inside_simulation_flag_,
-			bool screen_output_flag_,
-			bool screen_output_k_flag_,
-
-			double ending_time_,
-			bool &stopped_by_ending_time_flag_,
-			long int &number_of_realizations_with_ending_time_,
-
-			double ending_time_to_test_logarithmic_regime_,
-			
-			bool save_states_flag_,
-			mult_states_type *states_old_,//NULL or defined
-			mult_states_type *&states_new_,//resulted value
-			long int &M_thr_estimation_,//average score threshold corresponded to target_ALP_
-
-
-			bool futher_expanding_=false,
-			long int M_thr_=-inf,//the expanding starts from the ALP with the score >=M_thr_; used if >=0
-			IS1_general *IS1_general_cs_=NULL,
-			double *eps_K_=NULL,//relative error for K
-			long int *number_of_cs_steps_for_expanding_=NULL,
-			bool parameters_are_not_calculated_=false);
-
-		static void FSA_Align(
-
-			long int open1_,//gap opening penalty for the nucleotide sequence #1
-			long int open2_,//gap opening penalty for the amino acid sequence #2
-
-			long int epen1_,//gap extension penalty for the nucleotide sequence #1
-			long int epen2_,//gap extension penalty for the amino acid sequence #2
-
-			long int gamma_,//frameshift penalty gamma
-
-			std::string smatr_file_name_,//scoring matrix file name
-			std::string DNA_codon_table_file_name_,//a name of a file with DNA codon table
-
-			bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
-
-			std::string input_sequences_,//name of file with sequences for alignment (align mode)
-			std::string output_sequences_,//name of output file with alignment scores (align mode)
-			std::string gumbelparin_file_name_);//Gumbel parameters input file name
-
-
-		static void compare_direct_and_reverse_sampling(
-			long int number_of_realizations_,
-			long int seq2_length_,
-			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
-			IS1_general_simulation &IS1_general_simulation_test_,
-			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_reverse_,
-			IS1_general_simulation &IS1_general_simulation_test_reverse_,
-			IS1_general *IS1_general_cs_);
-
-
-
-		static void normalize_state_distributions(
-			long int alphabet_letters_number1_,//number of letters in the sequence #1
-			long int alphabet_letters_number2_,//number of letters in the sequence #2
-
-			long int number_of_states_,//number of states
-
-			std::pair<long int, long int> *states_description_,//description of the states; the index is a state number
-			double ***states_distr_);//distributions of the states; the index is a state number
-
-
-
-
-
-		public:
-
-
-		long int **d_alignment_matr;
-
-		IS1_general* d_IS1;
-
-		IS1_general_simulation *d_IS1_general_simulation;
-
-
-	};
-
-
-
-
-}
-
-#endif // GUMBEL_FSA1
-
+#ifndef GUMBEL_FSA1
+#define GUMBEL_FSA1
+
+/* $Id: $
+* ===========================================================================
+*
+*							PUBLIC DOMAIN NOTICE
+*			   National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_fsa1.hpp
+
+Author: Sergey Sheetlin
+
+Contents: Frameshift alignment algorithms 
+
+******************************************************************************/
+
+#include "sls_alp_regression.hpp"
+#include "sls_fsa1_utils.hpp"
+#include "sls_fsa1_parameters.hpp"
+#include "sls_fsa1_pvalues.hpp"
+
+#include "njn_localmaxstatmatrix.hpp"
+#include "njn_localmaxstatutil.hpp"
+
+#include "sls_fsa1_utils.hpp"
+
+const double mb_bytes=1048576.0;
+
+namespace Sls 
+{
+	const long int inf=LONG_MAX/10;
+
+	class IS1_general_simulation;
+	template<typename T> class two_dim_layer_alignment_algorithm;
+
+	struct par_test1_type
+	{
+		std::string d_gumbelparout_file_name;
+		long int d_seqlen1;
+		long int d_seqlen2;
+	};
+
+	
+	struct state_type
+	{
+		long int d_ALP_number;//number of ALPs simulated
+
+		array_positive<long int> *d_M_array;//global maximum corresponded to the ALP
+		array_positive<long int> *d_seq1_length_array;//length of sequence #1 corresponded to the ALP
+		array_positive<long int> *d_seq2_length_array;//length of sequence #2 corresponded to the ALP
+		array_positive<long int> *d_distance_along_direction_1_array;
+		array_positive<long int> *d_distance_along_direction_2_array;
+		array_positive<double> *d_ALP_weights_array;//IS weigths for the ALP points; dimension of the array is d_ALP_number+1
+
+
+
+		IS1_general_simulation *d_IS1_general_simulation;
+		two_dim_layer_alignment_algorithm<long int> *d_two_dim_layer_alignment_algorithm;
+
+		//for matrix expanding
+		bool d_expanding_finished_flag;
+		long int d_seq1_length_after_expanding;
+		long int d_seq2_length_after_expanding;
+		long int d_M_after_expanding;
+		array_v<double> d_scores_counts_after_expanding;
+
+
+		state_type()
+		{
+			d_M_array=NULL;
+			d_seq1_length_array=NULL;
+			d_seq2_length_array=NULL;
+			d_distance_along_direction_1_array=NULL;
+			d_distance_along_direction_2_array=NULL;
+			d_ALP_weights_array=NULL;
+
+		}
+	};
+
+	struct mult_states_type
+	{
+		long int d_number_of_realizations;
+		long int d_number_of_ALP;
+
+		double d_total_calculation_time;//time in seconds; includes information from the old object
+
+		double d_average_ALP_pos1_mult_ALP_pos2;//average of d_average_ALP_pos1*d_average_ALP_pos2
+		double d_average_ALP_pos1;//average of ALP position for the sequence #1
+		double d_average_ALP_pos2;//average of ALP position for the sequence #2
+		double d_average_expanding_length1;//average length of crude sampling expansion for the sequence #1
+		double d_average_expanding_length2;//average length of crude sampling expansion for the sequence #2
+		double d_average_expanding_length1_mult_expanding_length2;//average of d_average_expanding_length1*d_average_expanding_length2
+
+		//long long d_total_number_of_ALP_cells;
+		//long long d_total_number_of_exp_cells;
+
+		double d_total_number_of_ALP_cells;
+		double d_total_number_of_exp_cells;
+
+		long int d_total_number_of_ALPs;
+
+
+		
+
+		state_type *d_states;//dimension of the array is d_number_of_realizations
+
+		mult_states_type()
+		{
+			d_states=NULL;
+			d_number_of_realizations=-1;
+		}
+	};
+
+
+	class FSA;
+	class FSA_utils;
+
+
+
+	class FSA
+	{
+		public:
+
+		typedef void alignment_function_type(long int *seq1_,long int *seq2_,FSA *FAS_object_,void*par_);
+		struct struct_for_alignment
+		{
+			long int d_score;//alignment score
+		};
+
+
+
+
+		FSA(//constructor
+
+		bool reversed_seq_,//whether the sequences are reversed or not
+		std::string alignment_type_,//type of alignment; possible values "local", "global"
+
+		long int rand_,//randomization number
+		long int open1_,//gap opening penalty for the nucleotide sequence #1
+		long int open2_,//gap opening penalty for the amino acid sequence #2
+
+		long int epen1_,//gap extension penalty for the nucleotide sequence #1
+		long int epen2_,//gap extension penalty for the amino acid sequence #2
+
+		long int gamma_,//frameshift penalty gamma
+
+		std::string smatr_file_name_,//scoring matrix file name
+		std::string RR1_file_name_,//background frequencies file name for the sequence #1
+		std::string RR2_file_name_,//background frequencies file name for the sequence #2
+		std::string DNA_codon_table_file_name_,//a name of a file with DNA codon table
+		long int seq1_length_,//length of sequence #1
+		long int seq2_length_,//length of sequence #2
+		long int seq_number_);//number of tested alignments
+
+		~FSA();
+
+
+
+		long int random_AA1();
+
+		long int random_AA2();
+
+		long int convert_codon_into_AA(//returns AA corresponded to the codon
+		long int *codon_);
+
+		static void classical_global_alignment(
+		long int *seq1_,//sequence #1
+		long int *seq2_,//sequence #2
+		FSA *FAS_object_,//a pointer to FSA object
+		void*par_);//additonal parameters
+
+		static void a1_global_alignment(
+		long int *seq1_,//sequence #1
+		long int *seq2_,//sequence #2
+		FSA *FAS_object_,//a pointer to FSA object
+		void*par_);//additonal parameters
+
+		void DNA_AA_global(
+		std::string distr_file_name_,
+		alignment_function_type *alignment_function_);
+
+		void AA_AA_global(
+		std::string distr_file_name_,
+		alignment_function_type *alignment_function_);
+
+		void DNA_to_3_frames_AA_global(
+		std::string distr_file_name_,
+		alignment_function_type *alignment_function_);
+
+
+
+
+		public:
+
+		
+		//input parameters
+
+		bool d_reversed_seq;//whether the sequences are reversed or not
+		std::string d_alignment_type;//type of alignment; possible values "local", "global"
+
+		long int d_open1;//gap opening penalty for the nucleotide sequence #1
+		long int d_open2;//gap opening penalty for the amino acid sequence #2
+
+
+		long int d_epen1;//gap extension penalty for the nucleotide sequence #1
+		long int d_epen2;//gap extension penalty for the amino acid sequence #2
+
+		long int d_gamma;//frameshift penalty gamma
+
+
+		double d_max_time;//maximum allowed calculation time in seconds
+		double d_max_mem;//maximum allowed memory usage in MB
+		double d_memory_size_in_MB;//current allocated memory size
+
+
+		
+		//additional parameters
+
+		long int d_number_of_letters1;//number of letters for the sequence 1
+		long int d_number_of_letters2;//number of letters for the sequence 2
+
+		char *d_alphabet1;//alphabet letters for the sequence #1
+		char *d_alphabet2;//alphabet letters for the sequence #2
+
+		long int *d_alphabet1_to_long;//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+		long int *d_alphabet2_to_long;//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+
+		long int** d_smatr;//scoring matrix
+
+		double *d_RR1;//nucleotide probabilities
+		double *d_RR1_sum;//probability distribution function for d_RR1
+		long int *d_RR1_sum_elements;//numbers of nucleotide corresponded to d_RR1
+
+		double *d_RR2;//AA probabilities
+		double *d_RR2_sum;//probability distribution function for d_RR2
+		long int *d_RR2_sum_elements;//numbers of AA corresponded to d_RR2
+
+		long int d_seq1_length;//length of sequence #1
+		long int d_seq2_length;//length of sequence #2
+		long int d_seq_number;//number of tested alignments
+
+		long int d_codon_length;//codon length 
+		long int *d_codon_AA;//<codon code,AA number>
+
+		bool d_rand_flag;
+		long int d_random_factor;
+
+		//temporary arrays for alignments
+		long int **d_S_a1;
+		long int **d_I_a1;
+		long int **d_D_a1;
+
+		long int *d_seq1;
+		long int *d_seq2;
+
+	};
+
+	class IS1_general
+	{
+
+		public:
+
+		IS1_general(
+		long int alphabet_letters_number1_,//number of letters in the sequence #1
+		long int alphabet_letters_number2_,//number of letters in the sequence #2
+		double *RR1_,//background probability for the sequence #1
+		double *RR2_,//background probability for the sequence #2
+		long int number_of_states_,//number of states
+		double **transition_probabilities_,//transition probabilities between states; matrix d_number_of_states x d_number_of_states
+		std::pair<long int, long int> *states_description_,//description of the states; the index is a state number
+		double ***states_distr_);//distributions of the states; the first index is a state number
+								//the second and the third indexes correspond to an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+
+		~IS1_general();
+		
+		static long int letters_to_code(//returns a unique code for the array of letters
+		long int letters_number_,//total number of letters
+		long int letters_dim_,//dimension of the array with letters
+		long int*letters_);//array of letters
+		
+
+		static void code_to_letters(//returns a unique code for the array of letters
+		long int code_,//input code
+		long int letters_number_,//total number of letters
+		long int letters_dim_,//dimension of the array with letters
+		long int*letters_);//array of letters; the result
+		
+		static long int matr_indexes_to_code(
+		long int code1_,//code #1
+		long int code1_number_,//the range of code1_ is [0,code1_number_-1]
+		long int code2_,//code #2
+		long int code2_number_);//the range of code2_ is [0,code2_number_-1]
+
+		static void code_to_matr_indexes(
+		long int code_,//input code
+		long int &code1_,//code #1; the result
+		long int code1_number_,//the range of code1_ is [0,code1_number_-1]
+		long int &code2_,//code #2; the result
+		long int code2_number_);//the range of code2_ is [0,code2_number_-1]
+
+		static double ** allocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+			long int alphabet_letters_number1_,//number of letters in the sequence #1
+			long int alphabet_letters_number2_,//number of letters in the sequence #2
+			std::pair<long int, long int> state_description_);//state description
+
+		static void deallocate_state_distribution(//allocates an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+			double **&state_distr_,
+			long int alphabet_letters_number1_,//number of letters in the sequence #1
+			std::pair<long int, long int> state_description_);//state description
+
+		static void generate_one_state_sum_distr(//calculates sum-distributions corresponded to the input parameters
+			std::pair<long int, long int> state_distr_dims_,//dimensions of the matrix state_distr_
+			double **state_distr_,//state distribution in the same format as in d_states_distr[s]
+			double *&state_sum_distr_);//the result; the dimention is state_distr__dim1 x state_distr__dim2
+
+		void generate_random_letters_in_a_given_state(
+			long int state_number_,//state number
+			long int *letters1_,//the resulted letters for the sequence 1; the array must be allocated
+			long int *letters2_);//the resulted letters for the sequence 2; the array must be allocated
+
+		void one_step_of_the_importance_samping(//an initial state when sequences are empty must be defined outside
+		long int current_state_,//the current state
+		long int *seq1_add_letters_,//letters for the sequence #1; the array must be allocated
+		long int *seq2_add_letters_,//letters for the sequence #2; the array must be allocated
+		long int &new_state_);//a new state
+
+		void allocate_states_distr_sums();//allocates d_states_distr_sums
+		void deallocate_states_distr_sums();//deallocates d_states_distr_sums
+
+		void calculate_inverse_matrices_for_the_infinite_sums(
+			long int code1_,
+			long int code2_,
+			std::vector<std::vector<double> > *A1_inv_,
+			std::vector<std::vector<double> > *A2_inv_,
+			long int x1_,
+			long int x2_);
+
+
+			
+		public:
+
+		long int d_alphabet_letters_number1;//number of letters in the sequence #1
+		long int d_alphabet_letters_number2;//number of letters in the sequence #2
+
+		double *d_RR1;//background probability for the sequence #1
+		double *d_RR2;//background probability for the sequence #2
+
+		long int d_number_of_states;//number of states
+		double **d_transition_probabilities;//transition probabilities between states; matrix d_number_of_states x d_number_of_states
+
+		double **d_transition_probabilities_sum;//sum-distributions calculated from d_transition_probabilities[s]
+
+		std::pair<long int, long int> *d_states_description;//description of the states; the index is a state number
+		//.first: number of letters generated for the sequence #1
+		//.second: number of letters generated for the sequence #2
+
+		double ***d_states_distr;//distributions of the states; the first index is a state number
+								//the second and the third indexes correspond to an array of dimensions d_A_letters^state_description_type.first x d_B_letters^state_description_type.second
+
+		double *****d_states_distr_sums;//distributions of the sums for d_states_distr; the first index is a state number
+		//the second and the third indexes are number of letters retained for the first (x1) and the second (x2) sequence respectively
+		//x1=0..state_description_type.first; x2=0..state_description_type.second
+		//d_states_distr_sums[s][x1][x2] is the distribution and has the dimension d_A_letters^x1 x d_B_letters^x2
+
+		std::vector<std::vector<double> > d_A1_inv;
+		std::vector<std::vector<double> > d_A2_inv;
+		//the second index is x1 and x2 respectively; the third index is the code; 
+		//x1=0..state_description_type.first; x2=0..state_description_type.second
+		//the dimentions of the array d_A1_inv[s][x1] is d_A_letters^x1
+		//the dimentions of the array d_A2_inv[s][x2] is d_B_letters^x2
+
+
+		//calculated values
+		std::pair<long int, long int> *d_states_distr_dimensions;//contains dimensions of the matrix d_states_distr[s], s=0,...,d_number_of_states
+
+		double **d_states_sum_distr;//sum-distributions calculated from d_states_distr
+		long int *d_states_sum_distr_elements_for_all_states;//an array of with numbers 0,1,2,...
+		//can be used for d_states_sum_distr[s] or d_transition_probabilities_sum
+
+		std::pair<long int*, long int*> *d_tmp_letters;//an auxiliary array of length d_number_of_states; 
+												//element #s contains arrays of dimensions <d_states_description[s].first,d_states_description[s].second>
+
+		long int d_max_dim1;//maximum of d_states_description[s].first
+		long int d_max_dim2;//maximum of d_states_description[s].second
+
+	};
+
+	template<typename T> class two_dim_layer
+	{
+		public:
+
+		two_dim_layer(//constructor
+		long int max_ind1_,//max of the index #1 (minimum index is 0 by default)
+		long int max_ind2_,//max of the index #2 (minimum index is 0 by default)
+
+		long int layers_number1_,//number of layers for the index #1
+		long int layers_number2_,//number of layers for the index #2
+
+		T null_)
+		{
+			if(max_ind1_<=0||max_ind2_<=0||layers_number1_<=0||layers_number2_<=0)
+			{
+				throw error("Error - parameters of two_dim_layer::two_dim_layer must be positive\n",1);
+			};
+
+			if(layers_number1_-1>max_ind2_)
+			{
+				throw error("Error - layers_number1_-1>max_ind2_ in two_dim_layer::two_dim_layer\n",1);
+			};
+
+			if(layers_number2_-1>max_ind1_)
+			{
+				throw error("Error - layers_number2_-1>max_ind1_ in two_dim_layer::two_dim_layer\n",1);
+			};
+
+			d_max_ind1=max_ind1_;//max of the index #1
+			d_max_ind2=max_ind2_;//max of the index #2
+
+			d_layers_number1=layers_number1_;//number of layers for the index #1
+			d_layers_number2=layers_number2_;//number of layers for the index #2
+
+			d_current_max_ind1=layers_number1_-1;
+			d_current_max_ind2=layers_number2_-1;
+
+			d_current_min_ind1=0;
+			d_current_min_ind2=0;
+
+			d_layers1=NULL;
+			d_layers2=NULL;
+
+			d_null=null_;
+
+			d_layers1=new T*[d_layers_number1];
+			FSA_utils::assert_mem(d_layers1);
+
+			long int i;
+			for(i=0;i<d_layers_number1;i++)
+			{
+				d_layers1[i]=NULL;
+				d_layers1[i]=new T[d_max_ind2+1];
+				FSA_utils::assert_mem(d_layers1[i]);
+			};
+
+			d_layers2=new T*[d_layers_number2];
+			FSA_utils::assert_mem(d_layers2);
+
+			for(i=0;i<d_layers_number2;i++)
+			{
+				d_layers2[i]=NULL;
+				d_layers2[i]=new T[d_max_ind1+1];
+				FSA_utils::assert_mem(d_layers2[i]);
+			};
+
+			d_layers1_tmp=NULL;
+			d_layers1_tmp=new T*[d_layers_number1];
+			FSA_utils::assert_mem(d_layers1_tmp);
+
+			d_layers2_tmp=NULL;
+			d_layers2_tmp=new T*[d_layers_number2];
+			FSA_utils::assert_mem(d_layers2_tmp);
+
+		}
+
+		two_dim_layer(//constructor; copies data from two_dim_layer_ with minimally allocated memory
+		long int max_ind1_,
+		long int max_ind2_,
+		two_dim_layer *two_dim_layer_)
+		{
+
+			d_max_ind1=max_ind1_;//max of the index #1
+			d_max_ind2=max_ind2_;//max of the index #2
+
+			d_layers_number1=two_dim_layer_->d_layers_number1;//number of layers for the index #1
+			d_layers_number2=two_dim_layer_->d_layers_number2;//number of layers for the index #2
+
+			d_current_max_ind1=two_dim_layer_->d_current_max_ind1;
+			d_current_max_ind2=two_dim_layer_->d_current_max_ind2;
+
+			d_current_min_ind1=two_dim_layer_->d_current_min_ind1;
+			d_current_min_ind2=two_dim_layer_->d_current_min_ind2;
+
+			d_layers1=NULL;
+			d_layers2=NULL;
+
+			d_null=two_dim_layer_->d_null;
+
+			d_layers1=new T*[d_layers_number1];
+			FSA_utils::assert_mem(d_layers1);
+
+			long int i;
+			for(i=0;i<d_layers_number1;i++)
+			{
+				d_layers1[i]=NULL;
+				d_layers1[i]=new T[d_max_ind2+1];
+				FSA_utils::assert_mem(d_layers1[i]);
+			};
+
+			d_layers2=new T*[d_layers_number2];
+			FSA_utils::assert_mem(d_layers2);
+
+			for(i=0;i<d_layers_number2;i++)
+			{
+				d_layers2[i]=NULL;
+				d_layers2[i]=new T[d_max_ind1+1];
+				FSA_utils::assert_mem(d_layers2[i]);
+			};
+
+			d_layers1_tmp=NULL;
+			d_layers2_tmp=NULL;
+
+			//copying data
+			for(i=0;i<d_layers_number1;i++)
+			{
+				long int j;
+				for(j=0;j<=d_max_ind2;j++)
+				{
+					d_layers1[i][j]=two_dim_layer_->d_layers1[i][j];
+				};
+			};
+
+			for(i=0;i<d_layers_number2;i++)
+			{
+				long int j;
+				for(j=0;j<=d_max_ind1;j++)
+				{
+					d_layers2[i][j]=two_dim_layer_->d_layers2[i][j];
+				};
+			};
+
+		}
+
+		static void copy_2_into_1_two_dim_layer(//copies the layers from the second argument to the first; both objects must be defined and fully functional
+		two_dim_layer *two_dim_layer1_,
+		two_dim_layer *two_dim_layer2_)
+		{
+			if(two_dim_layer1_->d_layers_number1!=two_dim_layer2_->d_layers_number1||
+				two_dim_layer1_->d_layers_number2!=two_dim_layer2_->d_layers_number2)
+			{
+				throw error("Unexpected error - objects have different number of layers in copy_2_into_1_two_dim_layer\n",1);
+			};
+
+			if(two_dim_layer2_->d_max_ind2>two_dim_layer1_->d_max_ind2||
+				two_dim_layer2_->d_max_ind1>two_dim_layer1_->d_max_ind1)
+			{
+				throw error("Unexpected error in copy_2_into_1_two_dim_layer\n",1);
+			};
+
+			two_dim_layer1_->d_current_max_ind1=two_dim_layer2_->d_current_max_ind1;
+			two_dim_layer1_->d_current_max_ind2=two_dim_layer2_->d_current_max_ind2;
+
+			two_dim_layer1_->d_current_min_ind1=two_dim_layer2_->d_current_min_ind1;
+			two_dim_layer1_->d_current_min_ind2=two_dim_layer2_->d_current_min_ind2;
+
+
+			//copying data
+			long int i;
+			for(i=0;i<two_dim_layer2_->d_layers_number1;i++)
+			{
+				long int j;
+				for(j=0;j<=two_dim_layer2_->d_max_ind2;j++)
+				{
+					two_dim_layer1_->d_layers1[i][j]=two_dim_layer2_->d_layers1[i][j];
+				};
+			};
+
+			for(i=0;i<two_dim_layer2_->d_layers_number2;i++)
+			{
+				long int j;
+				for(j=0;j<=two_dim_layer2_->d_max_ind1;j++)
+				{
+					two_dim_layer1_->d_layers2[i][j]=two_dim_layer2_->d_layers2[i][j];
+				};
+			};
+
+		}
+
+
+		~two_dim_layer()
+		{
+			long int i;
+			if(d_layers1)
+			{
+				for(i=0;i<d_layers_number1;i++)
+				{
+					delete[]d_layers1[i];
+				};
+				delete[]d_layers1;
+			};
+
+			if(d_layers2)
+			{
+				for(i=0;i<d_layers_number2;i++)
+				{
+					delete[]d_layers2[i];
+				};
+				delete[]d_layers2;
+			};
+
+			delete[]d_layers1_tmp;
+			delete[]d_layers2_tmp;
+
+		}
+
+		T get_element(
+			long int i1_,
+			long int i2_)
+		{
+			if(d_current_min_ind1<=i1_&&i1_<=d_current_max_ind1&&i2_<=d_current_max_ind2)
+			{
+				long int layer1=i1_-d_current_min_ind1;
+				return d_layers1[layer1][i2_];
+			};
+
+			if(d_current_min_ind2<=i2_&&i2_<=d_current_max_ind2&&i1_<d_current_min_ind1)
+			{
+				long int layer2=i2_-d_current_min_ind2;
+				return d_layers2[layer2][i1_];
+			};
+
+			throw error("Error - element cannot be extracted in two_dim_layer::get_element\n",1);
+
+		}
+
+		void auxiliary_function_for_set_element(
+		long int i1_,
+		long int &current_min_ind1_,
+		long int &current_max_ind1_,
+		long int layers_number1_,
+		T**&layers1_,
+		T**&layers1_tmp_,
+
+		long int current_min_ind2_,
+		long int current_max_ind2_,
+		T**layers2_)
+
+		{
+			if(i1_>current_max_ind1_)
+			{
+				long int current_max_ind1_new=i1_;
+				long int current_min_ind1_new=i1_-layers_number1_+1;
+
+
+				long int i;
+				for(i=current_min_ind1_new;i<=current_max_ind1_;i++)
+				{
+					layers1_tmp_[i-current_min_ind1_new]=layers1_[i-current_min_ind1_];
+				};
+
+				long int ind_st=FSA_utils::Tmax(current_max_ind1_+1,current_min_ind1_new);
+				for(i=ind_st;i<=current_max_ind1_new;i++)
+				{
+					layers1_tmp_[i-current_min_ind1_new]=layers1_[i-ind_st];
+				};
+
+				T**tmp_array=layers1_tmp_;
+				layers1_tmp_=layers1_;
+				layers1_=tmp_array;
+
+				current_min_ind1_=current_min_ind1_new;
+				current_max_ind1_=current_max_ind1_new;
+				
+				return;
+
+			};
+
+			if(i1_<current_min_ind1_)
+			{
+				long int current_min_ind1_new=i1_;
+				long int current_max_ind1_new=i1_+layers_number1_-1;
+
+				long int i;
+				for(i=current_min_ind1_;i<=current_max_ind1_new;i++)
+				{
+					layers1_tmp_[i-current_min_ind1_new]=layers1_[i-current_min_ind1_];
+				};
+
+				long int ind_end=FSA_utils::Tmin(current_max_ind1_new,current_min_ind1_-1);
+				long int ind_tmp=FSA_utils::Tmax(-current_min_ind1_new,layers_number1_-current_min_ind1_);
+
+				for(i=current_min_ind1_new;i<=ind_end;i++)
+				{
+					layers1_tmp_[i-current_min_ind1_new]=layers1_[i+ind_tmp];
+				};
+
+				//transfer values
+				
+				for(i=current_min_ind1_new;i<=ind_end;i++)
+				{
+					long int j;
+					for(j=current_min_ind2_;j<=current_max_ind2_;j++)
+					{
+						layers1_tmp_[i-current_min_ind1_new][j]=layers2_[j-current_min_ind2_][i];
+					};
+				};
+
+
+
+				T**tmp_array=layers1_tmp_;
+				layers1_tmp_=layers1_;
+				layers1_=tmp_array;
+
+				current_min_ind1_=current_min_ind1_new;
+				current_max_ind1_=current_max_ind1_new;
+
+			};
+		}
+
+
+		void set_element(
+			long int i1_,
+			long int i2_,
+			T elem_)
+		{
+			if(i1_>d_max_ind1||i1_<0||i2_>d_max_ind2||i2_<0)
+			{
+				throw error("Error in the parameters i1_, i2_ of two_dim_layer::set_element\n",10);
+			};
+
+			bool success_flag0=false;
+			if(d_current_min_ind1<=i1_&&i1_<=d_current_max_ind1&&i2_<=d_current_max_ind2)
+			{
+				long int layer1=i1_-d_current_min_ind1;
+				d_layers1[layer1][i2_]=elem_;
+				success_flag0=true;
+			};
+
+			if(d_current_min_ind2<=i2_&&i2_<=d_current_max_ind2&&i1_<=d_current_max_ind1)
+			{
+				long int layer2=i2_-d_current_min_ind2;
+				d_layers2[layer2][i1_]=elem_;
+				success_flag0=true;
+			};
+
+			if(success_flag0)
+			{
+				return;
+			};
+
+
+		
+			auxiliary_function_for_set_element(
+			i1_,
+			d_current_min_ind1,
+			d_current_max_ind1,
+			d_layers_number1,
+			d_layers1,
+			d_layers1_tmp,
+			
+			d_current_min_ind2,
+			d_current_max_ind2,
+			d_layers2);
+
+			
+
+			auxiliary_function_for_set_element(
+			i2_,
+			d_current_min_ind2,
+			d_current_max_ind2,
+			d_layers_number2,
+			d_layers2,
+			d_layers2_tmp,
+			
+			d_current_min_ind1,
+			d_current_max_ind1,
+			d_layers1);
+
+
+			
+			bool success_flag=false;
+			if(d_current_min_ind1<=i1_&&i1_<=d_current_max_ind1&&i2_<=d_current_max_ind2)
+			{
+				long int layer1=i1_-d_current_min_ind1;
+				d_layers1[layer1][i2_]=elem_;
+				success_flag=true;
+			};
+
+			if(d_current_min_ind2<=i2_&&i2_<=d_current_max_ind2&&i1_<=d_current_max_ind1)
+			{
+				long int layer2=i2_-d_current_min_ind2;
+				d_layers2[layer2][i1_]=elem_;
+				success_flag=true;
+			};
+
+			if(!success_flag)
+			{
+				throw error("Unexpected error in two_dim_layer::set_element\n",1);
+			};
+			
+
+		}
+
+		void set_max_ind(//if the element (i1_,i2_) is not available, changes the maximum and minimum indexes
+			long int i1_,
+			long int i2_)
+		{
+			bool success_flag=false;
+			if(d_current_min_ind1<=i1_&&i1_<=d_current_max_ind1&&i2_<=d_current_max_ind2)
+			{
+				success_flag=true;
+			};
+
+			if(d_current_min_ind2<=i2_&&i2_<=d_current_max_ind2&&i1_<=d_current_max_ind1)
+			{
+				success_flag=true;
+			};
+
+			if(!success_flag)
+			{
+				set_element(i1_,i2_,d_null);
+			};
+
+
+		}
+
+		public:
+
+		long int d_max_ind1;//max of the index #1
+		long int d_max_ind2;//max of the index #2
+
+		long int d_current_max_ind1;//max of the index #1
+		long int d_current_max_ind2;//max of the index #2
+
+		long int d_current_min_ind1;//max of the index #1
+		long int d_current_min_ind2;//max of the index #2
+
+
+		long int d_layers_number1;//number of layers for the index #1
+		long int d_layers_number2;//number of layers for the index #2
+
+		T **d_layers1;//layers corresponded to the index #1; the dimension is d_layers_number1 x d_max_ind2
+		T **d_layers2;//layers corresponded to the index #2; the dimension is d_layers_number2 x d_max_ind1
+
+		T **d_layers1_tmp;
+		T **d_layers2_tmp;
+
+		T d_null;
+
+
+	};
+
+	template<typename T> class two_dim_layer_alignment_algorithm
+	{//the class is desinged to work with two_dim_layer object
+
+		public:
+
+		typedef void two_dim_layer_alignment_function_type(long int i1_,long int i2_,two_dim_layer_alignment_algorithm<T> *obj_,void*par_);
+			
+		two_dim_layer_alignment_algorithm(
+		long int number_of_variables_,//total number of variables in dynamic equations
+		long int depth1_,//the maximum difference of the first index in the dynamic equations
+		long int depth2_,//the maximum difference of the second index in the dynamic equations
+		long int max_ind1_,//max of the index #1 (minimum index is 0 by default)
+		long int max_ind2_,//max of the index #2 (minimum index is 0 by default)
+		T null_,//null element of T
+		long int *var_num_);//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
+
+		two_dim_layer_alignment_algorithm(//used to save data from two_dim_layer_alignment_algorithm_ with minimal memory allocation
+		long int max_ind1_,//max of the index #1
+		long int max_ind2_,//max of the index #2
+		two_dim_layer_alignment_algorithm<T> *two_dim_layer_alignment_algorithm_);
+
+
+		~two_dim_layer_alignment_algorithm();
+
+		void align_upto_target_lengths(//aligns the sequences upto the target sequence lengths including 
+		//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+		long int target_align1_length_,//target length for the sequence #1
+		long int target_align2_length_);//target length for the sequence #2
+
+		
+		void align_upto_target_lengths_step(//aligns the sequences upto the target sequence lengths including; checks whether the jump exeeds d_step
+		//the sequences #1, #2 must be defined upto target_seq1_length_-1 and target_seq2_length_-1 lengths 
+		long int target_align1_length_,//target length for the sequence #1
+		long int target_align2_length_);//target length for the sequence #2
+
+		void init();//initialization for a new alignment
+
+
+
+
+		public:
+
+		long int d_number_of_variables;//total number of variables in dynamic equations
+		long int d_depth1;//the maximum difference of the first index in the dynamic equations
+		long int d_depth2;//the maximum difference of the second index in the dynamic equations
+		long int *d_var_num;//d_variable_name_to_number[c] converts a letter 'c' (of type char) to order number of variable
+
+		long int d_max_ind1;//max of the index #1 (minimum index is 0 by default)
+		long int d_max_ind2;//max of the index #2 (minimum index is 0 by default)
+
+		long int d_current_align_ind1;//the alignment is calculated in the rectangle [0,d_current_ind1] x [0,d_current_ind2]
+		long int d_current_align_ind2;
+
+		long int d_step1;//maximum jump in sequence #1 lengths permitted in align_upto_target_lengths_step
+		long int d_step2;//maximum jump in sequence #2 lengths permitted in align_upto_target_lengths_step
+
+		long int d_edge_maximum_calculation_depth1;//the maximum difference of the first index for the edge maximum calculation
+		long int d_edge_maximum_calculation_depth2;//the maximum difference of the second index for the edge maximum calculation
+
+
+		T d_null;//null element
+
+
+		two_dim_layer<T> ** d_vars;//variables; the dimension of the array is d_number_of_variables
+
+		two_dim_layer_alignment_function_type * d_two_dim_layer_alignment_function;//the function used for the alingment
+		two_dim_layer_alignment_function_type * d_two_dim_layer_boundary_function;//the function used for the boundary conditions; must be defined in the rectangle [0,depth1_-1] x [0,depth2_-1]
+
+		void *d_par;//parameters for the last argument void*par_ of functions d_two_dim_layer_boundary_function and d_two_dim_layer_alignment_function
+
+		//statistics
+		//global maximum
+		bool d_M_flag;
+		long int d_M;
+
+		//edge maximum
+		bool d_E_flag;
+		long int d_E;
+
+		bool d_scores_counts_flag;
+		array_v<double> d_scores_counts;
+
+		long int d_M_threshold;
+
+		//FSC parameters
+		bool d_FSC_flag;
+		long int d_distance_along_direction_1;
+		long int d_distance_along_direction_2;
+
+
+
+	};
+
+//-----------------------------------------------------
+
+	class IS1_general_simulation
+	{
+		public:
+		IS1_general_simulation(
+			IS1_general *IS1_general_obj_,
+			long int initial_state_,//initial state for the IS
+			long int max_seq1_length_,//maximum sequence length
+			long int max_seq2_length_,//maximum sequence length
+			double *initial_distr_=NULL);//initial distribution of states; initial_state_ is ignored if d_initial_distr_ is defined
+
+		IS1_general_simulation(//creates a copy of IS1_general_simulation_ with smallest possible memory allocation
+		IS1_general_simulation *IS1_general_simulation_);//maximum sequence length
+
+
+		~IS1_general_simulation();
+
+		void init();//initialization for a new sequence generation
+
+		void simulate_upto_target_lengths(
+			long int target_seq1_length_,//target length of the sequence #1
+			long int target_seq2_length_);//target length of the sequence #2
+
+
+		//weights calculation
+		void calculate_weight_W1_one_step(//calculates the weight assuming all the weights used in the recursive equations are defined
+			long int target_length1_,//target length for sequence #1
+			long int target_length2_,//target length for sequence #2
+			long int i1_,//the first index (corresponded to the sequence #1)
+			long int i2_);//the second index (corresponded to the sequence #2)
+
+		void calculate_weight_W1_upto_target_lengths(
+			long int target_seq1_length_,//target length of the sequence #1
+			long int target_seq2_length_,//target length of the sequence #2
+			long int seq1_length_tmp_,//the weights are calculated upto this length for the sequence #1
+			long int seq2_length_tmp_);//the weights are calculated upto this length for the sequence #2
+
+
+		void calculate_weight_W1_for_fixed_lengths_using_infinite_sums(
+			long int target_seq1_length_,//target length of the sequence #1
+			long int target_seq2_length_,//target length of the sequence #2
+			double &weight_);//the resulted weight
+
+		void calculate_weight_W1_for_fixed_lengths_using_recursions(
+			long int target_seq1_length_,//target length of the sequence #1
+			long int target_seq2_length_,//target length of the sequence #2
+			double &weight_,//the resulted weight
+			bool save_matrices_=false,
+			std::vector<std::vector<double> > *A1_=NULL,
+			std::vector<std::vector<double> > *A2_=NULL);
+
+
+
+
+
+		public:
+
+		long int d_seq1_current_length;//current length of the sequence #1 simulated using the IS
+		long int d_seq2_current_length;//current length of the sequence #2 simulated using the IS
+
+		long int d_max_seq1_length;//maximum sequence length
+		long int d_max_seq2_length;//maximum sequence length
+
+		long int *d_seq1;
+		long int *d_seq2;
+
+		long int d_initial_state;
+		long int d_current_state;
+		double *d_initial_distr_sum;
+
+		IS1_general *d_IS1_general_obj;
+
+		//weights calculation
+
+		two_dim_layer<double> ** d_W1;//array of pointers to weights; dimention of the array is d_IS1_general_obj->d_number_of_states
+		long int d_W1_seq1_current_length;//current length of the sequence #1 simulated using the IS
+		long int d_W1_seq2_current_length;//current length of the sequence #2 simulated using the IS
+
+		long int d_W1_step1;//increase of number of layers of d_W1 for the index #1
+		long int d_W1_step2;//increase of number of layers of d_W1 for the index #2
+
+
+
+	};
+
+//-------------------------------------------------------------------------------------------
+	//objects for tests
+
+	class test
+	{
+		public:
+
+		struct data_for_lambda_equation//struct for lambda_equation
+		{
+			long int d_number_of_AA;//number of AA
+			long int** d_smatr;//scoring matrix
+			double *d_RR1;//AA probabilities
+			double *d_RR2;//AA probabilities
+		};
+
+		struct data_for_lambda_equation_FSA//struct for lambda_equation_FSA
+		{
+			long int d_number_of_letters1;//number of letters for the sequence #1
+			long int d_number_of_letters2;//number of letters for the sequence #2
+			long int** d_smatr;//scoring matrix
+			double *d_RR1;//nucleotide probabilities
+			double *d_RR2;//AA probabilities
+
+			long int d_codon_length;//codon length 
+			long int *d_codon_AA;//<codon code,AA number>
+
+		};
+
+
+		struct data_for_classical_alignment
+		{
+			long int d_open1;//gap opening penalty for the nucleotide sequence #1
+			long int d_open2;//gap opening penalty for the amino acid sequence #2
+
+			long int d_epen1;//gap extension penalty for the nucleotide sequence #1
+			long int d_epen2;//gap extension penalty for the amino acid sequence #2
+
+			long int**d_smatr;//the scoring matrix
+
+			long int *d_seq1;//sequence #1
+			long int *d_seq2;//sequence #2
+
+		};
+
+		struct data_for_FSA_alignment
+		{
+			long int d_alphabet_letters_number1;//number of letters in the sequence #1
+
+			long int d_open1;//gap opening penalty for the nucleotide sequence #1
+			long int d_open2;//gap opening penalty for the amino acid sequence #2
+
+			long int d_epen1;//gap extension penalty for the nucleotide sequence #1
+			long int d_epen2;//gap extension penalty for the amino acid sequence #2
+
+			long int d_gamma;//frame shift penalty
+
+			long int**d_smatr;//the scoring matrix
+
+			long int *d_seq1;//sequence #1
+			long int *d_seq2;//sequence #2
+
+			long int *d_codon_AA;//<codon code,AA number>
+
+			bool d_insertions_after_deletions;//if true, then insertions after deletions are allowed
+
+			std::string d_alignment_type;//possible values are "global" or "local"
+
+		};
+
+
+		void classical_IS(
+
+		unsigned rand_,//randomization number
+		long int open1_,//gap opening penalty for the nucleotide sequence #1
+		long int open2_,//gap opening penalty for the amino acid sequence #2
+
+		long int epen1_,//gap extension penalty for the nucleotide sequence #1
+		long int epen2_,//gap extension penalty for the amino acid sequence #2
+
+
+		std::string smatr_file_name_,//scoring matrix file name
+		std::string RR1_file_name_,//background frequencies file name for the sequence #1
+		std::string RR2_file_name_);//background frequencies file name for the sequence #2
+
+		//long int seq1_length_,//length of sequence #1
+		//long int seq2_length_,//length of sequence #2
+
+		//long int seq_number_);//number of tested alignments
+
+		static long int realization_number_into_set_number(//numeration of sets starts from 1
+		long int &realization_number_,//realization order number; the numeration starts from 0
+		long int &number_of_realizations_set_);//total number of sets
+
+		static std::pair<long int,long int> set_number_boundaries(//boundaries of realization order numbers for the set; numeration of realizations starts from 0
+		long int &set_number_,//set order number; the numeration starts from 1
+		long int &number_of_realizations_set_);//total number of realizations per set
+
+		static void combine_parameters_from_forward_and_reversed_calculations_generalized(
+		Sls::FALP_set_of_parameters &par_,//parameters from forward calculation
+		Sls::FALP_set_of_parameters &par_reversed_,//parameters from reversed calculation
+		Sls::FALP_set_of_parameters &par_result_);//the result
+
+
+		void input_data_for_the_constructor(
+
+		std::string DNA_codon_table_file_name_,//a name of a file with DNA codon table
+		std::string smatr_file_name_,//scoring matrix file name
+		std::string RR1_file_name_,//probabilities1 file name
+		std::string RR2_file_name_,//probabilities2 file name
+
+		long int &alphabetSize1_,
+		long int &alphabetSize2_,
+		long int **&substitutionScoreMatrix_,
+		double *&letterFreqs1_,
+		double *&letterFreqs2_,
+
+		char *&alphabet1_,//alphabet letters for the sequence #1
+		char *&alphabet2_,//alphabet letters for the sequence #2
+
+		long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+		long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+		long int &codon_length_,//codon length 
+		long int *&codon_AA_);//<codon code,AA number>
+
+		void FSA_IS(
+		//additional parameters for the library code
+		bool library_call_flag_,//if true, then the additional parameters are used
+		long ntAlphabetSize_,//a number of letters in the DNA alphabet; usually 4
+		long aaAlphabetSize_,//a number of letters in the amino acid alphabet; usually 4
+		const long *codonTable_,//defines the codon table; is an array of ntAlphabetSize_^3 integers
+		const long *const *substitutionScoreMatrix_,//scoring matrix; aaAlphabetSize_ X aaAlphabetSize_
+		const double *ntFreqs_,//background frequencies of letters in DNA sequences
+		const double *aaFreqs_,//background frequencies of letters in amino acid sequences
+		//additional parameters for the library code - end
+
+		long int rand_,//randomization number
+		long int open1_,//gap opening penalty for the nucleotide sequence #1
+		long int open2_,//gap opening penalty for the amino acid sequence #2
+
+		long int epen1_,//gap extension penalty for the nucleotide sequence #1
+		long int epen2_,//gap extension penalty for the amino acid sequence #2
+
+		long int gamma_,//frameshift penalty gamma
+
+
+		std::string smatr_file_name_,//scoring matrix file name
+		std::string RR1_file_name_,//background frequencies file name for the sequence #1
+		std::string RR2_file_name_,//background frequencies file name for the sequence #2
+		std::string DNA_codon_table_file_name_,//a name of a file with DNA codon table
+
+		double eps_lambda_,//relative error for lambda calculation
+		double eps_K_,//relative error for K calculation
+
+		bool gapped_flag_,//if true, then the gapped alingment is performed
+		double max_time_,//maximum allowed calculation time in seconds
+		double max_mem_,//maximum allowed memory usage in MB
+
+		long int seq_number_,//number of tested alignments
+		long int nalp_,//number of ALPs for the calculation
+		long int number_of_subsets_for_errors_calculation_,//number of subsets used for the splitting method
+		bool forward_and_reverse_screen_output_flag_,//determines whether the parameters are outputted for forward and reverse calculations
+		bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
+
+		//for test
+		double mult_for_is_lambda_,//multiplier for lambda in the IS
+
+		//the result
+		Sls::FALP_set_of_parameters &par_result_,//the resulted parameters
+		Sls::par_test1_type *par_test1_=NULL);//for tests
+
+
+
+
+		static void FSA_IS_transition_probabilities_calculation(
+		bool &FSA_flag,
+		double ***&states_distr,
+
+		bool &cs_flag,
+		double ***&states_distr_cs,
+
+		bool &sim_flag,
+		double ***&states_distr_sim,
+
+		long int &number_of_states,
+		long int &alphabet_letters_number1,
+		long int &alphabet_letters_number2,
+		std::pair<long int, long int> *&states_description,
+		long int &codon_length,
+		long int *&codon_AA,
+		double *&RR1,
+		double *&RR2,
+		std::map<std::string, long int> &state_name_into_number,
+		long int **&smatr,
+		double &ungappedlambda);
+
+
+		static void calculate_ungapped_lambda(
+		long int number_of_AA_,
+		double *RR1_,
+		double *RR2_,
+		long int**smatr_,
+		double &ungapped_lambda_);
+
+		static void calculate_ungapped_lambda_general(
+		function_type *func_,
+		void* func_pointer_,
+		double &ungapped_lambda_);
+
+
+
+
+		static double lambda_equation(double x_,void* func_number_);
+		static double lambda_equation_FSA(double x_,void* func_number_);
+
+		static void two_dim_layer_alignment_function_classical_global(
+			//function for global classical alignment
+			long int i1_,
+			long int i2_,
+			two_dim_layer_alignment_algorithm<long int> *obj_,
+			void*par_);
+
+		static void two_dim_layer_alignment_function_FSA(//function for the FSA a1-alignment
+			long int i1_,
+			long int i2_,
+			two_dim_layer_alignment_algorithm<long int> *obj_,
+			void*par_);
+
+		static void collect_and_output_M_distr_upto_fixed_lengths(
+			long int number_of_realizations_,
+			std::string M_distr_file_name_,
+			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+			IS1_general_simulation &IS1_general_simulation_test_,
+			long int target_seq1_length_,//target length of the sequence #1
+			long int target_seq2_length_);//target length of the sequence #2
+
+		static void collect_and_output_E_distr_upto_fixed_ALP(
+			long int number_of_realizations_,
+			std::string E_distr_file_name_,
+			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+			IS1_general_simulation &IS1_general_simulation_test_,
+			long int target_ALP_,//target ALP number
+			double ungapped_lambda_,
+			long int limit2_,
+			long int number_of_sets_,//number of sets for error calculation
+			Sls::FALP_set_of_parameters &par_,
+			bool screen_output_flag_,
+
+			bool futher_expanding_=false,
+			IS1_general *IS1_general_cs_=NULL,
+			double *eps_K_=NULL,//relative error for K
+			long int *number_of_cs_steps_for_expanding_=NULL);
+
+		static void delete_mult_states_type(
+			mult_states_type *&states_old1);
+
+		static void restore_arrays(
+			long int k_,
+			mult_states_type *states_old_,
+			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+			IS1_general_simulation &IS1_general_simulation_test_);
+
+		static void restore_arrays(
+			two_dim_layer_alignment_algorithm<long int> *two_dim_layer_alignment_algorithm_test_from_,
+			IS1_general_simulation *IS1_general_simulation_test_from_,
+			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+			IS1_general_simulation &IS1_general_simulation_test_);
+
+		static void compare_mult_states(
+			mult_states_type *states_old_,
+			mult_states_type *states_new_);
+
+
+
+		static void collect_and_output_E_distr_upto_fixed_ALP_with_saving_of_states(
+			bool compute_allocated_memory_flag_,//if true then total allocated memory is computed in allocated_memory_
+			double &allocated_memory_,
+
+
+			long int number_of_realizations_,
+			std::string E_distr_file_name_,
+			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+			IS1_general_simulation &IS1_general_simulation_test_,
+			long int target_ALP_,//target ALP number
+			double ungapped_lambda_,
+			long int limit2_,
+			long int number_of_sets_,//number of sets for error calculation
+			Sls::FALP_set_of_parameters &par_,
+			bool &inside_simulation_flag_,
+			bool screen_output_flag_,
+			bool screen_output_k_flag_,
+
+			double ending_time_,
+			bool &stopped_by_ending_time_flag_,
+			long int &number_of_realizations_with_ending_time_,
+
+			double ending_time_to_test_logarithmic_regime_,
+			
+			bool save_states_flag_,
+			mult_states_type *states_old_,//NULL or defined
+			mult_states_type *&states_new_,//resulted value
+			long int &M_thr_estimation_,//average score threshold corresponded to target_ALP_
+
+
+			bool futher_expanding_=false,
+			long int M_thr_=-inf,//the expanding starts from the ALP with the score >=M_thr_; used if >=0
+			IS1_general *IS1_general_cs_=NULL,
+			double *eps_K_=NULL,//relative error for K
+			long int *number_of_cs_steps_for_expanding_=NULL,
+			bool parameters_are_not_calculated_=false);
+
+		static void FSA_Align(
+
+			long int open1_,//gap opening penalty for the nucleotide sequence #1
+			long int open2_,//gap opening penalty for the amino acid sequence #2
+
+			long int epen1_,//gap extension penalty for the nucleotide sequence #1
+			long int epen2_,//gap extension penalty for the amino acid sequence #2
+
+			long int gamma_,//frameshift penalty gamma
+
+			std::string smatr_file_name_,//scoring matrix file name
+			std::string DNA_codon_table_file_name_,//a name of a file with DNA codon table
+
+			bool insertions_after_deletions_,//if true, then insertions after deletions are allowed
+
+			std::string input_sequences_,//name of file with sequences for alignment (align mode)
+			std::string output_sequences_,//name of output file with alignment scores (align mode)
+			std::string gumbelparin_file_name_);//Gumbel parameters input file name
+
+
+		static void compare_direct_and_reverse_sampling(
+			long int number_of_realizations_,
+			long int seq2_length_,
+			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_,
+			IS1_general_simulation &IS1_general_simulation_test_,
+			two_dim_layer_alignment_algorithm<long int> &two_dim_layer_alignment_algorithm_test_reverse_,
+			IS1_general_simulation &IS1_general_simulation_test_reverse_,
+			IS1_general *IS1_general_cs_);
+
+
+
+		static void normalize_state_distributions(
+			long int alphabet_letters_number1_,//number of letters in the sequence #1
+			long int alphabet_letters_number2_,//number of letters in the sequence #2
+
+			long int number_of_states_,//number of states
+
+			std::pair<long int, long int> *states_description_,//description of the states; the index is a state number
+			double ***states_distr_);//distributions of the states; the index is a state number
+
+
+
+
+
+		public:
+
+
+		long int **d_alignment_matr;
+
+		IS1_general* d_IS1;
+
+		IS1_general_simulation *d_IS1_general_simulation;
+
+
+	};
+
+
+
+
+}
+
+#endif // GUMBEL_FSA1
+
diff --git a/src/alp/sls_fsa1_parameters.cpp b/src/alp/sls_fsa1_parameters.cpp
index cc7ccdb..9e21800 100644
--- a/src/alp/sls_fsa1_parameters.cpp
+++ b/src/alp/sls_fsa1_parameters.cpp
@@ -1,1812 +1,1812 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_fsa1_parameters.cpp
-
-Author: Sergey Sheetlin
-
-Contents: Calculation of Gumbel parameters
-
-******************************************************************************/
-
-
-#include "sls_fsa1_parameters.hpp"
-
-using namespace Sls;
-using namespace std;
-
-//parameters calculation
-double fsa_par::function_for_lambda_calculation(
-double lambda_,
-void * data_)
-{
-
-	double *expect=NULL;
-	double *expect_errors=NULL;
-
-	try
-	{
-
-		struct_for_lambda_calculation *tmp_struct=(struct_for_lambda_calculation *)data_;
-		void **alp_distr=tmp_struct->d_alp_distr;
-		void **alp_distr_errors=tmp_struct->d_alp_distr_errors;
-		long int nalp=tmp_struct->d_nalp;
-
-		expect=new double[nalp];
-		FSA_utils::assert_mem(expect);
-		expect_errors=new double[nalp];
-		FSA_utils::assert_mem(expect_errors);
-
-		if(nalp<1)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-
-
-		long int k;
-		for(k=1;k<=nalp;k++)
-		{
-			array_v<double>* tmp=((array_v<double>*)alp_distr[k]);
-			array_v<double>* tmp_errors=((array_v<double>*)alp_distr_errors[k]);
-
-			double val=0;
-			double val_error=0;
-
-			long int j;
-			for(j=0;j<=tmp->d_dim;j++)
-			{
-				if(tmp->d_elem[j]<=0)
-				{
-					continue;
-				};
-				double exp_tmp=exp(lambda_*(j+tmp->d_ind0));
-				val+=exp_tmp*tmp->d_elem[j];
-				val_error+=exp_tmp*exp_tmp*tmp_errors->d_elem[j];
-			};
-			val_error=alp_reg::sqrt_for_errors(val_error);
-			expect[k-1]=val;
-			expect_errors[k-1]=val_error;
-
-		};
-
-		tmp_struct->d_last_sum=expect[nalp-1];
-		tmp_struct->d_last_sum_error=expect_errors[nalp-1];
-
-		if(nalp==1)
-		{
-			tmp_struct->d_before_last_sum=1.0;
-			tmp_struct->d_before_last_sum_error=0.0;
-		}
-		else
-		{
-			tmp_struct->d_before_last_sum=expect[nalp-2];
-			tmp_struct->d_before_last_sum_error=expect_errors[nalp-2];
-		};
-
-		if(tmp_struct->d_calculate_alp_number)
-		{
-			double tmp=0.0;
-			long int k;
-			for(k=0;k<nalp;k++)
-			{
-				if(expect_errors[k]!=0)
-				{
-					tmp+=1.0/(expect_errors[k]*expect_errors[k]);
-				};
-
-			};
-
-			long int tmp_alp=nalp;
-			double tmp1=0.0;
-			for(k=nalp-1;k>=0;k--)
-			{
-				if(expect_errors[k]!=0)
-				{
-					tmp1+=1.0/(expect_errors[k]*expect_errors[k]);
-				};
-				if(tmp1>0.2*tmp)
-				{
-					tmp_alp=k+1;
-					break;
-				};
-			};
-
-			tmp_struct->d_alp_number=tmp_alp;
-		};
-
-		if(nalp==1)
-		{
-			double tmp=expect[0]-1.0;
-			tmp_struct->d_f_error=expect_errors[0];
-			delete[]expect;expect=NULL;
-			delete[]expect_errors;expect_errors=NULL;
-			return tmp;
-		};
-
-
-		long int min_length=0;
-		long int number_of_elements=nalp;
-		bool cut_left_tail=true;
-		bool cut_right_tail=false;
-		double y=2;
-		double beta0;
-		double beta1;
-		double beta0_error;
-		double beta1_error;
-		long int k1_opt;
-		long int k2_opt;
-
-		bool res_was_calculated;
-
-		alp_reg::robust_regression_sum_with_cut_LSM(
-		min_length,
-		number_of_elements,
-		expect,
-		expect_errors,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		beta0,
-		beta1,
-		beta0_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-
-
-		if(!res_was_calculated)
-		{
-			throw error("",2);
-		};
-
-
-		delete[]expect;expect=NULL;
-		delete[]expect_errors;expect_errors=NULL;
-
-		tmp_struct->d_f_error=beta1_error;
-		return beta1;
-
-	}
-	catch (...)
-	{ 
-		delete[]expect;expect=NULL;
-		delete[]expect_errors;expect_errors=NULL;
-		throw;
-	};
-
-}
-
-void fsa_par::calculate_lambda(
-bool check_the_criteria_,
-long int nalp_,
-long int &nalp_thr_,
-bool &inside_simulation_flag_,
-void **alp_distr,
-void **alp_distr_errors,
-double ungapped_lambda_,
-double &lambda_,
-double &lambda_error_)
-{
-
-	bool ee_error_flag=false;
-	error ee_error("",0);
-
-	inside_simulation_flag_=false;
-
-	try
-	{
-
-		long int nalp=nalp_;
-
-		if(nalp<=0)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-		
-
-		struct_for_lambda_calculation tmp_struct;
-		tmp_struct.d_alp_distr=alp_distr;
-		tmp_struct.d_alp_distr_errors=alp_distr_errors;
-		tmp_struct.d_nalp=nalp;
-		tmp_struct.d_calculate_alp_number=false;
-
-
-		function_type *func=function_for_lambda_calculation;
-		void* func_pointer=&tmp_struct;
-		double a=0;
-		double b=ungapped_lambda_*2;
-		//double b=ungapped_lambda_*10;
-		long int n_partition=30;
-		//long int n_partition=300;
-		double eps=1e-10;
-		std::vector<double> res;
-
-		alp_reg::find_tetta_general(
-		func,
-		func_pointer,
-		a,//[a,b] is the interval for search of equation solution
-		b,
-		n_partition,
-		eps,
-		res);
-
-		
-
-
-		inside_simulation_flag_=true;
-		if(res.size()==0)
-		{
-			inside_simulation_flag_=false;
-			return;
-		};
-
-		
-
-		lambda_=get_root(res,ungapped_lambda_);
-		
-
-		tmp_struct.d_calculate_alp_number=true;
-		double f1=func(lambda_,func_pointer);
-		nalp_thr_=tmp_struct.d_alp_number;
-		tmp_struct.d_calculate_alp_number=false;
-
-		double slope_error=tmp_struct.d_f_error;
-
-		double delta_lambda=lambda_/100.0;
-		double f2=func(lambda_+delta_lambda,func_pointer);
-		
-		
-
-		if(delta_lambda==0||f1==f2)
-		{
-			lambda_error_=0.0;
-		}
-		else
-		{
-			double derivative=(f2-f1)/delta_lambda;
-			lambda_error_=fabs(slope_error/derivative);
-		};
-		
-		if(!check_the_criteria_)
-		{
-			return;
-		};
-
-
-	}
-	catch (error er)
-	{
-		ee_error_flag=true;
-		ee_error=er;		
-	};
-
-
-	if(ee_error_flag)
-	{
-		if(ee_error.st!="")
-		{
-			throw error(ee_error.st,ee_error.error_code);
-		}
-		else
-		{
-			inside_simulation_flag_=false;
-		};
-	};
-
-}
-
-void fsa_par::memory_releace_for_calculate_C(
-double *&P,
-double *&P_errors,
-double *&values_P_ratio,
-double *&errors_P_ratio,
-
-double *&E,
-double *&E_errors,
-
-double *&E_T_beta,
-double *&E_T_beta_errors)
-{
-	delete[]values_P_ratio;values_P_ratio=NULL;
-	delete[]errors_P_ratio;errors_P_ratio=NULL;
-
-
-	delete[]P;P=NULL;
-	delete[]P_errors;P_errors=NULL;
-
-	delete[]E;E=NULL;
-	delete[]E_T_beta;E_T_beta=NULL;
-	delete[]E_errors;E_errors=NULL;
-	delete[]E_T_beta_errors;E_T_beta_errors=NULL;
-}
-
-void fsa_par::calculate_C(
-long int starting_point,
-long int nalp_,
-void **alp_distr,
-void **alp_distr_errors,
-double lambda_,
-double lambda_error_,
-double &C_,
-double &C_error_,
-bool &inside_simulation_flag_)
-{
-	inside_simulation_flag_=true;
-
-	error ee_error("",0);
-
-	double *P=NULL;
-	double *P_errors=NULL;
-	double *values_P_ratio=NULL;
-	double *errors_P_ratio=NULL;
-
-	double *E=NULL;
-	double *E_errors=NULL;
-
-	double *E_T_beta=NULL;
-	double *E_T_beta_errors=NULL;
-
-
-	try
-	{
-	try
-	{
-
-		long int total_number_of_ALP=nalp_;
-
-		if(total_number_of_ALP<1)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-
-		//1)P(beta=infinity)
-		long int j;
-
-
-		P=new double[total_number_of_ALP+1];
-		FSA_utils::assert_mem(P);
-		P_errors=new double[total_number_of_ALP+1];
-		FSA_utils::assert_mem(P_errors);
-
-		P[0]=1.0;
-		P_errors[0]=0.0;
-
-		
-		for(j=1;j<=total_number_of_ALP;j++)
-		{
-			array_v<double>* tmp=((array_v<double>*)alp_distr[j]);
-			array_v<double>* tmp_errors=((array_v<double>*)alp_distr_errors[j]);
-
-			P[j]=0;
-			P_errors[j]=0;
-			long int i;
-			for(i=0;i<=tmp->d_dim;i++)
-			{
-				P[j]+=tmp->d_elem[i];
-				P_errors[j]+=tmp_errors->d_elem[i];
-			};
-
-			P_errors[j]=alp_reg::sqrt_for_errors(P_errors[j]);
-		};
-
-		
-
-		values_P_ratio=new double[total_number_of_ALP];
-		FSA_utils::assert_mem(values_P_ratio);
-		errors_P_ratio=new double[total_number_of_ALP];
-		FSA_utils::assert_mem(errors_P_ratio);
-
-		
-
-		for(j=0;j<total_number_of_ALP;j++)
-		{
-			if(P[j]<=0)
-			{
-				inside_simulation_flag_=false;
-				throw error("",1);
-			};
-			values_P_ratio[j]=P[j+1]/P[j];
-			errors_P_ratio[j]=FSA_utils::error_of_the_ratio(P[j+1],P_errors[j+1],P[j],P_errors[j]);
-		};
-
-
-
-		double beta1=0;
-		double beta1_error=0;
-
-		long int number_of_elements=total_number_of_ALP;
-
-		bool cut_left_tail=true;
-		bool cut_right_tail=false;
-
-		double y=2;
-
-		long int k1_opt;
-		long int k2_opt;
-
-
-		double P_beta_inf;
-		double P_beta_inf_error=0;
-
-		bool res_was_calculated;
-		
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements-starting_point,
-		values_P_ratio+starting_point,
-		errors_P_ratio+starting_point,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		P_beta_inf,
-		beta1,
-		P_beta_inf_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-
-		
-
-		if(!res_was_calculated)
-		{
-			//throw error("The program cannot estimate the parameters; please repeat the calculation9\n",2);
-			inside_simulation_flag_=false;
-			throw error("",1);
-		};
-
-		P_beta_inf=1-P_beta_inf;
-
-		
-
-		
-		//2)E(exp(lambda*T_beta)) and E(T_beta*exp(lambda*T_beta))
-		E=new double[total_number_of_ALP+1];
-		FSA_utils::assert_mem(E);
-		E_errors=new double[total_number_of_ALP+1];
-		FSA_utils::assert_mem(E_errors);
-
-		E_T_beta=new double[total_number_of_ALP+1];
-		FSA_utils::assert_mem(E_T_beta);
-		E_T_beta_errors=new double[total_number_of_ALP+1];
-		FSA_utils::assert_mem(E_T_beta);
-
-
-		E[0]=1;
-		E_T_beta[0]=0;
-
-		E_errors[0]=0;
-		E_T_beta_errors[0]=0;
-
-		
-
-
-		for(j=1;j<=total_number_of_ALP;j++)
-		{
-			array_v<double>* tmp=((array_v<double>*)alp_distr[j]);
-			array_v<double>* tmp_errors=((array_v<double>*)alp_distr_errors[j]);
-
-			E[j]=0;
-			E_T_beta[j]=0;
-
-			E_errors[j]=0;
-			E_T_beta_errors[j]=0;
-
-			long int i;
-			for(i=0;i<=tmp->d_dim;i++)
-			{
-				double tmp_double=exp(lambda_*(double)i);
-				E[j]+=tmp_double*tmp->d_elem[i];
-				E_errors[j]+=tmp_double*tmp_double*tmp_errors->d_elem[i];
-
-				tmp_double=(double)i*exp(lambda_*(double)i);
-				E_T_beta[j]+=tmp_double*tmp->d_elem[i];
-				E_T_beta_errors[j]+=tmp_double*tmp_double*tmp_errors->d_elem[i];
-			};
-
-			E_errors[j]=alp_reg::sqrt_for_errors(E_errors[j]);
-			E_T_beta_errors[j]=alp_reg::sqrt_for_errors(E_T_beta_errors[j]);
-
-		};
-
-
-		double E_aver;
-		double E_aver_error;
-
-		double E_T_beta_diff_aver;
-		double E_T_beta_diff_aver_error;
-
-
-		if(total_number_of_ALP==1)
-		{
-			E_aver=E[1];
-			E_aver_error=E_errors[1];
-
-			E_T_beta_diff_aver=E_T_beta[1]-E_T_beta[0];
-			E_T_beta_diff_aver_error=E_T_beta_errors[1];
-
-		}
-		else
-		{
-			long int number_of_elements=total_number_of_ALP;
-
-			bool cut_left_tail=true;
-			bool cut_right_tail=false;
-
-
-			double beta0;
-			double beta1=0;
-			double beta0_error;
-			double beta1_error=0;
-
-			bool res_was_calculated;
-
-			alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-			0,
-			number_of_elements-starting_point,
-			E+1+starting_point,
-			E_errors+1+starting_point,
-			cut_left_tail,
-			cut_right_tail,
-			y,
-			E_aver,
-			beta1,
-			E_aver_error,
-			beta1_error,
-			k1_opt,
-			k2_opt,
-			res_was_calculated);
-
-
-			if(!res_was_calculated)
-			{
-				inside_simulation_flag_=false;
-				throw error("",1);
-			};
-
-
-
-			number_of_elements=total_number_of_ALP;
-
-
-			alp_reg::robust_regression_sum_with_cut_LSM(
-			0,
-			number_of_elements-starting_point,
-			E_T_beta+1+starting_point,
-			E_T_beta_errors+1+starting_point,
-			cut_left_tail,
-			cut_right_tail,
-			y,
-			beta0,
-			beta1,
-			beta0_error,
-			beta1_error,
-			k1_opt,
-			k2_opt,
-			res_was_calculated);
-
-			
-
-			if(!res_was_calculated)
-			{
-				//throw error("The program cannot estimate the parameters; please repeat the calculation11\n",2);
-				inside_simulation_flag_=false;
-				throw error("",1);
-			};
-
-
-			E_T_beta_diff_aver=beta1;
-			E_T_beta_diff_aver_error=beta1_error;
-
-
-			
-			
-		};
-
-
-		double exp_lambda_error=exp(-lambda_)*lambda_error_;
-		double exp_lambda=(1-exp(-lambda_));
-
-		
-		double den_error=FSA_utils::error_of_the_product(E_T_beta_diff_aver,E_T_beta_diff_aver_error,exp_lambda,exp_lambda_error);
-		double den=(1-exp(-lambda_))*E_T_beta_diff_aver;
-
-
-		double nom_error=FSA_utils::error_of_the_product(P_beta_inf,P_beta_inf_error,E_aver,E_aver_error);
-		double nom=P_beta_inf*E_aver;
-
-
-		C_error_=FSA_utils::error_of_the_ratio(nom,nom_error,den,den_error);
-
-		if(den<=0)
-		{
-			inside_simulation_flag_=false;
-			throw error("",1);
-		};
-
-		C_=nom/den;
-
-		memory_releace_for_calculate_C(
-		P,
-		P_errors,
-		values_P_ratio,
-		errors_P_ratio,
-
-		E,
-		E_errors,
-
-		E_T_beta,
-		E_T_beta_errors);
-
-
-	}
-	catch (error er)
-	{
-		if(er.st!="")
-		{
-			throw;
-		}
-		else
-		{
-			memory_releace_for_calculate_C(
-			P,
-			P_errors,
-			values_P_ratio,
-			errors_P_ratio,
-
-			E,
-			E_errors,
-
-			E_T_beta,
-			E_T_beta_errors);
-		};
-
-	};
-	}
-	catch (...)
-	{ 
-		//memory release
-		memory_releace_for_calculate_C(
-		P,
-		P_errors,
-		values_P_ratio,
-		errors_P_ratio,
-
-		E,
-		E_errors,
-
-		E_T_beta,
-		E_T_beta_errors);
-		throw;
-	};
-
-
-
-}
-
-
-double fsa_par::get_root(
-const std::vector<double> &res_tmp_,
-double point_)
-{
-	if(res_tmp_.size()==0)
-	{
-		throw error("Error in alp_sim::get_root - the equation does not have any solutions\n",2);
-	};
-
-	long int i;
-	long int p=0;
-	double d1=fabs(point_-res_tmp_[0]);
-	for(i=1;i<(long int)res_tmp_.size();i++)
-	{
-		double d2=fabs(point_-res_tmp_[i]);
-		if(d2<d1)
-		{
-			p=i;
-			d1=d2;
-		};
-	};
-
-	return res_tmp_[p];
-}
-
-//------------------------------------------
-//FSC
-double fsa_par::lambda_exp(
-long int &i_,
-double *&exp_array_)
-{
-
-	if(exp_array_[i_]==-1)
-	{
-		throw error("The program is not able to calculate the parameters; rescaling penalties and scoring matrix might help\n",3);
-	};
-
-	return exp_array_[i_];
-}
-
-void fsa_par::memory_release_for_calculate_FSC(
-double *&exp_array,
-double *&delta_E,
-double *&delta_E_error,
-double *&delta_E_E,
-double *&delta_E_E_error,
-double *&delta_I,
-double *&delta_I_error,
-double *&delta_J,
-double *&delta_J_error,
-double *&delta_I_I,
-double *&delta_I_I_error,
-double *&delta_I_J,
-double *&delta_I_J_error,
-double *&delta_J_J,
-double *&delta_J_J_error,
-double *&cov_J_J,
-double *&cov_J_J_error,
-double *&cov_I_J,
-double *&cov_I_J_error,
-double *&cov_I_I,
-double *&cov_I_I_error,
-double *&cov_E_E,
-double *&cov_E_E_error,
-double *&C_S,
-double *&C_S_error)
-{
-	//memory release
-	delete[]exp_array;exp_array=NULL;
-
-	delete[]delta_E;delta_E=NULL;
-	delete[]delta_E_error;delta_E_error=NULL;
-	delete[]delta_E_E;delta_E_E=NULL;
-	delete[]delta_E_E_error;delta_E_E_error=NULL;
-
-	delete[]delta_I;delta_I=NULL;
-	delete[]delta_I_error;delta_I_error=NULL;
-	delete[]delta_J;delta_J=NULL;
-	delete[]delta_J_error;delta_J_error=NULL;
-
-	delete[]delta_I_J;delta_I_J=NULL;
-	delete[]delta_I_J_error;delta_I_J_error=NULL;
-	delete[]delta_J_J;delta_J_J=NULL;
-	delete[]delta_J_J_error;delta_J_J_error=NULL;
-	delete[]delta_I_I;delta_I_I=NULL;
-	delete[]delta_I_I_error;delta_I_I_error=NULL;
-
-	delete[]cov_I_J;cov_I_J=NULL;
-	delete[]cov_I_J_error;cov_I_J_error=NULL;
-	delete[]cov_J_J;cov_J_J=NULL;
-	delete[]cov_J_J_error;cov_J_J_error=NULL;
-	delete[]cov_I_I;cov_I_I=NULL;
-	delete[]cov_I_I_error;cov_I_I_error=NULL;
-	delete[]cov_E_E;cov_E_E=NULL;
-	delete[]cov_E_E_error;cov_E_E_error=NULL;
-
-	delete[]C_S;C_S=NULL;
-	delete[]C_S_error;C_S_error=NULL;
-}
-
-void fsa_par::calculate_FSC(
-long int nalp_,
-long int ind1_,
-long int ind2_,
-
-double lambda_,
-
-long int M_max_,
-
-array_positive<long int> *distance_along_direction_1_,
-array_positive<long int> *distance_along_direction_2_,
-
-array_positive<double> *ALP_weight_,
-array_positive<long int> *ALP_edge_max_,
-
-double &a_I_,
-double &a_I_error_,
-double &a_J_,
-double &a_J_error_,
-double &sigma_,
-double &sigma_error_,
-double &alpha_I_,
-double &alpha_I_error_,
-double &alpha_J_,
-double &alpha_J_error_,
-bool &inside_simulation_flag_,
-double *test_FSC_vect_)//for tests
-{
-	inside_simulation_flag_=true;
-
-	double *exp_array=NULL;
-
-	double *delta_E=NULL;
-	double *delta_E_error=NULL;
-
-	double *delta_E_E=NULL;
-	double *delta_E_E_error=NULL;
-
-
-	double *delta_I=NULL;
-	double *delta_I_error=NULL;
-
-	double *delta_J=NULL;
-	double *delta_J_error=NULL;
-
-	double *delta_I_I=NULL;
-	double *delta_I_I_error=NULL;
-
-	double *delta_I_J=NULL;
-	double *delta_I_J_error=NULL;
-
-	double *delta_J_J=NULL;
-	double *delta_J_J_error=NULL;
-
-	double *cov_J_J=NULL;
-	double *cov_J_J_error=NULL;
-
-	double *cov_I_J=NULL;
-	double *cov_I_J_error=NULL;
-
-	double *cov_I_I=NULL;
-	double *cov_I_I_error=NULL;
-
-	double *cov_E_E=NULL;
-	double *cov_E_E_error=NULL;
-
-	double *C_S=NULL;
-	double *C_S_error=NULL;
-
-
-	try
-	{
-	try
-	{
-
-
-		if(nalp_<1)
-		{
-			throw error("Unexpected error\n",4);
-		};
-
-		double dbl_max_log=log(DBL_MAX);
-
-
-		exp_array=new double[M_max_+1];
-		FSA_utils::assert_mem(exp_array);
-
-
-		long int i;
-		for(i=0;i<=M_max_;i++)
-		{
-			double tmp=(double)i*lambda_;
-			if(tmp<dbl_max_log)
-			{
-				exp_array[i]=exp(tmp);
-			}
-			else
-			{
-				exp_array[i]=-1;
-			};
-		};
-
-		
-
-
-		delta_E=new double[nalp_];
-		FSA_utils::assert_mem(delta_E);
-		delta_E_error=new double[nalp_];
-		FSA_utils::assert_mem(delta_E_error);
-
-		delta_E_E=new double[nalp_];
-		FSA_utils::assert_mem(delta_E_E);
-		delta_E_E_error=new double[nalp_];
-		FSA_utils::assert_mem(delta_E_E_error);
-
-		cov_E_E=new double[nalp_];
-		FSA_utils::assert_mem(cov_E_E);
-		cov_E_E_error=new double[nalp_];
-		FSA_utils::assert_mem(cov_E_E_error);
-
-
-		delta_I=new double[nalp_];
-		FSA_utils::assert_mem(delta_I);
-		delta_I_error=new double[nalp_];
-		FSA_utils::assert_mem(delta_I_error);
-
-		delta_J=new double[nalp_];
-		FSA_utils::assert_mem(delta_J);
-		delta_J_error=new double[nalp_];
-		FSA_utils::assert_mem(delta_J_error);
-
-		delta_I_I=new double[nalp_];
-		FSA_utils::assert_mem(delta_I_I);
-		delta_I_I_error=new double[nalp_];
-		FSA_utils::assert_mem(delta_I_I_error);
-
-		delta_I_J=new double[nalp_];
-		FSA_utils::assert_mem(delta_I_J);
-		delta_I_J_error=new double[nalp_];
-		FSA_utils::assert_mem(delta_I_J_error);
-
-		delta_J_J=new double[nalp_];
-		FSA_utils::assert_mem(delta_J_J);
-		delta_J_J_error=new double[nalp_];
-		FSA_utils::assert_mem(delta_J_J_error);
-
-		cov_J_J=new double[nalp_];
-		FSA_utils::assert_mem(cov_J_J);
-		cov_J_J_error=new double[nalp_];
-		FSA_utils::assert_mem(cov_J_J_error);
-
-		cov_I_J=new double[nalp_];
-		FSA_utils::assert_mem(cov_I_J);
-		cov_I_J_error=new double[nalp_];
-		FSA_utils::assert_mem(cov_I_J_error);
-
-		cov_I_I=new double[nalp_];
-		FSA_utils::assert_mem(cov_I_I);
-		cov_I_I_error=new double[nalp_];
-		FSA_utils::assert_mem(cov_I_I_error);
-
-		C_S=new double[nalp_];
-		FSA_utils::assert_mem(C_S);
-		C_S_error=new double[nalp_];
-		FSA_utils::assert_mem(C_S_error);
-
-
-		long int j;
-		for(j=0;j<nalp_;j++)
-		{
-			delta_E[j]=0.0;
-			delta_E_error[j]=0.0;
-
-			delta_E_E[j]=0.0;
-			delta_E_E_error[j]=0.0;
-
-			delta_I[j]=0.0;
-			delta_I_error[j]=0.0;
-			delta_J[j]=0.0;
-			delta_J_error[j]=0.0;
-
-			delta_I_I[j]=0.0;
-
-			delta_I_I_error[j]=0.0;
-			delta_I_J[j]=0.0;
-			delta_I_J_error[j]=0.0;
-			delta_J_J[j]=0.0;
-			delta_J_J_error[j]=0.0;
-
-			C_S[j]=0.0;
-			C_S_error[j]=0.0;
-
-		};
-
-		double C_S_constant=1.0;
-		//calculate the constant
-		bool calculate_C_S_constant_flag=true;
-		if(calculate_C_S_constant_flag)
-		{
-			long int i;
-			for(i=ind1_;i<=ind2_;i++)
-			{
-				long int j;
-				for(j=1;j<=nalp_;j++)
-				{
-
-					long int &E_j=ALP_edge_max_[i].d_elem[j];
-					double &weight_j=ALP_weight_[i].d_elem[j];
-
-
-					double tmp=lambda_exp(E_j,exp_array)*weight_j;
-
-					C_S[j-1]+=tmp;
-					C_S_error[j-1]+=tmp*tmp;
-				};
-			};
-
-			double ind_diff=(double)(ind2_-ind1_+1);
-			for(j=0;j<nalp_;j++)
-			{
-				C_S[j]/=ind_diff;
-				C_S_error[j]/=ind_diff;
-				C_S_error[j]-=C_S[j]*C_S[j];
-				C_S_error[j]/=ind_diff;
-				C_S_error[j]=alp_reg::sqrt_for_errors(C_S_error[j]);
-
-			};
-
-			//regression
-
-			double beta1=0;
-			double beta1_error=0;
-
-			long int number_of_elements=nalp_;
-
-			bool cut_left_tail=true;
-			bool cut_right_tail=false;
-
-			double y=2;
-
-			long int k1_opt;
-			long int k2_opt;
-
-
-			double C_S_constant_error;
-
-
-			bool res_was_calculated;
-			
-			alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-			0,
-			number_of_elements,
-			C_S,
-			C_S_error,
-			cut_left_tail,
-			cut_right_tail,
-			y,
-			C_S_constant,
-			beta1,
-			C_S_constant_error,
-			beta1_error,
-			k1_opt,
-			k2_opt,
-			res_was_calculated);
-
-			if(!res_was_calculated||C_S_constant<=0)
-			{
-				inside_simulation_flag_=false;
-				throw error("",1);
-			};
-
-		};
-
-		double one_div_C_S_constant=1.0/C_S_constant;
-
-
-		
-		for(i=ind1_;i<=ind2_;i++)
-		{
-
-			long int j;
-			for(j=1;j<=nalp_;j++)
-			{
-				long int j_1=j-1;
-
-				long int &E_j_1=ALP_edge_max_[i].d_elem[j_1];
-				long int &E_j=ALP_edge_max_[i].d_elem[j];
-				double &weight_j=ALP_weight_[i].d_elem[j];
-
-				long int &I_j_1=distance_along_direction_1_[i].d_elem[j_1];
-				long int &I_j=distance_along_direction_1_[i].d_elem[j];
-
-				long int &J_j_1=distance_along_direction_2_[i].d_elem[j_1];
-				long int &J_j=distance_along_direction_2_[i].d_elem[j];
-
-				double exp_tmp=lambda_exp(E_j,exp_array)*one_div_C_S_constant;
-
-				double delta_I_tmp=(I_j-I_j_1)*exp_tmp*weight_j;
-				double delta_J_tmp=(J_j-J_j_1)*exp_tmp*weight_j;
-				double delta_E_tmp=(E_j-E_j_1)*exp_tmp*weight_j;
-				double delta_E_E_tmp=(E_j-E_j_1)*(E_j-E_j_1)*exp_tmp*weight_j;
-
-				
-
-				
-				double delta_I_I_tmp=delta_I_tmp*(I_j-I_j_1);
-				double delta_J_J_tmp=delta_J_tmp*(J_j-J_j_1);
-				double delta_I_J_tmp=delta_I_tmp*(J_j-J_j_1);
-
-	
-
-
-				delta_E[j_1]+=delta_E_tmp;
-				delta_E_error[j_1]+=delta_E_tmp*delta_E_tmp;
-
-				delta_E_E[j_1]+=delta_E_E_tmp;
-				delta_E_E_error[j_1]+=delta_E_E_tmp*delta_E_E_tmp;
-
-				delta_I[j_1]+=delta_I_tmp;
-				delta_I_error[j_1]+=delta_I_tmp*delta_I_tmp;
-				delta_J[j_1]+=delta_J_tmp;
-				delta_J_error[j_1]+=delta_J_tmp*delta_J_tmp;
-
-				delta_I_I[j_1]+=delta_I_I_tmp;
-				delta_I_I_error[j_1]+=delta_I_I_tmp*delta_I_I_tmp;
-
-				delta_I_J[j_1]+=delta_I_J_tmp;
-				delta_I_J_error[j_1]+=delta_I_J_tmp*delta_I_J_tmp;
-
-				delta_J_J[j_1]+=delta_J_J_tmp;
-				delta_J_J_error[j_1]+=delta_J_J_tmp*delta_J_J_tmp;
-				
-			};
-		};
-
-
-		double ind_diff=(double)(ind2_-ind1_+1);
-		for(j=0;j<nalp_;j++)
-		{
-			delta_E[j]/=ind_diff;
-			delta_E_error[j]/=ind_diff;
-			delta_E_error[j]-=delta_E[j]*delta_E[j];
-			delta_E_error[j]/=ind_diff;
-			delta_E_error[j]=alp_reg::sqrt_for_errors(delta_E_error[j]);
-
-			
-
-			delta_E_E[j]/=ind_diff;
-			delta_E_E_error[j]/=ind_diff;
-			delta_E_E_error[j]-=delta_E_E[j]*delta_E_E[j];
-			delta_E_E_error[j]/=ind_diff;
-
-
-			delta_I[j]/=ind_diff;
-			delta_I_error[j]/=ind_diff;
-			delta_I_error[j]-=delta_I[j]*delta_I[j];
-			delta_I_error[j]/=ind_diff;
-			delta_I_error[j]=alp_reg::sqrt_for_errors(delta_I_error[j]);
-
-			delta_J[j]/=ind_diff;
-			delta_J_error[j]/=ind_diff;
-			delta_J_error[j]-=delta_J[j]*delta_J[j];
-			delta_J_error[j]/=ind_diff;
-			delta_J_error[j]=alp_reg::sqrt_for_errors(delta_J_error[j]);
-
-			delta_I_J[j]/=ind_diff;
-			delta_I_J_error[j]/=ind_diff;
-			delta_I_J_error[j]-=delta_I_J[j]*delta_I_J[j];
-			delta_I_J_error[j]/=ind_diff;
-
-
-			delta_I_I[j]/=ind_diff;
-			delta_I_I_error[j]/=ind_diff;
-			delta_I_I_error[j]-=delta_I_I[j]*delta_I_I[j];
-			delta_I_I_error[j]/=ind_diff;
-
-
-			delta_J_J[j]/=ind_diff;
-			delta_J_J_error[j]/=ind_diff;
-			delta_J_J_error[j]-=delta_J_J[j]*delta_J_J[j];
-			delta_J_J_error[j]/=ind_diff;
-
-
-			cov_I_J[j]=delta_I_J[j]-delta_I[j]*delta_J[j];
-			cov_I_I[j]=delta_I_I[j]-delta_I[j]*delta_I[j];
-			cov_J_J[j]=delta_J_J[j]-delta_J[j]*delta_J[j];
-
-			cov_E_E[j]=delta_E_E[j]-delta_E[j]*delta_E[j];
-
-			cov_I_J_error[j]=FSA_utils::error_of_the_product(delta_I[j],delta_I_error[j],delta_J[j],delta_J_error[j]);
-			cov_I_J_error[j]=sqrt(delta_I_J_error[j]+cov_I_J_error[j]*cov_I_J_error[j]);
-
-			cov_I_I_error[j]=FSA_utils::error_of_the_product(delta_I[j],delta_I_error[j],delta_I[j],delta_I_error[j]);
-			cov_I_I_error[j]=sqrt(delta_I_I_error[j]+cov_I_I_error[j]*cov_I_I_error[j]);
-
-			cov_J_J_error[j]=FSA_utils::error_of_the_product(delta_J[j],delta_J_error[j],delta_J[j],delta_J_error[j]);
-			cov_J_J_error[j]=sqrt(delta_J_J_error[j]+cov_J_J_error[j]*cov_J_J_error[j]);
-
-			cov_E_E_error[j]=FSA_utils::error_of_the_product(delta_E[j],delta_E_error[j],delta_E[j],delta_E_error[j]);
-			cov_E_E_error[j]=sqrt(delta_E_E_error[j]+cov_E_E_error[j]*cov_E_E_error[j]);
-
-
-		};
-
-
-		//regression
-
-		double beta1=0;
-		double beta1_error=0;
-
-		long int number_of_elements=nalp_;
-
-		bool cut_left_tail=true;
-		bool cut_right_tail=false;
-
-		double y=2;
-
-		long int k1_opt;
-		long int k2_opt;
-
-
-		double delta_I_aver;
-		double delta_I_aver_error;
-
-
-
-		bool res_was_calculated;
-		
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		delta_I,
-		delta_I_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		delta_I_aver,
-		beta1,
-		delta_I_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			inside_simulation_flag_=false;
-			throw error("",1);
-		};
-
-
-
-		double delta_J_aver;
-		double delta_J_aver_error;
-
-		
-		
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		delta_J,
-		delta_J_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		delta_J_aver,
-		beta1,
-		delta_J_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			inside_simulation_flag_=false;
-			throw error("",1);
-		};
-
-
-		double delta_E_aver;
-		double delta_E_aver_error;
-		
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		delta_E,
-		delta_E_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		delta_E_aver,
-		beta1,
-		delta_E_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			inside_simulation_flag_=false;
-			throw error("",1);
-		};
-
-		double cov_I_I_aver;
-		double cov_I_I_aver_error;
-
-		double cov_I_J_aver;
-		double cov_I_J_aver_error;
-
-		double cov_J_J_aver;
-		double cov_J_J_aver_error;
-
-		double cov_E_E_aver;
-		double cov_E_E_aver_error;
-
-
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		cov_I_J,
-		cov_I_J_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		cov_I_J_aver,
-		beta1,
-		cov_I_J_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			inside_simulation_flag_=false;
-			throw error("",1);
-		};
-
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		cov_I_I,
-		cov_I_I_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		cov_I_I_aver,
-		beta1,
-		cov_I_I_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-
-		if(!res_was_calculated)
-		{
-			inside_simulation_flag_=false;
-			throw error("",1);
-		};
-
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		cov_J_J,
-		cov_J_J_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		cov_J_J_aver,
-		beta1,
-		cov_J_J_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			inside_simulation_flag_=false;
-			throw error("",1);
-		};
-
-		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
-		0,
-		number_of_elements,
-		cov_E_E,
-		cov_E_E_error,
-		cut_left_tail,
-		cut_right_tail,
-		y,
-		cov_E_E_aver,
-		beta1,
-		cov_E_E_aver_error,
-		beta1_error,
-		k1_opt,
-		k2_opt,
-		res_was_calculated);
-
-		if(!res_was_calculated)
-		{
-			inside_simulation_flag_=false;
-			throw error("",1);
-		};
-
-
-
-		if(delta_E_aver<=0)
-		{
-			inside_simulation_flag_=false;
-			throw error("",1);
-		};
-
-
-
-		a_I_=delta_I_aver/delta_E_aver;
-		a_I_error_=FSA_utils::error_of_the_ratio(delta_I_aver,delta_I_aver_error,delta_E_aver,delta_E_aver_error);
-		a_J_=delta_J_aver/delta_E_aver;
-		a_J_error_=FSA_utils::error_of_the_ratio(delta_J_aver,delta_J_aver_error,delta_E_aver,delta_E_aver_error);
-		
-		sigma_calculation(
-		delta_I_aver,
-		delta_I_aver_error,
-		delta_J_aver,
-		delta_J_aver_error,
-		delta_E_aver,
-		delta_E_aver_error,
-		cov_E_E_aver,
-		cov_E_E_aver_error,
-		cov_I_J_aver,
-		cov_I_J_aver_error,
-		sigma_,
-		sigma_error_);
-
-
-		sigma_calculation(
-		delta_I_aver,
-		delta_I_aver_error,
-		delta_I_aver,
-		delta_I_aver_error,
-		delta_E_aver,
-		delta_E_aver_error,
-		cov_E_E_aver,
-		cov_E_E_aver_error,
-		cov_I_I_aver,
-		cov_I_I_aver_error,
-		alpha_I_,
-		alpha_I_error_);
-
-		//for test
-		if(test_FSC_vect_)
-		{
-			test_FSC_vect_[0]=alpha_I_;
-			long int j;
-			for(j=0;j<number_of_elements;j++)
-			{
-				test_FSC_vect_[j+1]=(delta_I[j]*delta_I[j]*cov_E_E[j]+delta_E[j]*delta_E[j]*cov_I_I[j])/(delta_E[j]*delta_E[j]*delta_E[j]);
-			};
-		};
-
-
-		if(test_FSC_vect_)
-		{
-			test_FSC_vect_[0]=lambda_;
-			long int i,j;
-			for(j=1;j<=nalp_;j++)
-			{
-				test_FSC_vect_[j]=0;
-			};
-
-			for(i=ind1_;i<=ind2_;i++)
-			{
-				
-
-				long int j;
-				for(j=1;j<=nalp_;j++)
-				{
-
-					long int &E_j=ALP_edge_max_[i].d_elem[j];
-					double &weight_j=ALP_weight_[i].d_elem[j];
-
-
-					double exp_tmp=lambda_exp(E_j,exp_array)*one_div_C_S_constant;
-
-					double tmp=exp_tmp*weight_j;
-					test_FSC_vect_[j]+=tmp;
-				};
-			};
-
-			for(j=1;j<=nalp_;j++)
-			{
-				test_FSC_vect_[j]/=(double)(ind2_-ind1_)+1;
-			};
-
-		};
-
-
-		sigma_calculation(
-		delta_J_aver,
-		delta_J_aver_error,
-		delta_J_aver,
-		delta_J_aver_error,
-		delta_E_aver,
-		delta_E_aver_error,
-		cov_E_E_aver,
-		cov_E_E_aver_error,
-		cov_J_J_aver,
-		cov_J_J_aver_error,
-		alpha_J_,
-		alpha_J_error_);
-
-		memory_release_for_calculate_FSC(
-		exp_array,
-		delta_E,
-		delta_E_error,
-		delta_E_E,
-		delta_E_E_error,
-		delta_I,
-		delta_I_error,
-		delta_J,
-		delta_J_error,
-		delta_I_I,
-		delta_I_I_error,
-		delta_I_J,
-		delta_I_J_error,
-		delta_J_J,
-		delta_J_J_error,
-		cov_J_J,
-		cov_J_J_error,
-		cov_I_J,
-		cov_I_J_error,
-		cov_I_I,
-		cov_I_I_error,
-		cov_E_E,
-		cov_E_E_error,
-		C_S,
-		C_S_error);
-
-
-	}
-	catch (error er)
-	{
-		if(er.st!="")
-		{
-			throw;
-		}
-		else
-		{
-
-			//memory release
-			memory_release_for_calculate_FSC(
-			exp_array,
-			delta_E,
-			delta_E_error,
-			delta_E_E,
-			delta_E_E_error,
-			delta_I,
-			delta_I_error,
-			delta_J,
-			delta_J_error,
-			delta_I_I,
-			delta_I_I_error,
-			delta_I_J,
-			delta_I_J_error,
-			delta_J_J,
-			delta_J_J_error,
-			cov_J_J,
-			cov_J_J_error,
-			cov_I_J,
-			cov_I_J_error,
-			cov_I_I,
-			cov_I_I_error,
-			cov_E_E,
-			cov_E_E_error,
-			C_S,
-			C_S_error);
-		};
-
-	};
-	}
-	catch (...)
-	{ 
-		//memory release
-		memory_release_for_calculate_FSC(
-		exp_array,
-		delta_E,
-		delta_E_error,
-		delta_E_E,
-		delta_E_E_error,
-		delta_I,
-		delta_I_error,
-		delta_J,
-		delta_J_error,
-		delta_I_I,
-		delta_I_I_error,
-		delta_I_J,
-		delta_I_J_error,
-		delta_J_J,
-		delta_J_J_error,
-		cov_J_J,
-		cov_J_J_error,
-		cov_I_J,
-		cov_I_J_error,
-		cov_I_I,
-		cov_I_I_error,
-		cov_E_E,
-		cov_E_E_error,
-		C_S,
-		C_S_error);
-		throw;
-	};
-}
-
-void fsa_par::sigma_calculation(
-double delta_I_aver_,
-double delta_I_aver_error_,
-double delta_J_aver_,
-double delta_J_aver_error_,
-double delta_E_aver_,
-double delta_E_aver_error_,
-double cov_E_E_aver_,
-double cov_E_E_aver_error_,
-double cov_I_J_aver_,
-double cov_I_J_aver_error_,
-double &sigma_,
-double &sigma_error_)
-{
-	double nom1_1=delta_I_aver_*delta_J_aver_;
-	double nom2_2=delta_E_aver_*delta_E_aver_;
-
-	double den=nom2_2*delta_E_aver_;
-
-	double nom1=nom1_1*cov_E_E_aver_;
-	double nom2=nom2_2*cov_I_J_aver_;
-
-	sigma_=(nom1+nom2)/den;
-
-	
-	double nom1_sigma_error=FSA_utils::error_of_the_product(delta_I_aver_,delta_I_aver_error_,delta_J_aver_,delta_J_aver_error_);
-	nom1_sigma_error=FSA_utils::error_of_the_product(nom1_1,nom1_sigma_error,cov_E_E_aver_,cov_E_E_aver_error_);
-
-	
-	double nom2_sigma_error_2=FSA_utils::error_of_the_product(delta_E_aver_,delta_E_aver_error_,delta_E_aver_,delta_E_aver_error_);
-	double nom2_sigma_error=FSA_utils::error_of_the_product(nom2_2,nom2_sigma_error_2,cov_I_J_aver_,cov_I_J_aver_error_);
-
-	
-	double den_sigma_error=FSA_utils::error_of_the_product(nom2_2,nom2_sigma_error_2,delta_E_aver_,delta_E_aver_error_);
-
-	double nom_sigma_error=FSA_utils::error_of_the_sum(nom1_sigma_error,nom2_sigma_error);
-
-	sigma_error_=FSA_utils::error_of_the_ratio(nom1+nom2,nom_sigma_error,den,den_sigma_error);
-
-}
-
-void fsa_par::Output_Pvalues(
-char type_,//'E' or 'P'
-long int score1_,
-long int score2_,
-vector<double> &pv_,
-vector<double> &pv_err_,
-string pvalout_file_name_)//P-values file name
-{
-	if(!(type_=='E'||type_=='P'))
-	{
-		throw error("Error - the type_ parameter can take only 'E' or 'P' values in void fsa_par::Output_Pvalues\n",1);
-	};
-
-	ofstream f(pvalout_file_name_.data());
-	if(!f)
-	{
-		throw error("Error - the file "+pvalout_file_name_+" cannot be created\n",4);
-	};
-
-	if(type_=='E')
-	{
-		f<<"Score\tE-value\tE-value error\n";
-	};
-
-	if(type_=='P')
-	{
-		f<<"Score\tP-value\tP-value error\n";
-	};
-
-	long int i;
-	for(i=score1_;i<=score2_;i++)
-	{
-		f<<i<<"\t"<<pv_[i-score1_]<<"\t"<<pv_err_[i-score1_]<<endl;
-	};
-
-
-	f.close();
-
-}
-
-void fsa_par::Output_Params(
-Sls::FALP_set_of_parameters &gumbel_params_,
-string gumbelparout_file_name_)
-{
-	ofstream f;
-	ifstream fin;
-
-
-	bool append_flag=false;
-
-	try
-	{
-
-		if(append_flag)
-		{
-			fin.open(gumbelparout_file_name_.data());
-			if(!fin)
-			{
-				append_flag=false;
-			}
-			else
-			{
-				fin.close();
-			};
-		};
-		
-		if(!append_flag)
-		{
-			f.open(gumbelparout_file_name_.data());
-		}
-		else
-		{
-			f.open(gumbelparout_file_name_.data(),ios::app);
-		};
-
-		if(!f)
-		{
-			throw error("Error - file "+gumbelparout_file_name_+" cannot be created\n",4);
-		};
-
-		f<<gumbel_params_;
-
-
-		f.close();
-	}
-	catch (...)
-	{ 
-		if(f.is_open())
-		{
-			f.close();
-		};
-
-		if(append_flag)
-		{
-			if(fin.is_open())
-			{
-				fin.close();
-			};
-		};
-
-		throw;
-	};
-
-}
-
-void fsa_par::Read_Params(
-Sls::FALP_set_of_parameters &gumbel_params_,
-string gumbelparin_file_name_)
-{
-	ifstream f;
-
-	try
-	{
-
-		gumbel_params_.d_params_flag=false;
-
-		f.open(gumbelparin_file_name_.data());
-		if(!f)
-		{
-			throw error("Error - file "+gumbelparin_file_name_+" is not found\n",4);
-		};
-
-		f>>gumbel_params_;
-
-		f.close();
-		gumbel_params_.d_params_flag=true;
-
-	}
-	catch (...)
-	{ 
-		gumbel_params_.d_params_flag=false;
-		if(f.is_open())
-		{
-			f.close();
-		};
-		throw;
-	};
-}
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_fsa1_parameters.cpp
+
+Author: Sergey Sheetlin
+
+Contents: Calculation of Gumbel parameters
+
+******************************************************************************/
+
+
+#include "sls_fsa1_parameters.hpp"
+
+using namespace Sls;
+using namespace std;
+
+//parameters calculation
+double fsa_par::function_for_lambda_calculation(
+double lambda_,
+void * data_)
+{
+
+	double *expect=NULL;
+	double *expect_errors=NULL;
+
+	try
+	{
+
+		struct_for_lambda_calculation *tmp_struct=(struct_for_lambda_calculation *)data_;
+		void **alp_distr=tmp_struct->d_alp_distr;
+		void **alp_distr_errors=tmp_struct->d_alp_distr_errors;
+		long int nalp=tmp_struct->d_nalp;
+
+		expect=new double[nalp];
+		FSA_utils::assert_mem(expect);
+		expect_errors=new double[nalp];
+		FSA_utils::assert_mem(expect_errors);
+
+		if(nalp<1)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+
+
+		long int k;
+		for(k=1;k<=nalp;k++)
+		{
+			array_v<double>* tmp=((array_v<double>*)alp_distr[k]);
+			array_v<double>* tmp_errors=((array_v<double>*)alp_distr_errors[k]);
+
+			double val=0;
+			double val_error=0;
+
+			long int j;
+			for(j=0;j<=tmp->d_dim;j++)
+			{
+				if(tmp->d_elem[j]<=0)
+				{
+					continue;
+				};
+				double exp_tmp=exp(lambda_*(j+tmp->d_ind0));
+				val+=exp_tmp*tmp->d_elem[j];
+				val_error+=exp_tmp*exp_tmp*tmp_errors->d_elem[j];
+			};
+			val_error=alp_reg::sqrt_for_errors(val_error);
+			expect[k-1]=val;
+			expect_errors[k-1]=val_error;
+
+		};
+
+		tmp_struct->d_last_sum=expect[nalp-1];
+		tmp_struct->d_last_sum_error=expect_errors[nalp-1];
+
+		if(nalp==1)
+		{
+			tmp_struct->d_before_last_sum=1.0;
+			tmp_struct->d_before_last_sum_error=0.0;
+		}
+		else
+		{
+			tmp_struct->d_before_last_sum=expect[nalp-2];
+			tmp_struct->d_before_last_sum_error=expect_errors[nalp-2];
+		};
+
+		if(tmp_struct->d_calculate_alp_number)
+		{
+			double tmp=0.0;
+			long int k;
+			for(k=0;k<nalp;k++)
+			{
+				if(expect_errors[k]!=0)
+				{
+					tmp+=1.0/(expect_errors[k]*expect_errors[k]);
+				};
+
+			};
+
+			long int tmp_alp=nalp;
+			double tmp1=0.0;
+			for(k=nalp-1;k>=0;k--)
+			{
+				if(expect_errors[k]!=0)
+				{
+					tmp1+=1.0/(expect_errors[k]*expect_errors[k]);
+				};
+				if(tmp1>0.2*tmp)
+				{
+					tmp_alp=k+1;
+					break;
+				};
+			};
+
+			tmp_struct->d_alp_number=tmp_alp;
+		};
+
+		if(nalp==1)
+		{
+			double tmp=expect[0]-1.0;
+			tmp_struct->d_f_error=expect_errors[0];
+			delete[]expect;expect=NULL;
+			delete[]expect_errors;expect_errors=NULL;
+			return tmp;
+		};
+
+
+		long int min_length=0;
+		long int number_of_elements=nalp;
+		bool cut_left_tail=true;
+		bool cut_right_tail=false;
+		double y=2;
+		double beta0;
+		double beta1;
+		double beta0_error;
+		double beta1_error;
+		long int k1_opt;
+		long int k2_opt;
+
+		bool res_was_calculated;
+
+		alp_reg::robust_regression_sum_with_cut_LSM(
+		min_length,
+		number_of_elements,
+		expect,
+		expect_errors,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		beta0,
+		beta1,
+		beta0_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+
+
+		if(!res_was_calculated)
+		{
+			throw error("",2);
+		};
+
+
+		delete[]expect;expect=NULL;
+		delete[]expect_errors;expect_errors=NULL;
+
+		tmp_struct->d_f_error=beta1_error;
+		return beta1;
+
+	}
+	catch (...)
+	{ 
+		delete[]expect;expect=NULL;
+		delete[]expect_errors;expect_errors=NULL;
+		throw;
+	};
+
+}
+
+void fsa_par::calculate_lambda(
+bool check_the_criteria_,
+long int nalp_,
+long int &nalp_thr_,
+bool &inside_simulation_flag_,
+void **alp_distr,
+void **alp_distr_errors,
+double ungapped_lambda_,
+double &lambda_,
+double &lambda_error_)
+{
+
+	bool ee_error_flag=false;
+	error ee_error("",0);
+
+	inside_simulation_flag_=false;
+
+	try
+	{
+
+		long int nalp=nalp_;
+
+		if(nalp<=0)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+		
+
+		struct_for_lambda_calculation tmp_struct;
+		tmp_struct.d_alp_distr=alp_distr;
+		tmp_struct.d_alp_distr_errors=alp_distr_errors;
+		tmp_struct.d_nalp=nalp;
+		tmp_struct.d_calculate_alp_number=false;
+
+
+		function_type *func=function_for_lambda_calculation;
+		void* func_pointer=&tmp_struct;
+		double a=0;
+		double b=ungapped_lambda_*2;
+		//double b=ungapped_lambda_*10;
+		long int n_partition=30;
+		//long int n_partition=300;
+		double eps=1e-10;
+		std::vector<double> res;
+
+		alp_reg::find_tetta_general(
+		func,
+		func_pointer,
+		a,//[a,b] is the interval for search of equation solution
+		b,
+		n_partition,
+		eps,
+		res);
+
+		
+
+
+		inside_simulation_flag_=true;
+		if(res.size()==0)
+		{
+			inside_simulation_flag_=false;
+			return;
+		};
+
+		
+
+		lambda_=get_root(res,ungapped_lambda_);
+		
+
+		tmp_struct.d_calculate_alp_number=true;
+		double f1=func(lambda_,func_pointer);
+		nalp_thr_=tmp_struct.d_alp_number;
+		tmp_struct.d_calculate_alp_number=false;
+
+		double slope_error=tmp_struct.d_f_error;
+
+		double delta_lambda=lambda_/100.0;
+		double f2=func(lambda_+delta_lambda,func_pointer);
+		
+		
+
+		if(delta_lambda==0||f1==f2)
+		{
+			lambda_error_=0.0;
+		}
+		else
+		{
+			double derivative=(f2-f1)/delta_lambda;
+			lambda_error_=fabs(slope_error/derivative);
+		};
+		
+		if(!check_the_criteria_)
+		{
+			return;
+		};
+
+
+	}
+	catch (error er)
+	{
+		ee_error_flag=true;
+		ee_error=er;		
+	};
+
+
+	if(ee_error_flag)
+	{
+		if(ee_error.st!="")
+		{
+			throw error(ee_error.st,ee_error.error_code);
+		}
+		else
+		{
+			inside_simulation_flag_=false;
+		};
+	};
+
+}
+
+void fsa_par::memory_releace_for_calculate_C(
+double *&P,
+double *&P_errors,
+double *&values_P_ratio,
+double *&errors_P_ratio,
+
+double *&E,
+double *&E_errors,
+
+double *&E_T_beta,
+double *&E_T_beta_errors)
+{
+	delete[]values_P_ratio;values_P_ratio=NULL;
+	delete[]errors_P_ratio;errors_P_ratio=NULL;
+
+
+	delete[]P;P=NULL;
+	delete[]P_errors;P_errors=NULL;
+
+	delete[]E;E=NULL;
+	delete[]E_T_beta;E_T_beta=NULL;
+	delete[]E_errors;E_errors=NULL;
+	delete[]E_T_beta_errors;E_T_beta_errors=NULL;
+}
+
+void fsa_par::calculate_C(
+long int starting_point,
+long int nalp_,
+void **alp_distr,
+void **alp_distr_errors,
+double lambda_,
+double lambda_error_,
+double &C_,
+double &C_error_,
+bool &inside_simulation_flag_)
+{
+	inside_simulation_flag_=true;
+
+	error ee_error("",0);
+
+	double *P=NULL;
+	double *P_errors=NULL;
+	double *values_P_ratio=NULL;
+	double *errors_P_ratio=NULL;
+
+	double *E=NULL;
+	double *E_errors=NULL;
+
+	double *E_T_beta=NULL;
+	double *E_T_beta_errors=NULL;
+
+
+	try
+	{
+	try
+	{
+
+		long int total_number_of_ALP=nalp_;
+
+		if(total_number_of_ALP<1)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+
+		//1)P(beta=infinity)
+		long int j;
+
+
+		P=new double[total_number_of_ALP+1];
+		FSA_utils::assert_mem(P);
+		P_errors=new double[total_number_of_ALP+1];
+		FSA_utils::assert_mem(P_errors);
+
+		P[0]=1.0;
+		P_errors[0]=0.0;
+
+		
+		for(j=1;j<=total_number_of_ALP;j++)
+		{
+			array_v<double>* tmp=((array_v<double>*)alp_distr[j]);
+			array_v<double>* tmp_errors=((array_v<double>*)alp_distr_errors[j]);
+
+			P[j]=0;
+			P_errors[j]=0;
+			long int i;
+			for(i=0;i<=tmp->d_dim;i++)
+			{
+				P[j]+=tmp->d_elem[i];
+				P_errors[j]+=tmp_errors->d_elem[i];
+			};
+
+			P_errors[j]=alp_reg::sqrt_for_errors(P_errors[j]);
+		};
+
+		
+
+		values_P_ratio=new double[total_number_of_ALP];
+		FSA_utils::assert_mem(values_P_ratio);
+		errors_P_ratio=new double[total_number_of_ALP];
+		FSA_utils::assert_mem(errors_P_ratio);
+
+		
+
+		for(j=0;j<total_number_of_ALP;j++)
+		{
+			if(P[j]<=0)
+			{
+				inside_simulation_flag_=false;
+				throw error("",1);
+			};
+			values_P_ratio[j]=P[j+1]/P[j];
+			errors_P_ratio[j]=FSA_utils::error_of_the_ratio(P[j+1],P_errors[j+1],P[j],P_errors[j]);
+		};
+
+
+
+		double beta1=0;
+		double beta1_error=0;
+
+		long int number_of_elements=total_number_of_ALP;
+
+		bool cut_left_tail=true;
+		bool cut_right_tail=false;
+
+		double y=2;
+
+		long int k1_opt;
+		long int k2_opt;
+
+
+		double P_beta_inf;
+		double P_beta_inf_error=0;
+
+		bool res_was_calculated;
+		
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements-starting_point,
+		values_P_ratio+starting_point,
+		errors_P_ratio+starting_point,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		P_beta_inf,
+		beta1,
+		P_beta_inf_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+
+		
+
+		if(!res_was_calculated)
+		{
+			//throw error("The program cannot estimate the parameters; please repeat the calculation9\n",2);
+			inside_simulation_flag_=false;
+			throw error("",1);
+		};
+
+		P_beta_inf=1-P_beta_inf;
+
+		
+
+		
+		//2)E(exp(lambda*T_beta)) and E(T_beta*exp(lambda*T_beta))
+		E=new double[total_number_of_ALP+1];
+		FSA_utils::assert_mem(E);
+		E_errors=new double[total_number_of_ALP+1];
+		FSA_utils::assert_mem(E_errors);
+
+		E_T_beta=new double[total_number_of_ALP+1];
+		FSA_utils::assert_mem(E_T_beta);
+		E_T_beta_errors=new double[total_number_of_ALP+1];
+		FSA_utils::assert_mem(E_T_beta);
+
+
+		E[0]=1;
+		E_T_beta[0]=0;
+
+		E_errors[0]=0;
+		E_T_beta_errors[0]=0;
+
+		
+
+
+		for(j=1;j<=total_number_of_ALP;j++)
+		{
+			array_v<double>* tmp=((array_v<double>*)alp_distr[j]);
+			array_v<double>* tmp_errors=((array_v<double>*)alp_distr_errors[j]);
+
+			E[j]=0;
+			E_T_beta[j]=0;
+
+			E_errors[j]=0;
+			E_T_beta_errors[j]=0;
+
+			long int i;
+			for(i=0;i<=tmp->d_dim;i++)
+			{
+				double tmp_double=exp(lambda_*(double)i);
+				E[j]+=tmp_double*tmp->d_elem[i];
+				E_errors[j]+=tmp_double*tmp_double*tmp_errors->d_elem[i];
+
+				tmp_double=(double)i*exp(lambda_*(double)i);
+				E_T_beta[j]+=tmp_double*tmp->d_elem[i];
+				E_T_beta_errors[j]+=tmp_double*tmp_double*tmp_errors->d_elem[i];
+			};
+
+			E_errors[j]=alp_reg::sqrt_for_errors(E_errors[j]);
+			E_T_beta_errors[j]=alp_reg::sqrt_for_errors(E_T_beta_errors[j]);
+
+		};
+
+
+		double E_aver;
+		double E_aver_error;
+
+		double E_T_beta_diff_aver;
+		double E_T_beta_diff_aver_error;
+
+
+		if(total_number_of_ALP==1)
+		{
+			E_aver=E[1];
+			E_aver_error=E_errors[1];
+
+			E_T_beta_diff_aver=E_T_beta[1]-E_T_beta[0];
+			E_T_beta_diff_aver_error=E_T_beta_errors[1];
+
+		}
+		else
+		{
+			long int number_of_elements=total_number_of_ALP;
+
+			bool cut_left_tail=true;
+			bool cut_right_tail=false;
+
+
+			double beta0;
+			double beta1=0;
+			double beta0_error;
+			double beta1_error=0;
+
+			bool res_was_calculated;
+
+			alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+			0,
+			number_of_elements-starting_point,
+			E+1+starting_point,
+			E_errors+1+starting_point,
+			cut_left_tail,
+			cut_right_tail,
+			y,
+			E_aver,
+			beta1,
+			E_aver_error,
+			beta1_error,
+			k1_opt,
+			k2_opt,
+			res_was_calculated);
+
+
+			if(!res_was_calculated)
+			{
+				inside_simulation_flag_=false;
+				throw error("",1);
+			};
+
+
+
+			number_of_elements=total_number_of_ALP;
+
+
+			alp_reg::robust_regression_sum_with_cut_LSM(
+			0,
+			number_of_elements-starting_point,
+			E_T_beta+1+starting_point,
+			E_T_beta_errors+1+starting_point,
+			cut_left_tail,
+			cut_right_tail,
+			y,
+			beta0,
+			beta1,
+			beta0_error,
+			beta1_error,
+			k1_opt,
+			k2_opt,
+			res_was_calculated);
+
+			
+
+			if(!res_was_calculated)
+			{
+				//throw error("The program cannot estimate the parameters; please repeat the calculation11\n",2);
+				inside_simulation_flag_=false;
+				throw error("",1);
+			};
+
+
+			E_T_beta_diff_aver=beta1;
+			E_T_beta_diff_aver_error=beta1_error;
+
+
+			
+			
+		};
+
+
+		double exp_lambda_error=exp(-lambda_)*lambda_error_;
+		double exp_lambda=(1-exp(-lambda_));
+
+		
+		double den_error=FSA_utils::error_of_the_product(E_T_beta_diff_aver,E_T_beta_diff_aver_error,exp_lambda,exp_lambda_error);
+		double den=(1-exp(-lambda_))*E_T_beta_diff_aver;
+
+
+		double nom_error=FSA_utils::error_of_the_product(P_beta_inf,P_beta_inf_error,E_aver,E_aver_error);
+		double nom=P_beta_inf*E_aver;
+
+
+		C_error_=FSA_utils::error_of_the_ratio(nom,nom_error,den,den_error);
+
+		if(den<=0)
+		{
+			inside_simulation_flag_=false;
+			throw error("",1);
+		};
+
+		C_=nom/den;
+
+		memory_releace_for_calculate_C(
+		P,
+		P_errors,
+		values_P_ratio,
+		errors_P_ratio,
+
+		E,
+		E_errors,
+
+		E_T_beta,
+		E_T_beta_errors);
+
+
+	}
+	catch (error er)
+	{
+		if(er.st!="")
+		{
+			throw;
+		}
+		else
+		{
+			memory_releace_for_calculate_C(
+			P,
+			P_errors,
+			values_P_ratio,
+			errors_P_ratio,
+
+			E,
+			E_errors,
+
+			E_T_beta,
+			E_T_beta_errors);
+		};
+
+	};
+	}
+	catch (...)
+	{ 
+		//memory release
+		memory_releace_for_calculate_C(
+		P,
+		P_errors,
+		values_P_ratio,
+		errors_P_ratio,
+
+		E,
+		E_errors,
+
+		E_T_beta,
+		E_T_beta_errors);
+		throw;
+	};
+
+
+
+}
+
+
+double fsa_par::get_root(
+const std::vector<double> &res_tmp_,
+double point_)
+{
+	if(res_tmp_.size()==0)
+	{
+		throw error("Error in alp_sim::get_root - the equation does not have any solutions\n",2);
+	};
+
+	long int i;
+	long int p=0;
+	double d1=fabs(point_-res_tmp_[0]);
+	for(i=1;i<(long int)res_tmp_.size();i++)
+	{
+		double d2=fabs(point_-res_tmp_[i]);
+		if(d2<d1)
+		{
+			p=i;
+			d1=d2;
+		};
+	};
+
+	return res_tmp_[p];
+}
+
+//------------------------------------------
+//FSC
+double fsa_par::lambda_exp(
+long int &i_,
+double *&exp_array_)
+{
+
+	if(exp_array_[i_]==-1)
+	{
+		throw error("The program is not able to calculate the parameters; rescaling penalties and scoring matrix might help\n",3);
+	};
+
+	return exp_array_[i_];
+}
+
+void fsa_par::memory_release_for_calculate_FSC(
+double *&exp_array,
+double *&delta_E,
+double *&delta_E_error,
+double *&delta_E_E,
+double *&delta_E_E_error,
+double *&delta_I,
+double *&delta_I_error,
+double *&delta_J,
+double *&delta_J_error,
+double *&delta_I_I,
+double *&delta_I_I_error,
+double *&delta_I_J,
+double *&delta_I_J_error,
+double *&delta_J_J,
+double *&delta_J_J_error,
+double *&cov_J_J,
+double *&cov_J_J_error,
+double *&cov_I_J,
+double *&cov_I_J_error,
+double *&cov_I_I,
+double *&cov_I_I_error,
+double *&cov_E_E,
+double *&cov_E_E_error,
+double *&C_S,
+double *&C_S_error)
+{
+	//memory release
+	delete[]exp_array;exp_array=NULL;
+
+	delete[]delta_E;delta_E=NULL;
+	delete[]delta_E_error;delta_E_error=NULL;
+	delete[]delta_E_E;delta_E_E=NULL;
+	delete[]delta_E_E_error;delta_E_E_error=NULL;
+
+	delete[]delta_I;delta_I=NULL;
+	delete[]delta_I_error;delta_I_error=NULL;
+	delete[]delta_J;delta_J=NULL;
+	delete[]delta_J_error;delta_J_error=NULL;
+
+	delete[]delta_I_J;delta_I_J=NULL;
+	delete[]delta_I_J_error;delta_I_J_error=NULL;
+	delete[]delta_J_J;delta_J_J=NULL;
+	delete[]delta_J_J_error;delta_J_J_error=NULL;
+	delete[]delta_I_I;delta_I_I=NULL;
+	delete[]delta_I_I_error;delta_I_I_error=NULL;
+
+	delete[]cov_I_J;cov_I_J=NULL;
+	delete[]cov_I_J_error;cov_I_J_error=NULL;
+	delete[]cov_J_J;cov_J_J=NULL;
+	delete[]cov_J_J_error;cov_J_J_error=NULL;
+	delete[]cov_I_I;cov_I_I=NULL;
+	delete[]cov_I_I_error;cov_I_I_error=NULL;
+	delete[]cov_E_E;cov_E_E=NULL;
+	delete[]cov_E_E_error;cov_E_E_error=NULL;
+
+	delete[]C_S;C_S=NULL;
+	delete[]C_S_error;C_S_error=NULL;
+}
+
+void fsa_par::calculate_FSC(
+long int nalp_,
+long int ind1_,
+long int ind2_,
+
+double lambda_,
+
+long int M_max_,
+
+array_positive<long int> *distance_along_direction_1_,
+array_positive<long int> *distance_along_direction_2_,
+
+array_positive<double> *ALP_weight_,
+array_positive<long int> *ALP_edge_max_,
+
+double &a_I_,
+double &a_I_error_,
+double &a_J_,
+double &a_J_error_,
+double &sigma_,
+double &sigma_error_,
+double &alpha_I_,
+double &alpha_I_error_,
+double &alpha_J_,
+double &alpha_J_error_,
+bool &inside_simulation_flag_,
+double *test_FSC_vect_)//for tests
+{
+	inside_simulation_flag_=true;
+
+	double *exp_array=NULL;
+
+	double *delta_E=NULL;
+	double *delta_E_error=NULL;
+
+	double *delta_E_E=NULL;
+	double *delta_E_E_error=NULL;
+
+
+	double *delta_I=NULL;
+	double *delta_I_error=NULL;
+
+	double *delta_J=NULL;
+	double *delta_J_error=NULL;
+
+	double *delta_I_I=NULL;
+	double *delta_I_I_error=NULL;
+
+	double *delta_I_J=NULL;
+	double *delta_I_J_error=NULL;
+
+	double *delta_J_J=NULL;
+	double *delta_J_J_error=NULL;
+
+	double *cov_J_J=NULL;
+	double *cov_J_J_error=NULL;
+
+	double *cov_I_J=NULL;
+	double *cov_I_J_error=NULL;
+
+	double *cov_I_I=NULL;
+	double *cov_I_I_error=NULL;
+
+	double *cov_E_E=NULL;
+	double *cov_E_E_error=NULL;
+
+	double *C_S=NULL;
+	double *C_S_error=NULL;
+
+
+	try
+	{
+	try
+	{
+
+
+		if(nalp_<1)
+		{
+			throw error("Unexpected error\n",4);
+		};
+
+		double dbl_max_log=log(DBL_MAX);
+
+
+		exp_array=new double[M_max_+1];
+		FSA_utils::assert_mem(exp_array);
+
+
+		long int i;
+		for(i=0;i<=M_max_;i++)
+		{
+			double tmp=(double)i*lambda_;
+			if(tmp<dbl_max_log)
+			{
+				exp_array[i]=exp(tmp);
+			}
+			else
+			{
+				exp_array[i]=-1;
+			};
+		};
+
+		
+
+
+		delta_E=new double[nalp_];
+		FSA_utils::assert_mem(delta_E);
+		delta_E_error=new double[nalp_];
+		FSA_utils::assert_mem(delta_E_error);
+
+		delta_E_E=new double[nalp_];
+		FSA_utils::assert_mem(delta_E_E);
+		delta_E_E_error=new double[nalp_];
+		FSA_utils::assert_mem(delta_E_E_error);
+
+		cov_E_E=new double[nalp_];
+		FSA_utils::assert_mem(cov_E_E);
+		cov_E_E_error=new double[nalp_];
+		FSA_utils::assert_mem(cov_E_E_error);
+
+
+		delta_I=new double[nalp_];
+		FSA_utils::assert_mem(delta_I);
+		delta_I_error=new double[nalp_];
+		FSA_utils::assert_mem(delta_I_error);
+
+		delta_J=new double[nalp_];
+		FSA_utils::assert_mem(delta_J);
+		delta_J_error=new double[nalp_];
+		FSA_utils::assert_mem(delta_J_error);
+
+		delta_I_I=new double[nalp_];
+		FSA_utils::assert_mem(delta_I_I);
+		delta_I_I_error=new double[nalp_];
+		FSA_utils::assert_mem(delta_I_I_error);
+
+		delta_I_J=new double[nalp_];
+		FSA_utils::assert_mem(delta_I_J);
+		delta_I_J_error=new double[nalp_];
+		FSA_utils::assert_mem(delta_I_J_error);
+
+		delta_J_J=new double[nalp_];
+		FSA_utils::assert_mem(delta_J_J);
+		delta_J_J_error=new double[nalp_];
+		FSA_utils::assert_mem(delta_J_J_error);
+
+		cov_J_J=new double[nalp_];
+		FSA_utils::assert_mem(cov_J_J);
+		cov_J_J_error=new double[nalp_];
+		FSA_utils::assert_mem(cov_J_J_error);
+
+		cov_I_J=new double[nalp_];
+		FSA_utils::assert_mem(cov_I_J);
+		cov_I_J_error=new double[nalp_];
+		FSA_utils::assert_mem(cov_I_J_error);
+
+		cov_I_I=new double[nalp_];
+		FSA_utils::assert_mem(cov_I_I);
+		cov_I_I_error=new double[nalp_];
+		FSA_utils::assert_mem(cov_I_I_error);
+
+		C_S=new double[nalp_];
+		FSA_utils::assert_mem(C_S);
+		C_S_error=new double[nalp_];
+		FSA_utils::assert_mem(C_S_error);
+
+
+		long int j;
+		for(j=0;j<nalp_;j++)
+		{
+			delta_E[j]=0.0;
+			delta_E_error[j]=0.0;
+
+			delta_E_E[j]=0.0;
+			delta_E_E_error[j]=0.0;
+
+			delta_I[j]=0.0;
+			delta_I_error[j]=0.0;
+			delta_J[j]=0.0;
+			delta_J_error[j]=0.0;
+
+			delta_I_I[j]=0.0;
+
+			delta_I_I_error[j]=0.0;
+			delta_I_J[j]=0.0;
+			delta_I_J_error[j]=0.0;
+			delta_J_J[j]=0.0;
+			delta_J_J_error[j]=0.0;
+
+			C_S[j]=0.0;
+			C_S_error[j]=0.0;
+
+		};
+
+		double C_S_constant=1.0;
+		//calculate the constant
+		bool calculate_C_S_constant_flag=true;
+		if(calculate_C_S_constant_flag)
+		{
+			long int i;
+			for(i=ind1_;i<=ind2_;i++)
+			{
+				long int j;
+				for(j=1;j<=nalp_;j++)
+				{
+
+					long int &E_j=ALP_edge_max_[i].d_elem[j];
+					double &weight_j=ALP_weight_[i].d_elem[j];
+
+
+					double tmp=lambda_exp(E_j,exp_array)*weight_j;
+
+					C_S[j-1]+=tmp;
+					C_S_error[j-1]+=tmp*tmp;
+				};
+			};
+
+			double ind_diff=(double)(ind2_-ind1_+1);
+			for(j=0;j<nalp_;j++)
+			{
+				C_S[j]/=ind_diff;
+				C_S_error[j]/=ind_diff;
+				C_S_error[j]-=C_S[j]*C_S[j];
+				C_S_error[j]/=ind_diff;
+				C_S_error[j]=alp_reg::sqrt_for_errors(C_S_error[j]);
+
+			};
+
+			//regression
+
+			double beta1=0;
+			double beta1_error=0;
+
+			long int number_of_elements=nalp_;
+
+			bool cut_left_tail=true;
+			bool cut_right_tail=false;
+
+			double y=2;
+
+			long int k1_opt;
+			long int k2_opt;
+
+
+			double C_S_constant_error;
+
+
+			bool res_was_calculated;
+			
+			alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+			0,
+			number_of_elements,
+			C_S,
+			C_S_error,
+			cut_left_tail,
+			cut_right_tail,
+			y,
+			C_S_constant,
+			beta1,
+			C_S_constant_error,
+			beta1_error,
+			k1_opt,
+			k2_opt,
+			res_was_calculated);
+
+			if(!res_was_calculated||C_S_constant<=0)
+			{
+				inside_simulation_flag_=false;
+				throw error("",1);
+			};
+
+		};
+
+		double one_div_C_S_constant=1.0/C_S_constant;
+
+
+		
+		for(i=ind1_;i<=ind2_;i++)
+		{
+
+			long int j;
+			for(j=1;j<=nalp_;j++)
+			{
+				long int j_1=j-1;
+
+				long int &E_j_1=ALP_edge_max_[i].d_elem[j_1];
+				long int &E_j=ALP_edge_max_[i].d_elem[j];
+				double &weight_j=ALP_weight_[i].d_elem[j];
+
+				long int &I_j_1=distance_along_direction_1_[i].d_elem[j_1];
+				long int &I_j=distance_along_direction_1_[i].d_elem[j];
+
+				long int &J_j_1=distance_along_direction_2_[i].d_elem[j_1];
+				long int &J_j=distance_along_direction_2_[i].d_elem[j];
+
+				double exp_tmp=lambda_exp(E_j,exp_array)*one_div_C_S_constant;
+
+				double delta_I_tmp=(I_j-I_j_1)*exp_tmp*weight_j;
+				double delta_J_tmp=(J_j-J_j_1)*exp_tmp*weight_j;
+				double delta_E_tmp=(E_j-E_j_1)*exp_tmp*weight_j;
+				double delta_E_E_tmp=(E_j-E_j_1)*(E_j-E_j_1)*exp_tmp*weight_j;
+
+				
+
+				
+				double delta_I_I_tmp=delta_I_tmp*(I_j-I_j_1);
+				double delta_J_J_tmp=delta_J_tmp*(J_j-J_j_1);
+				double delta_I_J_tmp=delta_I_tmp*(J_j-J_j_1);
+
+	
+
+
+				delta_E[j_1]+=delta_E_tmp;
+				delta_E_error[j_1]+=delta_E_tmp*delta_E_tmp;
+
+				delta_E_E[j_1]+=delta_E_E_tmp;
+				delta_E_E_error[j_1]+=delta_E_E_tmp*delta_E_E_tmp;
+
+				delta_I[j_1]+=delta_I_tmp;
+				delta_I_error[j_1]+=delta_I_tmp*delta_I_tmp;
+				delta_J[j_1]+=delta_J_tmp;
+				delta_J_error[j_1]+=delta_J_tmp*delta_J_tmp;
+
+				delta_I_I[j_1]+=delta_I_I_tmp;
+				delta_I_I_error[j_1]+=delta_I_I_tmp*delta_I_I_tmp;
+
+				delta_I_J[j_1]+=delta_I_J_tmp;
+				delta_I_J_error[j_1]+=delta_I_J_tmp*delta_I_J_tmp;
+
+				delta_J_J[j_1]+=delta_J_J_tmp;
+				delta_J_J_error[j_1]+=delta_J_J_tmp*delta_J_J_tmp;
+				
+			};
+		};
+
+
+		double ind_diff=(double)(ind2_-ind1_+1);
+		for(j=0;j<nalp_;j++)
+		{
+			delta_E[j]/=ind_diff;
+			delta_E_error[j]/=ind_diff;
+			delta_E_error[j]-=delta_E[j]*delta_E[j];
+			delta_E_error[j]/=ind_diff;
+			delta_E_error[j]=alp_reg::sqrt_for_errors(delta_E_error[j]);
+
+			
+
+			delta_E_E[j]/=ind_diff;
+			delta_E_E_error[j]/=ind_diff;
+			delta_E_E_error[j]-=delta_E_E[j]*delta_E_E[j];
+			delta_E_E_error[j]/=ind_diff;
+
+
+			delta_I[j]/=ind_diff;
+			delta_I_error[j]/=ind_diff;
+			delta_I_error[j]-=delta_I[j]*delta_I[j];
+			delta_I_error[j]/=ind_diff;
+			delta_I_error[j]=alp_reg::sqrt_for_errors(delta_I_error[j]);
+
+			delta_J[j]/=ind_diff;
+			delta_J_error[j]/=ind_diff;
+			delta_J_error[j]-=delta_J[j]*delta_J[j];
+			delta_J_error[j]/=ind_diff;
+			delta_J_error[j]=alp_reg::sqrt_for_errors(delta_J_error[j]);
+
+			delta_I_J[j]/=ind_diff;
+			delta_I_J_error[j]/=ind_diff;
+			delta_I_J_error[j]-=delta_I_J[j]*delta_I_J[j];
+			delta_I_J_error[j]/=ind_diff;
+
+
+			delta_I_I[j]/=ind_diff;
+			delta_I_I_error[j]/=ind_diff;
+			delta_I_I_error[j]-=delta_I_I[j]*delta_I_I[j];
+			delta_I_I_error[j]/=ind_diff;
+
+
+			delta_J_J[j]/=ind_diff;
+			delta_J_J_error[j]/=ind_diff;
+			delta_J_J_error[j]-=delta_J_J[j]*delta_J_J[j];
+			delta_J_J_error[j]/=ind_diff;
+
+
+			cov_I_J[j]=delta_I_J[j]-delta_I[j]*delta_J[j];
+			cov_I_I[j]=delta_I_I[j]-delta_I[j]*delta_I[j];
+			cov_J_J[j]=delta_J_J[j]-delta_J[j]*delta_J[j];
+
+			cov_E_E[j]=delta_E_E[j]-delta_E[j]*delta_E[j];
+
+			cov_I_J_error[j]=FSA_utils::error_of_the_product(delta_I[j],delta_I_error[j],delta_J[j],delta_J_error[j]);
+			cov_I_J_error[j]=sqrt(delta_I_J_error[j]+cov_I_J_error[j]*cov_I_J_error[j]);
+
+			cov_I_I_error[j]=FSA_utils::error_of_the_product(delta_I[j],delta_I_error[j],delta_I[j],delta_I_error[j]);
+			cov_I_I_error[j]=sqrt(delta_I_I_error[j]+cov_I_I_error[j]*cov_I_I_error[j]);
+
+			cov_J_J_error[j]=FSA_utils::error_of_the_product(delta_J[j],delta_J_error[j],delta_J[j],delta_J_error[j]);
+			cov_J_J_error[j]=sqrt(delta_J_J_error[j]+cov_J_J_error[j]*cov_J_J_error[j]);
+
+			cov_E_E_error[j]=FSA_utils::error_of_the_product(delta_E[j],delta_E_error[j],delta_E[j],delta_E_error[j]);
+			cov_E_E_error[j]=sqrt(delta_E_E_error[j]+cov_E_E_error[j]*cov_E_E_error[j]);
+
+
+		};
+
+
+		//regression
+
+		double beta1=0;
+		double beta1_error=0;
+
+		long int number_of_elements=nalp_;
+
+		bool cut_left_tail=true;
+		bool cut_right_tail=false;
+
+		double y=2;
+
+		long int k1_opt;
+		long int k2_opt;
+
+
+		double delta_I_aver;
+		double delta_I_aver_error;
+
+
+
+		bool res_was_calculated;
+		
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		delta_I,
+		delta_I_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		delta_I_aver,
+		beta1,
+		delta_I_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			inside_simulation_flag_=false;
+			throw error("",1);
+		};
+
+
+
+		double delta_J_aver;
+		double delta_J_aver_error;
+
+		
+		
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		delta_J,
+		delta_J_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		delta_J_aver,
+		beta1,
+		delta_J_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			inside_simulation_flag_=false;
+			throw error("",1);
+		};
+
+
+		double delta_E_aver;
+		double delta_E_aver_error;
+		
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		delta_E,
+		delta_E_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		delta_E_aver,
+		beta1,
+		delta_E_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			inside_simulation_flag_=false;
+			throw error("",1);
+		};
+
+		double cov_I_I_aver;
+		double cov_I_I_aver_error;
+
+		double cov_I_J_aver;
+		double cov_I_J_aver_error;
+
+		double cov_J_J_aver;
+		double cov_J_J_aver_error;
+
+		double cov_E_E_aver;
+		double cov_E_E_aver_error;
+
+
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		cov_I_J,
+		cov_I_J_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		cov_I_J_aver,
+		beta1,
+		cov_I_J_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			inside_simulation_flag_=false;
+			throw error("",1);
+		};
+
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		cov_I_I,
+		cov_I_I_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		cov_I_I_aver,
+		beta1,
+		cov_I_I_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+
+		if(!res_was_calculated)
+		{
+			inside_simulation_flag_=false;
+			throw error("",1);
+		};
+
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		cov_J_J,
+		cov_J_J_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		cov_J_J_aver,
+		beta1,
+		cov_J_J_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			inside_simulation_flag_=false;
+			throw error("",1);
+		};
+
+		alp_reg::robust_regression_sum_with_cut_LSM_beta1_is_defined(
+		0,
+		number_of_elements,
+		cov_E_E,
+		cov_E_E_error,
+		cut_left_tail,
+		cut_right_tail,
+		y,
+		cov_E_E_aver,
+		beta1,
+		cov_E_E_aver_error,
+		beta1_error,
+		k1_opt,
+		k2_opt,
+		res_was_calculated);
+
+		if(!res_was_calculated)
+		{
+			inside_simulation_flag_=false;
+			throw error("",1);
+		};
+
+
+
+		if(delta_E_aver<=0)
+		{
+			inside_simulation_flag_=false;
+			throw error("",1);
+		};
+
+
+
+		a_I_=delta_I_aver/delta_E_aver;
+		a_I_error_=FSA_utils::error_of_the_ratio(delta_I_aver,delta_I_aver_error,delta_E_aver,delta_E_aver_error);
+		a_J_=delta_J_aver/delta_E_aver;
+		a_J_error_=FSA_utils::error_of_the_ratio(delta_J_aver,delta_J_aver_error,delta_E_aver,delta_E_aver_error);
+		
+		sigma_calculation(
+		delta_I_aver,
+		delta_I_aver_error,
+		delta_J_aver,
+		delta_J_aver_error,
+		delta_E_aver,
+		delta_E_aver_error,
+		cov_E_E_aver,
+		cov_E_E_aver_error,
+		cov_I_J_aver,
+		cov_I_J_aver_error,
+		sigma_,
+		sigma_error_);
+
+
+		sigma_calculation(
+		delta_I_aver,
+		delta_I_aver_error,
+		delta_I_aver,
+		delta_I_aver_error,
+		delta_E_aver,
+		delta_E_aver_error,
+		cov_E_E_aver,
+		cov_E_E_aver_error,
+		cov_I_I_aver,
+		cov_I_I_aver_error,
+		alpha_I_,
+		alpha_I_error_);
+
+		//for test
+		if(test_FSC_vect_)
+		{
+			test_FSC_vect_[0]=alpha_I_;
+			long int j;
+			for(j=0;j<number_of_elements;j++)
+			{
+				test_FSC_vect_[j+1]=(delta_I[j]*delta_I[j]*cov_E_E[j]+delta_E[j]*delta_E[j]*cov_I_I[j])/(delta_E[j]*delta_E[j]*delta_E[j]);
+			};
+		};
+
+
+		if(test_FSC_vect_)
+		{
+			test_FSC_vect_[0]=lambda_;
+			long int i,j;
+			for(j=1;j<=nalp_;j++)
+			{
+				test_FSC_vect_[j]=0;
+			};
+
+			for(i=ind1_;i<=ind2_;i++)
+			{
+				
+
+				long int j;
+				for(j=1;j<=nalp_;j++)
+				{
+
+					long int &E_j=ALP_edge_max_[i].d_elem[j];
+					double &weight_j=ALP_weight_[i].d_elem[j];
+
+
+					double exp_tmp=lambda_exp(E_j,exp_array)*one_div_C_S_constant;
+
+					double tmp=exp_tmp*weight_j;
+					test_FSC_vect_[j]+=tmp;
+				};
+			};
+
+			for(j=1;j<=nalp_;j++)
+			{
+				test_FSC_vect_[j]/=(double)(ind2_-ind1_)+1;
+			};
+
+		};
+
+
+		sigma_calculation(
+		delta_J_aver,
+		delta_J_aver_error,
+		delta_J_aver,
+		delta_J_aver_error,
+		delta_E_aver,
+		delta_E_aver_error,
+		cov_E_E_aver,
+		cov_E_E_aver_error,
+		cov_J_J_aver,
+		cov_J_J_aver_error,
+		alpha_J_,
+		alpha_J_error_);
+
+		memory_release_for_calculate_FSC(
+		exp_array,
+		delta_E,
+		delta_E_error,
+		delta_E_E,
+		delta_E_E_error,
+		delta_I,
+		delta_I_error,
+		delta_J,
+		delta_J_error,
+		delta_I_I,
+		delta_I_I_error,
+		delta_I_J,
+		delta_I_J_error,
+		delta_J_J,
+		delta_J_J_error,
+		cov_J_J,
+		cov_J_J_error,
+		cov_I_J,
+		cov_I_J_error,
+		cov_I_I,
+		cov_I_I_error,
+		cov_E_E,
+		cov_E_E_error,
+		C_S,
+		C_S_error);
+
+
+	}
+	catch (error er)
+	{
+		if(er.st!="")
+		{
+			throw;
+		}
+		else
+		{
+
+			//memory release
+			memory_release_for_calculate_FSC(
+			exp_array,
+			delta_E,
+			delta_E_error,
+			delta_E_E,
+			delta_E_E_error,
+			delta_I,
+			delta_I_error,
+			delta_J,
+			delta_J_error,
+			delta_I_I,
+			delta_I_I_error,
+			delta_I_J,
+			delta_I_J_error,
+			delta_J_J,
+			delta_J_J_error,
+			cov_J_J,
+			cov_J_J_error,
+			cov_I_J,
+			cov_I_J_error,
+			cov_I_I,
+			cov_I_I_error,
+			cov_E_E,
+			cov_E_E_error,
+			C_S,
+			C_S_error);
+		};
+
+	};
+	}
+	catch (...)
+	{ 
+		//memory release
+		memory_release_for_calculate_FSC(
+		exp_array,
+		delta_E,
+		delta_E_error,
+		delta_E_E,
+		delta_E_E_error,
+		delta_I,
+		delta_I_error,
+		delta_J,
+		delta_J_error,
+		delta_I_I,
+		delta_I_I_error,
+		delta_I_J,
+		delta_I_J_error,
+		delta_J_J,
+		delta_J_J_error,
+		cov_J_J,
+		cov_J_J_error,
+		cov_I_J,
+		cov_I_J_error,
+		cov_I_I,
+		cov_I_I_error,
+		cov_E_E,
+		cov_E_E_error,
+		C_S,
+		C_S_error);
+		throw;
+	};
+}
+
+void fsa_par::sigma_calculation(
+double delta_I_aver_,
+double delta_I_aver_error_,
+double delta_J_aver_,
+double delta_J_aver_error_,
+double delta_E_aver_,
+double delta_E_aver_error_,
+double cov_E_E_aver_,
+double cov_E_E_aver_error_,
+double cov_I_J_aver_,
+double cov_I_J_aver_error_,
+double &sigma_,
+double &sigma_error_)
+{
+	double nom1_1=delta_I_aver_*delta_J_aver_;
+	double nom2_2=delta_E_aver_*delta_E_aver_;
+
+	double den=nom2_2*delta_E_aver_;
+
+	double nom1=nom1_1*cov_E_E_aver_;
+	double nom2=nom2_2*cov_I_J_aver_;
+
+	sigma_=(nom1+nom2)/den;
+
+	
+	double nom1_sigma_error=FSA_utils::error_of_the_product(delta_I_aver_,delta_I_aver_error_,delta_J_aver_,delta_J_aver_error_);
+	nom1_sigma_error=FSA_utils::error_of_the_product(nom1_1,nom1_sigma_error,cov_E_E_aver_,cov_E_E_aver_error_);
+
+	
+	double nom2_sigma_error_2=FSA_utils::error_of_the_product(delta_E_aver_,delta_E_aver_error_,delta_E_aver_,delta_E_aver_error_);
+	double nom2_sigma_error=FSA_utils::error_of_the_product(nom2_2,nom2_sigma_error_2,cov_I_J_aver_,cov_I_J_aver_error_);
+
+	
+	double den_sigma_error=FSA_utils::error_of_the_product(nom2_2,nom2_sigma_error_2,delta_E_aver_,delta_E_aver_error_);
+
+	double nom_sigma_error=FSA_utils::error_of_the_sum(nom1_sigma_error,nom2_sigma_error);
+
+	sigma_error_=FSA_utils::error_of_the_ratio(nom1+nom2,nom_sigma_error,den,den_sigma_error);
+
+}
+
+void fsa_par::Output_Pvalues(
+char type_,//'E' or 'P'
+long int score1_,
+long int score2_,
+vector<double> &pv_,
+vector<double> &pv_err_,
+string pvalout_file_name_)//P-values file name
+{
+	if(!(type_=='E'||type_=='P'))
+	{
+		throw error("Error - the type_ parameter can take only 'E' or 'P' values in void fsa_par::Output_Pvalues\n",1);
+	};
+
+	ofstream f(pvalout_file_name_.data());
+	if(!f)
+	{
+		throw error("Error - the file "+pvalout_file_name_+" cannot be created\n",4);
+	};
+
+	if(type_=='E')
+	{
+		f<<"Score\tE-value\tE-value error\n";
+	};
+
+	if(type_=='P')
+	{
+		f<<"Score\tP-value\tP-value error\n";
+	};
+
+	long int i;
+	for(i=score1_;i<=score2_;i++)
+	{
+		f<<i<<"\t"<<pv_[i-score1_]<<"\t"<<pv_err_[i-score1_]<<endl;
+	};
+
+
+	f.close();
+
+}
+
+void fsa_par::Output_Params(
+Sls::FALP_set_of_parameters &gumbel_params_,
+string gumbelparout_file_name_)
+{
+	ofstream f;
+	ifstream fin;
+
+
+	bool append_flag=false;
+
+	try
+	{
+
+		if(append_flag)
+		{
+			fin.open(gumbelparout_file_name_.data());
+			if(!fin)
+			{
+				append_flag=false;
+			}
+			else
+			{
+				fin.close();
+			};
+		};
+		
+		if(!append_flag)
+		{
+			f.open(gumbelparout_file_name_.data());
+		}
+		else
+		{
+			f.open(gumbelparout_file_name_.data(),ios::app);
+		};
+
+		if(!f)
+		{
+			throw error("Error - file "+gumbelparout_file_name_+" cannot be created\n",4);
+		};
+
+		f<<gumbel_params_;
+
+
+		f.close();
+	}
+	catch (...)
+	{ 
+		if(f.is_open())
+		{
+			f.close();
+		};
+
+		if(append_flag)
+		{
+			if(fin.is_open())
+			{
+				fin.close();
+			};
+		};
+
+		throw;
+	};
+
+}
+
+void fsa_par::Read_Params(
+Sls::FALP_set_of_parameters &gumbel_params_,
+string gumbelparin_file_name_)
+{
+	ifstream f;
+
+	try
+	{
+
+		gumbel_params_.d_params_flag=false;
+
+		f.open(gumbelparin_file_name_.data());
+		if(!f)
+		{
+			throw error("Error - file "+gumbelparin_file_name_+" is not found\n",4);
+		};
+
+		f>>gumbel_params_;
+
+		f.close();
+		gumbel_params_.d_params_flag=true;
+
+	}
+	catch (...)
+	{ 
+		gumbel_params_.d_params_flag=false;
+		if(f.is_open())
+		{
+			f.close();
+		};
+		throw;
+	};
+}
+
diff --git a/src/alp/sls_fsa1_parameters.hpp b/src/alp/sls_fsa1_parameters.hpp
index 6972777..046be9c 100644
--- a/src/alp/sls_fsa1_parameters.hpp
+++ b/src/alp/sls_fsa1_parameters.hpp
@@ -1,226 +1,226 @@
-#ifndef INCLUDED_SLS_FSA_PARAMETERS
-#define INCLUDED_SLS_FSA_PARAMETERS
-
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_fsa1_parameters.hpp
-
-Author: Sergey Sheetlin
-
-Contents: Calculation of Gumbel parameters
-
-******************************************************************************/
-
-#include "sls_fsa1_utils.hpp"
-#include "sls_alp_regression.hpp"
-#include "sls_fsa1_pvalues.hpp"
-
-
-
-namespace Sls { 
-
-	struct struct_for_lambda_calculation
-	{
-		void **d_alp_distr;
-		void **d_alp_distr_errors;
-		long int d_nalp;
-		double d_f_error;
-
-		double d_last_sum;
-		double d_last_sum_error;
-
-		double d_before_last_sum;
-		double d_before_last_sum_error;
-
-		bool d_calculate_alp_number;
-		long int d_alp_number;
-
-		
-	};
-
-
-	class fsa_par{
-
-
-		public:
-
-		static double function_for_lambda_calculation(
-		double lambda_,
-		void * data_);
-
-		static void calculate_lambda(
-		bool check_the_criteria_,
-		long int nalp_,
-		long int &nalp_thr_,
-		bool &inside_simulation_flag_,
-		void **alp_distr,
-		void **alp_distr_errors,
-		double ungapped_lambda_,
-		double &lambda_,
-		double &lambda_error_);
-
-		static void calculate_C(
-		long int starting_point,
-		long int nalp_,
-		void **alp_distr,
-		void **alp_distr_errors,
-		double lambda_,
-		double lambda_error_,
-		double &C_,
-		double &C_error_,
-		bool &inside_simulation_flag_);
-
-		static void memory_releace_for_calculate_C(
-		double *&P,
-		double *&P_errors,
-		double *&values_P_ratio,
-		double *&errors_P_ratio,
-
-		double *&E,
-		double *&E_errors,
-
-		double *&E_T_beta,
-		double *&E_T_beta_errors);
-
-		static double get_root(
-		const std::vector<double> &res_tmp_,
-		double point_);
-
-		static void memory_release_for_calculate_FSC(
-		double *&exp_array,
-		double *&delta_E,
-		double *&delta_E_error,
-		double *&delta_E_E,
-		double *&delta_E_E_error,
-		double *&delta_I,
-		double *&delta_I_error,
-		double *&delta_J,
-		double *&delta_J_error,
-		double *&delta_I_I,
-		double *&delta_I_I_error,
-		double *&delta_I_J,
-		double *&delta_I_J_error,
-		double *&delta_J_J,
-		double *&delta_J_J_error,
-		double *&cov_J_J,
-		double *&cov_J_J_error,
-		double *&cov_I_J,
-		double *&cov_I_J_error,
-		double *&cov_I_I,
-		double *&cov_I_I_error,
-		double *&cov_E_E,
-		double *&cov_E_E_error,
-		double *&C_S,
-		double *&C_S_error);
-
-		static void calculate_FSC(
-		long int nalp_,
-		long int ind1_,
-		long int ind2_,
-
-		double lambda_,
-
-		long int M_max_,
-
-		array_positive<long int> *distance_along_direction_1_,
-		array_positive<long int> *distance_along_direction_2_,
-
-		array_positive<double> *ALP_weight_,
-		array_positive<long int> *ALP_edge_max_,
-
-		double &a_I_,
-		double &a_I_error_,
-		double &a_J_,
-		double &a_J_error_,
-		double &sigma_,
-		double &sigma_error_,
-		double &alpha_I_,
-		double &alpha_I_error_,
-		double &alpha_J_,
-		double &alpha_J_error_,
-		bool &inside_simulation_flag_,
-		double *test_FSC_vect_=NULL);//for tests
-
-		static void sigma_calculation(
-		double delta_I_aver_,
-		double delta_I_aver_error_,
-		double delta_J_aver_,
-		double delta_J_aver_error_,
-		double delta_E_aver_,
-		double delta_E_aver_error_,
-		double cov_E_E_aver_,
-		double cov_E_E_aver_error_,
-		double cov_I_J_aver_,
-		double cov_I_J_aver_error_,
-		double &sigma_,
-		double &sigma_error_);
-
-		static double lambda_exp(
-		long int &i_,
-		double *&exp_array_);
-
-		static void Read_Params(
-		Sls::FALP_set_of_parameters &gumbel_params_,
-		std::string gumbelparin_file_name_);
-
-		static void Output_Params(
-		Sls::FALP_set_of_parameters &gumbel_params_,
-		std::string gumbelparout_file_name_);
-
-		friend std::ostream &operator<<(std::ostream &s_,
-		const Sls::FALP_set_of_parameters &gumbel_params_);
-
-		friend std::istream &operator>>(std::istream &s_,
-		FALP_set_of_parameters &gumbel_params_);
-
-
-
-		static void Output_Pvalues(
-		char type_,//'E' or 'P'
-		long int score1_,
-		long int score2_,
-		std::vector<double> &pv_,
-		std::vector<double> &pv_err_,
-		std::string pvalout_file_name_);//P-values file name
-
-
-
-
-
-
-		public:
-
-		long int d_tmp;
-
-
-	};
-}
-
-
-#endif
-
+#ifndef INCLUDED_SLS_FSA_PARAMETERS
+#define INCLUDED_SLS_FSA_PARAMETERS
+
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_fsa1_parameters.hpp
+
+Author: Sergey Sheetlin
+
+Contents: Calculation of Gumbel parameters
+
+******************************************************************************/
+
+#include "sls_fsa1_utils.hpp"
+#include "sls_alp_regression.hpp"
+#include "sls_fsa1_pvalues.hpp"
+
+
+
+namespace Sls { 
+
+	struct struct_for_lambda_calculation
+	{
+		void **d_alp_distr;
+		void **d_alp_distr_errors;
+		long int d_nalp;
+		double d_f_error;
+
+		double d_last_sum;
+		double d_last_sum_error;
+
+		double d_before_last_sum;
+		double d_before_last_sum_error;
+
+		bool d_calculate_alp_number;
+		long int d_alp_number;
+
+		
+	};
+
+
+	class fsa_par{
+
+
+		public:
+
+		static double function_for_lambda_calculation(
+		double lambda_,
+		void * data_);
+
+		static void calculate_lambda(
+		bool check_the_criteria_,
+		long int nalp_,
+		long int &nalp_thr_,
+		bool &inside_simulation_flag_,
+		void **alp_distr,
+		void **alp_distr_errors,
+		double ungapped_lambda_,
+		double &lambda_,
+		double &lambda_error_);
+
+		static void calculate_C(
+		long int starting_point,
+		long int nalp_,
+		void **alp_distr,
+		void **alp_distr_errors,
+		double lambda_,
+		double lambda_error_,
+		double &C_,
+		double &C_error_,
+		bool &inside_simulation_flag_);
+
+		static void memory_releace_for_calculate_C(
+		double *&P,
+		double *&P_errors,
+		double *&values_P_ratio,
+		double *&errors_P_ratio,
+
+		double *&E,
+		double *&E_errors,
+
+		double *&E_T_beta,
+		double *&E_T_beta_errors);
+
+		static double get_root(
+		const std::vector<double> &res_tmp_,
+		double point_);
+
+		static void memory_release_for_calculate_FSC(
+		double *&exp_array,
+		double *&delta_E,
+		double *&delta_E_error,
+		double *&delta_E_E,
+		double *&delta_E_E_error,
+		double *&delta_I,
+		double *&delta_I_error,
+		double *&delta_J,
+		double *&delta_J_error,
+		double *&delta_I_I,
+		double *&delta_I_I_error,
+		double *&delta_I_J,
+		double *&delta_I_J_error,
+		double *&delta_J_J,
+		double *&delta_J_J_error,
+		double *&cov_J_J,
+		double *&cov_J_J_error,
+		double *&cov_I_J,
+		double *&cov_I_J_error,
+		double *&cov_I_I,
+		double *&cov_I_I_error,
+		double *&cov_E_E,
+		double *&cov_E_E_error,
+		double *&C_S,
+		double *&C_S_error);
+
+		static void calculate_FSC(
+		long int nalp_,
+		long int ind1_,
+		long int ind2_,
+
+		double lambda_,
+
+		long int M_max_,
+
+		array_positive<long int> *distance_along_direction_1_,
+		array_positive<long int> *distance_along_direction_2_,
+
+		array_positive<double> *ALP_weight_,
+		array_positive<long int> *ALP_edge_max_,
+
+		double &a_I_,
+		double &a_I_error_,
+		double &a_J_,
+		double &a_J_error_,
+		double &sigma_,
+		double &sigma_error_,
+		double &alpha_I_,
+		double &alpha_I_error_,
+		double &alpha_J_,
+		double &alpha_J_error_,
+		bool &inside_simulation_flag_,
+		double *test_FSC_vect_=NULL);//for tests
+
+		static void sigma_calculation(
+		double delta_I_aver_,
+		double delta_I_aver_error_,
+		double delta_J_aver_,
+		double delta_J_aver_error_,
+		double delta_E_aver_,
+		double delta_E_aver_error_,
+		double cov_E_E_aver_,
+		double cov_E_E_aver_error_,
+		double cov_I_J_aver_,
+		double cov_I_J_aver_error_,
+		double &sigma_,
+		double &sigma_error_);
+
+		static double lambda_exp(
+		long int &i_,
+		double *&exp_array_);
+
+		static void Read_Params(
+		Sls::FALP_set_of_parameters &gumbel_params_,
+		std::string gumbelparin_file_name_);
+
+		static void Output_Params(
+		Sls::FALP_set_of_parameters &gumbel_params_,
+		std::string gumbelparout_file_name_);
+
+		friend std::ostream &operator<<(std::ostream &s_,
+		const Sls::FALP_set_of_parameters &gumbel_params_);
+
+		friend std::istream &operator>>(std::istream &s_,
+		FALP_set_of_parameters &gumbel_params_);
+
+
+
+		static void Output_Pvalues(
+		char type_,//'E' or 'P'
+		long int score1_,
+		long int score2_,
+		std::vector<double> &pv_,
+		std::vector<double> &pv_err_,
+		std::string pvalout_file_name_);//P-values file name
+
+
+
+
+
+
+		public:
+
+		long int d_tmp;
+
+
+	};
+}
+
+
+#endif
+
diff --git a/src/alp/sls_fsa1_pvalues.cpp b/src/alp/sls_fsa1_pvalues.cpp
index c0c1f07..8b1dcc5 100644
--- a/src/alp/sls_fsa1_pvalues.cpp
+++ b/src/alp/sls_fsa1_pvalues.cpp
@@ -1,1348 +1,1348 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_fsa1_pvalues.cpp
-
-Author: Sergey Sheetlin
-
-Contents: Calculation of P-values using precalculated Gumbel parameters
-
-******************************************************************************/
-
-#include "sls_fsa1_pvalues.hpp"
-#include "sls_fsa1_utils.hpp"
-#include "sls_normal_distr_array.hpp"
-
-using namespace Sls;
-using namespace std;
-
-const double nat_cut_off_in_max=2.0;//nat cut-off in max used in FSC
-
-void FALP_pvalues::compute_intercepts(
-FALP_set_of_parameters &par_)
-{
-	if(!par_.d_params_flag)
-	{
-		throw error("Unexpected error: FALP_pvalues::compute_intercepts is called for undefined parameters\n",1);
-	};
-
-	par_.b_I=2.0*par_.G*(par_.gapless_a_I-par_.a_I); 
-	par_.b_I_error=2.0*par_.G*FSA_utils::error_of_the_sum(par_.gapless_a_I_error,par_.a_I_error); 
-	par_.beta_I=2.0*par_.G*(par_.gapless_alpha_I-par_.alpha_I); 
-	par_.beta_I_error=2.0*par_.G*FSA_utils::error_of_the_sum(par_.gapless_alpha_I_error,par_.alpha_I_error); 
-
-	par_.b_J=2.0*par_.G*(par_.gapless_a_J-par_.a_J); 
-	par_.b_J_error=2.0*par_.G*FSA_utils::error_of_the_sum(par_.gapless_a_J_error,par_.a_J_error); 
-	par_.beta_J=2.0*par_.G*(par_.gapless_alpha_J-par_.alpha_J); 
-	par_.beta_J_error=2.0*par_.G*FSA_utils::error_of_the_sum(par_.gapless_alpha_J_error,par_.alpha_J_error); 
-
-	par_.tau=2.0*par_.G*(par_.gapless_sigma-par_.sigma);
-	par_.tau_error=2.0*par_.G*FSA_utils::error_of_the_sum(par_.gapless_sigma_error,par_.sigma_error);
-
-	long int vector_size=(long int)par_.m_LambdaSbs.size();
-
-	par_.m_BISbs.resize(vector_size);
-	par_.m_BJSbs.resize(vector_size);
-	par_.m_BetaISbs.resize(vector_size);
-	par_.m_BetaJSbs.resize(vector_size);
-	par_.m_TauSbs.resize(vector_size);
-
-	long int i;
-	for(i=0;i<vector_size;i++)
-	{
-		par_.m_BISbs[i]=2.0*par_.G*(par_.gapless_a_I-par_.m_AISbs[i]); 
-		par_.m_BetaISbs[i]=2.0*par_.G*(par_.gapless_alpha_I-par_.m_AlphaISbs[i]); 
-
-
-		par_.m_BJSbs[i]=2.0*par_.G*(par_.gapless_a_J-par_.m_AJSbs[i]); 
-		par_.m_BetaJSbs[i]=2.0*par_.G*(par_.gapless_alpha_J-par_.m_AlphaJSbs[i]); 
-
-
-		par_.m_TauSbs[i]=2.0*par_.G*(par_.gapless_sigma-par_.m_SigmaSbs[i]);
-
-	};
-
-	compute_tmp_values(par_);
-
-}
-
-void FALP_pvalues::get_appr_tail_prob_with_cov(
-const FALP_set_of_parameters &par_,
-bool blast_,
-double y_,
-
-double m_,
-double n_,
-
-
-double &P_,
-double &P_error_,
-
-double &E_,
-double &E_error_,
-
-double &area_,
-
-double a_normal_,
-double b_normal_,
-double h_normal_,
-long int N_normal_,
-double *p_normal_,
-
-bool &area_is_1_flag_)
-{
-
-	//to optimize performance
-	blast_=false;
-
-	double lambda_=par_.lambda;
-	double lambda_error_=par_.lambda_error;
-	double k_=par_.K;
-	double k_error_=par_.K_error;
-
-	double ai_hat_=par_.a_I;
-	double ai_hat_error_=par_.a_I_error;
-	double bi_hat_; 
-	double bi_hat_error_; 
-	double alphai_hat_=par_.alpha_I;
-	double alphai_hat_error_=par_.alpha_I_error;
-	double betai_hat_; 
-	double betai_hat_error_; 
-
-	double aj_hat_=par_.a_J;
-	double aj_hat_error_=par_.a_J_error;
-	double bj_hat_; 
-	double bj_hat_error_; 
-	double alphaj_hat_=par_.alpha_J;
-	double alphaj_hat_error_=par_.alpha_J_error;
-	double betaj_hat_; 
-	double betaj_hat_error_; 
-
-	double sigma_hat_=par_.sigma;
-	double sigma_hat_error_=par_.sigma_error;
-	double tau_hat_;
- 	double tau_hat_error_;
- 
-	{
-		bi_hat_=par_.b_I;
-		bi_hat_error_=par_.b_I_error;
-		betai_hat_=par_.beta_I;
-		betai_hat_error_=par_.beta_I_error;
-
-		bj_hat_=par_.b_J;
-		bj_hat_error_=par_.b_J_error;
-		betaj_hat_=par_.beta_J;
-		betaj_hat_error_=par_.beta_J_error;
-
-		tau_hat_=par_.tau;
-		tau_hat_error_=par_.tau_error;
-	};
-
-
-	if(blast_)
-	{
-		alphai_hat_=0;
-		alphai_hat_error_=0;
-		betai_hat_=0;
-		betai_hat_error_=0;
-
-		alphaj_hat_=0;
-		alphaj_hat_error_=0;
-		betaj_hat_=0;
-		betaj_hat_error_=0;
-
-		sigma_hat_=0;
-		sigma_hat_error_=0;
-		tau_hat_=0;
-		tau_hat_error_=0;
-	};
-
-	double eps=0.000001;
-
-	double m_li_y_error=0;
-	double m_li_y=0;
-
-	double tmp=ai_hat_*y_+bi_hat_;
-
-	m_li_y_error=FSA_utils::error_of_the_sum(fabs(y_)*ai_hat_error_,bi_hat_error_);
-	m_li_y=m_-tmp;
-
-	
-	double vi_y_error=0;
-	double vi_y=0;
-
-
-	vi_y_error=FSA_utils::error_of_the_sum(fabs(y_)*alphai_hat_error_,betai_hat_error_);
-	vi_y=FSA_utils::Tmax(par_.vi_y_thr,alphai_hat_*y_+betai_hat_);
-
-	double sqrt_vi_y_error=FSA_utils::error_of_the_sqrt(vi_y,vi_y_error);
-
-	double sqrt_vi_y=sqrt(vi_y);
-
-	double m_F=0;
-	double m_F_error=0;
-
-	if(sqrt_vi_y==0.0||blast_)
-	{
-		m_F=1e100;
-		m_F_error=0.0;
-	}
-	else
-	{
-		m_F_error=FSA_utils::error_of_the_ratio(m_li_y,m_li_y_error,sqrt_vi_y,sqrt_vi_y_error);
-		m_F=m_li_y/sqrt_vi_y;
-	};
-
-
-	double P_m_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,m_F,eps);
-	double P_m_F_error=const_val*exp(-0.5*m_F*m_F)*m_F_error;
-
-	double E_m_F=-const_val*exp(-0.5*m_F*m_F);
-	double E_m_F_error=fabs(-E_m_F*m_F)*m_F_error;
-
-	double m_li_y_P_m_F_error=FSA_utils::error_of_the_product(m_li_y,m_li_y_error,P_m_F,P_m_F_error);
-	double m_li_y_P_m_F=m_li_y*P_m_F;
-
-	double sqrt_vi_y_E_m_F_error=FSA_utils::error_of_the_product(sqrt_vi_y,sqrt_vi_y_error,E_m_F,E_m_F_error);
-	double sqrt_vi_y_E_m_F=sqrt_vi_y*E_m_F;
-
-	double p1_error=FSA_utils::error_of_the_sum(m_li_y_P_m_F_error,sqrt_vi_y_E_m_F_error);
-	double p1=m_li_y_P_m_F-sqrt_vi_y_E_m_F;
-
-
-	double n_lj_y_error=0;
-	double n_lj_y=0;
-
-	tmp=aj_hat_*y_+bj_hat_;
-
-	n_lj_y_error=FSA_utils::error_of_the_sum(fabs(y_)*aj_hat_error_,bj_hat_error_);
-	n_lj_y=n_-tmp;
-
-
-	double vj_y_error=0;
-	double vj_y=0;
-
-
-	vj_y_error=FSA_utils::error_of_the_sum(fabs(y_)*alphaj_hat_error_,betaj_hat_error_);
-
-	vj_y=FSA_utils::Tmax(par_.vj_y_thr,alphaj_hat_*y_+betaj_hat_);
-
-	double sqrt_vj_y_error=FSA_utils::error_of_the_sqrt(vj_y,vj_y_error);
-
-	double sqrt_vj_y=sqrt(vj_y);
-
-	double n_F=0;
-	double n_F_error=0;
-
-	if(sqrt_vj_y==0.0||blast_)
-	{
-		n_F=1e100;
-		n_F_error=0.0;
-	}
-	else
-	{
-		n_F_error=FSA_utils::error_of_the_ratio(n_lj_y,n_lj_y_error,sqrt_vj_y,sqrt_vj_y_error);
-
-		n_F=n_lj_y/sqrt_vj_y;
-	};
-
-	double P_n_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,n_F,eps);
-	double P_n_F_error=const_val*exp(-0.5*n_F*n_F)*n_F_error;
-
-	double E_n_F=-const_val*exp(-0.5*n_F*n_F);
-	double E_n_F_error=fabs(-E_n_F*n_F)*n_F_error;
-
-	double n_lj_y_P_n_F_error=FSA_utils::error_of_the_product(n_lj_y,n_lj_y_error,P_n_F,P_n_F_error);
-	double n_lj_y_P_n_F=n_lj_y*P_n_F;
-
-	double sqrt_vj_y_E_n_F_error=FSA_utils::error_of_the_product(sqrt_vj_y,sqrt_vj_y_error,E_n_F,E_n_F_error);
-	double sqrt_vj_y_E_n_F=sqrt_vj_y*E_n_F;
-
-	double p2_error=FSA_utils::error_of_the_sum(n_lj_y_P_n_F_error,sqrt_vj_y_E_n_F_error);
-	double p2=n_lj_y_P_n_F-sqrt_vj_y_E_n_F;
-
-
-
-
-	double c_y_error=0;
-	double c_y=0;
-
-	c_y_error=FSA_utils::error_of_the_sum(sigma_hat_error_*y_,tau_hat_error_);
-
-	c_y=FSA_utils::Tmax(par_.c_y_thr,sigma_hat_*y_+tau_hat_);
-
-	double P_m_F_P_n_F_error=FSA_utils::error_of_the_product(P_m_F,P_m_F_error,P_n_F,P_n_F_error);
-	double P_m_F_P_n_F=P_m_F*P_n_F;
-
-	double c_y_P_m_F_P_n_F_error=FSA_utils::error_of_the_product(c_y,c_y_error,P_m_F_P_n_F,P_m_F_P_n_F_error);
-	double c_y_P_m_F_P_n_F=c_y*P_m_F_P_n_F;
-
-	double p1_p2_error=FSA_utils::error_of_the_product(p1,p1_error,p2,p2_error);
-	double p1_p2=p1*p2;
-
-
-	double area_error=FSA_utils::error_of_the_sum(p1_p2_error,c_y_P_m_F_P_n_F_error);
-	double area=p1_p2+c_y_P_m_F_P_n_F;
-
-
-
-
-	if(!blast_)
-	{
-		//area=FSA_utils::Tmax(area,1.0);
-	}
-	else
-	{
-		if(area<=1.0)
-		{
-			area_is_1_flag_=true;
-		};
-
-		if(area_is_1_flag_)
-		{
-			area=1.0;
-		};
-	};
-
-	double exp_lambda_y_error=fabs(lambda_error_*y_*exp(-lambda_*y_));
-	double exp_lambda_y=exp(-lambda_*y_);
-
-	double k_exp_lambda_y_error=FSA_utils::error_of_the_product(k_,k_error_,exp_lambda_y,exp_lambda_y_error);
-	double k_exp_lambda_y=k_*exp_lambda_y;
-
-	double area_k_exp_lambda_y_error=FSA_utils::error_of_the_product(area,area_error,k_exp_lambda_y,k_exp_lambda_y_error);
-	double area_k_exp_lambda_y=-area*k_exp_lambda_y;
-
-	E_=-area_k_exp_lambda_y;
-	E_error_=area_k_exp_lambda_y_error;
-
-	P_error_=exp(area_k_exp_lambda_y)*area_k_exp_lambda_y_error;
-
-	P_=sls_basic::one_minus_exp_function(area_k_exp_lambda_y);
-//	P_=1-exp(-k_*area*exp(-lambda_*y_));
-
-	area_=area;
-}
-
-void FALP_pvalues::compute_tmp_values(FALP_set_of_parameters &par_)
-{
-	if(!par_.d_params_flag)
-	{
-		throw error("Unexpected call of FALP_pvalues::compute_tmp_values\n",1);
-	};
-
-	//tmp values
-	if(par_.lambda>0)
-	{
-		par_.vi_y_thr=FSA_utils::Tmax(nat_cut_off_in_max*par_.alpha_I/par_.lambda,0.0);
-		par_.vj_y_thr=FSA_utils::Tmax(nat_cut_off_in_max*par_.alpha_J/par_.lambda,0.0);
-		par_.c_y_thr=FSA_utils::Tmax(nat_cut_off_in_max*par_.sigma/par_.lambda,0.0);
-	}
-	else
-	{
-		par_.vi_y_thr=0;
-		par_.vj_y_thr=0;
-		par_.c_y_thr=0;
-
-		par_.d_params_flag=false;
-	};
-}
-
-void FALP_pvalues::get_appr_tail_prob_with_cov_without_errors(
-const FALP_set_of_parameters &par_,
-bool blast_,
-double y_,
-
-double m_,
-double n_,
-
-
-double &P_,
-double &E_,
-
-double &area_,
-
-double a_normal_,
-double b_normal_,
-double h_normal_,
-long int N_normal_,
-double *p_normal_,
-
-bool &area_is_1_flag_,
-bool compute_only_area_)
-{
-
-	//to optimize performance
-	blast_=false;
-
-	double lambda_=par_.lambda;
-	double k_=par_.K;
-
-	double ai_hat_=par_.a_I;
-	double bi_hat_;
-	double alphai_hat_=par_.alpha_I;
-	double betai_hat_;
-
-	double aj_hat_=par_.a_J;
-	double bj_hat_;
-	double alphaj_hat_=par_.alpha_J;
-	double betaj_hat_;
-
-	double sigma_hat_=par_.sigma;
-	double tau_hat_;
-
-	{
-		bi_hat_=par_.b_I;
-		betai_hat_=par_.beta_I;
-
-		bj_hat_=par_.b_J;
-		betaj_hat_=par_.beta_J;
-
-		tau_hat_=par_.tau;
-	};
-
-
-	if(blast_)
-	{
-		alphai_hat_=0;
-		betai_hat_=0;
-
-		alphaj_hat_=0;
-		betaj_hat_=0;
-
-		sigma_hat_=0;
-		tau_hat_=0;
-	};
-
-	double eps=0.000001;
-
-	double m_li_y=0;
-
-	double tmp=ai_hat_*y_+bi_hat_;
-	m_li_y=m_-tmp;
-	
-	double vi_y=0;
-
-	vi_y=FSA_utils::Tmax(par_.vi_y_thr,alphai_hat_*y_+betai_hat_);
-
-	double sqrt_vi_y=sqrt(vi_y);
-
-	double m_F;
-
-	if(sqrt_vi_y==0.0||blast_)
-	{
-		m_F=1e100;
-	}
-	else
-	{
-		m_F=m_li_y/sqrt_vi_y;
-	};
-
-
-	double P_m_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,m_F,eps);
-
-	double E_m_F=-const_val*exp(-0.5*m_F*m_F);
-
-	double m_li_y_P_m_F=m_li_y*P_m_F;
-
-	double sqrt_vi_y_E_m_F=sqrt_vi_y*E_m_F;
-
-	double p1=m_li_y_P_m_F-sqrt_vi_y_E_m_F;
-
-
-	double n_lj_y=0;
-
-	tmp=aj_hat_*y_+bj_hat_;
-
-	n_lj_y=n_-tmp;
-
-	double vj_y=0;
-
-
-	vj_y=FSA_utils::Tmax(par_.vj_y_thr,alphaj_hat_*y_+betaj_hat_);
-	
-	double sqrt_vj_y=sqrt(vj_y);
-
-	double n_F;
-
-	if(sqrt_vj_y==0.0||blast_)
-	{
-		n_F=1e100;
-	}
-	else
-	{
-		n_F=n_lj_y/sqrt_vj_y;
-	};
-
-	double P_n_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,n_F,eps);
-
-	double E_n_F=-const_val*exp(-0.5*n_F*n_F);
-
-	double n_lj_y_P_n_F=n_lj_y*P_n_F;
-
-	double sqrt_vj_y_E_n_F=sqrt_vj_y*E_n_F;
-
-	double p2=n_lj_y_P_n_F-sqrt_vj_y_E_n_F;
-
-
-
-
-	double c_y=0;
-
-	
-	c_y=FSA_utils::Tmax(par_.c_y_thr,sigma_hat_*y_+tau_hat_);
-
-	double P_m_F_P_n_F=P_m_F*P_n_F;
-
-	double c_y_P_m_F_P_n_F=c_y*P_m_F_P_n_F;
-
-	double p1_p2=p1*p2;
-
-	double area=p1_p2+c_y_P_m_F_P_n_F;
-
-	if(!blast_)
-	{
-		//area=FSA_utils::Tmax(area,1.0);
-	}
-	else
-	{
-		if(area<=1.0)
-		{
-			area_is_1_flag_=true;
-		};
-
-		if(area_is_1_flag_)
-		{
-			area=1.0;
-		};
-	};
-
-	area_=area;
-
-	if(compute_only_area_)
-	{
-		return;
-	};
-
-	double exp_lambda_y=exp(-lambda_*y_);
-
-	double k_exp_lambda_y=k_*exp_lambda_y;
-
-	double area_k_exp_lambda_y=-area*k_exp_lambda_y;
-
-	E_=-area_k_exp_lambda_y;
-
-	P_=sls_basic::one_minus_exp_function(area_k_exp_lambda_y);
-//	P_=1-exp(-k_*area*exp(-lambda_*y_));
-
-}
-
-void FALP_pvalues::get_P_error_using_splitting_method(
-const FALP_set_of_parameters &par_,
-bool blast_,
-double y_,
-
-double m_,
-double n_,
-
-
-double &P_,
-double &P_error_,
-
-double &E_,
-double &E_error_,
-
-double a_normal_,
-double b_normal_,
-double h_normal_,
-long int N_normal_,
-double *p_normal_,
-
-bool &area_is_1_flag_)
-{
-	long int dim=par_.m_LambdaSbs.size();
-	if(dim==0)
-	{
-		throw error("Unexpected error in get_P_error_using_splitting_method\n",1);
-	};
-
-	P_=0;
-	P_error_=0;
-
-	E_=0;
-	E_error_=0;
-
-	double exp_E_values_aver=0;
-	double exp_E_values_error=0;
-
-
-	vector<double> P_values(dim);
-	vector<double> E_values(dim);
-	vector<double> exp_E_values(dim);
-
-
-	long int i;
-	for(i=0;i<dim;i++)
-	{
-		FALP_set_of_parameters par_tmp;
-
-		par_tmp.a_I=par_.m_AISbs[i];
-		par_tmp.a_I_error=0;
-
-		par_tmp.a_J=par_.m_AJSbs[i];
-		par_tmp.a_J_error=0;
-
-		
-
-		par_tmp.gapless_a_I=par_.gapless_a_I;
-		par_tmp.gapless_a_I_error=par_.gapless_a_I_error;
-
-		par_tmp.gapless_a_J=par_.gapless_a_J;
-		par_tmp.gapless_a_J_error=par_.gapless_a_J_error;
-
-		par_tmp.sigma=par_.m_SigmaSbs[i];
-		par_tmp.sigma_error=0;
-
-		par_tmp.gapless_sigma=par_.gapless_sigma;
-		par_tmp.gapless_sigma_error=par_.gapless_sigma_error;
-
-
-		par_tmp.gapless_alpha_I=par_.gapless_alpha_I;
-		par_tmp.gapless_alpha_I_error=par_.gapless_alpha_I_error;
-
-		par_tmp.gapless_alpha_J=par_.gapless_alpha_J;
-		par_tmp.gapless_alpha_J_error=par_.gapless_alpha_J_error;
-
-
-		par_tmp.C=par_.m_CSbs[i];
-		par_tmp.C_error=0;
-
-		par_tmp.K=par_.m_KSbs[i];
-		par_tmp.K_error=0;
-
-
-		par_tmp.lambda=par_.m_LambdaSbs[i];
-		par_tmp.lambda_error=0;
-
-		par_tmp.alpha_I=par_.m_AlphaISbs[i];
-		par_tmp.alpha_I_error=0;
-
-		par_tmp.alpha_J=par_.m_AlphaJSbs[i];
-		par_tmp.alpha_J_error=0;
-
-		par_tmp.G=par_.G;
-		par_tmp.G1=par_.G1;
-		par_tmp.G2=par_.G2;
-
-		//intercepts
-
-		{
-			par_tmp.b_I=par_.m_BISbs[i];
-			par_tmp.b_I_error=0;
-
-			par_tmp.b_J=par_.m_BJSbs[i];
-			par_tmp.b_J_error=0;
-
-			par_tmp.beta_I=par_.m_BetaISbs[i];
-			par_tmp.beta_I_error=0;
-
-			par_tmp.beta_J=par_.m_BetaJSbs[i];
-			par_tmp.beta_J_error=0;
-
-			par_tmp.tau=par_.m_TauSbs[i];
-			par_tmp.tau_error=0;
-
-			par_tmp.d_params_flag=true;
-
-			compute_tmp_values(par_tmp);
-
-
-		};
-
-		double P_tmp,area_tmp,E_tmp;
-
-		get_appr_tail_prob_with_cov_without_errors(
-		par_tmp,
-		blast_,
-		y_,
-		m_,
-		n_,
-
-		P_tmp,
-		E_tmp,
-
-		area_tmp,
-
-		a_normal_,
-		b_normal_,
-		h_normal_,
-		N_normal_,
-		p_normal_,
-
-		area_is_1_flag_);
-
-		P_values[i]=P_tmp;
-
-		P_+=P_tmp;
-
-		E_values[i]=E_tmp;
-
-		E_+=E_tmp;
-
-		double exp_E_tmp=exp(-E_tmp);
-		exp_E_values[i]=exp_E_tmp;
-		exp_E_values_aver+=exp_E_tmp;
-
-
-	};
-
-	if(dim<=1)
-	{
-		return;
-	};
-
-
-	if(P_<=0)
-	{
-		return;
-	};
-
-	if(E_<=0)
-	{
-		return;
-	};
-
-
-	P_/=(double)dim;
-	E_/=(double)dim;
-	exp_E_values_aver/=(double)dim;
-
-	for(i=0;i<dim;i++)
-	{
-		double tmp=P_values[i]/P_;
-		P_error_+=tmp*tmp;
-
-		tmp=E_values[i]/E_;
-		E_error_+=tmp*tmp;
-
-		tmp=exp_E_values[i]/exp_E_values_aver;
-		exp_E_values_error+=tmp*tmp;
-
-	};
-
-	P_error_/=(double)dim;
-	P_error_-=1;
-	
-	E_error_/=(double)dim;
-	E_error_-=1;
-
-	exp_E_values_error/=(double)dim;
-	exp_E_values_error-=1;
-
-
-	if(P_<1e-4)
-	{
-		P_error_=P_*FSA_utils::sqrt_plus(P_error_/(double)dim);
-	}
-	else
-	{
-		P_error_=exp_E_values_aver*FSA_utils::sqrt_plus(exp_E_values_error/(double)dim);
-	};
-
-	E_error_=E_*FSA_utils::sqrt_plus(E_error_/(double)dim);
-
-}
-
-
-FALP_pvalues::FALP_pvalues()
-{
-	blast=false;
-	eps=0.0001;
-	a_normal=-10;
-	b_normal=10;
-	N_normal=NORMAL_DISTR_ARRAY_DIM;
-	h_normal=(b_normal-a_normal)/(double)N_normal;
-	p_normal=normal_distr_array_for_P_values_calculation;
-}
-
-
-FALP_pvalues::~FALP_pvalues()
-{
-	
-}
-
-void FALP_pvalues::calculate_P_values(
-long int Score1,
-long int Score2,
-double Seq1Len,
-double Seq2Len,
-const FALP_set_of_parameters &ParametersSet,
-vector<double> &P_values,
-vector<double> &P_values_errors,
-vector<double> &E_values,
-vector<double> &E_values_errors)
-{
-	if(Score2<Score1)
-	{
-		throw error("Error - Score2<Score1 in FALP_pvalues::calculate_P_values\n",2);
-	};
-
-	if(Seq1Len<=0||Seq2Len<=0)
-	{
-		throw error("Error - Seq1Len<=0||Seq2Len<=0 in FALP_pvalues::calculate_P_values\n",2);
-	};
-
-	P_values.resize(Score2-Score1+1);
-	P_values_errors.resize(Score2-Score1+1);
-
-	E_values.resize(Score2-Score1+1);
-	E_values_errors.resize(Score2-Score1+1);
-
-
-	long int y;
-	for(y=Score1;y<=Score2;y++)
-	{
-		calculate_P_values(
-		y,
-		Seq1Len,
-		Seq2Len,
-		ParametersSet,
-		P_values[y-Score1],
-		P_values_errors[y-Score1],
-		E_values[y-Score1],
-		E_values_errors[y-Score1]);
-	};
-
-}
-
-void FALP_pvalues::calculate_P_values(
-double Score,
-double Seq1Len,
-double Seq2Len,
-const FALP_set_of_parameters &ParametersSet,
-double &P_value,
-double &P_value_error,
-double &E_value,
-double &E_value_error,
-bool read_Sbs_par_flag)
-{
-
-	if(Seq1Len<=0||Seq2Len<=0)
-	{
-		throw error("Error - Seq1Len<=0||Seq2Len<=0 in FALP_pvalues::calculate_P_values\n",2);
-	};
-
-	double P;
-	double P_error;
-	double E;
-	double E_error;
-	double area;
-	bool area_is_1_flag=false;
-
-
-	if(read_Sbs_par_flag)
-	{
-		
-
-		get_appr_tail_prob_with_cov_without_errors(
-		ParametersSet,
-		blast,
-		Score,
-		Seq1Len,
-		Seq2Len,
-
-		P,
-
-		E,
-
-		area,
-		a_normal,
-		b_normal,
-		h_normal,
-		N_normal,
-		p_normal,
-		area_is_1_flag);
-
-
-		
-		double P_tmp,E_tmp;
-
-		if(ParametersSet.m_LambdaSbs.size()>0)
-		{
-			get_P_error_using_splitting_method(
-			ParametersSet,
-			blast,
-			Score,
-			Seq1Len,
-			Seq2Len,
-
-			P_tmp,
-			P_error,
-
-			E_tmp,
-			E_error,
-
-			a_normal,
-			b_normal,
-			h_normal,
-			N_normal,
-			p_normal,
-			area_is_1_flag);
-
-
-			if(P_tmp>0)
-			{
-				P_error=P_error/P_tmp*P;
-			};
-
-			P_value_error=P_error;
-
-			if(E_tmp>0)
-			{
-				E_error=E_error/E_tmp*E;
-			};
-
-			E_value_error=E_error;
-
-		}
-		else
-		{
-			P_value_error=-DBL_MAX;
-			E_value_error=-DBL_MAX;
-		};
-
-		
-		
-	}
-	else
-	{
-		get_appr_tail_prob_with_cov(
-		ParametersSet,
-		blast,
-		Score,
-		Seq1Len,
-		Seq2Len,
-
-		P,
-		P_error,
-
-		E,
-		E_error,
-
-		area,
-		a_normal,
-		b_normal,
-		h_normal,
-		N_normal,
-		p_normal,
-		area_is_1_flag);
-
-		P_value_error=P_error;
-		E_value_error=E_error;
-	};
-
-	P_value=P;
-	E_value=E;
-}
-
-
-//input/output Gumbel parameters
-
-namespace Sls {
-
-std::ostream &operator<<(std::ostream &s_,
-const FALP_set_of_parameters &gumbel_params_)
-{
-
-	s_<<"Lambda\tLambda error\tK\tK error\tC\tC error\ta_1\ta_1 error\ta_2\ta_2 error\tsigma\tsigma error\talpha_1\talpha_1 error\talpha_2\talpha_2 error\tGapless a_1\tGapless a_1 error\tGapless a_2\tGapless a_2 error\tGapless sigma\tGapless sigma error\tGapless alpha_1\tGapless alpha_1 error\tGapless alpha_2\tGapless alpha_2 error\tG\tCalculation time\tArrays for error calculation\n";
-	s_.precision(20);
-	s_<<
-		gumbel_params_.lambda<<"\t"<<gumbel_params_.lambda_error<<"\t"<<
-		gumbel_params_.K<<"\t"<<gumbel_params_.K_error<<"\t"<<
-		gumbel_params_.C<<"\t"<<gumbel_params_.C_error<<"\t"<<
-		gumbel_params_.a_I<<"\t"<<gumbel_params_.a_I_error<<"\t"<<
-		gumbel_params_.a_J<<"\t"<<gumbel_params_.a_J_error<<"\t"<<
-		gumbel_params_.sigma<<"\t"<<gumbel_params_.sigma_error<<"\t"<<
-		gumbel_params_.alpha_I<<"\t"<<gumbel_params_.alpha_I_error<<"\t"<<
-		gumbel_params_.alpha_J<<"\t"<<gumbel_params_.alpha_J_error<<"\t"<<
-		gumbel_params_.gapless_a_I<<"\t"<<gumbel_params_.gapless_a_I_error<<"\t"<<
-		gumbel_params_.gapless_a_J<<"\t"<<gumbel_params_.gapless_a_J_error<<"\t"<<
-		gumbel_params_.gapless_sigma<<"\t"<<gumbel_params_.gapless_sigma_error<<"\t"<<
-		gumbel_params_.gapless_alpha_I<<"\t"<<gumbel_params_.gapless_alpha_I_error<<"\t"<<
-		gumbel_params_.gapless_alpha_J<<"\t"<<gumbel_params_.gapless_alpha_J_error<<"\t"<<
-		gumbel_params_.G<<"\t"<<
-		gumbel_params_.m_CalcTime<<"\t";
-
-	long int i;
-
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_LambdaSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_KSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_CSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_AISbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_AJSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_SigmaSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_AlphaISbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_AlphaJSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-	s_<<endl;
-
-	return s_;
-
-
-}
-
-std::istream &operator>>(std::istream &s_,
-FALP_set_of_parameters &gumbel_params_)
-{
-
-
-	string st;
-	getline(s_,st);
-	s_>>
-		gumbel_params_.lambda>>gumbel_params_.lambda_error>>
-		gumbel_params_.K>>gumbel_params_.K_error>>
-		gumbel_params_.C>>gumbel_params_.C_error>>
-		gumbel_params_.a_I>>gumbel_params_.a_I_error>>
-		gumbel_params_.a_J>>gumbel_params_.a_J_error>>
-		gumbel_params_.sigma>>gumbel_params_.sigma_error>>
-		gumbel_params_.alpha_I>>gumbel_params_.alpha_I_error>>
-		gumbel_params_.alpha_J>>gumbel_params_.alpha_J_error>>
-		gumbel_params_.gapless_a_I>>gumbel_params_.gapless_a_I_error>>
-		gumbel_params_.gapless_a_J>>gumbel_params_.gapless_a_J_error>>
-		gumbel_params_.gapless_sigma>>gumbel_params_.gapless_sigma_error>>
-		gumbel_params_.gapless_alpha_I>>gumbel_params_.gapless_alpha_I_error>>
-		gumbel_params_.gapless_alpha_J>>gumbel_params_.gapless_alpha_J_error>>
-		gumbel_params_.G>>
-		gumbel_params_.m_CalcTime;
-
-	long int i;
-
-
-	{
-		vector<double> &tmp=gumbel_params_.m_LambdaSbs;
-		long int tmp_size;
-		s_>>tmp_size;
-		if(tmp_size<=0)
-		{
-			throw error("Error in the input parameters\n",4);
-		};
-		tmp.resize(tmp_size);
-		for(i=0;i<tmp_size;i++)
-		{
-			s_>>tmp[i];
-		};
-	};
-
-	{
-		vector<double> &tmp=gumbel_params_.m_KSbs;
-		long int tmp_size;
-		s_>>tmp_size;
-		if(tmp_size<=0)
-		{
-			throw error("Error in the input parameters\n",4);
-		};
-		tmp.resize(tmp_size);
-		for(i=0;i<tmp_size;i++)
-		{
-			s_>>tmp[i];
-		};
-	};
-
-
-	{
-		vector<double> &tmp=gumbel_params_.m_CSbs;
-		long int tmp_size;
-		s_>>tmp_size;
-		if(tmp_size<=0)
-		{
-			throw error("Error in the input parameters\n",4);
-		};
-		tmp.resize(tmp_size);
-		for(i=0;i<tmp_size;i++)
-		{
-			s_>>tmp[i];
-		};
-	};
-
-
-
-
-	{
-		vector<double> &tmp=gumbel_params_.m_AISbs;
-		long int tmp_size;
-		s_>>tmp_size;
-		if(tmp_size<=0)
-		{
-			throw error("Error in the input parameters\n",4);
-		};
-		tmp.resize(tmp_size);
-		for(i=0;i<tmp_size;i++)
-		{
-			s_>>tmp[i];
-		};
-	};
-
-	{
-		vector<double> &tmp=gumbel_params_.m_AJSbs;
-		long int tmp_size;
-		s_>>tmp_size;
-		if(tmp_size<=0)
-		{
-			throw error("Error in the input parameters\n",4);
-		};
-		tmp.resize(tmp_size);
-		for(i=0;i<tmp_size;i++)
-		{
-			s_>>tmp[i];
-		};
-	};
-
-
-	{
-		vector<double> &tmp=gumbel_params_.m_SigmaSbs;
-		long int tmp_size;
-		s_>>tmp_size;
-		if(tmp_size<=0)
-		{
-			throw error("Error in the input parameters\n",4);
-		};
-		tmp.resize(tmp_size);
-		for(i=0;i<tmp_size;i++)
-		{
-			s_>>tmp[i];
-		};
-	};
-
-
-
-	{
-		vector<double> &tmp=gumbel_params_.m_AlphaISbs;
-		long int tmp_size;
-		s_>>tmp_size;
-		if(tmp_size<=0)
-		{
-			throw error("Error in the input parameters\n",4);
-		};
-		tmp.resize(tmp_size);
-		for(i=0;i<tmp_size;i++)
-		{
-			s_>>tmp[i];
-		};
-	};
-
-	{
-		vector<double> &tmp=gumbel_params_.m_AlphaJSbs;
-		long int tmp_size;
-		s_>>tmp_size;
-		if(tmp_size<=0)
-		{
-			throw error("Error in the input parameters\n",4);
-		};
-		tmp.resize(tmp_size);
-		for(i=0;i<tmp_size;i++)
-		{
-			s_>>tmp[i];
-		};
-	};
-
-
-	return s_;
-
-}
-
-//returns "true" if the Gumbel parameters are properly defined and "false" otherwise
-bool FALP_pvalues::assert_Gumbel_parameters(
-const FALP_set_of_parameters &par_)//a set of Gumbel parameters
-{
-		if(par_.lambda<=0||
-		par_.lambda_error<0||
-
-		//the parameters C and K_C are not necessary for the P-value calculation
-		//par_.C<0||
-		//par_.C_error<0||
-
-		//par_.K_C<0||
-		//par_.K_C_error<0||
-
-		par_.K<=0||
-		par_.K_error<0||
-
-		par_.a_I<0||
-		par_.a_I_error<0||
-
-		par_.a_J<0||
-		par_.a_J_error<0||
-
-		par_.sigma<0||
-		par_.sigma_error<0||
-
-		par_.alpha_I<0||
-		par_.alpha_I_error<0||
-
-		par_.alpha_J<0||
-		par_.alpha_J_error<0||
-
-		par_.gapless_a_I<0||
-		par_.gapless_a_I_error<0||
-
-		par_.gapless_a_J<0||
-		par_.gapless_a_J_error<0||
-
-
-
-		par_.gapless_alpha_I<0||
-		par_.gapless_alpha_I_error<0||
-
-		par_.gapless_alpha_J<0||
-		par_.gapless_alpha_J_error<0||
-
-		par_.gapless_sigma<0||
-		par_.gapless_sigma_error<0||
-
-		par_.G<0||
-		par_.G1<0||
-		par_.G2<0||
-
-		//intercepts
-		par_.b_I_error<0||
-
-		par_.b_J_error<0||
-
-		par_.beta_I_error<0||
-
-		par_.beta_J_error<0||
-
-		par_.tau_error<0
-
-		)
-		{
-			return false;
-		};
-
-
-
-		size_t size_tmp=par_.m_LambdaSbs.size();
-		if(
-		par_.m_KSbs.size()!=size_tmp||
-		//par_.m_K_CSbs.size()!=size_tmp||
-		//par_.m_CSbs.size()!=size_tmp||
-
-		par_.m_SigmaSbs.size()!=size_tmp||
-
-		par_.m_AlphaISbs.size()!=size_tmp||
-		par_.m_AlphaJSbs.size()!=size_tmp||
-
-		par_.m_AISbs.size()!=size_tmp||
-		par_.m_AJSbs.size()!=size_tmp||
-
-		par_.m_BISbs.size()!=size_tmp||
-		par_.m_BJSbs.size()!=size_tmp||
-
-		par_.m_BetaISbs.size()!=size_tmp||
-		par_.m_BetaJSbs.size()!=size_tmp||
-
-		par_.m_TauSbs.size()!=size_tmp)
-		{
-			return false;
-		};
-
-
-		return true;
-
-}
-
-
-}
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_fsa1_pvalues.cpp
+
+Author: Sergey Sheetlin
+
+Contents: Calculation of P-values using precalculated Gumbel parameters
+
+******************************************************************************/
+
+#include "sls_fsa1_pvalues.hpp"
+#include "sls_fsa1_utils.hpp"
+#include "sls_normal_distr_array.hpp"
+
+using namespace Sls;
+using namespace std;
+
+const double nat_cut_off_in_max=2.0;//nat cut-off in max used in FSC
+
+void FALP_pvalues::compute_intercepts(
+FALP_set_of_parameters &par_)
+{
+	if(!par_.d_params_flag)
+	{
+		throw error("Unexpected error: FALP_pvalues::compute_intercepts is called for undefined parameters\n",1);
+	};
+
+	par_.b_I=2.0*par_.G*(par_.gapless_a_I-par_.a_I); 
+	par_.b_I_error=2.0*par_.G*FSA_utils::error_of_the_sum(par_.gapless_a_I_error,par_.a_I_error); 
+	par_.beta_I=2.0*par_.G*(par_.gapless_alpha_I-par_.alpha_I); 
+	par_.beta_I_error=2.0*par_.G*FSA_utils::error_of_the_sum(par_.gapless_alpha_I_error,par_.alpha_I_error); 
+
+	par_.b_J=2.0*par_.G*(par_.gapless_a_J-par_.a_J); 
+	par_.b_J_error=2.0*par_.G*FSA_utils::error_of_the_sum(par_.gapless_a_J_error,par_.a_J_error); 
+	par_.beta_J=2.0*par_.G*(par_.gapless_alpha_J-par_.alpha_J); 
+	par_.beta_J_error=2.0*par_.G*FSA_utils::error_of_the_sum(par_.gapless_alpha_J_error,par_.alpha_J_error); 
+
+	par_.tau=2.0*par_.G*(par_.gapless_sigma-par_.sigma);
+	par_.tau_error=2.0*par_.G*FSA_utils::error_of_the_sum(par_.gapless_sigma_error,par_.sigma_error);
+
+	long int vector_size=(long int)par_.m_LambdaSbs.size();
+
+	par_.m_BISbs.resize(vector_size);
+	par_.m_BJSbs.resize(vector_size);
+	par_.m_BetaISbs.resize(vector_size);
+	par_.m_BetaJSbs.resize(vector_size);
+	par_.m_TauSbs.resize(vector_size);
+
+	long int i;
+	for(i=0;i<vector_size;i++)
+	{
+		par_.m_BISbs[i]=2.0*par_.G*(par_.gapless_a_I-par_.m_AISbs[i]); 
+		par_.m_BetaISbs[i]=2.0*par_.G*(par_.gapless_alpha_I-par_.m_AlphaISbs[i]); 
+
+
+		par_.m_BJSbs[i]=2.0*par_.G*(par_.gapless_a_J-par_.m_AJSbs[i]); 
+		par_.m_BetaJSbs[i]=2.0*par_.G*(par_.gapless_alpha_J-par_.m_AlphaJSbs[i]); 
+
+
+		par_.m_TauSbs[i]=2.0*par_.G*(par_.gapless_sigma-par_.m_SigmaSbs[i]);
+
+	};
+
+	compute_tmp_values(par_);
+
+}
+
+void FALP_pvalues::get_appr_tail_prob_with_cov(
+const FALP_set_of_parameters &par_,
+bool blast_,
+double y_,
+
+double m_,
+double n_,
+
+
+double &P_,
+double &P_error_,
+
+double &E_,
+double &E_error_,
+
+double &area_,
+
+double a_normal_,
+double b_normal_,
+double h_normal_,
+long int N_normal_,
+double *p_normal_,
+
+bool &area_is_1_flag_)
+{
+
+	//to optimize performance
+	blast_=false;
+
+	double lambda_=par_.lambda;
+	double lambda_error_=par_.lambda_error;
+	double k_=par_.K;
+	double k_error_=par_.K_error;
+
+	double ai_hat_=par_.a_I;
+	double ai_hat_error_=par_.a_I_error;
+	double bi_hat_; 
+	double bi_hat_error_; 
+	double alphai_hat_=par_.alpha_I;
+	double alphai_hat_error_=par_.alpha_I_error;
+	double betai_hat_; 
+	double betai_hat_error_; 
+
+	double aj_hat_=par_.a_J;
+	double aj_hat_error_=par_.a_J_error;
+	double bj_hat_; 
+	double bj_hat_error_; 
+	double alphaj_hat_=par_.alpha_J;
+	double alphaj_hat_error_=par_.alpha_J_error;
+	double betaj_hat_; 
+	double betaj_hat_error_; 
+
+	double sigma_hat_=par_.sigma;
+	double sigma_hat_error_=par_.sigma_error;
+	double tau_hat_;
+ 	double tau_hat_error_;
+ 
+	{
+		bi_hat_=par_.b_I;
+		bi_hat_error_=par_.b_I_error;
+		betai_hat_=par_.beta_I;
+		betai_hat_error_=par_.beta_I_error;
+
+		bj_hat_=par_.b_J;
+		bj_hat_error_=par_.b_J_error;
+		betaj_hat_=par_.beta_J;
+		betaj_hat_error_=par_.beta_J_error;
+
+		tau_hat_=par_.tau;
+		tau_hat_error_=par_.tau_error;
+	};
+
+
+	if(blast_)
+	{
+		alphai_hat_=0;
+		alphai_hat_error_=0;
+		betai_hat_=0;
+		betai_hat_error_=0;
+
+		alphaj_hat_=0;
+		alphaj_hat_error_=0;
+		betaj_hat_=0;
+		betaj_hat_error_=0;
+
+		sigma_hat_=0;
+		sigma_hat_error_=0;
+		tau_hat_=0;
+		tau_hat_error_=0;
+	};
+
+	double eps=0.000001;
+
+	double m_li_y_error=0;
+	double m_li_y=0;
+
+	double tmp=ai_hat_*y_+bi_hat_;
+
+	m_li_y_error=FSA_utils::error_of_the_sum(fabs(y_)*ai_hat_error_,bi_hat_error_);
+	m_li_y=m_-tmp;
+
+	
+	double vi_y_error=0;
+	double vi_y=0;
+
+
+	vi_y_error=FSA_utils::error_of_the_sum(fabs(y_)*alphai_hat_error_,betai_hat_error_);
+	vi_y=FSA_utils::Tmax(par_.vi_y_thr,alphai_hat_*y_+betai_hat_);
+
+	double sqrt_vi_y_error=FSA_utils::error_of_the_sqrt(vi_y,vi_y_error);
+
+	double sqrt_vi_y=sqrt(vi_y);
+
+	double m_F=0;
+	double m_F_error=0;
+
+	if(sqrt_vi_y==0.0||blast_)
+	{
+		m_F=1e100;
+		m_F_error=0.0;
+	}
+	else
+	{
+		m_F_error=FSA_utils::error_of_the_ratio(m_li_y,m_li_y_error,sqrt_vi_y,sqrt_vi_y_error);
+		m_F=m_li_y/sqrt_vi_y;
+	};
+
+
+	double P_m_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,m_F,eps);
+	double P_m_F_error=const_val*exp(-0.5*m_F*m_F)*m_F_error;
+
+	double E_m_F=-const_val*exp(-0.5*m_F*m_F);
+	double E_m_F_error=fabs(-E_m_F*m_F)*m_F_error;
+
+	double m_li_y_P_m_F_error=FSA_utils::error_of_the_product(m_li_y,m_li_y_error,P_m_F,P_m_F_error);
+	double m_li_y_P_m_F=m_li_y*P_m_F;
+
+	double sqrt_vi_y_E_m_F_error=FSA_utils::error_of_the_product(sqrt_vi_y,sqrt_vi_y_error,E_m_F,E_m_F_error);
+	double sqrt_vi_y_E_m_F=sqrt_vi_y*E_m_F;
+
+	double p1_error=FSA_utils::error_of_the_sum(m_li_y_P_m_F_error,sqrt_vi_y_E_m_F_error);
+	double p1=m_li_y_P_m_F-sqrt_vi_y_E_m_F;
+
+
+	double n_lj_y_error=0;
+	double n_lj_y=0;
+
+	tmp=aj_hat_*y_+bj_hat_;
+
+	n_lj_y_error=FSA_utils::error_of_the_sum(fabs(y_)*aj_hat_error_,bj_hat_error_);
+	n_lj_y=n_-tmp;
+
+
+	double vj_y_error=0;
+	double vj_y=0;
+
+
+	vj_y_error=FSA_utils::error_of_the_sum(fabs(y_)*alphaj_hat_error_,betaj_hat_error_);
+
+	vj_y=FSA_utils::Tmax(par_.vj_y_thr,alphaj_hat_*y_+betaj_hat_);
+
+	double sqrt_vj_y_error=FSA_utils::error_of_the_sqrt(vj_y,vj_y_error);
+
+	double sqrt_vj_y=sqrt(vj_y);
+
+	double n_F=0;
+	double n_F_error=0;
+
+	if(sqrt_vj_y==0.0||blast_)
+	{
+		n_F=1e100;
+		n_F_error=0.0;
+	}
+	else
+	{
+		n_F_error=FSA_utils::error_of_the_ratio(n_lj_y,n_lj_y_error,sqrt_vj_y,sqrt_vj_y_error);
+
+		n_F=n_lj_y/sqrt_vj_y;
+	};
+
+	double P_n_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,n_F,eps);
+	double P_n_F_error=const_val*exp(-0.5*n_F*n_F)*n_F_error;
+
+	double E_n_F=-const_val*exp(-0.5*n_F*n_F);
+	double E_n_F_error=fabs(-E_n_F*n_F)*n_F_error;
+
+	double n_lj_y_P_n_F_error=FSA_utils::error_of_the_product(n_lj_y,n_lj_y_error,P_n_F,P_n_F_error);
+	double n_lj_y_P_n_F=n_lj_y*P_n_F;
+
+	double sqrt_vj_y_E_n_F_error=FSA_utils::error_of_the_product(sqrt_vj_y,sqrt_vj_y_error,E_n_F,E_n_F_error);
+	double sqrt_vj_y_E_n_F=sqrt_vj_y*E_n_F;
+
+	double p2_error=FSA_utils::error_of_the_sum(n_lj_y_P_n_F_error,sqrt_vj_y_E_n_F_error);
+	double p2=n_lj_y_P_n_F-sqrt_vj_y_E_n_F;
+
+
+
+
+	double c_y_error=0;
+	double c_y=0;
+
+	c_y_error=FSA_utils::error_of_the_sum(sigma_hat_error_*y_,tau_hat_error_);
+
+	c_y=FSA_utils::Tmax(par_.c_y_thr,sigma_hat_*y_+tau_hat_);
+
+	double P_m_F_P_n_F_error=FSA_utils::error_of_the_product(P_m_F,P_m_F_error,P_n_F,P_n_F_error);
+	double P_m_F_P_n_F=P_m_F*P_n_F;
+
+	double c_y_P_m_F_P_n_F_error=FSA_utils::error_of_the_product(c_y,c_y_error,P_m_F_P_n_F,P_m_F_P_n_F_error);
+	double c_y_P_m_F_P_n_F=c_y*P_m_F_P_n_F;
+
+	double p1_p2_error=FSA_utils::error_of_the_product(p1,p1_error,p2,p2_error);
+	double p1_p2=p1*p2;
+
+
+	double area_error=FSA_utils::error_of_the_sum(p1_p2_error,c_y_P_m_F_P_n_F_error);
+	double area=p1_p2+c_y_P_m_F_P_n_F;
+
+
+
+
+	if(!blast_)
+	{
+		//area=FSA_utils::Tmax(area,1.0);
+	}
+	else
+	{
+		if(area<=1.0)
+		{
+			area_is_1_flag_=true;
+		};
+
+		if(area_is_1_flag_)
+		{
+			area=1.0;
+		};
+	};
+
+	double exp_lambda_y_error=fabs(lambda_error_*y_*exp(-lambda_*y_));
+	double exp_lambda_y=exp(-lambda_*y_);
+
+	double k_exp_lambda_y_error=FSA_utils::error_of_the_product(k_,k_error_,exp_lambda_y,exp_lambda_y_error);
+	double k_exp_lambda_y=k_*exp_lambda_y;
+
+	double area_k_exp_lambda_y_error=FSA_utils::error_of_the_product(area,area_error,k_exp_lambda_y,k_exp_lambda_y_error);
+	double area_k_exp_lambda_y=-area*k_exp_lambda_y;
+
+	E_=-area_k_exp_lambda_y;
+	E_error_=area_k_exp_lambda_y_error;
+
+	P_error_=exp(area_k_exp_lambda_y)*area_k_exp_lambda_y_error;
+
+	P_=sls_basic::one_minus_exp_function(area_k_exp_lambda_y);
+//	P_=1-exp(-k_*area*exp(-lambda_*y_));
+
+	area_=area;
+}
+
+void FALP_pvalues::compute_tmp_values(FALP_set_of_parameters &par_)
+{
+	if(!par_.d_params_flag)
+	{
+		throw error("Unexpected call of FALP_pvalues::compute_tmp_values\n",1);
+	};
+
+	//tmp values
+	if(par_.lambda>0)
+	{
+		par_.vi_y_thr=FSA_utils::Tmax(nat_cut_off_in_max*par_.alpha_I/par_.lambda,0.0);
+		par_.vj_y_thr=FSA_utils::Tmax(nat_cut_off_in_max*par_.alpha_J/par_.lambda,0.0);
+		par_.c_y_thr=FSA_utils::Tmax(nat_cut_off_in_max*par_.sigma/par_.lambda,0.0);
+	}
+	else
+	{
+		par_.vi_y_thr=0;
+		par_.vj_y_thr=0;
+		par_.c_y_thr=0;
+
+		par_.d_params_flag=false;
+	};
+}
+
+void FALP_pvalues::get_appr_tail_prob_with_cov_without_errors(
+const FALP_set_of_parameters &par_,
+bool blast_,
+double y_,
+
+double m_,
+double n_,
+
+
+double &P_,
+double &E_,
+
+double &area_,
+
+double a_normal_,
+double b_normal_,
+double h_normal_,
+long int N_normal_,
+double *p_normal_,
+
+bool &area_is_1_flag_,
+bool compute_only_area_)
+{
+
+	//to optimize performance
+	blast_=false;
+
+	double lambda_=par_.lambda;
+	double k_=par_.K;
+
+	double ai_hat_=par_.a_I;
+	double bi_hat_;
+	double alphai_hat_=par_.alpha_I;
+	double betai_hat_;
+
+	double aj_hat_=par_.a_J;
+	double bj_hat_;
+	double alphaj_hat_=par_.alpha_J;
+	double betaj_hat_;
+
+	double sigma_hat_=par_.sigma;
+	double tau_hat_;
+
+	{
+		bi_hat_=par_.b_I;
+		betai_hat_=par_.beta_I;
+
+		bj_hat_=par_.b_J;
+		betaj_hat_=par_.beta_J;
+
+		tau_hat_=par_.tau;
+	};
+
+
+	if(blast_)
+	{
+		alphai_hat_=0;
+		betai_hat_=0;
+
+		alphaj_hat_=0;
+		betaj_hat_=0;
+
+		sigma_hat_=0;
+		tau_hat_=0;
+	};
+
+	double eps=0.000001;
+
+	double m_li_y=0;
+
+	double tmp=ai_hat_*y_+bi_hat_;
+	m_li_y=m_-tmp;
+	
+	double vi_y=0;
+
+	vi_y=FSA_utils::Tmax(par_.vi_y_thr,alphai_hat_*y_+betai_hat_);
+
+	double sqrt_vi_y=sqrt(vi_y);
+
+	double m_F;
+
+	if(sqrt_vi_y==0.0||blast_)
+	{
+		m_F=1e100;
+	}
+	else
+	{
+		m_F=m_li_y/sqrt_vi_y;
+	};
+
+
+	double P_m_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,m_F,eps);
+
+	double E_m_F=-const_val*exp(-0.5*m_F*m_F);
+
+	double m_li_y_P_m_F=m_li_y*P_m_F;
+
+	double sqrt_vi_y_E_m_F=sqrt_vi_y*E_m_F;
+
+	double p1=m_li_y_P_m_F-sqrt_vi_y_E_m_F;
+
+
+	double n_lj_y=0;
+
+	tmp=aj_hat_*y_+bj_hat_;
+
+	n_lj_y=n_-tmp;
+
+	double vj_y=0;
+
+
+	vj_y=FSA_utils::Tmax(par_.vj_y_thr,alphaj_hat_*y_+betaj_hat_);
+	
+	double sqrt_vj_y=sqrt(vj_y);
+
+	double n_F;
+
+	if(sqrt_vj_y==0.0||blast_)
+	{
+		n_F=1e100;
+	}
+	else
+	{
+		n_F=n_lj_y/sqrt_vj_y;
+	};
+
+	double P_n_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,n_F,eps);
+
+	double E_n_F=-const_val*exp(-0.5*n_F*n_F);
+
+	double n_lj_y_P_n_F=n_lj_y*P_n_F;
+
+	double sqrt_vj_y_E_n_F=sqrt_vj_y*E_n_F;
+
+	double p2=n_lj_y_P_n_F-sqrt_vj_y_E_n_F;
+
+
+
+
+	double c_y=0;
+
+	
+	c_y=FSA_utils::Tmax(par_.c_y_thr,sigma_hat_*y_+tau_hat_);
+
+	double P_m_F_P_n_F=P_m_F*P_n_F;
+
+	double c_y_P_m_F_P_n_F=c_y*P_m_F_P_n_F;
+
+	double p1_p2=p1*p2;
+
+	double area=p1_p2+c_y_P_m_F_P_n_F;
+
+	if(!blast_)
+	{
+		//area=FSA_utils::Tmax(area,1.0);
+	}
+	else
+	{
+		if(area<=1.0)
+		{
+			area_is_1_flag_=true;
+		};
+
+		if(area_is_1_flag_)
+		{
+			area=1.0;
+		};
+	};
+
+	area_=area;
+
+	if(compute_only_area_)
+	{
+		return;
+	};
+
+	double exp_lambda_y=exp(-lambda_*y_);
+
+	double k_exp_lambda_y=k_*exp_lambda_y;
+
+	double area_k_exp_lambda_y=-area*k_exp_lambda_y;
+
+	E_=-area_k_exp_lambda_y;
+
+	P_=sls_basic::one_minus_exp_function(area_k_exp_lambda_y);
+//	P_=1-exp(-k_*area*exp(-lambda_*y_));
+
+}
+
+void FALP_pvalues::get_P_error_using_splitting_method(
+const FALP_set_of_parameters &par_,
+bool blast_,
+double y_,
+
+double m_,
+double n_,
+
+
+double &P_,
+double &P_error_,
+
+double &E_,
+double &E_error_,
+
+double a_normal_,
+double b_normal_,
+double h_normal_,
+long int N_normal_,
+double *p_normal_,
+
+bool &area_is_1_flag_)
+{
+	long int dim=par_.m_LambdaSbs.size();
+	if(dim==0)
+	{
+		throw error("Unexpected error in get_P_error_using_splitting_method\n",1);
+	};
+
+	P_=0;
+	P_error_=0;
+
+	E_=0;
+	E_error_=0;
+
+	double exp_E_values_aver=0;
+	double exp_E_values_error=0;
+
+
+	vector<double> P_values(dim);
+	vector<double> E_values(dim);
+	vector<double> exp_E_values(dim);
+
+
+	long int i;
+	for(i=0;i<dim;i++)
+	{
+		FALP_set_of_parameters par_tmp;
+
+		par_tmp.a_I=par_.m_AISbs[i];
+		par_tmp.a_I_error=0;
+
+		par_tmp.a_J=par_.m_AJSbs[i];
+		par_tmp.a_J_error=0;
+
+		
+
+		par_tmp.gapless_a_I=par_.gapless_a_I;
+		par_tmp.gapless_a_I_error=par_.gapless_a_I_error;
+
+		par_tmp.gapless_a_J=par_.gapless_a_J;
+		par_tmp.gapless_a_J_error=par_.gapless_a_J_error;
+
+		par_tmp.sigma=par_.m_SigmaSbs[i];
+		par_tmp.sigma_error=0;
+
+		par_tmp.gapless_sigma=par_.gapless_sigma;
+		par_tmp.gapless_sigma_error=par_.gapless_sigma_error;
+
+
+		par_tmp.gapless_alpha_I=par_.gapless_alpha_I;
+		par_tmp.gapless_alpha_I_error=par_.gapless_alpha_I_error;
+
+		par_tmp.gapless_alpha_J=par_.gapless_alpha_J;
+		par_tmp.gapless_alpha_J_error=par_.gapless_alpha_J_error;
+
+
+		par_tmp.C=par_.m_CSbs[i];
+		par_tmp.C_error=0;
+
+		par_tmp.K=par_.m_KSbs[i];
+		par_tmp.K_error=0;
+
+
+		par_tmp.lambda=par_.m_LambdaSbs[i];
+		par_tmp.lambda_error=0;
+
+		par_tmp.alpha_I=par_.m_AlphaISbs[i];
+		par_tmp.alpha_I_error=0;
+
+		par_tmp.alpha_J=par_.m_AlphaJSbs[i];
+		par_tmp.alpha_J_error=0;
+
+		par_tmp.G=par_.G;
+		par_tmp.G1=par_.G1;
+		par_tmp.G2=par_.G2;
+
+		//intercepts
+
+		{
+			par_tmp.b_I=par_.m_BISbs[i];
+			par_tmp.b_I_error=0;
+
+			par_tmp.b_J=par_.m_BJSbs[i];
+			par_tmp.b_J_error=0;
+
+			par_tmp.beta_I=par_.m_BetaISbs[i];
+			par_tmp.beta_I_error=0;
+
+			par_tmp.beta_J=par_.m_BetaJSbs[i];
+			par_tmp.beta_J_error=0;
+
+			par_tmp.tau=par_.m_TauSbs[i];
+			par_tmp.tau_error=0;
+
+			par_tmp.d_params_flag=true;
+
+			compute_tmp_values(par_tmp);
+
+
+		};
+
+		double P_tmp,area_tmp,E_tmp;
+
+		get_appr_tail_prob_with_cov_without_errors(
+		par_tmp,
+		blast_,
+		y_,
+		m_,
+		n_,
+
+		P_tmp,
+		E_tmp,
+
+		area_tmp,
+
+		a_normal_,
+		b_normal_,
+		h_normal_,
+		N_normal_,
+		p_normal_,
+
+		area_is_1_flag_);
+
+		P_values[i]=P_tmp;
+
+		P_+=P_tmp;
+
+		E_values[i]=E_tmp;
+
+		E_+=E_tmp;
+
+		double exp_E_tmp=exp(-E_tmp);
+		exp_E_values[i]=exp_E_tmp;
+		exp_E_values_aver+=exp_E_tmp;
+
+
+	};
+
+	if(dim<=1)
+	{
+		return;
+	};
+
+
+	if(P_<=0)
+	{
+		return;
+	};
+
+	if(E_<=0)
+	{
+		return;
+	};
+
+
+	P_/=(double)dim;
+	E_/=(double)dim;
+	exp_E_values_aver/=(double)dim;
+
+	for(i=0;i<dim;i++)
+	{
+		double tmp=P_values[i]/P_;
+		P_error_+=tmp*tmp;
+
+		tmp=E_values[i]/E_;
+		E_error_+=tmp*tmp;
+
+		tmp=exp_E_values[i]/exp_E_values_aver;
+		exp_E_values_error+=tmp*tmp;
+
+	};
+
+	P_error_/=(double)dim;
+	P_error_-=1;
+	
+	E_error_/=(double)dim;
+	E_error_-=1;
+
+	exp_E_values_error/=(double)dim;
+	exp_E_values_error-=1;
+
+
+	if(P_<1e-4)
+	{
+		P_error_=P_*FSA_utils::sqrt_plus(P_error_/(double)dim);
+	}
+	else
+	{
+		P_error_=exp_E_values_aver*FSA_utils::sqrt_plus(exp_E_values_error/(double)dim);
+	};
+
+	E_error_=E_*FSA_utils::sqrt_plus(E_error_/(double)dim);
+
+}
+
+
+FALP_pvalues::FALP_pvalues()
+{
+	blast=false;
+	eps=0.0001;
+	a_normal=-10;
+	b_normal=10;
+	N_normal=NORMAL_DISTR_ARRAY_DIM;
+	h_normal=(b_normal-a_normal)/(double)N_normal;
+	p_normal=normal_distr_array_for_P_values_calculation;
+}
+
+
+FALP_pvalues::~FALP_pvalues()
+{
+	
+}
+
+void FALP_pvalues::calculate_P_values(
+long int Score1,
+long int Score2,
+double Seq1Len,
+double Seq2Len,
+const FALP_set_of_parameters &ParametersSet,
+vector<double> &P_values,
+vector<double> &P_values_errors,
+vector<double> &E_values,
+vector<double> &E_values_errors)
+{
+	if(Score2<Score1)
+	{
+		throw error("Error - Score2<Score1 in FALP_pvalues::calculate_P_values\n",2);
+	};
+
+	if(Seq1Len<=0||Seq2Len<=0)
+	{
+		throw error("Error - Seq1Len<=0||Seq2Len<=0 in FALP_pvalues::calculate_P_values\n",2);
+	};
+
+	P_values.resize(Score2-Score1+1);
+	P_values_errors.resize(Score2-Score1+1);
+
+	E_values.resize(Score2-Score1+1);
+	E_values_errors.resize(Score2-Score1+1);
+
+
+	long int y;
+	for(y=Score1;y<=Score2;y++)
+	{
+		calculate_P_values(
+		y,
+		Seq1Len,
+		Seq2Len,
+		ParametersSet,
+		P_values[y-Score1],
+		P_values_errors[y-Score1],
+		E_values[y-Score1],
+		E_values_errors[y-Score1]);
+	};
+
+}
+
+void FALP_pvalues::calculate_P_values(
+double Score,
+double Seq1Len,
+double Seq2Len,
+const FALP_set_of_parameters &ParametersSet,
+double &P_value,
+double &P_value_error,
+double &E_value,
+double &E_value_error,
+bool read_Sbs_par_flag)
+{
+
+	if(Seq1Len<=0||Seq2Len<=0)
+	{
+		throw error("Error - Seq1Len<=0||Seq2Len<=0 in FALP_pvalues::calculate_P_values\n",2);
+	};
+
+	double P;
+	double P_error;
+	double E;
+	double E_error;
+	double area;
+	bool area_is_1_flag=false;
+
+
+	if(read_Sbs_par_flag)
+	{
+		
+
+		get_appr_tail_prob_with_cov_without_errors(
+		ParametersSet,
+		blast,
+		Score,
+		Seq1Len,
+		Seq2Len,
+
+		P,
+
+		E,
+
+		area,
+		a_normal,
+		b_normal,
+		h_normal,
+		N_normal,
+		p_normal,
+		area_is_1_flag);
+
+
+		
+		double P_tmp,E_tmp;
+
+		if(ParametersSet.m_LambdaSbs.size()>0)
+		{
+			get_P_error_using_splitting_method(
+			ParametersSet,
+			blast,
+			Score,
+			Seq1Len,
+			Seq2Len,
+
+			P_tmp,
+			P_error,
+
+			E_tmp,
+			E_error,
+
+			a_normal,
+			b_normal,
+			h_normal,
+			N_normal,
+			p_normal,
+			area_is_1_flag);
+
+
+			if(P_tmp>0)
+			{
+				P_error=P_error/P_tmp*P;
+			};
+
+			P_value_error=P_error;
+
+			if(E_tmp>0)
+			{
+				E_error=E_error/E_tmp*E;
+			};
+
+			E_value_error=E_error;
+
+		}
+		else
+		{
+			P_value_error=-DBL_MAX;
+			E_value_error=-DBL_MAX;
+		};
+
+		
+		
+	}
+	else
+	{
+		get_appr_tail_prob_with_cov(
+		ParametersSet,
+		blast,
+		Score,
+		Seq1Len,
+		Seq2Len,
+
+		P,
+		P_error,
+
+		E,
+		E_error,
+
+		area,
+		a_normal,
+		b_normal,
+		h_normal,
+		N_normal,
+		p_normal,
+		area_is_1_flag);
+
+		P_value_error=P_error;
+		E_value_error=E_error;
+	};
+
+	P_value=P;
+	E_value=E;
+}
+
+
+//input/output Gumbel parameters
+
+namespace Sls {
+
+std::ostream &operator<<(std::ostream &s_,
+const FALP_set_of_parameters &gumbel_params_)
+{
+
+	s_<<"Lambda\tLambda error\tK\tK error\tC\tC error\ta_1\ta_1 error\ta_2\ta_2 error\tsigma\tsigma error\talpha_1\talpha_1 error\talpha_2\talpha_2 error\tGapless a_1\tGapless a_1 error\tGapless a_2\tGapless a_2 error\tGapless sigma\tGapless sigma error\tGapless alpha_1\tGapless alpha_1 error\tGapless alpha_2\tGapless alpha_2 error\tG\tCalculation time\tArrays for error calculation\n";
+	s_.precision(20);
+	s_<<
+		gumbel_params_.lambda<<"\t"<<gumbel_params_.lambda_error<<"\t"<<
+		gumbel_params_.K<<"\t"<<gumbel_params_.K_error<<"\t"<<
+		gumbel_params_.C<<"\t"<<gumbel_params_.C_error<<"\t"<<
+		gumbel_params_.a_I<<"\t"<<gumbel_params_.a_I_error<<"\t"<<
+		gumbel_params_.a_J<<"\t"<<gumbel_params_.a_J_error<<"\t"<<
+		gumbel_params_.sigma<<"\t"<<gumbel_params_.sigma_error<<"\t"<<
+		gumbel_params_.alpha_I<<"\t"<<gumbel_params_.alpha_I_error<<"\t"<<
+		gumbel_params_.alpha_J<<"\t"<<gumbel_params_.alpha_J_error<<"\t"<<
+		gumbel_params_.gapless_a_I<<"\t"<<gumbel_params_.gapless_a_I_error<<"\t"<<
+		gumbel_params_.gapless_a_J<<"\t"<<gumbel_params_.gapless_a_J_error<<"\t"<<
+		gumbel_params_.gapless_sigma<<"\t"<<gumbel_params_.gapless_sigma_error<<"\t"<<
+		gumbel_params_.gapless_alpha_I<<"\t"<<gumbel_params_.gapless_alpha_I_error<<"\t"<<
+		gumbel_params_.gapless_alpha_J<<"\t"<<gumbel_params_.gapless_alpha_J_error<<"\t"<<
+		gumbel_params_.G<<"\t"<<
+		gumbel_params_.m_CalcTime<<"\t";
+
+	long int i;
+
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_LambdaSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_KSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_CSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_AISbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_AJSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_SigmaSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_AlphaISbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_AlphaJSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+	s_<<endl;
+
+	return s_;
+
+
+}
+
+std::istream &operator>>(std::istream &s_,
+FALP_set_of_parameters &gumbel_params_)
+{
+
+
+	string st;
+	getline(s_,st);
+	s_>>
+		gumbel_params_.lambda>>gumbel_params_.lambda_error>>
+		gumbel_params_.K>>gumbel_params_.K_error>>
+		gumbel_params_.C>>gumbel_params_.C_error>>
+		gumbel_params_.a_I>>gumbel_params_.a_I_error>>
+		gumbel_params_.a_J>>gumbel_params_.a_J_error>>
+		gumbel_params_.sigma>>gumbel_params_.sigma_error>>
+		gumbel_params_.alpha_I>>gumbel_params_.alpha_I_error>>
+		gumbel_params_.alpha_J>>gumbel_params_.alpha_J_error>>
+		gumbel_params_.gapless_a_I>>gumbel_params_.gapless_a_I_error>>
+		gumbel_params_.gapless_a_J>>gumbel_params_.gapless_a_J_error>>
+		gumbel_params_.gapless_sigma>>gumbel_params_.gapless_sigma_error>>
+		gumbel_params_.gapless_alpha_I>>gumbel_params_.gapless_alpha_I_error>>
+		gumbel_params_.gapless_alpha_J>>gumbel_params_.gapless_alpha_J_error>>
+		gumbel_params_.G>>
+		gumbel_params_.m_CalcTime;
+
+	long int i;
+
+
+	{
+		vector<double> &tmp=gumbel_params_.m_LambdaSbs;
+		long int tmp_size;
+		s_>>tmp_size;
+		if(tmp_size<=0)
+		{
+			throw error("Error in the input parameters\n",4);
+		};
+		tmp.resize(tmp_size);
+		for(i=0;i<tmp_size;i++)
+		{
+			s_>>tmp[i];
+		};
+	};
+
+	{
+		vector<double> &tmp=gumbel_params_.m_KSbs;
+		long int tmp_size;
+		s_>>tmp_size;
+		if(tmp_size<=0)
+		{
+			throw error("Error in the input parameters\n",4);
+		};
+		tmp.resize(tmp_size);
+		for(i=0;i<tmp_size;i++)
+		{
+			s_>>tmp[i];
+		};
+	};
+
+
+	{
+		vector<double> &tmp=gumbel_params_.m_CSbs;
+		long int tmp_size;
+		s_>>tmp_size;
+		if(tmp_size<=0)
+		{
+			throw error("Error in the input parameters\n",4);
+		};
+		tmp.resize(tmp_size);
+		for(i=0;i<tmp_size;i++)
+		{
+			s_>>tmp[i];
+		};
+	};
+
+
+
+
+	{
+		vector<double> &tmp=gumbel_params_.m_AISbs;
+		long int tmp_size;
+		s_>>tmp_size;
+		if(tmp_size<=0)
+		{
+			throw error("Error in the input parameters\n",4);
+		};
+		tmp.resize(tmp_size);
+		for(i=0;i<tmp_size;i++)
+		{
+			s_>>tmp[i];
+		};
+	};
+
+	{
+		vector<double> &tmp=gumbel_params_.m_AJSbs;
+		long int tmp_size;
+		s_>>tmp_size;
+		if(tmp_size<=0)
+		{
+			throw error("Error in the input parameters\n",4);
+		};
+		tmp.resize(tmp_size);
+		for(i=0;i<tmp_size;i++)
+		{
+			s_>>tmp[i];
+		};
+	};
+
+
+	{
+		vector<double> &tmp=gumbel_params_.m_SigmaSbs;
+		long int tmp_size;
+		s_>>tmp_size;
+		if(tmp_size<=0)
+		{
+			throw error("Error in the input parameters\n",4);
+		};
+		tmp.resize(tmp_size);
+		for(i=0;i<tmp_size;i++)
+		{
+			s_>>tmp[i];
+		};
+	};
+
+
+
+	{
+		vector<double> &tmp=gumbel_params_.m_AlphaISbs;
+		long int tmp_size;
+		s_>>tmp_size;
+		if(tmp_size<=0)
+		{
+			throw error("Error in the input parameters\n",4);
+		};
+		tmp.resize(tmp_size);
+		for(i=0;i<tmp_size;i++)
+		{
+			s_>>tmp[i];
+		};
+	};
+
+	{
+		vector<double> &tmp=gumbel_params_.m_AlphaJSbs;
+		long int tmp_size;
+		s_>>tmp_size;
+		if(tmp_size<=0)
+		{
+			throw error("Error in the input parameters\n",4);
+		};
+		tmp.resize(tmp_size);
+		for(i=0;i<tmp_size;i++)
+		{
+			s_>>tmp[i];
+		};
+	};
+
+
+	return s_;
+
+}
+
+//returns "true" if the Gumbel parameters are properly defined and "false" otherwise
+bool FALP_pvalues::assert_Gumbel_parameters(
+const FALP_set_of_parameters &par_)//a set of Gumbel parameters
+{
+		if(par_.lambda<=0||
+		par_.lambda_error<0||
+
+		//the parameters C and K_C are not necessary for the P-value calculation
+		//par_.C<0||
+		//par_.C_error<0||
+
+		//par_.K_C<0||
+		//par_.K_C_error<0||
+
+		par_.K<=0||
+		par_.K_error<0||
+
+		par_.a_I<0||
+		par_.a_I_error<0||
+
+		par_.a_J<0||
+		par_.a_J_error<0||
+
+		par_.sigma<0||
+		par_.sigma_error<0||
+
+		par_.alpha_I<0||
+		par_.alpha_I_error<0||
+
+		par_.alpha_J<0||
+		par_.alpha_J_error<0||
+
+		par_.gapless_a_I<0||
+		par_.gapless_a_I_error<0||
+
+		par_.gapless_a_J<0||
+		par_.gapless_a_J_error<0||
+
+
+
+		par_.gapless_alpha_I<0||
+		par_.gapless_alpha_I_error<0||
+
+		par_.gapless_alpha_J<0||
+		par_.gapless_alpha_J_error<0||
+
+		par_.gapless_sigma<0||
+		par_.gapless_sigma_error<0||
+
+		par_.G<0||
+		par_.G1<0||
+		par_.G2<0||
+
+		//intercepts
+		par_.b_I_error<0||
+
+		par_.b_J_error<0||
+
+		par_.beta_I_error<0||
+
+		par_.beta_J_error<0||
+
+		par_.tau_error<0
+
+		)
+		{
+			return false;
+		};
+
+
+
+		size_t size_tmp=par_.m_LambdaSbs.size();
+		if(
+		par_.m_KSbs.size()!=size_tmp||
+		//par_.m_K_CSbs.size()!=size_tmp||
+		//par_.m_CSbs.size()!=size_tmp||
+
+		par_.m_SigmaSbs.size()!=size_tmp||
+
+		par_.m_AlphaISbs.size()!=size_tmp||
+		par_.m_AlphaJSbs.size()!=size_tmp||
+
+		par_.m_AISbs.size()!=size_tmp||
+		par_.m_AJSbs.size()!=size_tmp||
+
+		par_.m_BISbs.size()!=size_tmp||
+		par_.m_BJSbs.size()!=size_tmp||
+
+		par_.m_BetaISbs.size()!=size_tmp||
+		par_.m_BetaJSbs.size()!=size_tmp||
+
+		par_.m_TauSbs.size()!=size_tmp)
+		{
+			return false;
+		};
+
+
+		return true;
+
+}
+
+
+}
+
diff --git a/src/alp/sls_fsa1_pvalues.hpp b/src/alp/sls_fsa1_pvalues.hpp
index a106dff..c32cac0 100644
--- a/src/alp/sls_fsa1_pvalues.hpp
+++ b/src/alp/sls_fsa1_pvalues.hpp
@@ -1,343 +1,343 @@
-#ifndef INCLUDED_FSA1_SLS_PVALUES
-#define INCLUDED_FSA1_SLS_PVALUES
-
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_fsa1_pvalues.hpp
-
-Author: Sergey Sheetlin
-
-Contents: P-values calculation routines
-
-******************************************************************************/
-
-#include "sls_basic.hpp"
-
-#include <vector>
-#include <string>
-#include <math.h>
-#include <cstdlib>
-
-
-namespace Sls {
-
-	struct FALP_set_of_parameters
-	{
-
-		FALP_set_of_parameters()
-		{
-			d_params_flag=false;
-
-			b_I=0;
-			b_I_error=0;
-
-			b_J=0;
-			b_J_error=0;
-
-			beta_I=0;
-			beta_I_error=0;
-
-			beta_J=0;
-			beta_J_error=0;
-
-			tau=0;
-			tau_error=0;
-
-		};
-
-		double lambda;
-		double lambda_error;
-
-		double lambda_last_ALP_relative_error;
-
-		double C;
-		double C_error;
-
-		double K_C;
-		double K_C_error;
-
-		double K;
-		double K_error;
-
-		double a_I;
-		double a_I_error;
-
-		double a_J;
-		double a_J_error;
-
-		double sigma;
-		double sigma_error;
-
-		double alpha_I;
-		double alpha_I_error;
-
-		double alpha_J;
-		double alpha_J_error;
-
-		double gapless_a_I;
-		double gapless_a_I_error;
-
-		double gapless_a_J;
-		double gapless_a_J_error;
-
-
-
-		double gapless_alpha_I;
-		double gapless_alpha_I_error;
-
-		double gapless_alpha_J;
-		double gapless_alpha_J_error;
-
-		double gapless_sigma;
-		double gapless_sigma_error;
-
-		long int G;
-		long int G1;
-		long int G2;
-
-		long int realizations_number;
-
-		std::vector<double > m_LambdaSbs;
-		std::vector<double > m_KSbs;
-		std::vector<double > m_K_CSbs;
-		std::vector<double > m_CSbs;
-
-		std::vector<double > m_SigmaSbs;
-
-		std::vector<double > m_AlphaISbs;
-		std::vector<double > m_AlphaJSbs;
-
-		std::vector<double > m_AISbs;
-		std::vector<double > m_AJSbs;
-
-		double m_CalcTime;
-		
-
-		bool d_params_flag;//if true, then the parameters are defined and P-values can be calculated
-
-		//intercepts
-		double b_I;
-		double b_I_error;
-
-		double b_J;
-		double b_J_error;
-
-		double beta_I;
-		double beta_I_error;
-
-		double beta_J;
-		double beta_J_error;
-
-		double tau;
-		double tau_error;
-
-		std::vector<double > m_BISbs;
-		std::vector<double > m_BJSbs;
-
-		std::vector<double > m_BetaISbs;
-		std::vector<double > m_BetaJSbs;
-
-		std::vector<double > m_TauSbs;
-
-		//tmp values
-		double vi_y_thr;
-		double vj_y_thr;
-		double c_y_thr;
-
-	};
-
-	std::ostream &operator<<(std::ostream &s_,
-	const FALP_set_of_parameters &gumbel_params_);
-
-	std::istream &operator>>(std::istream &s_,
-	FALP_set_of_parameters &gumbel_params_);
-
-
-
-	class FALP_pvalues{
-
-		public:
-
-
-		FALP_pvalues();
-
-		~FALP_pvalues();
-
-
-		public:
-
-		static void get_appr_tail_prob_with_cov(
-		const FALP_set_of_parameters &par_,
-		bool blast_,
-		double y_,
-
-		double m_,
-		double n_,
-
-		double &P_,
-		double &P_error_,
-
-		double &E_,
-		double &E_error_,
-
-		double &area_,
-
-		double a_normal_,
-		double b_normal_,
-		double h_normal_,
-		long int N_normal_,
-		double *p_normal_,
-
-		bool &area_is_1_flag_);
-
-		static void compute_tmp_values(FALP_set_of_parameters &par_);
-
-		static void get_appr_tail_prob_with_cov_without_errors(
-		const FALP_set_of_parameters &par_,
-		bool blast_,
-		double y_,
-
-		double m_,
-		double n_,
-
-		double &P_,
-		double &E_,
-
-		double &area_,
-
-		double a_normal_,
-		double b_normal_,
-		double h_normal_,
-		long int N_normal_,
-		double *p_normal_,
-
-		bool &area_is_1_flag_,
-		bool compute_only_area_=false);
-
-		static void get_P_error_using_splitting_method(
-		const FALP_set_of_parameters &par_,
-		bool blast_,
-		double y_,
-
-		double m_,
-		double n_,
-
-		double &P_,
-		double &P_error_,
-
-		double &E_,
-		double &E_error_,
-
-
-		double a_normal_,
-		double b_normal_,
-		double h_normal_,
-		long int N_normal_,
-		double *p_normal_,
-
-		bool &area_is_1_flag_);
-
-
-		public:
-
-		static void compute_intercepts(
-		FALP_set_of_parameters &par_);
-
-		void calculate_P_values(
-		long int Score1,
-		long int Score2,
-
-		double Seq1Len,
-		double Seq2Len,
-
-		const FALP_set_of_parameters &ParametersSet,
-		std::vector<double> &P_values,
-		std::vector<double> &P_values_errors,
-		std::vector<double> &E_values,
-		std::vector<double> &E_values_errors);
-
-		void calculate_P_values(
-		double Score,
-		double Seq1Len,
-		double Seq2Len,
-		const FALP_set_of_parameters &ParametersSet,
-		double &P_value,
-		double &P_value_error,
-		double &E_value,
-		double &E_value_error,
-		bool read_Sbs_par_flag=true);
-
-		//returns "true" if the Gumbel parameters are properly defined and "false" otherwise
-		static bool assert_Gumbel_parameters(
-		const FALP_set_of_parameters &par_);//a set of Gumbel parameters
-
-		static inline double ran3()//generates the next random value
-		{
-			double rand_C=(double)((double)rand()/(double)RAND_MAX);
-			return rand_C;	
-		}
-
-		static inline double standard_normal()//generates standard normal random value using the Box�Muller transform
-		{
-			double r1=0;
-			while(r1==0)
-			{
-				r1=ran3();
-			};
-			double r2=0;
-			while(r2==0)
-			{
-				r2=ran3();
-			};
-
-			double v1=-2*log(r1);
-			if(v1<0)
-			{
-				v1=0;
-			};
-			return sqrt(v1)*cos(2*pi*r2);
-		}
-
-
-		public:
-
-
-		bool blast;
-		double eps;
-		double a_normal;
-		double b_normal;
-		long int N_normal;
-		double h_normal;
-		double *p_normal;
-
-
-	};
-}
-
-#endif //! INCLUDED
-
+#ifndef INCLUDED_FSA1_SLS_PVALUES
+#define INCLUDED_FSA1_SLS_PVALUES
+
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_fsa1_pvalues.hpp
+
+Author: Sergey Sheetlin
+
+Contents: P-values calculation routines
+
+******************************************************************************/
+
+#include "sls_basic.hpp"
+
+#include <vector>
+#include <string>
+#include <math.h>
+#include <cstdlib>
+
+
+namespace Sls {
+
+	struct FALP_set_of_parameters
+	{
+
+		FALP_set_of_parameters()
+		{
+			d_params_flag=false;
+
+			b_I=0;
+			b_I_error=0;
+
+			b_J=0;
+			b_J_error=0;
+
+			beta_I=0;
+			beta_I_error=0;
+
+			beta_J=0;
+			beta_J_error=0;
+
+			tau=0;
+			tau_error=0;
+
+		};
+
+		double lambda;
+		double lambda_error;
+
+		double lambda_last_ALP_relative_error;
+
+		double C;
+		double C_error;
+
+		double K_C;
+		double K_C_error;
+
+		double K;
+		double K_error;
+
+		double a_I;
+		double a_I_error;
+
+		double a_J;
+		double a_J_error;
+
+		double sigma;
+		double sigma_error;
+
+		double alpha_I;
+		double alpha_I_error;
+
+		double alpha_J;
+		double alpha_J_error;
+
+		double gapless_a_I;
+		double gapless_a_I_error;
+
+		double gapless_a_J;
+		double gapless_a_J_error;
+
+
+
+		double gapless_alpha_I;
+		double gapless_alpha_I_error;
+
+		double gapless_alpha_J;
+		double gapless_alpha_J_error;
+
+		double gapless_sigma;
+		double gapless_sigma_error;
+
+		long int G;
+		long int G1;
+		long int G2;
+
+		long int realizations_number;
+
+		std::vector<double > m_LambdaSbs;
+		std::vector<double > m_KSbs;
+		std::vector<double > m_K_CSbs;
+		std::vector<double > m_CSbs;
+
+		std::vector<double > m_SigmaSbs;
+
+		std::vector<double > m_AlphaISbs;
+		std::vector<double > m_AlphaJSbs;
+
+		std::vector<double > m_AISbs;
+		std::vector<double > m_AJSbs;
+
+		double m_CalcTime;
+		
+
+		bool d_params_flag;//if true, then the parameters are defined and P-values can be calculated
+
+		//intercepts
+		double b_I;
+		double b_I_error;
+
+		double b_J;
+		double b_J_error;
+
+		double beta_I;
+		double beta_I_error;
+
+		double beta_J;
+		double beta_J_error;
+
+		double tau;
+		double tau_error;
+
+		std::vector<double > m_BISbs;
+		std::vector<double > m_BJSbs;
+
+		std::vector<double > m_BetaISbs;
+		std::vector<double > m_BetaJSbs;
+
+		std::vector<double > m_TauSbs;
+
+		//tmp values
+		double vi_y_thr;
+		double vj_y_thr;
+		double c_y_thr;
+
+	};
+
+	std::ostream &operator<<(std::ostream &s_,
+	const FALP_set_of_parameters &gumbel_params_);
+
+	std::istream &operator>>(std::istream &s_,
+	FALP_set_of_parameters &gumbel_params_);
+
+
+
+	class FALP_pvalues{
+
+		public:
+
+
+		FALP_pvalues();
+
+		~FALP_pvalues();
+
+
+		public:
+
+		static void get_appr_tail_prob_with_cov(
+		const FALP_set_of_parameters &par_,
+		bool blast_,
+		double y_,
+
+		double m_,
+		double n_,
+
+		double &P_,
+		double &P_error_,
+
+		double &E_,
+		double &E_error_,
+
+		double &area_,
+
+		double a_normal_,
+		double b_normal_,
+		double h_normal_,
+		long int N_normal_,
+		double *p_normal_,
+
+		bool &area_is_1_flag_);
+
+		static void compute_tmp_values(FALP_set_of_parameters &par_);
+
+		static void get_appr_tail_prob_with_cov_without_errors(
+		const FALP_set_of_parameters &par_,
+		bool blast_,
+		double y_,
+
+		double m_,
+		double n_,
+
+		double &P_,
+		double &E_,
+
+		double &area_,
+
+		double a_normal_,
+		double b_normal_,
+		double h_normal_,
+		long int N_normal_,
+		double *p_normal_,
+
+		bool &area_is_1_flag_,
+		bool compute_only_area_=false);
+
+		static void get_P_error_using_splitting_method(
+		const FALP_set_of_parameters &par_,
+		bool blast_,
+		double y_,
+
+		double m_,
+		double n_,
+
+		double &P_,
+		double &P_error_,
+
+		double &E_,
+		double &E_error_,
+
+
+		double a_normal_,
+		double b_normal_,
+		double h_normal_,
+		long int N_normal_,
+		double *p_normal_,
+
+		bool &area_is_1_flag_);
+
+
+		public:
+
+		static void compute_intercepts(
+		FALP_set_of_parameters &par_);
+
+		void calculate_P_values(
+		long int Score1,
+		long int Score2,
+
+		double Seq1Len,
+		double Seq2Len,
+
+		const FALP_set_of_parameters &ParametersSet,
+		std::vector<double> &P_values,
+		std::vector<double> &P_values_errors,
+		std::vector<double> &E_values,
+		std::vector<double> &E_values_errors);
+
+		void calculate_P_values(
+		double Score,
+		double Seq1Len,
+		double Seq2Len,
+		const FALP_set_of_parameters &ParametersSet,
+		double &P_value,
+		double &P_value_error,
+		double &E_value,
+		double &E_value_error,
+		bool read_Sbs_par_flag=true);
+
+		//returns "true" if the Gumbel parameters are properly defined and "false" otherwise
+		static bool assert_Gumbel_parameters(
+		const FALP_set_of_parameters &par_);//a set of Gumbel parameters
+
+		static inline double ran3()//generates the next random value
+		{
+			double rand_C=(double)((double)rand()/(double)RAND_MAX);
+			return rand_C;	
+		}
+
+		static inline double standard_normal()//generates standard normal random value using the Box�Muller transform
+		{
+			double r1=0;
+			while(r1==0)
+			{
+				r1=ran3();
+			};
+			double r2=0;
+			while(r2==0)
+			{
+				r2=ran3();
+			};
+
+			double v1=-2*log(r1);
+			if(v1<0)
+			{
+				v1=0;
+			};
+			return sqrt(v1)*cos(2*pi*r2);
+		}
+
+
+		public:
+
+
+		bool blast;
+		double eps;
+		double a_normal;
+		double b_normal;
+		long int N_normal;
+		double h_normal;
+		double *p_normal;
+
+
+	};
+}
+
+#endif //! INCLUDED
+
diff --git a/src/alp/sls_fsa1_utils.cpp b/src/alp/sls_fsa1_utils.cpp
index d593896..18aa419 100644
--- a/src/alp/sls_fsa1_utils.cpp
+++ b/src/alp/sls_fsa1_utils.cpp
@@ -1,2200 +1,2200 @@
-/* $Id: $
-* ===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's offical duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_fsa1_utils.cpp
-
-Author: Sergey Sheetlin
-
-Contents: Frameshift alignment algorithms 
-
-******************************************************************************/
-
-#include "sls_fsa1_utils.hpp"
-
-using namespace Sls;
-using namespace std;
-
-static long int length_max=1000;
-
-void FSA_utils::read_RR(
-string RR_file_name_,
-double *&RR_,
-double *&RR_sum_,
-long int *&RR_sum_elements_,
-long int &number_of_AA_RR_,
-long int number_of_AA_RR_default_)
-{
-	read_RR(
-	RR_file_name_,
-	RR_,
-	number_of_AA_RR_,
-	number_of_AA_RR_default_);
-
-	calculate_RR_sum(
-	RR_,
-	number_of_AA_RR_,
-	RR_sum_,
-	RR_sum_elements_);
-
-}
-
-void FSA_utils::check_RR_sum(
-double sum_tmp_,
-long int number_of_AA_RR_,
-string RR_file_name_)
-{
-
-
-	if(number_of_AA_RR_<=0)
-	{
-		throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
-	};
-
-	double diff_tmp=fabs(sum_tmp_-1.0);
-	if(diff_tmp>0)
-	{
-		double lg_diff=-(log(diff_tmp)-log((double)number_of_AA_RR_))/log(10.0);
-		double lg_eps=-log(DBL_EPSILON)/log(10.0)-1;
-		if(lg_diff<lg_eps)
-		{
-
-			if(sum_tmp_<=0)
-			{
-				if(RR_file_name_!="")
-				{
-					throw error("Error: the sum of the probabilities from the file "+RR_file_name_+" is non-positive\n",3);
-				}
-				else
-				{
-					throw error("Error: the sum of the probabilities is non-positive\n",3);
-				};
-
-			};
-
-			if(RR_file_name_!="")
-			{
-				static map<string, bool> flag_RR;
-
-				if(!flag_RR[RR_file_name_])
-				{
-					cout<<"\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
-					cout<<"Warning: the sum of the probabilities from the file "<<RR_file_name_<<" is not equal to 1\n";
-					cout<<"The probabilities will be normalized for the computation\n";
-					cout<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n";
-
-					flag_RR[RR_file_name_]=true;
-				};
-			}
-			else
-			{
-				//no messages if called from the library functions
-			};
-
-		};
-
-	};
-
-}
-
-void FSA_utils::calculate_RR_sum(
-double *RR_,
-long int number_of_AA_RR_,
-double *&RR_sum_,
-long int *&RR_sum_elements_)
-{
-
-	RR_sum_=NULL;
-	RR_sum_elements_=NULL;
-
-
-	try
-	{
-
-		long int i;
-		if(number_of_AA_RR_<=0)
-		{
-			throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
-		};
-		
-		RR_sum_=new double[number_of_AA_RR_];
-		assert_mem(RR_sum_);
-
-		RR_sum_elements_=new long int [number_of_AA_RR_];
-		assert_mem(RR_sum_elements_);
-
-
-		for(i=0;i<number_of_AA_RR_;i++)
-		{
-			if(RR_[i]<0)
-			{
-				throw error("Error - the frequencies must be non-negative\n",3);
-			};
-
-			if(i!=0)
-			{
-				RR_sum_[i]=RR_sum_[i-1]+RR_[i];
-			}
-			else
-			{
-				RR_sum_[i]=RR_[i];
-			};
-			RR_sum_elements_[i]=i;
-		};
-
-		double sum_tmp=RR_sum_[number_of_AA_RR_-1];
-
-		check_RR_sum(
-		sum_tmp,
-		number_of_AA_RR_,
-		"");
-
-		if(sum_tmp>0)
-		{
-			long int i;
-			for(i=0;i<number_of_AA_RR_;i++)
-			{
-				RR_[i]/=sum_tmp;
-				RR_sum_[i]/=sum_tmp;
-			};
-		};
-
-	}
-	catch (...)
-	{ 
-		delete[]RR_sum_;RR_sum_=NULL;
-		delete[]RR_sum_elements_;RR_sum_elements_=NULL;
-		throw;
-	};
-
-
-}
-
-void FSA_utils::read_RR(
-string RR_file_name_,
-double *&RR_,
-long int &number_of_AA_RR_,
-long int number_of_AA_RR_default_)
-{
-	ifstream f;
-
-	RR_=NULL;
-
-	try
-	{
-
-		if(RR_file_name_=="")
-		{
-		
-			if(number_of_AA_RR_default_==4)
-			{
-				//default for RR1
-				number_of_AA_RR_=4;
-
-				RR_=new double[number_of_AA_RR_];
-				assert_mem(RR_);
-
-
-				RR_[0]=0.25; RR_[1]=0.25; RR_[2]=0.25; RR_[3]=0.25; 
-				return;
-			};
-
-			if(number_of_AA_RR_default_==25)
-			{
-				//default for RR2
-				number_of_AA_RR_=25;
-
-				RR_=new double[number_of_AA_RR_];
-				assert_mem(RR_);
-
-				RR_[0]=0.07805; RR_[1]=0.05129; RR_[2]=0.04487; RR_[3]=0.05364; RR_[4]=0.01925; RR_[5]=0.04264; RR_[6]=0.06295; RR_[7]=0.07377; RR_[8]=0.02199; RR_[9]=0.05142; RR_[10]=0.09019; RR_[11]=0.05744; RR_[12]=0.02243; RR_[13]=0.03856; RR_[14]=0.05203; RR_[15]=0.0712; RR_[16]=0.05841; RR_[17]=0.0133; RR_[18]=0.03216; RR_[19]=0.06441; RR_[20]=0; RR_[21]=0; RR_[22]=0; RR_[23]=0; RR_[24]=0; 
-				return;
-			};
-
-			throw error("Unexpected parameters in void FSA_utils::read_RR\n",1);
-
-		};
-
-		long int i;
-		f.open(RR_file_name_.data(),ios::in);
-		if(!f)
-		{
-			throw error("Error - file "+RR_file_name_+" is not found\n",3);
-		};
-
-		f>>number_of_AA_RR_;
-
-		if(number_of_AA_RR_<=0)
-		{
-			throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
-		};
-		
-		RR_=new double[number_of_AA_RR_];
-		assert_mem(RR_);
-
-
-		double sum_tmp=0;
-		for(i=0;i<number_of_AA_RR_;i++)
-		{
-			f>>RR_[i];
-
-			if(RR_[i]<0)
-			{
-				throw error("Error - the frequencies defined in the file "+RR_file_name_+" must be non-negative\n",3);
-			};
-
-			sum_tmp+=RR_[i];
-
-		};
-
-		check_RR_sum(
-		sum_tmp,
-		number_of_AA_RR_,
-		RR_file_name_);
-
-		f.close();
-	}
-	catch (...)
-	{ 
-		if(f.is_open())
-		{
-			f.close();
-		};
-		delete[]RR_;RR_=NULL;
-		throw;
-	};
-
-}
-
-void FSA_utils::read_smatr(
-string smatr_file_name_,
-long int **&smatr_,
-long int &number_of_AA_smatr_,
-long int &smatr_min_)
-{
-	ifstream f;
-
-	try
-	{
-
-		if(smatr_file_name_=="")
-		{
-			//default for the scoring matrix (BLOSUM80)
-			number_of_AA_smatr_=25;
-			FSA_utils::get_memory_for_matrix(number_of_AA_smatr_,number_of_AA_smatr_,smatr_);
-			smatr_min_=-6;
-
-			smatr_[0][0]=5; smatr_[0][1]=-2; smatr_[0][2]=-2; smatr_[0][3]=-2; smatr_[0][4]=-1; smatr_[0][5]=-1; smatr_[0][6]=-1; smatr_[0][7]=0; smatr_[0][8]=-2; smatr_[0][9]=-2; smatr_[0][10]=-2; smatr_[0][11]=-1; smatr_[0][12]=-1; smatr_[0][13]=-3; smatr_[0][14]=-1; smatr_[0][15]=1; smatr_[0][16]=0; smatr_[0][17]=-3; smatr_[0][18]=-2; smatr_[0][19]=0; smatr_[0][20]=-2; smatr_[0][21]=-2; smatr_[0][22]=-1; smatr_[0][23]=-1; smatr_[0][24]=-6; 
-			smatr_[1][0]=-2; smatr_[1][1]=6; smatr_[1][2]=-1; smatr_[1][3]=-2; smatr_[1][4]=-4; smatr_[1][5]=1; smatr_[1][6]=-1; smatr_[1][7]=-3; smatr_[1][8]=0; smatr_[1][9]=-3; smatr_[1][10]=-3; smatr_[1][11]=2; smatr_[1][12]=-2; smatr_[1][13]=-4; smatr_[1][14]=-2; smatr_[1][15]=-1; smatr_[1][16]=-1; smatr_[1][17]=-4; smatr_[1][18]=-3; smatr_[1][19]=-3; smatr_[1][20]=-1; smatr_[1][21]=-3; smatr_[1][22]=0; smatr_[1][23]=-1; smatr_[1][24]=-6; 
-			smatr_[2][0]=-2; smatr_[2][1]=-1; smatr_[2][2]=6; smatr_[2][3]=1; smatr_[2][4]=-3; smatr_[2][5]=0; smatr_[2][6]=-1; smatr_[2][7]=-1; smatr_[2][8]=0; smatr_[2][9]=-4; smatr_[2][10]=-4; smatr_[2][11]=0; smatr_[2][12]=-3; smatr_[2][13]=-4; smatr_[2][14]=-3; smatr_[2][15]=0; smatr_[2][16]=0; smatr_[2][17]=-4; smatr_[2][18]=-3; smatr_[2][19]=-4; smatr_[2][20]=5; smatr_[2][21]=-4; smatr_[2][22]=0; smatr_[2][23]=-1; smatr_[2][24]=-6; 
-			smatr_[3][0]=-2; smatr_[3][1]=-2; smatr_[3][2]=1; smatr_[3][3]=6; smatr_[3][4]=-4; smatr_[3][5]=-1; smatr_[3][6]=1; smatr_[3][7]=-2; smatr_[3][8]=-2; smatr_[3][9]=-4; smatr_[3][10]=-5; smatr_[3][11]=-1; smatr_[3][12]=-4; smatr_[3][13]=-4; smatr_[3][14]=-2; smatr_[3][15]=-1; smatr_[3][16]=-1; smatr_[3][17]=-6; smatr_[3][18]=-4; smatr_[3][19]=-4; smatr_[3][20]=5; smatr_[3][21]=-5; smatr_[3][22]=1; smatr_[3][23]=-1; smatr_[3][24]=-6; 
-			smatr_[4][0]=-1; smatr_[4][1]=-4; smatr_[4][2]=-3; smatr_[4][3]=-4; smatr_[4][4]=9; smatr_[4][5]=-4; smatr_[4][6]=-5; smatr_[4][7]=-4; smatr_[4][8]=-4; smatr_[4][9]=-2; smatr_[4][10]=-2; smatr_[4][11]=-4; smatr_[4][12]=-2; smatr_[4][13]=-3; smatr_[4][14]=-4; smatr_[4][15]=-2; smatr_[4][16]=-1; smatr_[4][17]=-3; smatr_[4][18]=-3; smatr_[4][19]=-1; smatr_[4][20]=-4; smatr_[4][21]=-2; smatr_[4][22]=-4; smatr_[4][23]=-1; smatr_[4][24]=-6; 
-			smatr_[5][0]=-1; smatr_[5][1]=1; smatr_[5][2]=0; smatr_[5][3]=-1; smatr_[5][4]=-4; smatr_[5][5]=6; smatr_[5][6]=2; smatr_[5][7]=-2; smatr_[5][8]=1; smatr_[5][9]=-3; smatr_[5][10]=-3; smatr_[5][11]=1; smatr_[5][12]=0; smatr_[5][13]=-4; smatr_[5][14]=-2; smatr_[5][15]=0; smatr_[5][16]=-1; smatr_[5][17]=-3; smatr_[5][18]=-2; smatr_[5][19]=-3; smatr_[5][20]=0; smatr_[5][21]=-3; smatr_[5][22]=4; smatr_[5][23]=-1; smatr_[5][24]=-6; 
-			smatr_[6][0]=-1; smatr_[6][1]=-1; smatr_[6][2]=-1; smatr_[6][3]=1; smatr_[6][4]=-5; smatr_[6][5]=2; smatr_[6][6]=6; smatr_[6][7]=-3; smatr_[6][8]=0; smatr_[6][9]=-4; smatr_[6][10]=-4; smatr_[6][11]=1; smatr_[6][12]=-2; smatr_[6][13]=-4; smatr_[6][14]=-2; smatr_[6][15]=0; smatr_[6][16]=-1; smatr_[6][17]=-4; smatr_[6][18]=-3; smatr_[6][19]=-3; smatr_[6][20]=1; smatr_[6][21]=-4; smatr_[6][22]=5; smatr_[6][23]=-1; smatr_[6][24]=-6; 
-			smatr_[7][0]=0; smatr_[7][1]=-3; smatr_[7][2]=-1; smatr_[7][3]=-2; smatr_[7][4]=-4; smatr_[7][5]=-2; smatr_[7][6]=-3; smatr_[7][7]=6; smatr_[7][8]=-3; smatr_[7][9]=-5; smatr_[7][10]=-4; smatr_[7][11]=-2; smatr_[7][12]=-4; smatr_[7][13]=-4; smatr_[7][14]=-3; smatr_[7][15]=-1; smatr_[7][16]=-2; smatr_[7][17]=-4; smatr_[7][18]=-4; smatr_[7][19]=-4; smatr_[7][20]=-1; smatr_[7][21]=-5; smatr_[7][22]=-3; smatr_[7][23]=-1; smatr_[7][24]=-6; 
-			smatr_[8][0]=-2; smatr_[8][1]=0; smatr_[8][2]=0; smatr_[8][3]=-2; smatr_[8][4]=-4; smatr_[8][5]=1; smatr_[8][6]=0; smatr_[8][7]=-3; smatr_[8][8]=8; smatr_[8][9]=-4; smatr_[8][10]=-3; smatr_[8][11]=-1; smatr_[8][12]=-2; smatr_[8][13]=-2; smatr_[8][14]=-3; smatr_[8][15]=-1; smatr_[8][16]=-2; smatr_[8][17]=-3; smatr_[8][18]=2; smatr_[8][19]=-4; smatr_[8][20]=-1; smatr_[8][21]=-4; smatr_[8][22]=0; smatr_[8][23]=-1; smatr_[8][24]=-6; 
-			smatr_[9][0]=-2; smatr_[9][1]=-3; smatr_[9][2]=-4; smatr_[9][3]=-4; smatr_[9][4]=-2; smatr_[9][5]=-3; smatr_[9][6]=-4; smatr_[9][7]=-5; smatr_[9][8]=-4; smatr_[9][9]=5; smatr_[9][10]=1; smatr_[9][11]=-3; smatr_[9][12]=1; smatr_[9][13]=-1; smatr_[9][14]=-4; smatr_[9][15]=-3; smatr_[9][16]=-1; smatr_[9][17]=-3; smatr_[9][18]=-2; smatr_[9][19]=3; smatr_[9][20]=-4; smatr_[9][21]=3; smatr_[9][22]=-4; smatr_[9][23]=-1; smatr_[9][24]=-6; 
-			smatr_[10][0]=-2; smatr_[10][1]=-3; smatr_[10][2]=-4; smatr_[10][3]=-5; smatr_[10][4]=-2; smatr_[10][5]=-3; smatr_[10][6]=-4; smatr_[10][7]=-4; smatr_[10][8]=-3; smatr_[10][9]=1; smatr_[10][10]=4; smatr_[10][11]=-3; smatr_[10][12]=2; smatr_[10][13]=0; smatr_[10][14]=-3; smatr_[10][15]=-3; smatr_[10][16]=-2; smatr_[10][17]=-2; smatr_[10][18]=-2; smatr_[10][19]=1; smatr_[10][20]=-4; smatr_[10][21]=3; smatr_[10][22]=-3; smatr_[10][23]=-1; smatr_[10][24]=-6; 
-			smatr_[11][0]=-1; smatr_[11][1]=2; smatr_[11][2]=0; smatr_[11][3]=-1; smatr_[11][4]=-4; smatr_[11][5]=1; smatr_[11][6]=1; smatr_[11][7]=-2; smatr_[11][8]=-1; smatr_[11][9]=-3; smatr_[11][10]=-3; smatr_[11][11]=5; smatr_[11][12]=-2; smatr_[11][13]=-4; smatr_[11][14]=-1; smatr_[11][15]=-1; smatr_[11][16]=-1; smatr_[11][17]=-4; smatr_[11][18]=-3; smatr_[11][19]=-3; smatr_[11][20]=-1; smatr_[11][21]=-3; smatr_[11][22]=1; smatr_[11][23]=-1; smatr_[11][24]=-6; 
-			smatr_[12][0]=-1; smatr_[12][1]=-2; smatr_[12][2]=-3; smatr_[12][3]=-4; smatr_[12][4]=-2; smatr_[12][5]=0; smatr_[12][6]=-2; smatr_[12][7]=-4; smatr_[12][8]=-2; smatr_[12][9]=1; smatr_[12][10]=2; smatr_[12][11]=-2; smatr_[12][12]=6; smatr_[12][13]=0; smatr_[12][14]=-3; smatr_[12][15]=-2; smatr_[12][16]=-1; smatr_[12][17]=-2; smatr_[12][18]=-2; smatr_[12][19]=1; smatr_[12][20]=-3; smatr_[12][21]=2; smatr_[12][22]=-1; smatr_[12][23]=-1; smatr_[12][24]=-6; 
-			smatr_[13][0]=-3; smatr_[13][1]=-4; smatr_[13][2]=-4; smatr_[13][3]=-4; smatr_[13][4]=-3; smatr_[13][5]=-4; smatr_[13][6]=-4; smatr_[13][7]=-4; smatr_[13][8]=-2; smatr_[13][9]=-1; smatr_[13][10]=0; smatr_[13][11]=-4; smatr_[13][12]=0; smatr_[13][13]=6; smatr_[13][14]=-4; smatr_[13][15]=-3; smatr_[13][16]=-2; smatr_[13][17]=0; smatr_[13][18]=3; smatr_[13][19]=-1; smatr_[13][20]=-4; smatr_[13][21]=0; smatr_[13][22]=-4; smatr_[13][23]=-1; smatr_[13][24]=-6; 
-			smatr_[14][0]=-1; smatr_[14][1]=-2; smatr_[14][2]=-3; smatr_[14][3]=-2; smatr_[14][4]=-4; smatr_[14][5]=-2; smatr_[14][6]=-2; smatr_[14][7]=-3; smatr_[14][8]=-3; smatr_[14][9]=-4; smatr_[14][10]=-3; smatr_[14][11]=-1; smatr_[14][12]=-3; smatr_[14][13]=-4; smatr_[14][14]=8; smatr_[14][15]=-1; smatr_[14][16]=-2; smatr_[14][17]=-5; smatr_[14][18]=-4; smatr_[14][19]=-3; smatr_[14][20]=-2; smatr_[14][21]=-4; smatr_[14][22]=-2; smatr_[14][23]=-1; smatr_[14][24]=-6; 
-			smatr_[15][0]=1; smatr_[15][1]=-1; smatr_[15][2]=0; smatr_[15][3]=-1; smatr_[15][4]=-2; smatr_[15][5]=0; smatr_[15][6]=0; smatr_[15][7]=-1; smatr_[15][8]=-1; smatr_[15][9]=-3; smatr_[15][10]=-3; smatr_[15][11]=-1; smatr_[15][12]=-2; smatr_[15][13]=-3; smatr_[15][14]=-1; smatr_[15][15]=5; smatr_[15][16]=1; smatr_[15][17]=-4; smatr_[15][18]=-2; smatr_[15][19]=-2; smatr_[15][20]=0; smatr_[15][21]=-3; smatr_[15][22]=0; smatr_[15][23]=-1; smatr_[15][24]=-6; 
-			smatr_[16][0]=0; smatr_[16][1]=-1; smatr_[16][2]=0; smatr_[16][3]=-1; smatr_[16][4]=-1; smatr_[16][5]=-1; smatr_[16][6]=-1; smatr_[16][7]=-2; smatr_[16][8]=-2; smatr_[16][9]=-1; smatr_[16][10]=-2; smatr_[16][11]=-1; smatr_[16][12]=-1; smatr_[16][13]=-2; smatr_[16][14]=-2; smatr_[16][15]=1; smatr_[16][16]=5; smatr_[16][17]=-4; smatr_[16][18]=-2; smatr_[16][19]=0; smatr_[16][20]=-1; smatr_[16][21]=-1; smatr_[16][22]=-1; smatr_[16][23]=-1; smatr_[16][24]=-6; 
-			smatr_[17][0]=-3; smatr_[17][1]=-4; smatr_[17][2]=-4; smatr_[17][3]=-6; smatr_[17][4]=-3; smatr_[17][5]=-3; smatr_[17][6]=-4; smatr_[17][7]=-4; smatr_[17][8]=-3; smatr_[17][9]=-3; smatr_[17][10]=-2; smatr_[17][11]=-4; smatr_[17][12]=-2; smatr_[17][13]=0; smatr_[17][14]=-5; smatr_[17][15]=-4; smatr_[17][16]=-4; smatr_[17][17]=11; smatr_[17][18]=2; smatr_[17][19]=-3; smatr_[17][20]=-5; smatr_[17][21]=-3; smatr_[17][22]=-3; smatr_[17][23]=-1; smatr_[17][24]=-6; 
-			smatr_[18][0]=-2; smatr_[18][1]=-3; smatr_[18][2]=-3; smatr_[18][3]=-4; smatr_[18][4]=-3; smatr_[18][5]=-2; smatr_[18][6]=-3; smatr_[18][7]=-4; smatr_[18][8]=2; smatr_[18][9]=-2; smatr_[18][10]=-2; smatr_[18][11]=-3; smatr_[18][12]=-2; smatr_[18][13]=3; smatr_[18][14]=-4; smatr_[18][15]=-2; smatr_[18][16]=-2; smatr_[18][17]=2; smatr_[18][18]=7; smatr_[18][19]=-2; smatr_[18][20]=-3; smatr_[18][21]=-2; smatr_[18][22]=-3; smatr_[18][23]=-1; smatr_[18][24]=-6; 
-			smatr_[19][0]=0; smatr_[19][1]=-3; smatr_[19][2]=-4; smatr_[19][3]=-4; smatr_[19][4]=-1; smatr_[19][5]=-3; smatr_[19][6]=-3; smatr_[19][7]=-4; smatr_[19][8]=-4; smatr_[19][9]=3; smatr_[19][10]=1; smatr_[19][11]=-3; smatr_[19][12]=1; smatr_[19][13]=-1; smatr_[19][14]=-3; smatr_[19][15]=-2; smatr_[19][16]=0; smatr_[19][17]=-3; smatr_[19][18]=-2; smatr_[19][19]=4; smatr_[19][20]=-4; smatr_[19][21]=2; smatr_[19][22]=-3; smatr_[19][23]=-1; smatr_[19][24]=-6; 
-			smatr_[20][0]=-2; smatr_[20][1]=-1; smatr_[20][2]=5; smatr_[20][3]=5; smatr_[20][4]=-4; smatr_[20][5]=0; smatr_[20][6]=1; smatr_[20][7]=-1; smatr_[20][8]=-1; smatr_[20][9]=-4; smatr_[20][10]=-4; smatr_[20][11]=-1; smatr_[20][12]=-3; smatr_[20][13]=-4; smatr_[20][14]=-2; smatr_[20][15]=0; smatr_[20][16]=-1; smatr_[20][17]=-5; smatr_[20][18]=-3; smatr_[20][19]=-4; smatr_[20][20]=5; smatr_[20][21]=-4; smatr_[20][22]=0; smatr_[20][23]=-1; smatr_[20][24]=-6; 
-			smatr_[21][0]=-2; smatr_[21][1]=-3; smatr_[21][2]=-4; smatr_[21][3]=-5; smatr_[21][4]=-2; smatr_[21][5]=-3; smatr_[21][6]=-4; smatr_[21][7]=-5; smatr_[21][8]=-4; smatr_[21][9]=3; smatr_[21][10]=3; smatr_[21][11]=-3; smatr_[21][12]=2; smatr_[21][13]=0; smatr_[21][14]=-4; smatr_[21][15]=-3; smatr_[21][16]=-1; smatr_[21][17]=-3; smatr_[21][18]=-2; smatr_[21][19]=2; smatr_[21][20]=-4; smatr_[21][21]=3; smatr_[21][22]=-3; smatr_[21][23]=-1; smatr_[21][24]=-6; 
-			smatr_[22][0]=-1; smatr_[22][1]=0; smatr_[22][2]=0; smatr_[22][3]=1; smatr_[22][4]=-4; smatr_[22][5]=4; smatr_[22][6]=5; smatr_[22][7]=-3; smatr_[22][8]=0; smatr_[22][9]=-4; smatr_[22][10]=-3; smatr_[22][11]=1; smatr_[22][12]=-1; smatr_[22][13]=-4; smatr_[22][14]=-2; smatr_[22][15]=0; smatr_[22][16]=-1; smatr_[22][17]=-3; smatr_[22][18]=-3; smatr_[22][19]=-3; smatr_[22][20]=0; smatr_[22][21]=-3; smatr_[22][22]=5; smatr_[22][23]=-1; smatr_[22][24]=-6; 
-			smatr_[23][0]=-1; smatr_[23][1]=-1; smatr_[23][2]=-1; smatr_[23][3]=-1; smatr_[23][4]=-1; smatr_[23][5]=-1; smatr_[23][6]=-1; smatr_[23][7]=-1; smatr_[23][8]=-1; smatr_[23][9]=-1; smatr_[23][10]=-1; smatr_[23][11]=-1; smatr_[23][12]=-1; smatr_[23][13]=-1; smatr_[23][14]=-1; smatr_[23][15]=-1; smatr_[23][16]=-1; smatr_[23][17]=-1; smatr_[23][18]=-1; smatr_[23][19]=-1; smatr_[23][20]=-1; smatr_[23][21]=-1; smatr_[23][22]=-1; smatr_[23][23]=-1; smatr_[23][24]=-6; 
-			smatr_[24][0]=-6; smatr_[24][1]=-6; smatr_[24][2]=-6; smatr_[24][3]=-6; smatr_[24][4]=-6; smatr_[24][5]=-6; smatr_[24][6]=-6; smatr_[24][7]=-6; smatr_[24][8]=-6; smatr_[24][9]=-6; smatr_[24][10]=-6; smatr_[24][11]=-6; smatr_[24][12]=-6; smatr_[24][13]=-6; smatr_[24][14]=-6; smatr_[24][15]=-6; smatr_[24][16]=-6; smatr_[24][17]=-6; smatr_[24][18]=-6; smatr_[24][19]=-6; smatr_[24][20]=-6; smatr_[24][21]=-6; smatr_[24][22]=-6; smatr_[24][23]=-6; smatr_[24][24]=1; 
-
-			return;
-		};
-
-
-		long int i,j;
-		f.open(smatr_file_name_.data(),ios::in);
-		if(!f)
-		{
-			throw error("Error - file "+smatr_file_name_+" is not found\n",3);
-		};
-
-		f>>number_of_AA_smatr_;
-
-		if(number_of_AA_smatr_<=0)
-		{
-			throw error("Error - number of letters in the scoring matrix file must be greater than 0\n",3);
-		};
-
-		get_memory_for_matrix(number_of_AA_smatr_,number_of_AA_smatr_,smatr_);
-
-
-		for(i=0;i<number_of_AA_smatr_;i++)
-		{
-			for(j=0;j<number_of_AA_smatr_;j++)
-			{
-				if(f.eof())
-				{
-					throw error("Error - file "+smatr_file_name_+" is not correct (please check dimensions of the scoring matrix)\n",3);
-				};
-
-				f>>smatr_[i][j];
-			};
-		};
-
-		f.close();
-
-
-		smatr_min(
-		smatr_,
-		number_of_AA_smatr_,
-		smatr_min_);
-
-		
-	}
-	catch (...)
-	{ 
-		if(f.is_open())
-		{
-			f.close();
-		};
-		throw;
-	};
-
-}
-
-void FSA_utils::smatr_min(
-long int **smatr_,
-long int number_of_AA_smatr_,
-long int &smatr_min_)
-{
-	long int small_number=numeric_limits<long int>::min()/10000;
-	long int i,j;
-
-	for(i=0;i<number_of_AA_smatr_;i++)
-	{
-		for(j=0;j<number_of_AA_smatr_;j++)
-		{
-			if(smatr_[i][j]<small_number)
-			{
-				smatr_[i][j]=small_number;
-			};
-
-			if(i==0&&j==0)
-			{
-				smatr_min_=smatr_[0][0];
-			}
-			else
-			{
-				if(smatr_min_>smatr_[i][j])
-				{
-					smatr_min_=smatr_[i][j];
-				};
-			};
-		};
-	};
-
-}
-
-void FSA_utils::remove_zero_probabilities(
-double *&RR1_,
-double *&RR1_sum_,
-long int *&RR1_sum_elements_,
-long int &alphabet_letters_number1_,
-double *&RR2_,
-double *&RR2_sum_,
-long int *&RR2_sum_elements_,
-long int &alphabet_letters_number2_,
-long int **&smatr_,
-long int &number_of_AA_smatr_,
-long int &smatr_min_,
-
-long int &number_of_letters1_,//number of letters for the sequence 1
-long int &number_of_letters2_,//number of letters for the sequence 2
-
-char *&alphabet1_,//alphabet letters for the sequence #1
-char *&alphabet2_,//alphabet letters for the sequence #2
-
-long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-long int &codon_length_,//codon length 
-long int *&codon_AA_)//<codon code,AA number>
-{
-
-	vector<bool> codon_flag_RR2;
-	
-	{
-		long int number_of_codons_old=FSA_utils::power_long(alphabet_letters_number1_,codon_length_);
-		codon_flag_RR2.resize(number_of_codons_old,false);
-		long int i;
-		for(i=0;i<number_of_codons_old;i++)
-		{
-			codon_flag_RR2[codon_AA_[i]]=true;
-		};
-	};
-
-
-	map<long int,bool> zero_flag_RR1;
-	map<long int,bool> zero_flag_RR2;
-
-	map<long int,long int> old1_numbering_to_the_new1;
-	map<long int,long int> new1_numbering_to_the_old1;
-	long int count1=-1;
-	long int i;
-	for(i=0;i<alphabet_letters_number1_;i++)
-	{
-		if(RR1_[i]==0)
-		{
-			zero_flag_RR1[i]=true;
-			old1_numbering_to_the_new1[i]=-1;
-		}
-		else
-		{
-			zero_flag_RR1[i]=false;
-			count1++;
-			old1_numbering_to_the_new1[i]=count1;
-			new1_numbering_to_the_old1[count1]=i;
-		};
-
-	};
-
-	map<long int,long int> old2_numbering_to_the_new2;
-	map<long int,long int> new2_numbering_to_the_old2;
-	long int count2=-1;
-	for(i=0;i<alphabet_letters_number2_;i++)
-	{
-		if(RR2_[i]==0&&!codon_flag_RR2[i])
-		{
-			zero_flag_RR2[i]=true;
-			old2_numbering_to_the_new2[i]=-1;
-		}
-		else
-		{
-			zero_flag_RR2[i]=false;
-			count2++;
-			old2_numbering_to_the_new2[i]=count2;
-			new2_numbering_to_the_old2[count2]=i;
-		};
-	};
-//-------------------------------------
-	long int alphabet_letters_number1_new=count1+1;
-	double *RR1_new=new double[alphabet_letters_number1_new];
-	double *RR1_sum_new=new double[alphabet_letters_number1_new];
-	long int *RR1_sum_elements_new=new long int[alphabet_letters_number1_new];
-	
-	long int alphabet_letters_number2_new=count2+1;
-	double *RR2_new=new double[alphabet_letters_number2_new];
-	double *RR2_sum_new=new double[alphabet_letters_number2_new];
-	long int *RR2_sum_elements_new=new long int[alphabet_letters_number2_new];
-
-
-	long int c1;
-	for(c1=0;c1<alphabet_letters_number1_new;c1++)
-	{
-		RR1_new[c1]=RR1_[new1_numbering_to_the_old1[c1]];
-		RR1_sum_new[c1]=RR1_sum_[new1_numbering_to_the_old1[c1]];
-		RR1_sum_elements_new[c1]=c1;
-	};
-
-	long int c2;
-	for(c2=0;c2<alphabet_letters_number2_new;c2++)
-	{
-		RR2_new[c2]=RR2_[new2_numbering_to_the_old2[c2]];
-		RR2_sum_new[c2]=RR2_sum_[new2_numbering_to_the_old2[c2]];
-		RR2_sum_elements_new[c2]=c2;
-	};
-
-
-
-	//reallocation
-	
-	delete[]RR1_;
-	RR1_=RR1_new;
-	delete[]RR1_sum_;
-	RR1_sum_=RR1_sum_new;
-	delete[]RR1_sum_elements_;
-	RR1_sum_elements_=RR1_sum_elements_new;
-
-	
-	delete[]RR2_;
-	RR2_=RR2_new;
-	delete[]RR2_sum_;
-	RR2_sum_=RR2_sum_new;
-	delete[]RR2_sum_elements_;
-	RR2_sum_elements_=RR2_sum_elements_new;
-
-
-//----------------------------
-
-	long int **smatr_new=NULL;
-
-	FSA_utils::get_memory_for_matrix(alphabet_letters_number2_new,alphabet_letters_number2_new,smatr_new);
-
-	long int smatr_min_new=smatr_[new2_numbering_to_the_old2[0]][new2_numbering_to_the_old2[0]];
-	for(c1=0;c1<alphabet_letters_number2_new;c1++)
-	{
-		for(c2=0;c2<alphabet_letters_number2_new;c2++)
-		{
-			smatr_new[c1][c2]=
-				smatr_[new2_numbering_to_the_old2[c1]][new2_numbering_to_the_old2[c2]];
-
-			smatr_min_new=FSA_utils::Tmin(smatr_min_new,
-				smatr_new[c1][c2]);
-
-		};
-	};
-
-	FSA_utils::delete_memory_for_matrix(number_of_AA_smatr_,smatr_);
-	smatr_=smatr_new;
-
-	char *alphabet1_new=new char[alphabet_letters_number1_new];
-	char *alphabet2_new=new char[alphabet_letters_number2_new];
-
-	for(c1=0;c1<alphabet_letters_number1_new;c1++)
-	{
-		alphabet1_new[c1]=alphabet1_[new1_numbering_to_the_old1[c1]];
-	};
-
-	for(c2=0;c2<alphabet_letters_number2_new;c2++)
-	{
-		alphabet2_new[c2]=alphabet2_[new2_numbering_to_the_old2[c2]];
-	};
-
-	delete[]alphabet1_;
-	alphabet1_=alphabet1_new;
-	delete[]alphabet2_;
-	alphabet2_=alphabet2_new;
-
-	//-----------------------------
-
-	
-	{
-		long int k;
-		long int*alphabet1_to_long_new=new long int [length_max];
-		FSA_utils::assert_mem(alphabet1_to_long_new);
-		long int*alphabet2_to_long_new=new long int [length_max];
-		FSA_utils::assert_mem(alphabet2_to_long_new);
-
-		for(k=0;k<length_max;k++)
-		{
-			alphabet1_to_long_new[k]=-1;
-			alphabet2_to_long_new[k]=-1;
-		};
-
-		for(k=0;k<alphabet_letters_number1_new;k++)
-		{
-			alphabet1_to_long_new[(size_t)alphabet1_[k]]=k;
-		};
-		for(k=0;k<alphabet_letters_number2_new;k++)
-		{
-			alphabet2_to_long_new[(size_t)alphabet2_[k]]=k;
-		};
-
-		delete[]alphabet1_to_long_;
-		alphabet1_to_long_=alphabet1_to_long_new;
-		delete[]alphabet2_to_long_;
-		alphabet2_to_long_=alphabet2_to_long_new;
-
-	};
-
-
-
-	//-----------------------------
-
-	long int number_of_codons_new=FSA_utils::power_long(alphabet_letters_number1_new,codon_length_);
-	long int *codon_AA_new = new long int[number_of_codons_new];//<codon code,AA number>
-
-	long int *codon=new long int [codon_length_];
-	FSA_utils::assert_mem(codon);
-
-	for(c1=0;c1<number_of_codons_new;c1++)
-	{
-		FSA_utils::convert_code_into_codon(
-		c1,//the input code
-		codon_length_,//codon length 
-		alphabet_letters_number1_new,//number of letters for the sequence 1
-		codon);//must be allocated
-
-		long int k;
-		for(k=0;k<codon_length_;k++)
-		{
-			codon[k]=new1_numbering_to_the_old1[codon[k]];
-		};
-
-		long int code_old=FSA_utils::convert_codon_into_code(
-		codon_length_,//codon length 
-		alphabet_letters_number1_,//number of letters for the sequence 1
-		codon);//input codon
-
-
-		codon_AA_new[c1]=old2_numbering_to_the_new2[codon_AA_[code_old]];
-	};
-
-	delete[]codon;
-
-	delete[]codon_AA_;
-	codon_AA_=codon_AA_new;
-
-
-	//-----------------------------
-	alphabet_letters_number1_=alphabet_letters_number1_new;
-	alphabet_letters_number2_=alphabet_letters_number2_new;
-	number_of_AA_smatr_=alphabet_letters_number2_new;
-	smatr_min_=smatr_min_new;
-	number_of_letters1_=alphabet_letters_number1_new;
-	number_of_letters2_=alphabet_letters_number2_new;
-
-}
-
-
-void FSA_utils::reverse_codons(
-long int *codon_AA_,//<codon code,AA number>; original codons
-long int alphabet_letters_number1_,//number of letters for the sequence #1
-long int codon_length_,//codon length 
-long int *&codon_AA_reversed_)//<codon code,AA number>; reversed codons
-{
-
-	long int number_of_codons=FSA_utils::power_long(alphabet_letters_number1_,codon_length_);
-
-	codon_AA_reversed_ = new long int[number_of_codons];//<codon code,AA number>
-	FSA_utils::assert_mem(codon_AA_reversed_);
-
-	long int *codon=new long int [codon_length_];
-	FSA_utils::assert_mem(codon);
-	long int *codon2=new long int [codon_length_];
-	FSA_utils::assert_mem(codon2);
-
-	long int c1;
-	for(c1=0;c1<number_of_codons;c1++)
-	{
-		FSA_utils::convert_code_into_codon(
-		c1,//the input code
-		codon_length_,//codon length 
-		alphabet_letters_number1_,//number of letters for the sequence 1
-		codon);//must be allocated
-
-		long int k;
-		for(k=0;k<codon_length_;k++)
-		{
-			codon2[k]=codon[codon_length_-1-k];
-		};
-
-		long int code_reversed=FSA_utils::convert_codon_into_code(
-		codon_length_,//codon length 
-		alphabet_letters_number1_,//number of letters for the sequence 1
-		codon2);//input codon
-
-
-		codon_AA_reversed_[code_reversed]=codon_AA_[c1];
-
-
-	};
-
-	delete[]codon;
-	delete[]codon2;
-
-}
-
-
-long int FSA_utils::convert_codon_into_code(
-long int codon_length_,//codon length 
-long int number_of_letters1_,//number of letters for the sequence 1
-long int *codon_)//input codon
-{
-	long int codon_code=codon_[0];
-	long int i;
-	for(i=1;i<codon_length_;i++)
-	{
-		codon_code=codon_code*number_of_letters1_+codon_[i];
-	};
-
-	return codon_code;
-
-}
-
-
-long int FSA_utils::convert_codon_into_AA(
-long int codon_length_,//codon length 
-long int *codon_AA_,//<codon code,AA number>
-long int number_of_letters1_,//number of letters for the sequence 1
-long int *codon_)
-{
-	long int codon_code=codon_[0];
-	long int i;
-	for(i=1;i<codon_length_;i++)
-	{
-		codon_code=codon_code*number_of_letters1_+codon_[i];
-	};
-
-	return codon_AA_[codon_code];
-
-}
-
-void FSA_utils::convert_code_into_codon(
-long int code_,//the input code
-long int codon_length_,//codon length 
-long int number_of_letters1_,//number of letters for the sequence 1
-long int *codon_)//must be allocated
-{
-	long int i;
-	for(i=codon_length_-1;i>=0;i--)
-	{
-		codon_[i]=code_%number_of_letters1_;
-		code_-=codon_[i];
-		code_/=number_of_letters1_;
-	};
-
-}
-
-void FSA_utils::read_codon_AA_file(
-string file_name_,
-long int &number_of_letters1_,//number of letters for the sequence 1
-long int &number_of_letters2_,//number of letters for the sequence 2
-char *&alphabet1_,//alphabet letters for the sequence #1
-char *&alphabet2_,//alphabet letters for the sequence #2
-
-long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-long int &codon_length_,//codon length 
-long int *&codon_AA_,//<codon code,AA number>
-bool reverse_codons_flag_)//if true, then the codons are reversed
-{
-	ifstream f;
-
-	alphabet1_=NULL;
-	alphabet2_=NULL;
-	alphabet1_to_long_=NULL;
-	alphabet2_to_long_=NULL;
-	codon_AA_=NULL;
-	try
-	{
-
-
-		if(file_name_=="")
-		{
-			number_of_letters1_=4;
-			alphabet1_=new char[4];
-			FSA_utils::assert_mem(alphabet1_);
-			alphabet1_[0]='A'; alphabet1_[1]='C'; alphabet1_[2]='G'; alphabet1_[3]='T'; 
-			number_of_letters2_=25;
-			alphabet2_=new char[25];
-			FSA_utils::assert_mem(alphabet2_);
-			alphabet2_[0]='A'; alphabet2_[1]='R'; alphabet2_[2]='N'; alphabet2_[3]='D'; alphabet2_[4]='C'; alphabet2_[5]='Q'; alphabet2_[6]='E'; alphabet2_[7]='G'; alphabet2_[8]='H'; alphabet2_[9]='I'; alphabet2_[10]='L'; alphabet2_[11]='K'; alphabet2_[12]='M'; alphabet2_[13]='F'; alphabet2_[14]='P'; alphabet2_[15]='S'; alphabet2_[16]='T'; alphabet2_[17]='W'; alphabet2_[18]='Y'; alphabet2_[19]='V'; alphabet2_[20]='B'; alphabet2_[21]='J'; alphabet2_[22]='Z'; alphabet2_[23]='X'; alphabet2_[24]='*'; 
-			alphabet1_to_long_=new long int [length_max];
-			FSA_utils::assert_mem(alphabet1_to_long_);
-			alphabet2_to_long_=new long int [length_max];
-			FSA_utils::assert_mem(alphabet2_to_long_);
-
-			long int k;
-			for(k=0;k<length_max;k++)
-			{
-				alphabet1_to_long_[k]=-1;
-				alphabet2_to_long_[k]=-1;
-			};
-
-			for(k=0;k<number_of_letters1_;k++)
-			{
-				alphabet1_to_long_[(size_t)alphabet1_[k]]=k;
-			};
-			for(k=0;k<number_of_letters2_;k++)
-			{
-				alphabet2_to_long_[(size_t)alphabet2_[k]]=k;
-			};
-
-
-			codon_length_=3;
-			codon_AA_=new long int [64];
-			FSA_utils::assert_mem(codon_AA_);
-			codon_AA_[63]=13; codon_AA_[61]=13; codon_AA_[60]=10; codon_AA_[62]=10; codon_AA_[31]=10; codon_AA_[29]=10; codon_AA_[28]=10; codon_AA_[30]=10; codon_AA_[15]=9; codon_AA_[13]=9; codon_AA_[12]=9; codon_AA_[14]=12; codon_AA_[47]=19; codon_AA_[45]=19; codon_AA_[44]=19; codon_AA_[46]=19; codon_AA_[55]=15; codon_AA_[53]=15; codon_AA_[52]=15; codon_AA_[54]=15; codon_AA_[23]=14; codon_AA_[21]=14; codon_AA_[20]=14; codon_AA_[22]=14; codon_AA_[7]=16; codon_AA_[5]=16; codon_AA_[4]=16; codon_AA_ [...]
-
-			return;
-		};
-
-		f.open(file_name_.data(),ios::in);
-		if(!f)
-		{
-			throw error("Error - the file "+file_name_+" is not found\n",3);
-		};
-
-		//reading alphabet #1
-		f>>number_of_letters1_;
-
-		if(number_of_letters1_<=0)
-		{
-			throw error("Error - the file "+file_name_+" is not correct: the number of letters must be positive\n",3);
-		};
-
-		alphabet1_=new char[number_of_letters1_];
-		FSA_utils::assert_mem(alphabet1_);
-
-		string line_tmp="";
-
-		f>>line_tmp;
-
-		if((long int)line_tmp.length()<number_of_letters1_)
-		{
-			throw error("Error - the file "+file_name_+" is not correct\n",3);
-		};
-
-		long int k;
-		for(k=0;k<(long int)line_tmp.length();k++)
-		{
-			if(!isalpha(line_tmp[k]))
-			{
-				throw error("Error - the file "+file_name_+" is not correct\n",3);
-			};
-			alphabet1_[k]=line_tmp[k];
-		};
-
-
-		//reading alphabet #2
-		f>>number_of_letters2_;
-
-		if(number_of_letters2_<=0)
-		{
-			throw error("Error - the file "+file_name_+" is not correct\n",3);
-		};
-
-		alphabet2_=new char[number_of_letters2_];
-		FSA_utils::assert_mem(alphabet2_);
-
-		line_tmp="";
-
-		f>>line_tmp;
-
-		if((long int)line_tmp.length()<number_of_letters2_)
-		{
-			throw error("Error - the file "+file_name_+" is not correct\n",3);
-		};
-
-		for(k=0;k<(long int)line_tmp.length();k++)
-		{
-			//if(!isalpha(line_tmp[k]))
-			if(!isalpha(line_tmp[k])&&line_tmp[k]!='*')
-			{
-				throw error("Error - the file "+file_name_+" is not correct\n",3);
-			};
-			alphabet2_[k]=line_tmp[k];
-		};
-
-
-		alphabet1_to_long_=new long int [length_max];
-		FSA_utils::assert_mem(alphabet1_to_long_);
-		alphabet2_to_long_=new long int [length_max];
-		FSA_utils::assert_mem(alphabet2_to_long_);
-
-		for(k=0;k<length_max;k++)
-		{
-			alphabet1_to_long_[k]=-1;
-			alphabet2_to_long_[k]=-1;
-		};
-
-		for(k=0;k<number_of_letters1_;k++)
-		{
-			alphabet1_to_long_[(size_t)alphabet1_[k]]=k;
-		};
-		for(k=0;k<number_of_letters2_;k++)
-		{
-			alphabet2_to_long_[(size_t)alphabet2_[k]]=k;
-		};
-
-		long int AA_length;
-		//f>>codon_length_>>AA_length;
-		codon_length_=3;
-		AA_length=1;
-		if(AA_length!=1||codon_length_<=0)
-		{
-			throw error("Error - the file "+file_name_+" is not correct\n",3);
-		};
-		//read the table
-		long int number_of_codons=1;
-		for(k=0;k<codon_length_;k++)
-		{
-			number_of_codons*=number_of_letters1_;
-		};
-
-		codon_AA_=new long int [number_of_codons];
-		FSA_utils::assert_mem(codon_AA_);
-
-		for(k=0;k<number_of_codons;k++)
-		{
-			string line_tmp_codon,line_tmp_AA;
-
-			f>>line_tmp_codon;
-			if(reverse_codons_flag_)
-			{
-				line_tmp_codon=string(line_tmp_codon.rbegin(),line_tmp_codon.rend()); 
-			};
-			f>>line_tmp_AA;
-
-			if((codon_length_!=(long int)line_tmp_codon.length())||(AA_length!=(long int)line_tmp_AA.length()))
-			{
-				throw error("Error - the file "+file_name_+" is not correct\n",3);
-			};
-
-			long int codon_code=alphabet1_to_long_[(size_t)line_tmp_codon[0]];
-			if(alphabet1_to_long_[(size_t)line_tmp_codon[0]]<0)
-			{
-				throw error("Error - the file "+file_name_+" is not correct\n",3);
-			};
-			long int i;
-			for(i=1;i<(long int)line_tmp_codon.length();i++)
-			{
-				if(alphabet1_to_long_[(size_t)line_tmp_codon[i]]<0)
-				{
-					throw error("Error - the file "+file_name_+" is not correct\n",3);
-				};
-				codon_code=codon_code*number_of_letters1_+alphabet1_to_long_[(size_t)line_tmp_codon[i]];
-			};
-
-			if(alphabet2_to_long_[(size_t)line_tmp_AA[0]]<0)
-			{
-				throw error("Error - the file "+file_name_+" is not correct\n",3);
-			};
-
-
-			codon_AA_[codon_code]=alphabet2_to_long_[(size_t)line_tmp_AA[0]];
-		};
-
-		
-
-
-		f.close();
-	}
-	catch (...)
-	{ 
-		delete[]alphabet1_;alphabet1_=NULL;
-		delete[]alphabet2_;alphabet2_=NULL;
-		delete[]alphabet1_to_long_;alphabet1_to_long_=NULL;
-		delete[]alphabet2_to_long_;alphabet2_to_long_=NULL;
-		delete[]codon_AA_;codon_AA_=NULL;
-		if(f.is_open())
-		{
-			f.close();
-		};
-		throw;
-	};
-
-
-}
-
-string FSA_utils::long_to_string(//convert interer ot string
-long int number_)
-{
-	string res_="";
-	string tmp_string;
-	if(number_>0)
-	{
-		tmp_string="";
-	}
-	else
-	{
-		if(number_==0)
-		{
-			tmp_string="";
-		}
-		else
-		{
-			tmp_string="-";
-		};
-	};
-	number_=labs(number_);
-
-	for( ; ; )
-	{
-		long int reminder=number_%10;
-		number_=(number_-reminder)/10;
-		res_=digit_to_string(reminder)+res_;
-		if (number_==0)
-		{
-			break;
-		};
-	};
-
-	return tmp_string+res_;
-}
-
-char FSA_utils::digit_to_string(//convert interer ot string
-long int digit_)
-{
-	switch(digit_)
-	{
-	case 0:return '0';
-	case 1:return '1';
-	case 2:return '2';
-	case 3:return '3';
-	case 4:return '4';
-	case 5:return '5';
-	case 6:return '6';
-	case 7:return '7';
-	case 8:return '8';
-	case 9:return '9';
-	default:return '?';
-	};
-}
-
-bool FSA_utils::the_value_is_double(
-string str_,
-double &val_)
-{
-	if(str_=="")
-	{
-		return false;
-	};
-
-	bool res=false;
-	errno=0;
-	char *p;
-	val_=strtod(str_.c_str(),&p);
-	if(errno!=0)
-	{
-		res=false;
-	}
-	else
-	{
-		res=(*p==0);
-	};
-	return res;
-}
-
-bool FSA_utils::the_value_is_long(
-string str_,
-long int &val_)
-{
-
-	if(str_.length()==0)
-	{
-		return false;
-	};
-	if(!(str_[0]=='+'||str_[0]=='-'||isdigit(str_[0])))
-	{
-		return false;
-	};
-
-	long int start_digit=0;
-
-	if(str_[0]=='+'||str_[0]=='-')
-	{
-		start_digit=1;
-	};
-
-
-	long int i;
-	for(i=start_digit;i<(long int)str_.size();i++)
-	{
-		if(!isdigit(str_[i]))
-		{
-			return false;
-		};
-	};
-
-	if(((long int)str_.size()-start_digit)<=0)
-	{
-		return false;
-	};
-
-	if(((long int)str_.size()-start_digit)>1)
-	{
-		while(str_[start_digit]=='0')
-		{
-			string::iterator it=str_.begin()+start_digit;
-
-
-			str_.erase(it);
-			if((long int)str_.size()<=start_digit+1)
-			{
-				break;
-			};
-		};
-	};
-
-	if(((long int)str_.size()-start_digit>10)||((long int)str_.size()-start_digit)<=0)
-	{
-		return false;
-	};
-
-
-	if((long int)str_.size()-start_digit==10)
-	{
-		if(!(str_[start_digit]=='1'||str_[start_digit]=='2'))
-		{
-			return false;
-		};
-
-		if(str_[start_digit]=='2')
-		{
-
-			long int val2;
-			string str2=str_.substr(start_digit+1,9);
-			int flag=sscanf(str2.c_str(),"%ld",&val2);
-			if(flag!=1)
-			{
-				return false;
-			};
-
-			bool positive=true;
-			if(start_digit>0)
-			{
-				if(str_[0]=='-')
-				{
-					positive=false;
-				};
-			};
-
-			if(positive)
-			{
-				if(val2>147483647)
-				{
-					return false;
-				};
-			}
-			else
-			{
-				if(val2>147483648)
-				{
-					return false;
-				};
-			};
-
-		};
-	};
-
-	int flag=sscanf(str_.c_str(),"%ld",&val_);
-	if(flag!=1)
-	{
-		return false;
-	};
-
-	return true;
-}
-
-double FSA_utils::sqrt_plus(
-double x_)
-{
-	if(x_>=0)
-	{
-		return sqrt(x_);
-	}
-	else
-	{
-		return 0;
-	};
-}
-
-double FSA_utils::error_of_the_sum(//v1_+v2_
-double v1_error_,
-double v2_error_)
-{
-	if(v1_error_>=1e100||v2_error_>=1e100)
-	{
-		return 1e100;
-	};
-
-	return sqrt(v1_error_*v1_error_+v2_error_*v2_error_);
-}
-
-double FSA_utils::error_of_the_product(//v1_*v2_
-double v1_,
-double v1_error_,
-double v2_,
-double v2_error_)
-{
-	if(v1_error_>=1e100||v2_error_>=1e100)
-	{
-		return 1e100;
-	};
-
-	double a1=(v1_+v1_error_)*(v2_+v2_error_);
-	double a2=(v1_-v1_error_)*(v2_+v2_error_);
-	double a3=(v1_+v1_error_)*(v2_-v2_error_);
-	double a4=(v1_-v1_error_)*(v2_-v2_error_);
-
-	double a=v1_*v2_;
-
-	return FSA_utils::Tmax(fabs(a1-a),fabs(a2-a),fabs(a3-a),fabs(a4-a));
-
-}
-
-double FSA_utils::error_of_the_lg(//lg(v1_)
-double v1_,
-double v1_error_)
-{
-	if(v1_error_>=1e100||v1_<=0)
-	{
-		return 1e100;
-	};
-
-	return FSA_utils::Tmin(fabs(log(v1_)/log(10.0)),v1_error_/v1_/log(10.0));
-}
-
-double FSA_utils::error_of_the_sqrt(//sqrt(v1_)
-double v1_,
-double v1_error_)
-{
-	if(v1_error_>=1e100||v1_<0)
-	{
-		return 1e100;
-	};
-
-	double s=sqrt(v1_);
-	double s1=sqrt(FSA_utils::Tmax(0.0,v1_-v1_error_));
-	double s2=sqrt(FSA_utils::Tmax(0.0,v1_+v1_error_));
-
-	return FSA_utils::Tmax(fabs(s-s1),fabs(s-s2));
-}
-
-double FSA_utils::error_of_the_ratio(//v1_/v2_
-double v1_,
-double v1_error_,
-double v2_,
-double v2_error_)
-{
-	if(v1_error_>=1e100||v2_error_>=1e100)
-	{
-		return 1e100;
-	};
-
-
-	if(v2_==0)
-	{
-		return 1e100;
-	};
-
-	if(v1_==0&&v1_error_==0)
-	{
-		return 0.0;
-	};
-
-	double a=v1_/v2_;
-
-
-	if(((v2_+v2_error_)*v2_<=0))
-	{
-		double a3=(v1_+v1_error_)/(v2_-v2_error_);
-		double a4=(v1_-v1_error_)/(v2_-v2_error_);
-		return FSA_utils::Tmax(fabs(a-a3),fabs(a-a4));
-	};
-
-	if(((v2_-v2_error_)*v2_<=0))
-	{
-		double a1=(v1_+v1_error_)/(v2_+v2_error_);
-		double a2=(v1_-v1_error_)/(v2_+v2_error_);
-		return FSA_utils::Tmax(fabs(a-a1),fabs(a-a2));
-	};
-
-
-	double a1=(v1_+v1_error_)/(v2_+v2_error_);
-	double a2=(v1_-v1_error_)/(v2_+v2_error_);
-	double a3=(v1_+v1_error_)/(v2_-v2_error_);
-	double a4=(v1_-v1_error_)/(v2_-v2_error_);
-
-	return FSA_utils::Tmax(fabs(a-a1),fabs(a-a2),fabs(a-a3),fabs(a-a4));
-}
-
-double FSA_utils::error_of_the_sum_with_coeff(//c1_*v1_+c2_*v2_
-double c1_,
-double v1_error_,
-double c2_,
-double v2_error_)
-{
-	if(v1_error_>=1e100||v2_error_>=1e100)
-	{
-		return 1e100;
-	};
-
-	return sqrt(c1_*c1_*v1_error_*v1_error_+c2_*c2_*v2_error_*v2_error_);
-}
-
-
-void FSA_utils::read_alphabet(
-string alphabet_file_name_,
-long int &number_of_AA_alphabet_,
-char* &alphabet_)
-{
-	ifstream a(alphabet_file_name_.data());
-	if(!a)
-	{
-		throw error("Error - the file "+alphabet_file_name_+" is not found\n",1);
-	};
-
-	a>>number_of_AA_alphabet_;
-	if(number_of_AA_alphabet_<=0)
-	{
-		throw error("Error - the file "+alphabet_file_name_+" is wrong\n",1);
-	};
-	alphabet_=new char[number_of_AA_alphabet_];
-	FSA_utils::assert_mem(alphabet_);
-
-	long int i;
-	for(i=0;i<number_of_AA_alphabet_;i++)
-	{
-		if(a.eof())
-		{
-			throw error("Error - the file "+alphabet_file_name_+" is wrong\n",1);
-		};
-		a>>alphabet_[i];
-	};
-
-	a.close();
-
-}
-
-void FSA_utils::calculate_composition_frequencies(
-double number_of_AA_alphabet_,
-char* alphabet_,
-string fasta_file_name_,
-double *comp_frequencies_)
-{
-
-	long int max_c=1000;
-	long int *letter_to_int=new long int[max_c];
-	FSA_utils::assert_mem(letter_to_int);
-
-	long int i;
-	for(i=0;i<max_c;i++)
-	{
-		letter_to_int[i]=-1;
-	};
-
-	for(i=0;i<number_of_AA_alphabet_;i++)
-	{
-		letter_to_int[(size_t)alphabet_[i]]=i;
-		comp_frequencies_[i]=0;
-	};
-
-	ifstream f(fasta_file_name_.data());
-	if(!f)
-	{
-		throw error("Error - the file "+fasta_file_name_+" is not found\n",1);
-	};
-
-
-
-
-	
-	string header;
-
-	if(f.eof())
-	{
-		throw error("Error - the file "+fasta_file_name_+" is incorrect\n",1);
-	};
-
-	getline(f,header);
-
-	if(header.size()==0)
-	{
-		throw error("Error - the file "+fasta_file_name_+" is incorrect\n",1);
-	};
-
-
-	if(header[0]!='>')
-	{
-		throw error("Error - the file "+fasta_file_name_+" is incorrect\n",1);
-	};
-	
-
-	string st;
-	if(f.eof())
-	{
-		throw error("Error - the file "+fasta_file_name_+" is incorrect\n",1);
-	};
-
-	getline(f,st);
-	if(st.size()==0)
-	{
-		throw error("Error - the file "+fasta_file_name_+" is incorrect\n",1);
-	};
-	for( ; ; )
-	{
-		long int j;
-		for(j=0;j<(long int)st.size();j++)
-		{
-			long int letter_ind=letter_to_int[(size_t)st[j]];
-			if(letter_ind<0||letter_ind>=number_of_AA_alphabet_)
-			{
-				continue;
-			};
-			comp_frequencies_[letter_ind]++;
-		};
-
-		if(f.eof())
-		{
-			break;
-		};
-
-		getline(f,st);
-		if(st.size()==0)
-		{
-			break;
-		};
-	};
-
-	f.close();	
-
-	double sum=0;
-	for(i=0;i<number_of_AA_alphabet_;i++)
-	{
-		sum+=comp_frequencies_[i];
-	};
-	cout<<"Total number of allowed letters = "<<sum<<endl;
-
-	if(sum>0)
-	{
-		for(i=0;i<number_of_AA_alphabet_;i++)
-		{
-			comp_frequencies_[i]/=sum;
-		};
-	}
-	else
-	{
-		throw error("Error - the file "+fasta_file_name_+" does not have letters from the allowed alphabet\n",1);
-	};
-
-	delete[]letter_to_int;
-}
-
-void FSA_utils::reverse_sequence(//reverse the letters of the sequence
-long int *seq_,
-long int seq_length_)
-{
-	long int i;
-	for(i=0;i<=(long int)floor((double)seq_length_/2.0)-1;i++)
-	{
-		long int reverse_ind=seq_length_-i-1;
-		long int tmp=seq_[i];
-		seq_[i]=seq_[reverse_ind];
-		seq_[reverse_ind]=tmp;
-	};
-}
-
-void FSA_utils::extract_AA_frequencies_for_DNA_sequence(
-const long int *codon_AA_,//<codon code,AA number>
-long int &codon_length_,//codon length 
-long int number_of_letters1_,//number of letters for the sequence 1
-long int number_of_letters2_,//number of letters for the sequence 2
-const double *RR1_,//nucleotide probabilities
-double *&RR1_AA_)//the resulted frequencies
-{
-	long int *codon_tmp=new long int [codon_length_];
-	FSA_utils::assert_mem(codon_tmp);
-
-	RR1_AA_=new double[number_of_letters2_];
-	FSA_utils::assert_mem(RR1_AA_);
-
-	long int k;
-	for(k=0;k<number_of_letters2_;k++)
-	{
-		RR1_AA_[k]=0.0;
-	};
-
-	long int number_of_codons=FSA_utils::power_long(number_of_letters1_,codon_length_);
-	for(k=0;k<number_of_codons;k++)
-	{
-		convert_code_into_codon(
-		k,//the input code
-		codon_length_,//codon length 
-		number_of_letters1_,//number of letters for the sequence 1
-		codon_tmp);//must be allocated
-
-		long int AA1=codon_AA_[k];
-		if(AA1<0||AA1>=number_of_letters2_)
-		{
-			throw error("Unexpected errro in FSA_utils::extract_AA_frequencies_for_DNA_sequence\n",1);
-		};
-
-		double prob_tmp=1.0;
-		long int i;
-		for(i=0;i<codon_length_;i++)
-		{
-			prob_tmp*=RR1_[codon_tmp[i]];
-		};
-
-		RR1_AA_[AA1]+=prob_tmp;
-
-	};
-
-	delete[]codon_tmp;
-}
-
-
-long int FSA_utils::power_long(//returns a_^b_
-long int a_,
-long int b_)
-{
-	if(b_<0)
-	{
-		throw error("Error - unexpected parameter b_<0 in the function FSA_utils::power_long\n",1);
-	};
-
-	long int res=1;
-	long int i;
-	for(i=1;i<=b_;i++)
-	{
-		res*=a_;
-	};
-
-	return res;
-
-}
-
-void FSA_utils::convert_distr_into_sum(//convert distr_[0], distr_[1], distr_[2],... into distr_[0], distr_[0]+distr_[1], distr_[0]+distr_[1]+distr_[2],...
-long int dim_,
-double *distr_)
-{
-	long int i;
-	for(i=1;i<dim_;i++)
-	{
-		distr_[i]=distr_[i]+distr_[i-1];
-	};
-}
-
-bool FSA_utils::Gauss(
-std::vector<std::vector<double> > A_,//matrix n*(n+1)
-std::vector<double> &x_,//solution
-double inside_eps_,
-std::vector<std::vector<double> > *inv_A_)
-{
-	
-
-	long int i,j,jj;
-	long int matr_size=(long int)A_.size();
-	if(matr_size==0)
-	{
-		//throw error("Error in FSA_utils::Gauss - sizes of matrix are wrong\n",1);
-		return false;
-	};
-
-	std::vector<std::vector<double> > E;
-
-	if(inv_A_)
-	{
-		vector<double> zero(matr_size,0);
-		(*inv_A_).resize(matr_size, zero);
-		
-		E.resize(matr_size, zero);
-		long int i;
-		for(i=0;i<matr_size;i++)
-		{
-			E[i][i]=1.0;
-		};
-	};
-
-
-	for(i=0;i<matr_size;i++)
-	{
-		if((long int)A_[i].size()!=matr_size+1)
-		{
-			throw error("Error in FSA_utils::Gauss - sizes of matrix are wrong\n",1);
-		};
-	};
-	x_.clear();
-	x_.resize(matr_size);
-	//forward trace
-	for(j=0;j<matr_size;j++)
-	{
-		long int absmax=j;
-		for(i=j+1;i<matr_size;i++)
-		{
-			if(fabs(A_[absmax][j])<fabs(A_[i][j]))
-			{
-				absmax=i;
-			};
-		};
-
-		if(j!=absmax)
-		{
-			for(jj=j;jj<matr_size+1;jj++)
-			{
-				double tmp=A_[absmax][jj];
-				A_[absmax][jj]=A_[j][jj];
-				A_[j][jj]=tmp;
-			};
-
-			if(inv_A_)
-			{
-				for(jj=0;jj<matr_size;jj++)
-				{
-					double tmp=E[absmax][jj];
-					E[absmax][jj]=E[j][jj];
-					E[j][jj]=tmp;
-				};
-			};
-		};
-
-		if(fabs(A_[j][j])<=inside_eps_)
-		{
-			throw error("Error in FSA_utils::Gauss - matrix is singular\n",1);
-		};
-
-		for(i=j+1;i<matr_size;i++)
-		{
-			double tmp=A_[i][j]/A_[j][j];
-			for(jj=j+1;jj<matr_size+1;jj++)
-			{
-				A_[i][jj]=A_[i][jj]-tmp*A_[j][jj];
-			};
-
-			if(inv_A_)
-			{
-				for(jj=0;jj<matr_size;jj++)
-				{
-					E[i][jj]=E[i][jj]-tmp*E[j][jj];
-				};
-			};
-		};
-	};
-
-	//reverse trace
-	x_[matr_size-1]=A_[matr_size-1][matr_size]/A_[matr_size-1][matr_size-1];
-	for(i=matr_size-2;i>=0;i--)
-	{
-		x_[i]=A_[i][matr_size];
-		for(j=i+1;j<matr_size;j++)
-		{
-			x_[i]-=A_[i][j]*x_[j];
-		};
-		x_[i]/=A_[i][i];
-	};
-
-	if(inv_A_)
-	{
-		long int k;
-		for(k=0;k<matr_size;k++)
-		{
-			(*inv_A_)[matr_size-1][k]=E[matr_size-1][k]/A_[matr_size-1][matr_size-1];
-			long int i;
-			for(i=matr_size-2;i>=0;i--)
-			{
-				(*inv_A_)[i][k]=E[i][k];
-				long int j;
-				for(j=i+1;j<matr_size;j++)
-				{
-					(*inv_A_)[i][k]-=A_[i][j]*(*inv_A_)[j][k];
-				};
-				(*inv_A_)[i][k]/=A_[i][i];
-			};
-		};
-
-	};
-
-	return true;
-}
-
-void FSA_utils::multiply_matrices(
-const std::vector<std::vector<double> > &A_,
-const std::vector<std::vector<double> > &B_,
-std::vector<std::vector<double> > &res_)
-{
-	long int size1=(long int)A_.size();
-	if(size1==0)
-	{
-		throw error("Error in FSA_utils::multiply_matrices\n",1);
-	};
-	long int size2=(long int)A_[0].size();
-	if(size2==0)
-	{
-		throw error("Error in FSA_utils::multiply_matrices\n",1);
-	};
-
-	long int i,j,k;
-	for(i=1;i<size1;i++)
-	{
-		if((long int)A_[i].size()!=size2)
-		{
-			throw error("Error in FSA_utils::multiply_matrices\n",1);
-		};
-	};
-
-	if(size2!=(long int)B_.size())
-	{
-		throw error("Error in FSA_utils::multiply_matrices\n",1);
-	};
-
-	long int size3=(long int)B_[0].size();
-	if(size3==0)
-	{
-		throw error("Error in FSA_utils::multiply_matrices\n",1);
-	};
-
-	for(i=1;i<size2;i++)
-	{
-		if((long int)B_[i].size()!=size3)
-		{
-			throw error("Error in FSA_utils::multiply_matrices\n",1);
-		};
-	};
-
-	res_.clear();
-	res_.resize(size1);
-	for(i=0;i<size1;i++)
-	{
-		res_[i].resize(size3,0);
-	};
-
-	for(i=0;i<size1;i++)
-	{
-		for(j=0;j<size3;j++)
-		{
-			for(k=0;k<size2;k++)
-			{
-				res_[i][j]+=A_[i][k]*B_[k][j];
-			};
-		};
-	};
-}
-
-void FSA_utils::multiply_matrix_and_vector(
-const std::vector<std::vector<double> > &A_,
-const std::vector<double> &y_,
-std::vector<double> &res_)
-{
-	long int size1=(long int)A_.size();
-	if(size1==0)
-	{
-		throw error("Error in FSA_utils::multiply_matrix_and_vector\n",1);
-	};
-	long int size2=(long int)A_[0].size();
-	if(size2==0)
-	{
-		throw error("Error in FSA_utils::multiply_matrix_and_vector\n",1);
-	};
-
-	long int i,k;
-	for(i=1;i<size1;i++)
-	{
-		if((long int)A_[i].size()!=size2)
-		{
-			throw error("Error in FSA_utils::multiply_matrix_and_vector\n",1);
-		};
-	};
-
-	if(size2!=(long int)y_.size())
-	{
-		throw error("Error in FSA_utils::multiply_matrix_and_vector\n",1);
-	};
-
-
-	res_.clear();
-	res_.resize(size1,0);
-
-	for(i=0;i<size1;i++)
-	{
-		for(k=0;k<size2;k++)
-		{
-			res_[i]+=A_[i][k]*y_[k];
-		};
-	};
-}
-
-void FSA_utils::transpose_matrix(
-const std::vector<std::vector<double> > &A_,
-std::vector<std::vector<double> > &res_)
-{
-	long int size1=(long int)A_.size();
-	if(size1==0)
-	{
-		res_.clear();
-		return;
-	};
-	long int size2=(long int)A_[0].size();
-
-	long int i,j;
-	for(i=1;i<size1;i++)
-	{
-		if((long int)A_[i].size()!=size2)
-		{
-			throw error("Error in FSA_utils::transpose_matrix\n",1);
-		};
-	};
-
-	res_.clear();
-	res_.resize(size2);
-	for(i=0;i<size2;i++)
-	{
-		res_[i].resize(size1);
-	};
-
-	for(i=0;i<size2;i++)
-	{
-		for(j=0;j<size1;j++)
-		{
-			res_[i][j]=A_[j][i];
-		};
-	};
-}
-
-void FSA_utils::print_matrix(
-const std::vector<std::vector<double> > A_)
-{
-	long int i,j;
-	for(i=0;i<(long int)A_.size();i++)
-	{
-		for(j=0;j<(long int)A_[i].size();j++)
-		{
-			if(j<(long int)A_[i].size()-1)
-			{
-				cout<<A_[i][j]<<"\t";
-			}
-			else
-			{
-				cout<<A_[i][j]<<"\n";
-			};
-		};
-	};
-}
-
-void FSA_utils::process_random_factor(
-long int &random_factor_,
-bool *rand_flag_)
-{
-	if(rand_flag_)
-	{
-		*rand_flag_=true;
-	};
-
-	if(random_factor_<0)
-	{
-		random_factor_=(long int)time(NULL);
-		#ifndef _MSC_VER //UNIX program
-			struct timeval tv;
-			struct timezone tz;
-			gettimeofday(&tv, &tz);
-			random_factor_+=tv.tv_usec*10000000;
-		#else
-			struct _timeb timebuffer;
-			char *timeline;
-			_ftime( &timebuffer );
-			timeline = ctime( & ( timebuffer.time ) );
-			random_factor_+=timebuffer.millitm*10000000;
-		#endif
-
-		random_factor_=abs(random_factor_);
-
-		if(rand_flag_)
-		{
-			*rand_flag_=false;
-		};
-
-	};
-}
-
-double FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
-long int dim_,
-double *vect_)
-{
-	if(dim_<1)
-	{
-		throw error("Unexpected error in FSA_utils::standard_deviation\n",1);
-	};
-
-	if(dim_==1)
-	{
-		return 0;
-	};
-
-	double E=0;
-	long int i;
-	for(i=0;i<dim_;i++)
-	{
-		E+=vect_[i];
-	};
-	E/=(double)dim_;
-
-	double E2=0;
-	for(i=0;i<dim_;i++)
-	{
-		E2+=(vect_[i]-E)*(vect_[i]-E);
-	};
-
-	E2=sqrt(E2/(double)((dim_-1)*dim_));
-
-	return E2;
-
-}
-
-double FSA_utils::average(//average of elements of vect_
-long int dim_,
-double *vect_)
-{
-	if(dim_<1)
-	{
-		throw error("Unexpected error in FSA_utils::average\n",1);
-	};
-
-	double E=0;
-	long int i;
-	for(i=0;i<dim_;i++)
-	{
-		E+=vect_[i];
-	};
-	E/=(double)dim_;
-
-	return E;
-
-}
-
-void FSA_utils::read_string(
-ifstream &f_,
-string &st_,
-bool &end_of_file_flag_)
-{
-	if(f_.eof())
-	{
-		end_of_file_flag_=true;
-		return;
-	};
-
-	st_="";
-	end_of_file_flag_=false;
-	while(!end_of_file_flag_)
-	{
-		getline(f_,st_);
-
-		if(st_.size()>0)
-		{
-			bool flag=true;
-			long int i;
-			for(i=0;i<(long int)st_.size();i++)
-			{
-				if(!(st_[i]==' '||(long int)st_[i]==13))
-				{
-					flag=false;
-					break;
-				};
-			};
-			if(flag)
-			{
-				continue;
-			};
-		};
-
-		if(st_.size()>0)
-		{
-			if((long int)st_[st_.size()-1]==13)
-			{
-				st_.resize(st_.size()-1);
-			};
-			break;
-		};
-		if(f_.eof())
-		{
-			end_of_file_flag_=true;
-		};
-	};
-}
-
-void FSA_utils::read_sequences_for_alingment(
-
-string input_file_name_,
-
-long int &number_of_letters1_,//number of letters for the sequence 1
-long int &number_of_letters2_,//number of letters for the sequence 2
-
-char *&alphabet1_,//alphabet letters for the sequence #1
-char *&alphabet2_,//alphabet letters for the sequence #2
-
-long int& number_of_sequences_,
-
-string *&headers_,
-long int *&lengths1_,//lengths of the sequences #1
-long int *&lengths2_,//lengths of the sequences #2
-long int **&sequences1_,//the first index numerates sequences; the second - sequence letters
-long int **&sequences2_)
-{
-
-	long int max_c=1000;
-	long int *letter_to_int1=new long int[max_c];
-	long int *letter_to_int2=new long int[max_c];
-
-	long int i;
-	for(i=0;i<max_c;i++)
-	{
-		letter_to_int1[i]=-1;
-		letter_to_int2[i]=-1;
-	};
-
-	for(i=0;i<number_of_letters1_;i++)
-	{
-		letter_to_int1[(size_t)alphabet1_[i]]=i;
-	};
-	for(i=0;i<number_of_letters2_;i++)
-	{
-		letter_to_int2[(size_t)alphabet2_[i]]=i;
-	};
-
-	long int k;
-	ifstream f(input_file_name_.data());
-	if(!f)
-	{
-		throw error("Error - the input file "+input_file_name_+" is not found\n",1);
-	};
-
-	
-
-	long int count=0;
-
-	vector<long int *> sequences1_vect;
-	vector<long int *> sequences2_vect;
-	vector<long int > lengths1_vect;
-	vector<long int > lengths2_vect;
-	vector<string> headers_vect;
-
-	for( ; ; )
-	{
-
-		bool end_of_file_flag;
-		string header;
-
-		read_string(
-		f,
-		header,
-		end_of_file_flag);
-
-		
-		if(end_of_file_flag)
-		{
-			if(header!="")
-			{
-				throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
-			};
-
-			if(count==0)
-			{
-				throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
-			};
-			break;
-		};
-
-
-		if(header[0]!='>')
-		{
-			throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
-		};
-		
-
-		string st1="";
-		string st2="";
-		if(f.eof())
-		{
-			throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
-		};
-
-		read_string(
-		f,
-		st1,
-		end_of_file_flag);
-
-		if(st1.size()==0||end_of_file_flag)
-		{
-			throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
-		};
-
-		read_string(
-		f,
-		st2,
-		end_of_file_flag);
-
-		if(st2.size()==0||end_of_file_flag)
-		{
-			throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
-		};
-		count++;
-
-		//checking the sequences
-		long int *sequences1_tmp=new long int [st1.size()];
-		FSA_utils::assert_mem(sequences1_tmp);
-		long int *sequences2_tmp=new long int [st2.size()];
-		FSA_utils::assert_mem(sequences2_tmp);
-
-		headers_vect.push_back(header);
-		sequences1_vect.push_back(sequences1_tmp);
-		sequences2_vect.push_back(sequences2_tmp);
-		lengths1_vect.push_back((long int)st1.size());
-		lengths2_vect.push_back((long int)st2.size());
-
-		for(k=0;k<(long int)st1.size();k++)
-		{
-
-			long int long_tmp=letter_to_int1[(size_t)st1[k]];
-			if(long_tmp>=0)
-			{
-				sequences1_tmp[k]=long_tmp;
-			}
-			else
-			{
-				throw error("Error - the file "+input_file_name_+" is incorrect: a non-alphabet letter with the code "+FSA_utils::long_to_string((long int)st1[k])+"\n",1);
-			};
-		};
-		for(k=0;k<(long int)st2.size();k++)
-		{
-
-			long int long_tmp=letter_to_int2[(size_t)st2[k]];
-			if(long_tmp>=0)
-			{
-				sequences2_tmp[k]=long_tmp;
-			}
-			else
-			{
-				throw error("Error - the file "+input_file_name_+" is incorrect: a non-alphabet letter with the code "+FSA_utils::long_to_string((long int)st2[k])+"\n",1);
-			};
-		};
-
-	};
-
-	f.close();
-
-	delete[]letter_to_int1;
-	delete[]letter_to_int2;
-
-	//allocate memory for the arrays
-	number_of_sequences_=count;
-	sequences1_=new long int*[number_of_sequences_];
-	FSA_utils::assert_mem(sequences1_);
-	sequences2_=new long int*[number_of_sequences_];
-	FSA_utils::assert_mem(sequences2_);
-	
-	lengths1_=new long int[number_of_sequences_];
-	FSA_utils::assert_mem(lengths1_);
-	lengths2_=new long int[number_of_sequences_];
-	FSA_utils::assert_mem(lengths2_);
-	headers_=new string[number_of_sequences_];
-	FSA_utils::assert_mem(headers_);
-
-	for(k=0;k<number_of_sequences_;k++)
-	{
-		headers_[k]=headers_vect[k];
-		lengths1_[k]=lengths1_vect[k];
-		lengths2_[k]=lengths2_vect[k];
-		sequences1_[k]=sequences1_vect[k];
-		sequences2_[k]=sequences2_vect[k];
-	};
-
-}
-
+/* $Id: $
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's offical duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_fsa1_utils.cpp
+
+Author: Sergey Sheetlin
+
+Contents: Frameshift alignment algorithms 
+
+******************************************************************************/
+
+#include "sls_fsa1_utils.hpp"
+
+using namespace Sls;
+using namespace std;
+
+static long int length_max=1000;
+
+void FSA_utils::read_RR(
+string RR_file_name_,
+double *&RR_,
+double *&RR_sum_,
+long int *&RR_sum_elements_,
+long int &number_of_AA_RR_,
+long int number_of_AA_RR_default_)
+{
+	read_RR(
+	RR_file_name_,
+	RR_,
+	number_of_AA_RR_,
+	number_of_AA_RR_default_);
+
+	calculate_RR_sum(
+	RR_,
+	number_of_AA_RR_,
+	RR_sum_,
+	RR_sum_elements_);
+
+}
+
+void FSA_utils::check_RR_sum(
+double sum_tmp_,
+long int number_of_AA_RR_,
+string RR_file_name_)
+{
+
+
+	if(number_of_AA_RR_<=0)
+	{
+		throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
+	};
+
+	double diff_tmp=fabs(sum_tmp_-1.0);
+	if(diff_tmp>0)
+	{
+		double lg_diff=-(log(diff_tmp)-log((double)number_of_AA_RR_))/log(10.0);
+		double lg_eps=-log(DBL_EPSILON)/log(10.0)-1;
+		if(lg_diff<lg_eps)
+		{
+
+			if(sum_tmp_<=0)
+			{
+				if(RR_file_name_!="")
+				{
+					throw error("Error: the sum of the probabilities from the file "+RR_file_name_+" is non-positive\n",3);
+				}
+				else
+				{
+					throw error("Error: the sum of the probabilities is non-positive\n",3);
+				};
+
+			};
+
+			if(RR_file_name_!="")
+			{
+				static map<string, bool> flag_RR;
+
+				if(!flag_RR[RR_file_name_])
+				{
+					cout<<"\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
+					cout<<"Warning: the sum of the probabilities from the file "<<RR_file_name_<<" is not equal to 1\n";
+					cout<<"The probabilities will be normalized for the computation\n";
+					cout<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n";
+
+					flag_RR[RR_file_name_]=true;
+				};
+			}
+			else
+			{
+				//no messages if called from the library functions
+			};
+
+		};
+
+	};
+
+}
+
+void FSA_utils::calculate_RR_sum(
+double *RR_,
+long int number_of_AA_RR_,
+double *&RR_sum_,
+long int *&RR_sum_elements_)
+{
+
+	RR_sum_=NULL;
+	RR_sum_elements_=NULL;
+
+
+	try
+	{
+
+		long int i;
+		if(number_of_AA_RR_<=0)
+		{
+			throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
+		};
+		
+		RR_sum_=new double[number_of_AA_RR_];
+		assert_mem(RR_sum_);
+
+		RR_sum_elements_=new long int [number_of_AA_RR_];
+		assert_mem(RR_sum_elements_);
+
+
+		for(i=0;i<number_of_AA_RR_;i++)
+		{
+			if(RR_[i]<0)
+			{
+				throw error("Error - the frequencies must be non-negative\n",3);
+			};
+
+			if(i!=0)
+			{
+				RR_sum_[i]=RR_sum_[i-1]+RR_[i];
+			}
+			else
+			{
+				RR_sum_[i]=RR_[i];
+			};
+			RR_sum_elements_[i]=i;
+		};
+
+		double sum_tmp=RR_sum_[number_of_AA_RR_-1];
+
+		check_RR_sum(
+		sum_tmp,
+		number_of_AA_RR_,
+		"");
+
+		if(sum_tmp>0)
+		{
+			long int i;
+			for(i=0;i<number_of_AA_RR_;i++)
+			{
+				RR_[i]/=sum_tmp;
+				RR_sum_[i]/=sum_tmp;
+			};
+		};
+
+	}
+	catch (...)
+	{ 
+		delete[]RR_sum_;RR_sum_=NULL;
+		delete[]RR_sum_elements_;RR_sum_elements_=NULL;
+		throw;
+	};
+
+
+}
+
+void FSA_utils::read_RR(
+string RR_file_name_,
+double *&RR_,
+long int &number_of_AA_RR_,
+long int number_of_AA_RR_default_)
+{
+	ifstream f;
+
+	RR_=NULL;
+
+	try
+	{
+
+		if(RR_file_name_=="")
+		{
+		
+			if(number_of_AA_RR_default_==4)
+			{
+				//default for RR1
+				number_of_AA_RR_=4;
+
+				RR_=new double[number_of_AA_RR_];
+				assert_mem(RR_);
+
+
+				RR_[0]=0.25; RR_[1]=0.25; RR_[2]=0.25; RR_[3]=0.25; 
+				return;
+			};
+
+			if(number_of_AA_RR_default_==25)
+			{
+				//default for RR2
+				number_of_AA_RR_=25;
+
+				RR_=new double[number_of_AA_RR_];
+				assert_mem(RR_);
+
+				RR_[0]=0.07805; RR_[1]=0.05129; RR_[2]=0.04487; RR_[3]=0.05364; RR_[4]=0.01925; RR_[5]=0.04264; RR_[6]=0.06295; RR_[7]=0.07377; RR_[8]=0.02199; RR_[9]=0.05142; RR_[10]=0.09019; RR_[11]=0.05744; RR_[12]=0.02243; RR_[13]=0.03856; RR_[14]=0.05203; RR_[15]=0.0712; RR_[16]=0.05841; RR_[17]=0.0133; RR_[18]=0.03216; RR_[19]=0.06441; RR_[20]=0; RR_[21]=0; RR_[22]=0; RR_[23]=0; RR_[24]=0; 
+				return;
+			};
+
+			throw error("Unexpected parameters in void FSA_utils::read_RR\n",1);
+
+		};
+
+		long int i;
+		f.open(RR_file_name_.data(),ios::in);
+		if(!f)
+		{
+			throw error("Error - file "+RR_file_name_+" is not found\n",3);
+		};
+
+		f>>number_of_AA_RR_;
+
+		if(number_of_AA_RR_<=0)
+		{
+			throw error("Error - number of letters in the probabilities file must be greater than 0\n",3);
+		};
+		
+		RR_=new double[number_of_AA_RR_];
+		assert_mem(RR_);
+
+
+		double sum_tmp=0;
+		for(i=0;i<number_of_AA_RR_;i++)
+		{
+			f>>RR_[i];
+
+			if(RR_[i]<0)
+			{
+				throw error("Error - the frequencies defined in the file "+RR_file_name_+" must be non-negative\n",3);
+			};
+
+			sum_tmp+=RR_[i];
+
+		};
+
+		check_RR_sum(
+		sum_tmp,
+		number_of_AA_RR_,
+		RR_file_name_);
+
+		f.close();
+	}
+	catch (...)
+	{ 
+		if(f.is_open())
+		{
+			f.close();
+		};
+		delete[]RR_;RR_=NULL;
+		throw;
+	};
+
+}
+
+void FSA_utils::read_smatr(
+string smatr_file_name_,
+long int **&smatr_,
+long int &number_of_AA_smatr_,
+long int &smatr_min_)
+{
+	ifstream f;
+
+	try
+	{
+
+		if(smatr_file_name_=="")
+		{
+			//default for the scoring matrix (BLOSUM80)
+			number_of_AA_smatr_=25;
+			FSA_utils::get_memory_for_matrix(number_of_AA_smatr_,number_of_AA_smatr_,smatr_);
+			smatr_min_=-6;
+
+			smatr_[0][0]=5; smatr_[0][1]=-2; smatr_[0][2]=-2; smatr_[0][3]=-2; smatr_[0][4]=-1; smatr_[0][5]=-1; smatr_[0][6]=-1; smatr_[0][7]=0; smatr_[0][8]=-2; smatr_[0][9]=-2; smatr_[0][10]=-2; smatr_[0][11]=-1; smatr_[0][12]=-1; smatr_[0][13]=-3; smatr_[0][14]=-1; smatr_[0][15]=1; smatr_[0][16]=0; smatr_[0][17]=-3; smatr_[0][18]=-2; smatr_[0][19]=0; smatr_[0][20]=-2; smatr_[0][21]=-2; smatr_[0][22]=-1; smatr_[0][23]=-1; smatr_[0][24]=-6; 
+			smatr_[1][0]=-2; smatr_[1][1]=6; smatr_[1][2]=-1; smatr_[1][3]=-2; smatr_[1][4]=-4; smatr_[1][5]=1; smatr_[1][6]=-1; smatr_[1][7]=-3; smatr_[1][8]=0; smatr_[1][9]=-3; smatr_[1][10]=-3; smatr_[1][11]=2; smatr_[1][12]=-2; smatr_[1][13]=-4; smatr_[1][14]=-2; smatr_[1][15]=-1; smatr_[1][16]=-1; smatr_[1][17]=-4; smatr_[1][18]=-3; smatr_[1][19]=-3; smatr_[1][20]=-1; smatr_[1][21]=-3; smatr_[1][22]=0; smatr_[1][23]=-1; smatr_[1][24]=-6; 
+			smatr_[2][0]=-2; smatr_[2][1]=-1; smatr_[2][2]=6; smatr_[2][3]=1; smatr_[2][4]=-3; smatr_[2][5]=0; smatr_[2][6]=-1; smatr_[2][7]=-1; smatr_[2][8]=0; smatr_[2][9]=-4; smatr_[2][10]=-4; smatr_[2][11]=0; smatr_[2][12]=-3; smatr_[2][13]=-4; smatr_[2][14]=-3; smatr_[2][15]=0; smatr_[2][16]=0; smatr_[2][17]=-4; smatr_[2][18]=-3; smatr_[2][19]=-4; smatr_[2][20]=5; smatr_[2][21]=-4; smatr_[2][22]=0; smatr_[2][23]=-1; smatr_[2][24]=-6; 
+			smatr_[3][0]=-2; smatr_[3][1]=-2; smatr_[3][2]=1; smatr_[3][3]=6; smatr_[3][4]=-4; smatr_[3][5]=-1; smatr_[3][6]=1; smatr_[3][7]=-2; smatr_[3][8]=-2; smatr_[3][9]=-4; smatr_[3][10]=-5; smatr_[3][11]=-1; smatr_[3][12]=-4; smatr_[3][13]=-4; smatr_[3][14]=-2; smatr_[3][15]=-1; smatr_[3][16]=-1; smatr_[3][17]=-6; smatr_[3][18]=-4; smatr_[3][19]=-4; smatr_[3][20]=5; smatr_[3][21]=-5; smatr_[3][22]=1; smatr_[3][23]=-1; smatr_[3][24]=-6; 
+			smatr_[4][0]=-1; smatr_[4][1]=-4; smatr_[4][2]=-3; smatr_[4][3]=-4; smatr_[4][4]=9; smatr_[4][5]=-4; smatr_[4][6]=-5; smatr_[4][7]=-4; smatr_[4][8]=-4; smatr_[4][9]=-2; smatr_[4][10]=-2; smatr_[4][11]=-4; smatr_[4][12]=-2; smatr_[4][13]=-3; smatr_[4][14]=-4; smatr_[4][15]=-2; smatr_[4][16]=-1; smatr_[4][17]=-3; smatr_[4][18]=-3; smatr_[4][19]=-1; smatr_[4][20]=-4; smatr_[4][21]=-2; smatr_[4][22]=-4; smatr_[4][23]=-1; smatr_[4][24]=-6; 
+			smatr_[5][0]=-1; smatr_[5][1]=1; smatr_[5][2]=0; smatr_[5][3]=-1; smatr_[5][4]=-4; smatr_[5][5]=6; smatr_[5][6]=2; smatr_[5][7]=-2; smatr_[5][8]=1; smatr_[5][9]=-3; smatr_[5][10]=-3; smatr_[5][11]=1; smatr_[5][12]=0; smatr_[5][13]=-4; smatr_[5][14]=-2; smatr_[5][15]=0; smatr_[5][16]=-1; smatr_[5][17]=-3; smatr_[5][18]=-2; smatr_[5][19]=-3; smatr_[5][20]=0; smatr_[5][21]=-3; smatr_[5][22]=4; smatr_[5][23]=-1; smatr_[5][24]=-6; 
+			smatr_[6][0]=-1; smatr_[6][1]=-1; smatr_[6][2]=-1; smatr_[6][3]=1; smatr_[6][4]=-5; smatr_[6][5]=2; smatr_[6][6]=6; smatr_[6][7]=-3; smatr_[6][8]=0; smatr_[6][9]=-4; smatr_[6][10]=-4; smatr_[6][11]=1; smatr_[6][12]=-2; smatr_[6][13]=-4; smatr_[6][14]=-2; smatr_[6][15]=0; smatr_[6][16]=-1; smatr_[6][17]=-4; smatr_[6][18]=-3; smatr_[6][19]=-3; smatr_[6][20]=1; smatr_[6][21]=-4; smatr_[6][22]=5; smatr_[6][23]=-1; smatr_[6][24]=-6; 
+			smatr_[7][0]=0; smatr_[7][1]=-3; smatr_[7][2]=-1; smatr_[7][3]=-2; smatr_[7][4]=-4; smatr_[7][5]=-2; smatr_[7][6]=-3; smatr_[7][7]=6; smatr_[7][8]=-3; smatr_[7][9]=-5; smatr_[7][10]=-4; smatr_[7][11]=-2; smatr_[7][12]=-4; smatr_[7][13]=-4; smatr_[7][14]=-3; smatr_[7][15]=-1; smatr_[7][16]=-2; smatr_[7][17]=-4; smatr_[7][18]=-4; smatr_[7][19]=-4; smatr_[7][20]=-1; smatr_[7][21]=-5; smatr_[7][22]=-3; smatr_[7][23]=-1; smatr_[7][24]=-6; 
+			smatr_[8][0]=-2; smatr_[8][1]=0; smatr_[8][2]=0; smatr_[8][3]=-2; smatr_[8][4]=-4; smatr_[8][5]=1; smatr_[8][6]=0; smatr_[8][7]=-3; smatr_[8][8]=8; smatr_[8][9]=-4; smatr_[8][10]=-3; smatr_[8][11]=-1; smatr_[8][12]=-2; smatr_[8][13]=-2; smatr_[8][14]=-3; smatr_[8][15]=-1; smatr_[8][16]=-2; smatr_[8][17]=-3; smatr_[8][18]=2; smatr_[8][19]=-4; smatr_[8][20]=-1; smatr_[8][21]=-4; smatr_[8][22]=0; smatr_[8][23]=-1; smatr_[8][24]=-6; 
+			smatr_[9][0]=-2; smatr_[9][1]=-3; smatr_[9][2]=-4; smatr_[9][3]=-4; smatr_[9][4]=-2; smatr_[9][5]=-3; smatr_[9][6]=-4; smatr_[9][7]=-5; smatr_[9][8]=-4; smatr_[9][9]=5; smatr_[9][10]=1; smatr_[9][11]=-3; smatr_[9][12]=1; smatr_[9][13]=-1; smatr_[9][14]=-4; smatr_[9][15]=-3; smatr_[9][16]=-1; smatr_[9][17]=-3; smatr_[9][18]=-2; smatr_[9][19]=3; smatr_[9][20]=-4; smatr_[9][21]=3; smatr_[9][22]=-4; smatr_[9][23]=-1; smatr_[9][24]=-6; 
+			smatr_[10][0]=-2; smatr_[10][1]=-3; smatr_[10][2]=-4; smatr_[10][3]=-5; smatr_[10][4]=-2; smatr_[10][5]=-3; smatr_[10][6]=-4; smatr_[10][7]=-4; smatr_[10][8]=-3; smatr_[10][9]=1; smatr_[10][10]=4; smatr_[10][11]=-3; smatr_[10][12]=2; smatr_[10][13]=0; smatr_[10][14]=-3; smatr_[10][15]=-3; smatr_[10][16]=-2; smatr_[10][17]=-2; smatr_[10][18]=-2; smatr_[10][19]=1; smatr_[10][20]=-4; smatr_[10][21]=3; smatr_[10][22]=-3; smatr_[10][23]=-1; smatr_[10][24]=-6; 
+			smatr_[11][0]=-1; smatr_[11][1]=2; smatr_[11][2]=0; smatr_[11][3]=-1; smatr_[11][4]=-4; smatr_[11][5]=1; smatr_[11][6]=1; smatr_[11][7]=-2; smatr_[11][8]=-1; smatr_[11][9]=-3; smatr_[11][10]=-3; smatr_[11][11]=5; smatr_[11][12]=-2; smatr_[11][13]=-4; smatr_[11][14]=-1; smatr_[11][15]=-1; smatr_[11][16]=-1; smatr_[11][17]=-4; smatr_[11][18]=-3; smatr_[11][19]=-3; smatr_[11][20]=-1; smatr_[11][21]=-3; smatr_[11][22]=1; smatr_[11][23]=-1; smatr_[11][24]=-6; 
+			smatr_[12][0]=-1; smatr_[12][1]=-2; smatr_[12][2]=-3; smatr_[12][3]=-4; smatr_[12][4]=-2; smatr_[12][5]=0; smatr_[12][6]=-2; smatr_[12][7]=-4; smatr_[12][8]=-2; smatr_[12][9]=1; smatr_[12][10]=2; smatr_[12][11]=-2; smatr_[12][12]=6; smatr_[12][13]=0; smatr_[12][14]=-3; smatr_[12][15]=-2; smatr_[12][16]=-1; smatr_[12][17]=-2; smatr_[12][18]=-2; smatr_[12][19]=1; smatr_[12][20]=-3; smatr_[12][21]=2; smatr_[12][22]=-1; smatr_[12][23]=-1; smatr_[12][24]=-6; 
+			smatr_[13][0]=-3; smatr_[13][1]=-4; smatr_[13][2]=-4; smatr_[13][3]=-4; smatr_[13][4]=-3; smatr_[13][5]=-4; smatr_[13][6]=-4; smatr_[13][7]=-4; smatr_[13][8]=-2; smatr_[13][9]=-1; smatr_[13][10]=0; smatr_[13][11]=-4; smatr_[13][12]=0; smatr_[13][13]=6; smatr_[13][14]=-4; smatr_[13][15]=-3; smatr_[13][16]=-2; smatr_[13][17]=0; smatr_[13][18]=3; smatr_[13][19]=-1; smatr_[13][20]=-4; smatr_[13][21]=0; smatr_[13][22]=-4; smatr_[13][23]=-1; smatr_[13][24]=-6; 
+			smatr_[14][0]=-1; smatr_[14][1]=-2; smatr_[14][2]=-3; smatr_[14][3]=-2; smatr_[14][4]=-4; smatr_[14][5]=-2; smatr_[14][6]=-2; smatr_[14][7]=-3; smatr_[14][8]=-3; smatr_[14][9]=-4; smatr_[14][10]=-3; smatr_[14][11]=-1; smatr_[14][12]=-3; smatr_[14][13]=-4; smatr_[14][14]=8; smatr_[14][15]=-1; smatr_[14][16]=-2; smatr_[14][17]=-5; smatr_[14][18]=-4; smatr_[14][19]=-3; smatr_[14][20]=-2; smatr_[14][21]=-4; smatr_[14][22]=-2; smatr_[14][23]=-1; smatr_[14][24]=-6; 
+			smatr_[15][0]=1; smatr_[15][1]=-1; smatr_[15][2]=0; smatr_[15][3]=-1; smatr_[15][4]=-2; smatr_[15][5]=0; smatr_[15][6]=0; smatr_[15][7]=-1; smatr_[15][8]=-1; smatr_[15][9]=-3; smatr_[15][10]=-3; smatr_[15][11]=-1; smatr_[15][12]=-2; smatr_[15][13]=-3; smatr_[15][14]=-1; smatr_[15][15]=5; smatr_[15][16]=1; smatr_[15][17]=-4; smatr_[15][18]=-2; smatr_[15][19]=-2; smatr_[15][20]=0; smatr_[15][21]=-3; smatr_[15][22]=0; smatr_[15][23]=-1; smatr_[15][24]=-6; 
+			smatr_[16][0]=0; smatr_[16][1]=-1; smatr_[16][2]=0; smatr_[16][3]=-1; smatr_[16][4]=-1; smatr_[16][5]=-1; smatr_[16][6]=-1; smatr_[16][7]=-2; smatr_[16][8]=-2; smatr_[16][9]=-1; smatr_[16][10]=-2; smatr_[16][11]=-1; smatr_[16][12]=-1; smatr_[16][13]=-2; smatr_[16][14]=-2; smatr_[16][15]=1; smatr_[16][16]=5; smatr_[16][17]=-4; smatr_[16][18]=-2; smatr_[16][19]=0; smatr_[16][20]=-1; smatr_[16][21]=-1; smatr_[16][22]=-1; smatr_[16][23]=-1; smatr_[16][24]=-6; 
+			smatr_[17][0]=-3; smatr_[17][1]=-4; smatr_[17][2]=-4; smatr_[17][3]=-6; smatr_[17][4]=-3; smatr_[17][5]=-3; smatr_[17][6]=-4; smatr_[17][7]=-4; smatr_[17][8]=-3; smatr_[17][9]=-3; smatr_[17][10]=-2; smatr_[17][11]=-4; smatr_[17][12]=-2; smatr_[17][13]=0; smatr_[17][14]=-5; smatr_[17][15]=-4; smatr_[17][16]=-4; smatr_[17][17]=11; smatr_[17][18]=2; smatr_[17][19]=-3; smatr_[17][20]=-5; smatr_[17][21]=-3; smatr_[17][22]=-3; smatr_[17][23]=-1; smatr_[17][24]=-6; 
+			smatr_[18][0]=-2; smatr_[18][1]=-3; smatr_[18][2]=-3; smatr_[18][3]=-4; smatr_[18][4]=-3; smatr_[18][5]=-2; smatr_[18][6]=-3; smatr_[18][7]=-4; smatr_[18][8]=2; smatr_[18][9]=-2; smatr_[18][10]=-2; smatr_[18][11]=-3; smatr_[18][12]=-2; smatr_[18][13]=3; smatr_[18][14]=-4; smatr_[18][15]=-2; smatr_[18][16]=-2; smatr_[18][17]=2; smatr_[18][18]=7; smatr_[18][19]=-2; smatr_[18][20]=-3; smatr_[18][21]=-2; smatr_[18][22]=-3; smatr_[18][23]=-1; smatr_[18][24]=-6; 
+			smatr_[19][0]=0; smatr_[19][1]=-3; smatr_[19][2]=-4; smatr_[19][3]=-4; smatr_[19][4]=-1; smatr_[19][5]=-3; smatr_[19][6]=-3; smatr_[19][7]=-4; smatr_[19][8]=-4; smatr_[19][9]=3; smatr_[19][10]=1; smatr_[19][11]=-3; smatr_[19][12]=1; smatr_[19][13]=-1; smatr_[19][14]=-3; smatr_[19][15]=-2; smatr_[19][16]=0; smatr_[19][17]=-3; smatr_[19][18]=-2; smatr_[19][19]=4; smatr_[19][20]=-4; smatr_[19][21]=2; smatr_[19][22]=-3; smatr_[19][23]=-1; smatr_[19][24]=-6; 
+			smatr_[20][0]=-2; smatr_[20][1]=-1; smatr_[20][2]=5; smatr_[20][3]=5; smatr_[20][4]=-4; smatr_[20][5]=0; smatr_[20][6]=1; smatr_[20][7]=-1; smatr_[20][8]=-1; smatr_[20][9]=-4; smatr_[20][10]=-4; smatr_[20][11]=-1; smatr_[20][12]=-3; smatr_[20][13]=-4; smatr_[20][14]=-2; smatr_[20][15]=0; smatr_[20][16]=-1; smatr_[20][17]=-5; smatr_[20][18]=-3; smatr_[20][19]=-4; smatr_[20][20]=5; smatr_[20][21]=-4; smatr_[20][22]=0; smatr_[20][23]=-1; smatr_[20][24]=-6; 
+			smatr_[21][0]=-2; smatr_[21][1]=-3; smatr_[21][2]=-4; smatr_[21][3]=-5; smatr_[21][4]=-2; smatr_[21][5]=-3; smatr_[21][6]=-4; smatr_[21][7]=-5; smatr_[21][8]=-4; smatr_[21][9]=3; smatr_[21][10]=3; smatr_[21][11]=-3; smatr_[21][12]=2; smatr_[21][13]=0; smatr_[21][14]=-4; smatr_[21][15]=-3; smatr_[21][16]=-1; smatr_[21][17]=-3; smatr_[21][18]=-2; smatr_[21][19]=2; smatr_[21][20]=-4; smatr_[21][21]=3; smatr_[21][22]=-3; smatr_[21][23]=-1; smatr_[21][24]=-6; 
+			smatr_[22][0]=-1; smatr_[22][1]=0; smatr_[22][2]=0; smatr_[22][3]=1; smatr_[22][4]=-4; smatr_[22][5]=4; smatr_[22][6]=5; smatr_[22][7]=-3; smatr_[22][8]=0; smatr_[22][9]=-4; smatr_[22][10]=-3; smatr_[22][11]=1; smatr_[22][12]=-1; smatr_[22][13]=-4; smatr_[22][14]=-2; smatr_[22][15]=0; smatr_[22][16]=-1; smatr_[22][17]=-3; smatr_[22][18]=-3; smatr_[22][19]=-3; smatr_[22][20]=0; smatr_[22][21]=-3; smatr_[22][22]=5; smatr_[22][23]=-1; smatr_[22][24]=-6; 
+			smatr_[23][0]=-1; smatr_[23][1]=-1; smatr_[23][2]=-1; smatr_[23][3]=-1; smatr_[23][4]=-1; smatr_[23][5]=-1; smatr_[23][6]=-1; smatr_[23][7]=-1; smatr_[23][8]=-1; smatr_[23][9]=-1; smatr_[23][10]=-1; smatr_[23][11]=-1; smatr_[23][12]=-1; smatr_[23][13]=-1; smatr_[23][14]=-1; smatr_[23][15]=-1; smatr_[23][16]=-1; smatr_[23][17]=-1; smatr_[23][18]=-1; smatr_[23][19]=-1; smatr_[23][20]=-1; smatr_[23][21]=-1; smatr_[23][22]=-1; smatr_[23][23]=-1; smatr_[23][24]=-6; 
+			smatr_[24][0]=-6; smatr_[24][1]=-6; smatr_[24][2]=-6; smatr_[24][3]=-6; smatr_[24][4]=-6; smatr_[24][5]=-6; smatr_[24][6]=-6; smatr_[24][7]=-6; smatr_[24][8]=-6; smatr_[24][9]=-6; smatr_[24][10]=-6; smatr_[24][11]=-6; smatr_[24][12]=-6; smatr_[24][13]=-6; smatr_[24][14]=-6; smatr_[24][15]=-6; smatr_[24][16]=-6; smatr_[24][17]=-6; smatr_[24][18]=-6; smatr_[24][19]=-6; smatr_[24][20]=-6; smatr_[24][21]=-6; smatr_[24][22]=-6; smatr_[24][23]=-6; smatr_[24][24]=1; 
+
+			return;
+		};
+
+
+		long int i,j;
+		f.open(smatr_file_name_.data(),ios::in);
+		if(!f)
+		{
+			throw error("Error - file "+smatr_file_name_+" is not found\n",3);
+		};
+
+		f>>number_of_AA_smatr_;
+
+		if(number_of_AA_smatr_<=0)
+		{
+			throw error("Error - number of letters in the scoring matrix file must be greater than 0\n",3);
+		};
+
+		get_memory_for_matrix(number_of_AA_smatr_,number_of_AA_smatr_,smatr_);
+
+
+		for(i=0;i<number_of_AA_smatr_;i++)
+		{
+			for(j=0;j<number_of_AA_smatr_;j++)
+			{
+				if(f.eof())
+				{
+					throw error("Error - file "+smatr_file_name_+" is not correct (please check dimensions of the scoring matrix)\n",3);
+				};
+
+				f>>smatr_[i][j];
+			};
+		};
+
+		f.close();
+
+
+		smatr_min(
+		smatr_,
+		number_of_AA_smatr_,
+		smatr_min_);
+
+		
+	}
+	catch (...)
+	{ 
+		if(f.is_open())
+		{
+			f.close();
+		};
+		throw;
+	};
+
+}
+
+void FSA_utils::smatr_min(
+long int **smatr_,
+long int number_of_AA_smatr_,
+long int &smatr_min_)
+{
+	long int small_number=numeric_limits<long int>::min()/10000;
+	long int i,j;
+
+	for(i=0;i<number_of_AA_smatr_;i++)
+	{
+		for(j=0;j<number_of_AA_smatr_;j++)
+		{
+			if(smatr_[i][j]<small_number)
+			{
+				smatr_[i][j]=small_number;
+			};
+
+			if(i==0&&j==0)
+			{
+				smatr_min_=smatr_[0][0];
+			}
+			else
+			{
+				if(smatr_min_>smatr_[i][j])
+				{
+					smatr_min_=smatr_[i][j];
+				};
+			};
+		};
+	};
+
+}
+
+void FSA_utils::remove_zero_probabilities(
+double *&RR1_,
+double *&RR1_sum_,
+long int *&RR1_sum_elements_,
+long int &alphabet_letters_number1_,
+double *&RR2_,
+double *&RR2_sum_,
+long int *&RR2_sum_elements_,
+long int &alphabet_letters_number2_,
+long int **&smatr_,
+long int &number_of_AA_smatr_,
+long int &smatr_min_,
+
+long int &number_of_letters1_,//number of letters for the sequence 1
+long int &number_of_letters2_,//number of letters for the sequence 2
+
+char *&alphabet1_,//alphabet letters for the sequence #1
+char *&alphabet2_,//alphabet letters for the sequence #2
+
+long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+long int &codon_length_,//codon length 
+long int *&codon_AA_)//<codon code,AA number>
+{
+
+	vector<bool> codon_flag_RR2;
+	
+	{
+		long int number_of_codons_old=FSA_utils::power_long(alphabet_letters_number1_,codon_length_);
+		codon_flag_RR2.resize(number_of_codons_old,false);
+		long int i;
+		for(i=0;i<number_of_codons_old;i++)
+		{
+			codon_flag_RR2[codon_AA_[i]]=true;
+		};
+	};
+
+
+	map<long int,bool> zero_flag_RR1;
+	map<long int,bool> zero_flag_RR2;
+
+	map<long int,long int> old1_numbering_to_the_new1;
+	map<long int,long int> new1_numbering_to_the_old1;
+	long int count1=-1;
+	long int i;
+	for(i=0;i<alphabet_letters_number1_;i++)
+	{
+		if(RR1_[i]==0)
+		{
+			zero_flag_RR1[i]=true;
+			old1_numbering_to_the_new1[i]=-1;
+		}
+		else
+		{
+			zero_flag_RR1[i]=false;
+			count1++;
+			old1_numbering_to_the_new1[i]=count1;
+			new1_numbering_to_the_old1[count1]=i;
+		};
+
+	};
+
+	map<long int,long int> old2_numbering_to_the_new2;
+	map<long int,long int> new2_numbering_to_the_old2;
+	long int count2=-1;
+	for(i=0;i<alphabet_letters_number2_;i++)
+	{
+		if(RR2_[i]==0&&!codon_flag_RR2[i])
+		{
+			zero_flag_RR2[i]=true;
+			old2_numbering_to_the_new2[i]=-1;
+		}
+		else
+		{
+			zero_flag_RR2[i]=false;
+			count2++;
+			old2_numbering_to_the_new2[i]=count2;
+			new2_numbering_to_the_old2[count2]=i;
+		};
+	};
+//-------------------------------------
+	long int alphabet_letters_number1_new=count1+1;
+	double *RR1_new=new double[alphabet_letters_number1_new];
+	double *RR1_sum_new=new double[alphabet_letters_number1_new];
+	long int *RR1_sum_elements_new=new long int[alphabet_letters_number1_new];
+	
+	long int alphabet_letters_number2_new=count2+1;
+	double *RR2_new=new double[alphabet_letters_number2_new];
+	double *RR2_sum_new=new double[alphabet_letters_number2_new];
+	long int *RR2_sum_elements_new=new long int[alphabet_letters_number2_new];
+
+
+	long int c1;
+	for(c1=0;c1<alphabet_letters_number1_new;c1++)
+	{
+		RR1_new[c1]=RR1_[new1_numbering_to_the_old1[c1]];
+		RR1_sum_new[c1]=RR1_sum_[new1_numbering_to_the_old1[c1]];
+		RR1_sum_elements_new[c1]=c1;
+	};
+
+	long int c2;
+	for(c2=0;c2<alphabet_letters_number2_new;c2++)
+	{
+		RR2_new[c2]=RR2_[new2_numbering_to_the_old2[c2]];
+		RR2_sum_new[c2]=RR2_sum_[new2_numbering_to_the_old2[c2]];
+		RR2_sum_elements_new[c2]=c2;
+	};
+
+
+
+	//reallocation
+	
+	delete[]RR1_;
+	RR1_=RR1_new;
+	delete[]RR1_sum_;
+	RR1_sum_=RR1_sum_new;
+	delete[]RR1_sum_elements_;
+	RR1_sum_elements_=RR1_sum_elements_new;
+
+	
+	delete[]RR2_;
+	RR2_=RR2_new;
+	delete[]RR2_sum_;
+	RR2_sum_=RR2_sum_new;
+	delete[]RR2_sum_elements_;
+	RR2_sum_elements_=RR2_sum_elements_new;
+
+
+//----------------------------
+
+	long int **smatr_new=NULL;
+
+	FSA_utils::get_memory_for_matrix(alphabet_letters_number2_new,alphabet_letters_number2_new,smatr_new);
+
+	long int smatr_min_new=smatr_[new2_numbering_to_the_old2[0]][new2_numbering_to_the_old2[0]];
+	for(c1=0;c1<alphabet_letters_number2_new;c1++)
+	{
+		for(c2=0;c2<alphabet_letters_number2_new;c2++)
+		{
+			smatr_new[c1][c2]=
+				smatr_[new2_numbering_to_the_old2[c1]][new2_numbering_to_the_old2[c2]];
+
+			smatr_min_new=FSA_utils::Tmin(smatr_min_new,
+				smatr_new[c1][c2]);
+
+		};
+	};
+
+	FSA_utils::delete_memory_for_matrix(number_of_AA_smatr_,smatr_);
+	smatr_=smatr_new;
+
+	char *alphabet1_new=new char[alphabet_letters_number1_new];
+	char *alphabet2_new=new char[alphabet_letters_number2_new];
+
+	for(c1=0;c1<alphabet_letters_number1_new;c1++)
+	{
+		alphabet1_new[c1]=alphabet1_[new1_numbering_to_the_old1[c1]];
+	};
+
+	for(c2=0;c2<alphabet_letters_number2_new;c2++)
+	{
+		alphabet2_new[c2]=alphabet2_[new2_numbering_to_the_old2[c2]];
+	};
+
+	delete[]alphabet1_;
+	alphabet1_=alphabet1_new;
+	delete[]alphabet2_;
+	alphabet2_=alphabet2_new;
+
+	//-----------------------------
+
+	
+	{
+		long int k;
+		long int*alphabet1_to_long_new=new long int [length_max];
+		FSA_utils::assert_mem(alphabet1_to_long_new);
+		long int*alphabet2_to_long_new=new long int [length_max];
+		FSA_utils::assert_mem(alphabet2_to_long_new);
+
+		for(k=0;k<length_max;k++)
+		{
+			alphabet1_to_long_new[k]=-1;
+			alphabet2_to_long_new[k]=-1;
+		};
+
+		for(k=0;k<alphabet_letters_number1_new;k++)
+		{
+			alphabet1_to_long_new[(size_t)alphabet1_[k]]=k;
+		};
+		for(k=0;k<alphabet_letters_number2_new;k++)
+		{
+			alphabet2_to_long_new[(size_t)alphabet2_[k]]=k;
+		};
+
+		delete[]alphabet1_to_long_;
+		alphabet1_to_long_=alphabet1_to_long_new;
+		delete[]alphabet2_to_long_;
+		alphabet2_to_long_=alphabet2_to_long_new;
+
+	};
+
+
+
+	//-----------------------------
+
+	long int number_of_codons_new=FSA_utils::power_long(alphabet_letters_number1_new,codon_length_);
+	long int *codon_AA_new = new long int[number_of_codons_new];//<codon code,AA number>
+
+	long int *codon=new long int [codon_length_];
+	FSA_utils::assert_mem(codon);
+
+	for(c1=0;c1<number_of_codons_new;c1++)
+	{
+		FSA_utils::convert_code_into_codon(
+		c1,//the input code
+		codon_length_,//codon length 
+		alphabet_letters_number1_new,//number of letters for the sequence 1
+		codon);//must be allocated
+
+		long int k;
+		for(k=0;k<codon_length_;k++)
+		{
+			codon[k]=new1_numbering_to_the_old1[codon[k]];
+		};
+
+		long int code_old=FSA_utils::convert_codon_into_code(
+		codon_length_,//codon length 
+		alphabet_letters_number1_,//number of letters for the sequence 1
+		codon);//input codon
+
+
+		codon_AA_new[c1]=old2_numbering_to_the_new2[codon_AA_[code_old]];
+	};
+
+	delete[]codon;
+
+	delete[]codon_AA_;
+	codon_AA_=codon_AA_new;
+
+
+	//-----------------------------
+	alphabet_letters_number1_=alphabet_letters_number1_new;
+	alphabet_letters_number2_=alphabet_letters_number2_new;
+	number_of_AA_smatr_=alphabet_letters_number2_new;
+	smatr_min_=smatr_min_new;
+	number_of_letters1_=alphabet_letters_number1_new;
+	number_of_letters2_=alphabet_letters_number2_new;
+
+}
+
+
+void FSA_utils::reverse_codons(
+long int *codon_AA_,//<codon code,AA number>; original codons
+long int alphabet_letters_number1_,//number of letters for the sequence #1
+long int codon_length_,//codon length 
+long int *&codon_AA_reversed_)//<codon code,AA number>; reversed codons
+{
+
+	long int number_of_codons=FSA_utils::power_long(alphabet_letters_number1_,codon_length_);
+
+	codon_AA_reversed_ = new long int[number_of_codons];//<codon code,AA number>
+	FSA_utils::assert_mem(codon_AA_reversed_);
+
+	long int *codon=new long int [codon_length_];
+	FSA_utils::assert_mem(codon);
+	long int *codon2=new long int [codon_length_];
+	FSA_utils::assert_mem(codon2);
+
+	long int c1;
+	for(c1=0;c1<number_of_codons;c1++)
+	{
+		FSA_utils::convert_code_into_codon(
+		c1,//the input code
+		codon_length_,//codon length 
+		alphabet_letters_number1_,//number of letters for the sequence 1
+		codon);//must be allocated
+
+		long int k;
+		for(k=0;k<codon_length_;k++)
+		{
+			codon2[k]=codon[codon_length_-1-k];
+		};
+
+		long int code_reversed=FSA_utils::convert_codon_into_code(
+		codon_length_,//codon length 
+		alphabet_letters_number1_,//number of letters for the sequence 1
+		codon2);//input codon
+
+
+		codon_AA_reversed_[code_reversed]=codon_AA_[c1];
+
+
+	};
+
+	delete[]codon;
+	delete[]codon2;
+
+}
+
+
+long int FSA_utils::convert_codon_into_code(
+long int codon_length_,//codon length 
+long int number_of_letters1_,//number of letters for the sequence 1
+long int *codon_)//input codon
+{
+	long int codon_code=codon_[0];
+	long int i;
+	for(i=1;i<codon_length_;i++)
+	{
+		codon_code=codon_code*number_of_letters1_+codon_[i];
+	};
+
+	return codon_code;
+
+}
+
+
+long int FSA_utils::convert_codon_into_AA(
+long int codon_length_,//codon length 
+long int *codon_AA_,//<codon code,AA number>
+long int number_of_letters1_,//number of letters for the sequence 1
+long int *codon_)
+{
+	long int codon_code=codon_[0];
+	long int i;
+	for(i=1;i<codon_length_;i++)
+	{
+		codon_code=codon_code*number_of_letters1_+codon_[i];
+	};
+
+	return codon_AA_[codon_code];
+
+}
+
+void FSA_utils::convert_code_into_codon(
+long int code_,//the input code
+long int codon_length_,//codon length 
+long int number_of_letters1_,//number of letters for the sequence 1
+long int *codon_)//must be allocated
+{
+	long int i;
+	for(i=codon_length_-1;i>=0;i--)
+	{
+		codon_[i]=code_%number_of_letters1_;
+		code_-=codon_[i];
+		code_/=number_of_letters1_;
+	};
+
+}
+
+void FSA_utils::read_codon_AA_file(
+string file_name_,
+long int &number_of_letters1_,//number of letters for the sequence 1
+long int &number_of_letters2_,//number of letters for the sequence 2
+char *&alphabet1_,//alphabet letters for the sequence #1
+char *&alphabet2_,//alphabet letters for the sequence #2
+
+long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+long int &codon_length_,//codon length 
+long int *&codon_AA_,//<codon code,AA number>
+bool reverse_codons_flag_)//if true, then the codons are reversed
+{
+	ifstream f;
+
+	alphabet1_=NULL;
+	alphabet2_=NULL;
+	alphabet1_to_long_=NULL;
+	alphabet2_to_long_=NULL;
+	codon_AA_=NULL;
+	try
+	{
+
+
+		if(file_name_=="")
+		{
+			number_of_letters1_=4;
+			alphabet1_=new char[4];
+			FSA_utils::assert_mem(alphabet1_);
+			alphabet1_[0]='A'; alphabet1_[1]='C'; alphabet1_[2]='G'; alphabet1_[3]='T'; 
+			number_of_letters2_=25;
+			alphabet2_=new char[25];
+			FSA_utils::assert_mem(alphabet2_);
+			alphabet2_[0]='A'; alphabet2_[1]='R'; alphabet2_[2]='N'; alphabet2_[3]='D'; alphabet2_[4]='C'; alphabet2_[5]='Q'; alphabet2_[6]='E'; alphabet2_[7]='G'; alphabet2_[8]='H'; alphabet2_[9]='I'; alphabet2_[10]='L'; alphabet2_[11]='K'; alphabet2_[12]='M'; alphabet2_[13]='F'; alphabet2_[14]='P'; alphabet2_[15]='S'; alphabet2_[16]='T'; alphabet2_[17]='W'; alphabet2_[18]='Y'; alphabet2_[19]='V'; alphabet2_[20]='B'; alphabet2_[21]='J'; alphabet2_[22]='Z'; alphabet2_[23]='X'; alphabet2_[24]='*'; 
+			alphabet1_to_long_=new long int [length_max];
+			FSA_utils::assert_mem(alphabet1_to_long_);
+			alphabet2_to_long_=new long int [length_max];
+			FSA_utils::assert_mem(alphabet2_to_long_);
+
+			long int k;
+			for(k=0;k<length_max;k++)
+			{
+				alphabet1_to_long_[k]=-1;
+				alphabet2_to_long_[k]=-1;
+			};
+
+			for(k=0;k<number_of_letters1_;k++)
+			{
+				alphabet1_to_long_[(size_t)alphabet1_[k]]=k;
+			};
+			for(k=0;k<number_of_letters2_;k++)
+			{
+				alphabet2_to_long_[(size_t)alphabet2_[k]]=k;
+			};
+
+
+			codon_length_=3;
+			codon_AA_=new long int [64];
+			FSA_utils::assert_mem(codon_AA_);
+			codon_AA_[63]=13; codon_AA_[61]=13; codon_AA_[60]=10; codon_AA_[62]=10; codon_AA_[31]=10; codon_AA_[29]=10; codon_AA_[28]=10; codon_AA_[30]=10; codon_AA_[15]=9; codon_AA_[13]=9; codon_AA_[12]=9; codon_AA_[14]=12; codon_AA_[47]=19; codon_AA_[45]=19; codon_AA_[44]=19; codon_AA_[46]=19; codon_AA_[55]=15; codon_AA_[53]=15; codon_AA_[52]=15; codon_AA_[54]=15; codon_AA_[23]=14; codon_AA_[21]=14; codon_AA_[20]=14; codon_AA_[22]=14; codon_AA_[7]=16; codon_AA_[5]=16; codon_AA_[4]=16; codon_AA_ [...]
+
+			return;
+		};
+
+		f.open(file_name_.data(),ios::in);
+		if(!f)
+		{
+			throw error("Error - the file "+file_name_+" is not found\n",3);
+		};
+
+		//reading alphabet #1
+		f>>number_of_letters1_;
+
+		if(number_of_letters1_<=0)
+		{
+			throw error("Error - the file "+file_name_+" is not correct: the number of letters must be positive\n",3);
+		};
+
+		alphabet1_=new char[number_of_letters1_];
+		FSA_utils::assert_mem(alphabet1_);
+
+		string line_tmp="";
+
+		f>>line_tmp;
+
+		if((long int)line_tmp.length()<number_of_letters1_)
+		{
+			throw error("Error - the file "+file_name_+" is not correct\n",3);
+		};
+
+		long int k;
+		for(k=0;k<(long int)line_tmp.length();k++)
+		{
+			if(!isalpha(line_tmp[k]))
+			{
+				throw error("Error - the file "+file_name_+" is not correct\n",3);
+			};
+			alphabet1_[k]=line_tmp[k];
+		};
+
+
+		//reading alphabet #2
+		f>>number_of_letters2_;
+
+		if(number_of_letters2_<=0)
+		{
+			throw error("Error - the file "+file_name_+" is not correct\n",3);
+		};
+
+		alphabet2_=new char[number_of_letters2_];
+		FSA_utils::assert_mem(alphabet2_);
+
+		line_tmp="";
+
+		f>>line_tmp;
+
+		if((long int)line_tmp.length()<number_of_letters2_)
+		{
+			throw error("Error - the file "+file_name_+" is not correct\n",3);
+		};
+
+		for(k=0;k<(long int)line_tmp.length();k++)
+		{
+			//if(!isalpha(line_tmp[k]))
+			if(!isalpha(line_tmp[k])&&line_tmp[k]!='*')
+			{
+				throw error("Error - the file "+file_name_+" is not correct\n",3);
+			};
+			alphabet2_[k]=line_tmp[k];
+		};
+
+
+		alphabet1_to_long_=new long int [length_max];
+		FSA_utils::assert_mem(alphabet1_to_long_);
+		alphabet2_to_long_=new long int [length_max];
+		FSA_utils::assert_mem(alphabet2_to_long_);
+
+		for(k=0;k<length_max;k++)
+		{
+			alphabet1_to_long_[k]=-1;
+			alphabet2_to_long_[k]=-1;
+		};
+
+		for(k=0;k<number_of_letters1_;k++)
+		{
+			alphabet1_to_long_[(size_t)alphabet1_[k]]=k;
+		};
+		for(k=0;k<number_of_letters2_;k++)
+		{
+			alphabet2_to_long_[(size_t)alphabet2_[k]]=k;
+		};
+
+		long int AA_length;
+		//f>>codon_length_>>AA_length;
+		codon_length_=3;
+		AA_length=1;
+		if(AA_length!=1||codon_length_<=0)
+		{
+			throw error("Error - the file "+file_name_+" is not correct\n",3);
+		};
+		//read the table
+		long int number_of_codons=1;
+		for(k=0;k<codon_length_;k++)
+		{
+			number_of_codons*=number_of_letters1_;
+		};
+
+		codon_AA_=new long int [number_of_codons];
+		FSA_utils::assert_mem(codon_AA_);
+
+		for(k=0;k<number_of_codons;k++)
+		{
+			string line_tmp_codon,line_tmp_AA;
+
+			f>>line_tmp_codon;
+			if(reverse_codons_flag_)
+			{
+				line_tmp_codon=string(line_tmp_codon.rbegin(),line_tmp_codon.rend()); 
+			};
+			f>>line_tmp_AA;
+
+			if((codon_length_!=(long int)line_tmp_codon.length())||(AA_length!=(long int)line_tmp_AA.length()))
+			{
+				throw error("Error - the file "+file_name_+" is not correct\n",3);
+			};
+
+			long int codon_code=alphabet1_to_long_[(size_t)line_tmp_codon[0]];
+			if(alphabet1_to_long_[(size_t)line_tmp_codon[0]]<0)
+			{
+				throw error("Error - the file "+file_name_+" is not correct\n",3);
+			};
+			long int i;
+			for(i=1;i<(long int)line_tmp_codon.length();i++)
+			{
+				if(alphabet1_to_long_[(size_t)line_tmp_codon[i]]<0)
+				{
+					throw error("Error - the file "+file_name_+" is not correct\n",3);
+				};
+				codon_code=codon_code*number_of_letters1_+alphabet1_to_long_[(size_t)line_tmp_codon[i]];
+			};
+
+			if(alphabet2_to_long_[(size_t)line_tmp_AA[0]]<0)
+			{
+				throw error("Error - the file "+file_name_+" is not correct\n",3);
+			};
+
+
+			codon_AA_[codon_code]=alphabet2_to_long_[(size_t)line_tmp_AA[0]];
+		};
+
+		
+
+
+		f.close();
+	}
+	catch (...)
+	{ 
+		delete[]alphabet1_;alphabet1_=NULL;
+		delete[]alphabet2_;alphabet2_=NULL;
+		delete[]alphabet1_to_long_;alphabet1_to_long_=NULL;
+		delete[]alphabet2_to_long_;alphabet2_to_long_=NULL;
+		delete[]codon_AA_;codon_AA_=NULL;
+		if(f.is_open())
+		{
+			f.close();
+		};
+		throw;
+	};
+
+
+}
+
+string FSA_utils::long_to_string(//convert interer ot string
+long int number_)
+{
+	string res_="";
+	string tmp_string;
+	if(number_>0)
+	{
+		tmp_string="";
+	}
+	else
+	{
+		if(number_==0)
+		{
+			tmp_string="";
+		}
+		else
+		{
+			tmp_string="-";
+		};
+	};
+	number_=labs(number_);
+
+	for( ; ; )
+	{
+		long int reminder=number_%10;
+		number_=(number_-reminder)/10;
+		res_=digit_to_string(reminder)+res_;
+		if (number_==0)
+		{
+			break;
+		};
+	};
+
+	return tmp_string+res_;
+}
+
+char FSA_utils::digit_to_string(//convert interer ot string
+long int digit_)
+{
+	switch(digit_)
+	{
+	case 0:return '0';
+	case 1:return '1';
+	case 2:return '2';
+	case 3:return '3';
+	case 4:return '4';
+	case 5:return '5';
+	case 6:return '6';
+	case 7:return '7';
+	case 8:return '8';
+	case 9:return '9';
+	default:return '?';
+	};
+}
+
+bool FSA_utils::the_value_is_double(
+string str_,
+double &val_)
+{
+	if(str_=="")
+	{
+		return false;
+	};
+
+	bool res=false;
+	errno=0;
+	char *p;
+	val_=strtod(str_.c_str(),&p);
+	if(errno!=0)
+	{
+		res=false;
+	}
+	else
+	{
+		res=(*p==0);
+	};
+	return res;
+}
+
+bool FSA_utils::the_value_is_long(
+string str_,
+long int &val_)
+{
+
+	if(str_.length()==0)
+	{
+		return false;
+	};
+	if(!(str_[0]=='+'||str_[0]=='-'||isdigit(str_[0])))
+	{
+		return false;
+	};
+
+	long int start_digit=0;
+
+	if(str_[0]=='+'||str_[0]=='-')
+	{
+		start_digit=1;
+	};
+
+
+	long int i;
+	for(i=start_digit;i<(long int)str_.size();i++)
+	{
+		if(!isdigit(str_[i]))
+		{
+			return false;
+		};
+	};
+
+	if(((long int)str_.size()-start_digit)<=0)
+	{
+		return false;
+	};
+
+	if(((long int)str_.size()-start_digit)>1)
+	{
+		while(str_[start_digit]=='0')
+		{
+			string::iterator it=str_.begin()+start_digit;
+
+
+			str_.erase(it);
+			if((long int)str_.size()<=start_digit+1)
+			{
+				break;
+			};
+		};
+	};
+
+	if(((long int)str_.size()-start_digit>10)||((long int)str_.size()-start_digit)<=0)
+	{
+		return false;
+	};
+
+
+	if((long int)str_.size()-start_digit==10)
+	{
+		if(!(str_[start_digit]=='1'||str_[start_digit]=='2'))
+		{
+			return false;
+		};
+
+		if(str_[start_digit]=='2')
+		{
+
+			long int val2;
+			string str2=str_.substr(start_digit+1,9);
+			int flag=sscanf(str2.c_str(),"%ld",&val2);
+			if(flag!=1)
+			{
+				return false;
+			};
+
+			bool positive=true;
+			if(start_digit>0)
+			{
+				if(str_[0]=='-')
+				{
+					positive=false;
+				};
+			};
+
+			if(positive)
+			{
+				if(val2>147483647)
+				{
+					return false;
+				};
+			}
+			else
+			{
+				if(val2>147483648)
+				{
+					return false;
+				};
+			};
+
+		};
+	};
+
+	int flag=sscanf(str_.c_str(),"%ld",&val_);
+	if(flag!=1)
+	{
+		return false;
+	};
+
+	return true;
+}
+
+double FSA_utils::sqrt_plus(
+double x_)
+{
+	if(x_>=0)
+	{
+		return sqrt(x_);
+	}
+	else
+	{
+		return 0;
+	};
+}
+
+double FSA_utils::error_of_the_sum(//v1_+v2_
+double v1_error_,
+double v2_error_)
+{
+	if(v1_error_>=1e100||v2_error_>=1e100)
+	{
+		return 1e100;
+	};
+
+	return sqrt(v1_error_*v1_error_+v2_error_*v2_error_);
+}
+
+double FSA_utils::error_of_the_product(//v1_*v2_
+double v1_,
+double v1_error_,
+double v2_,
+double v2_error_)
+{
+	if(v1_error_>=1e100||v2_error_>=1e100)
+	{
+		return 1e100;
+	};
+
+	double a1=(v1_+v1_error_)*(v2_+v2_error_);
+	double a2=(v1_-v1_error_)*(v2_+v2_error_);
+	double a3=(v1_+v1_error_)*(v2_-v2_error_);
+	double a4=(v1_-v1_error_)*(v2_-v2_error_);
+
+	double a=v1_*v2_;
+
+	return FSA_utils::Tmax(fabs(a1-a),fabs(a2-a),fabs(a3-a),fabs(a4-a));
+
+}
+
+double FSA_utils::error_of_the_lg(//lg(v1_)
+double v1_,
+double v1_error_)
+{
+	if(v1_error_>=1e100||v1_<=0)
+	{
+		return 1e100;
+	};
+
+	return FSA_utils::Tmin(fabs(log(v1_)/log(10.0)),v1_error_/v1_/log(10.0));
+}
+
+double FSA_utils::error_of_the_sqrt(//sqrt(v1_)
+double v1_,
+double v1_error_)
+{
+	if(v1_error_>=1e100||v1_<0)
+	{
+		return 1e100;
+	};
+
+	double s=sqrt(v1_);
+	double s1=sqrt(FSA_utils::Tmax(0.0,v1_-v1_error_));
+	double s2=sqrt(FSA_utils::Tmax(0.0,v1_+v1_error_));
+
+	return FSA_utils::Tmax(fabs(s-s1),fabs(s-s2));
+}
+
+double FSA_utils::error_of_the_ratio(//v1_/v2_
+double v1_,
+double v1_error_,
+double v2_,
+double v2_error_)
+{
+	if(v1_error_>=1e100||v2_error_>=1e100)
+	{
+		return 1e100;
+	};
+
+
+	if(v2_==0)
+	{
+		return 1e100;
+	};
+
+	if(v1_==0&&v1_error_==0)
+	{
+		return 0.0;
+	};
+
+	double a=v1_/v2_;
+
+
+	if(((v2_+v2_error_)*v2_<=0))
+	{
+		double a3=(v1_+v1_error_)/(v2_-v2_error_);
+		double a4=(v1_-v1_error_)/(v2_-v2_error_);
+		return FSA_utils::Tmax(fabs(a-a3),fabs(a-a4));
+	};
+
+	if(((v2_-v2_error_)*v2_<=0))
+	{
+		double a1=(v1_+v1_error_)/(v2_+v2_error_);
+		double a2=(v1_-v1_error_)/(v2_+v2_error_);
+		return FSA_utils::Tmax(fabs(a-a1),fabs(a-a2));
+	};
+
+
+	double a1=(v1_+v1_error_)/(v2_+v2_error_);
+	double a2=(v1_-v1_error_)/(v2_+v2_error_);
+	double a3=(v1_+v1_error_)/(v2_-v2_error_);
+	double a4=(v1_-v1_error_)/(v2_-v2_error_);
+
+	return FSA_utils::Tmax(fabs(a-a1),fabs(a-a2),fabs(a-a3),fabs(a-a4));
+}
+
+double FSA_utils::error_of_the_sum_with_coeff(//c1_*v1_+c2_*v2_
+double c1_,
+double v1_error_,
+double c2_,
+double v2_error_)
+{
+	if(v1_error_>=1e100||v2_error_>=1e100)
+	{
+		return 1e100;
+	};
+
+	return sqrt(c1_*c1_*v1_error_*v1_error_+c2_*c2_*v2_error_*v2_error_);
+}
+
+
+void FSA_utils::read_alphabet(
+string alphabet_file_name_,
+long int &number_of_AA_alphabet_,
+char* &alphabet_)
+{
+	ifstream a(alphabet_file_name_.data());
+	if(!a)
+	{
+		throw error("Error - the file "+alphabet_file_name_+" is not found\n",1);
+	};
+
+	a>>number_of_AA_alphabet_;
+	if(number_of_AA_alphabet_<=0)
+	{
+		throw error("Error - the file "+alphabet_file_name_+" is wrong\n",1);
+	};
+	alphabet_=new char[number_of_AA_alphabet_];
+	FSA_utils::assert_mem(alphabet_);
+
+	long int i;
+	for(i=0;i<number_of_AA_alphabet_;i++)
+	{
+		if(a.eof())
+		{
+			throw error("Error - the file "+alphabet_file_name_+" is wrong\n",1);
+		};
+		a>>alphabet_[i];
+	};
+
+	a.close();
+
+}
+
+void FSA_utils::calculate_composition_frequencies(
+double number_of_AA_alphabet_,
+char* alphabet_,
+string fasta_file_name_,
+double *comp_frequencies_)
+{
+
+	long int max_c=1000;
+	long int *letter_to_int=new long int[max_c];
+	FSA_utils::assert_mem(letter_to_int);
+
+	long int i;
+	for(i=0;i<max_c;i++)
+	{
+		letter_to_int[i]=-1;
+	};
+
+	for(i=0;i<number_of_AA_alphabet_;i++)
+	{
+		letter_to_int[(size_t)alphabet_[i]]=i;
+		comp_frequencies_[i]=0;
+	};
+
+	ifstream f(fasta_file_name_.data());
+	if(!f)
+	{
+		throw error("Error - the file "+fasta_file_name_+" is not found\n",1);
+	};
+
+
+
+
+	
+	string header;
+
+	if(f.eof())
+	{
+		throw error("Error - the file "+fasta_file_name_+" is incorrect\n",1);
+	};
+
+	getline(f,header);
+
+	if(header.size()==0)
+	{
+		throw error("Error - the file "+fasta_file_name_+" is incorrect\n",1);
+	};
+
+
+	if(header[0]!='>')
+	{
+		throw error("Error - the file "+fasta_file_name_+" is incorrect\n",1);
+	};
+	
+
+	string st;
+	if(f.eof())
+	{
+		throw error("Error - the file "+fasta_file_name_+" is incorrect\n",1);
+	};
+
+	getline(f,st);
+	if(st.size()==0)
+	{
+		throw error("Error - the file "+fasta_file_name_+" is incorrect\n",1);
+	};
+	for( ; ; )
+	{
+		long int j;
+		for(j=0;j<(long int)st.size();j++)
+		{
+			long int letter_ind=letter_to_int[(size_t)st[j]];
+			if(letter_ind<0||letter_ind>=number_of_AA_alphabet_)
+			{
+				continue;
+			};
+			comp_frequencies_[letter_ind]++;
+		};
+
+		if(f.eof())
+		{
+			break;
+		};
+
+		getline(f,st);
+		if(st.size()==0)
+		{
+			break;
+		};
+	};
+
+	f.close();	
+
+	double sum=0;
+	for(i=0;i<number_of_AA_alphabet_;i++)
+	{
+		sum+=comp_frequencies_[i];
+	};
+	cout<<"Total number of allowed letters = "<<sum<<endl;
+
+	if(sum>0)
+	{
+		for(i=0;i<number_of_AA_alphabet_;i++)
+		{
+			comp_frequencies_[i]/=sum;
+		};
+	}
+	else
+	{
+		throw error("Error - the file "+fasta_file_name_+" does not have letters from the allowed alphabet\n",1);
+	};
+
+	delete[]letter_to_int;
+}
+
+void FSA_utils::reverse_sequence(//reverse the letters of the sequence
+long int *seq_,
+long int seq_length_)
+{
+	long int i;
+	for(i=0;i<=(long int)floor((double)seq_length_/2.0)-1;i++)
+	{
+		long int reverse_ind=seq_length_-i-1;
+		long int tmp=seq_[i];
+		seq_[i]=seq_[reverse_ind];
+		seq_[reverse_ind]=tmp;
+	};
+}
+
+void FSA_utils::extract_AA_frequencies_for_DNA_sequence(
+const long int *codon_AA_,//<codon code,AA number>
+long int &codon_length_,//codon length 
+long int number_of_letters1_,//number of letters for the sequence 1
+long int number_of_letters2_,//number of letters for the sequence 2
+const double *RR1_,//nucleotide probabilities
+double *&RR1_AA_)//the resulted frequencies
+{
+	long int *codon_tmp=new long int [codon_length_];
+	FSA_utils::assert_mem(codon_tmp);
+
+	RR1_AA_=new double[number_of_letters2_];
+	FSA_utils::assert_mem(RR1_AA_);
+
+	long int k;
+	for(k=0;k<number_of_letters2_;k++)
+	{
+		RR1_AA_[k]=0.0;
+	};
+
+	long int number_of_codons=FSA_utils::power_long(number_of_letters1_,codon_length_);
+	for(k=0;k<number_of_codons;k++)
+	{
+		convert_code_into_codon(
+		k,//the input code
+		codon_length_,//codon length 
+		number_of_letters1_,//number of letters for the sequence 1
+		codon_tmp);//must be allocated
+
+		long int AA1=codon_AA_[k];
+		if(AA1<0||AA1>=number_of_letters2_)
+		{
+			throw error("Unexpected errro in FSA_utils::extract_AA_frequencies_for_DNA_sequence\n",1);
+		};
+
+		double prob_tmp=1.0;
+		long int i;
+		for(i=0;i<codon_length_;i++)
+		{
+			prob_tmp*=RR1_[codon_tmp[i]];
+		};
+
+		RR1_AA_[AA1]+=prob_tmp;
+
+	};
+
+	delete[]codon_tmp;
+}
+
+
+long int FSA_utils::power_long(//returns a_^b_
+long int a_,
+long int b_)
+{
+	if(b_<0)
+	{
+		throw error("Error - unexpected parameter b_<0 in the function FSA_utils::power_long\n",1);
+	};
+
+	long int res=1;
+	long int i;
+	for(i=1;i<=b_;i++)
+	{
+		res*=a_;
+	};
+
+	return res;
+
+}
+
+void FSA_utils::convert_distr_into_sum(//convert distr_[0], distr_[1], distr_[2],... into distr_[0], distr_[0]+distr_[1], distr_[0]+distr_[1]+distr_[2],...
+long int dim_,
+double *distr_)
+{
+	long int i;
+	for(i=1;i<dim_;i++)
+	{
+		distr_[i]=distr_[i]+distr_[i-1];
+	};
+}
+
+bool FSA_utils::Gauss(
+std::vector<std::vector<double> > A_,//matrix n*(n+1)
+std::vector<double> &x_,//solution
+double inside_eps_,
+std::vector<std::vector<double> > *inv_A_)
+{
+	
+
+	long int i,j,jj;
+	long int matr_size=(long int)A_.size();
+	if(matr_size==0)
+	{
+		//throw error("Error in FSA_utils::Gauss - sizes of matrix are wrong\n",1);
+		return false;
+	};
+
+	std::vector<std::vector<double> > E;
+
+	if(inv_A_)
+	{
+		vector<double> zero(matr_size,0);
+		(*inv_A_).resize(matr_size, zero);
+		
+		E.resize(matr_size, zero);
+		long int i;
+		for(i=0;i<matr_size;i++)
+		{
+			E[i][i]=1.0;
+		};
+	};
+
+
+	for(i=0;i<matr_size;i++)
+	{
+		if((long int)A_[i].size()!=matr_size+1)
+		{
+			throw error("Error in FSA_utils::Gauss - sizes of matrix are wrong\n",1);
+		};
+	};
+	x_.clear();
+	x_.resize(matr_size);
+	//forward trace
+	for(j=0;j<matr_size;j++)
+	{
+		long int absmax=j;
+		for(i=j+1;i<matr_size;i++)
+		{
+			if(fabs(A_[absmax][j])<fabs(A_[i][j]))
+			{
+				absmax=i;
+			};
+		};
+
+		if(j!=absmax)
+		{
+			for(jj=j;jj<matr_size+1;jj++)
+			{
+				double tmp=A_[absmax][jj];
+				A_[absmax][jj]=A_[j][jj];
+				A_[j][jj]=tmp;
+			};
+
+			if(inv_A_)
+			{
+				for(jj=0;jj<matr_size;jj++)
+				{
+					double tmp=E[absmax][jj];
+					E[absmax][jj]=E[j][jj];
+					E[j][jj]=tmp;
+				};
+			};
+		};
+
+		if(fabs(A_[j][j])<=inside_eps_)
+		{
+			throw error("Error in FSA_utils::Gauss - matrix is singular\n",1);
+		};
+
+		for(i=j+1;i<matr_size;i++)
+		{
+			double tmp=A_[i][j]/A_[j][j];
+			for(jj=j+1;jj<matr_size+1;jj++)
+			{
+				A_[i][jj]=A_[i][jj]-tmp*A_[j][jj];
+			};
+
+			if(inv_A_)
+			{
+				for(jj=0;jj<matr_size;jj++)
+				{
+					E[i][jj]=E[i][jj]-tmp*E[j][jj];
+				};
+			};
+		};
+	};
+
+	//reverse trace
+	x_[matr_size-1]=A_[matr_size-1][matr_size]/A_[matr_size-1][matr_size-1];
+	for(i=matr_size-2;i>=0;i--)
+	{
+		x_[i]=A_[i][matr_size];
+		for(j=i+1;j<matr_size;j++)
+		{
+			x_[i]-=A_[i][j]*x_[j];
+		};
+		x_[i]/=A_[i][i];
+	};
+
+	if(inv_A_)
+	{
+		long int k;
+		for(k=0;k<matr_size;k++)
+		{
+			(*inv_A_)[matr_size-1][k]=E[matr_size-1][k]/A_[matr_size-1][matr_size-1];
+			long int i;
+			for(i=matr_size-2;i>=0;i--)
+			{
+				(*inv_A_)[i][k]=E[i][k];
+				long int j;
+				for(j=i+1;j<matr_size;j++)
+				{
+					(*inv_A_)[i][k]-=A_[i][j]*(*inv_A_)[j][k];
+				};
+				(*inv_A_)[i][k]/=A_[i][i];
+			};
+		};
+
+	};
+
+	return true;
+}
+
+void FSA_utils::multiply_matrices(
+const std::vector<std::vector<double> > &A_,
+const std::vector<std::vector<double> > &B_,
+std::vector<std::vector<double> > &res_)
+{
+	long int size1=(long int)A_.size();
+	if(size1==0)
+	{
+		throw error("Error in FSA_utils::multiply_matrices\n",1);
+	};
+	long int size2=(long int)A_[0].size();
+	if(size2==0)
+	{
+		throw error("Error in FSA_utils::multiply_matrices\n",1);
+	};
+
+	long int i,j,k;
+	for(i=1;i<size1;i++)
+	{
+		if((long int)A_[i].size()!=size2)
+		{
+			throw error("Error in FSA_utils::multiply_matrices\n",1);
+		};
+	};
+
+	if(size2!=(long int)B_.size())
+	{
+		throw error("Error in FSA_utils::multiply_matrices\n",1);
+	};
+
+	long int size3=(long int)B_[0].size();
+	if(size3==0)
+	{
+		throw error("Error in FSA_utils::multiply_matrices\n",1);
+	};
+
+	for(i=1;i<size2;i++)
+	{
+		if((long int)B_[i].size()!=size3)
+		{
+			throw error("Error in FSA_utils::multiply_matrices\n",1);
+		};
+	};
+
+	res_.clear();
+	res_.resize(size1);
+	for(i=0;i<size1;i++)
+	{
+		res_[i].resize(size3,0);
+	};
+
+	for(i=0;i<size1;i++)
+	{
+		for(j=0;j<size3;j++)
+		{
+			for(k=0;k<size2;k++)
+			{
+				res_[i][j]+=A_[i][k]*B_[k][j];
+			};
+		};
+	};
+}
+
+void FSA_utils::multiply_matrix_and_vector(
+const std::vector<std::vector<double> > &A_,
+const std::vector<double> &y_,
+std::vector<double> &res_)
+{
+	long int size1=(long int)A_.size();
+	if(size1==0)
+	{
+		throw error("Error in FSA_utils::multiply_matrix_and_vector\n",1);
+	};
+	long int size2=(long int)A_[0].size();
+	if(size2==0)
+	{
+		throw error("Error in FSA_utils::multiply_matrix_and_vector\n",1);
+	};
+
+	long int i,k;
+	for(i=1;i<size1;i++)
+	{
+		if((long int)A_[i].size()!=size2)
+		{
+			throw error("Error in FSA_utils::multiply_matrix_and_vector\n",1);
+		};
+	};
+
+	if(size2!=(long int)y_.size())
+	{
+		throw error("Error in FSA_utils::multiply_matrix_and_vector\n",1);
+	};
+
+
+	res_.clear();
+	res_.resize(size1,0);
+
+	for(i=0;i<size1;i++)
+	{
+		for(k=0;k<size2;k++)
+		{
+			res_[i]+=A_[i][k]*y_[k];
+		};
+	};
+}
+
+void FSA_utils::transpose_matrix(
+const std::vector<std::vector<double> > &A_,
+std::vector<std::vector<double> > &res_)
+{
+	long int size1=(long int)A_.size();
+	if(size1==0)
+	{
+		res_.clear();
+		return;
+	};
+	long int size2=(long int)A_[0].size();
+
+	long int i,j;
+	for(i=1;i<size1;i++)
+	{
+		if((long int)A_[i].size()!=size2)
+		{
+			throw error("Error in FSA_utils::transpose_matrix\n",1);
+		};
+	};
+
+	res_.clear();
+	res_.resize(size2);
+	for(i=0;i<size2;i++)
+	{
+		res_[i].resize(size1);
+	};
+
+	for(i=0;i<size2;i++)
+	{
+		for(j=0;j<size1;j++)
+		{
+			res_[i][j]=A_[j][i];
+		};
+	};
+}
+
+void FSA_utils::print_matrix(
+const std::vector<std::vector<double> > A_)
+{
+	long int i,j;
+	for(i=0;i<(long int)A_.size();i++)
+	{
+		for(j=0;j<(long int)A_[i].size();j++)
+		{
+			if(j<(long int)A_[i].size()-1)
+			{
+				cout<<A_[i][j]<<"\t";
+			}
+			else
+			{
+				cout<<A_[i][j]<<"\n";
+			};
+		};
+	};
+}
+
+void FSA_utils::process_random_factor(
+long int &random_factor_,
+bool *rand_flag_)
+{
+	if(rand_flag_)
+	{
+		*rand_flag_=true;
+	};
+
+	if(random_factor_<0)
+	{
+		random_factor_=(long int)time(NULL);
+		#ifndef _MSC_VER //UNIX program
+			struct timeval tv;
+			struct timezone tz;
+			gettimeofday(&tv, &tz);
+			random_factor_+=tv.tv_usec*10000000;
+		#else
+			struct _timeb timebuffer;
+			char *timeline;
+			_ftime( &timebuffer );
+			timeline = ctime( & ( timebuffer.time ) );
+			random_factor_+=timebuffer.millitm*10000000;
+		#endif
+
+		random_factor_=abs(random_factor_);
+
+		if(rand_flag_)
+		{
+			*rand_flag_=false;
+		};
+
+	};
+}
+
+double FSA_utils::standard_deviation(//standard deviation for average of elements of vect_
+long int dim_,
+double *vect_)
+{
+	if(dim_<1)
+	{
+		throw error("Unexpected error in FSA_utils::standard_deviation\n",1);
+	};
+
+	if(dim_==1)
+	{
+		return 0;
+	};
+
+	double E=0;
+	long int i;
+	for(i=0;i<dim_;i++)
+	{
+		E+=vect_[i];
+	};
+	E/=(double)dim_;
+
+	double E2=0;
+	for(i=0;i<dim_;i++)
+	{
+		E2+=(vect_[i]-E)*(vect_[i]-E);
+	};
+
+	E2=sqrt(E2/(double)((dim_-1)*dim_));
+
+	return E2;
+
+}
+
+double FSA_utils::average(//average of elements of vect_
+long int dim_,
+double *vect_)
+{
+	if(dim_<1)
+	{
+		throw error("Unexpected error in FSA_utils::average\n",1);
+	};
+
+	double E=0;
+	long int i;
+	for(i=0;i<dim_;i++)
+	{
+		E+=vect_[i];
+	};
+	E/=(double)dim_;
+
+	return E;
+
+}
+
+void FSA_utils::read_string(
+ifstream &f_,
+string &st_,
+bool &end_of_file_flag_)
+{
+	if(f_.eof())
+	{
+		end_of_file_flag_=true;
+		return;
+	};
+
+	st_="";
+	end_of_file_flag_=false;
+	while(!end_of_file_flag_)
+	{
+		getline(f_,st_);
+
+		if(st_.size()>0)
+		{
+			bool flag=true;
+			long int i;
+			for(i=0;i<(long int)st_.size();i++)
+			{
+				if(!(st_[i]==' '||(long int)st_[i]==13))
+				{
+					flag=false;
+					break;
+				};
+			};
+			if(flag)
+			{
+				continue;
+			};
+		};
+
+		if(st_.size()>0)
+		{
+			if((long int)st_[st_.size()-1]==13)
+			{
+				st_.resize(st_.size()-1);
+			};
+			break;
+		};
+		if(f_.eof())
+		{
+			end_of_file_flag_=true;
+		};
+	};
+}
+
+void FSA_utils::read_sequences_for_alingment(
+
+string input_file_name_,
+
+long int &number_of_letters1_,//number of letters for the sequence 1
+long int &number_of_letters2_,//number of letters for the sequence 2
+
+char *&alphabet1_,//alphabet letters for the sequence #1
+char *&alphabet2_,//alphabet letters for the sequence #2
+
+long int& number_of_sequences_,
+
+string *&headers_,
+long int *&lengths1_,//lengths of the sequences #1
+long int *&lengths2_,//lengths of the sequences #2
+long int **&sequences1_,//the first index numerates sequences; the second - sequence letters
+long int **&sequences2_)
+{
+
+	long int max_c=1000;
+	long int *letter_to_int1=new long int[max_c];
+	long int *letter_to_int2=new long int[max_c];
+
+	long int i;
+	for(i=0;i<max_c;i++)
+	{
+		letter_to_int1[i]=-1;
+		letter_to_int2[i]=-1;
+	};
+
+	for(i=0;i<number_of_letters1_;i++)
+	{
+		letter_to_int1[(size_t)alphabet1_[i]]=i;
+	};
+	for(i=0;i<number_of_letters2_;i++)
+	{
+		letter_to_int2[(size_t)alphabet2_[i]]=i;
+	};
+
+	long int k;
+	ifstream f(input_file_name_.data());
+	if(!f)
+	{
+		throw error("Error - the input file "+input_file_name_+" is not found\n",1);
+	};
+
+	
+
+	long int count=0;
+
+	vector<long int *> sequences1_vect;
+	vector<long int *> sequences2_vect;
+	vector<long int > lengths1_vect;
+	vector<long int > lengths2_vect;
+	vector<string> headers_vect;
+
+	for( ; ; )
+	{
+
+		bool end_of_file_flag;
+		string header;
+
+		read_string(
+		f,
+		header,
+		end_of_file_flag);
+
+		
+		if(end_of_file_flag)
+		{
+			if(header!="")
+			{
+				throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
+			};
+
+			if(count==0)
+			{
+				throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
+			};
+			break;
+		};
+
+
+		if(header[0]!='>')
+		{
+			throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
+		};
+		
+
+		string st1="";
+		string st2="";
+		if(f.eof())
+		{
+			throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
+		};
+
+		read_string(
+		f,
+		st1,
+		end_of_file_flag);
+
+		if(st1.size()==0||end_of_file_flag)
+		{
+			throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
+		};
+
+		read_string(
+		f,
+		st2,
+		end_of_file_flag);
+
+		if(st2.size()==0||end_of_file_flag)
+		{
+			throw error("Error - the file "+input_file_name_+" is incorrect\n",1);
+		};
+		count++;
+
+		//checking the sequences
+		long int *sequences1_tmp=new long int [st1.size()];
+		FSA_utils::assert_mem(sequences1_tmp);
+		long int *sequences2_tmp=new long int [st2.size()];
+		FSA_utils::assert_mem(sequences2_tmp);
+
+		headers_vect.push_back(header);
+		sequences1_vect.push_back(sequences1_tmp);
+		sequences2_vect.push_back(sequences2_tmp);
+		lengths1_vect.push_back((long int)st1.size());
+		lengths2_vect.push_back((long int)st2.size());
+
+		for(k=0;k<(long int)st1.size();k++)
+		{
+
+			long int long_tmp=letter_to_int1[(size_t)st1[k]];
+			if(long_tmp>=0)
+			{
+				sequences1_tmp[k]=long_tmp;
+			}
+			else
+			{
+				throw error("Error - the file "+input_file_name_+" is incorrect: a non-alphabet letter with the code "+FSA_utils::long_to_string((long int)st1[k])+"\n",1);
+			};
+		};
+		for(k=0;k<(long int)st2.size();k++)
+		{
+
+			long int long_tmp=letter_to_int2[(size_t)st2[k]];
+			if(long_tmp>=0)
+			{
+				sequences2_tmp[k]=long_tmp;
+			}
+			else
+			{
+				throw error("Error - the file "+input_file_name_+" is incorrect: a non-alphabet letter with the code "+FSA_utils::long_to_string((long int)st2[k])+"\n",1);
+			};
+		};
+
+	};
+
+	f.close();
+
+	delete[]letter_to_int1;
+	delete[]letter_to_int2;
+
+	//allocate memory for the arrays
+	number_of_sequences_=count;
+	sequences1_=new long int*[number_of_sequences_];
+	FSA_utils::assert_mem(sequences1_);
+	sequences2_=new long int*[number_of_sequences_];
+	FSA_utils::assert_mem(sequences2_);
+	
+	lengths1_=new long int[number_of_sequences_];
+	FSA_utils::assert_mem(lengths1_);
+	lengths2_=new long int[number_of_sequences_];
+	FSA_utils::assert_mem(lengths2_);
+	headers_=new string[number_of_sequences_];
+	FSA_utils::assert_mem(headers_);
+
+	for(k=0;k<number_of_sequences_;k++)
+	{
+		headers_[k]=headers_vect[k];
+		lengths1_[k]=lengths1_vect[k];
+		lengths2_[k]=lengths2_vect[k];
+		sequences1_[k]=sequences1_vect[k];
+		sequences2_[k]=sequences2_vect[k];
+	};
+
+}
+
diff --git a/src/alp/sls_fsa1_utils.hpp b/src/alp/sls_fsa1_utils.hpp
index 637f32f..e991047 100644
--- a/src/alp/sls_fsa1_utils.hpp
+++ b/src/alp/sls_fsa1_utils.hpp
@@ -1,1137 +1,1137 @@
-#ifndef GUMBEL_FSA1_UTILS
-#define GUMBEL_FSA1_UTILS
-
-/* $Id: $
-* ===========================================================================
-*
-*							PUBLIC DOMAIN NOTICE
-*			   National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_fsa1_utils.hpp
-
-Author: Sergey Sheetlin, Martin Frith
-
-Contents: Frameshift alignment algorithms utilities
-
-******************************************************************************/
-#include "sls_basic.hpp"
-
-#include <vector>
-#include <complex>
-#include <iostream>
-#include <map>
-#include <vector>
-#include <fstream>
-#include <float.h> 
-#include <algorithm>
-#include <sstream>
-#include <ctime>
-#include <limits>
-#include <climits>
-#include <errno.h>
-
-#ifndef _MSC_VER //UNIX program
-#include <sys/time.h>
-#else
-#include <sys/timeb.h>
-#endif
-
-#include "njn_random.hpp"
-#include "njn_uniform.hpp"
-
-namespace Sls 
-{
-
-	class FSA_utils: public sls_basic//contains general functions
-	{
-		public:
-
-		static void read_RR(
-		std::string RR_file_name_,
-		double *&RR_,
-		double *&RR_sum_,
-		long int *&RR_sum_elements_,
-		long int &number_of_AA_RR_,
-		long int number_of_AA_RR_default_=0);
-
-		static void check_RR_sum(
-		double sum_tmp_,
-		long int number_of_AA_RR_,
-		std::string RR_file_name_);
-
-		static void calculate_RR_sum(
-		double *RR_,
-		long int number_of_AA_RR_,
-		double *&RR_sum_,
-		long int *&RR_sum_elements_);
-
-		static void read_RR(
-		std::string RR_file_name_,
-		double *&RR_,
-		long int &number_of_AA_RR_,
-		long int number_of_AA_RR_default_=0);
-
-		static void read_smatr(
-		std::string smatr_file_name_,
-		long int **&smatr_,
-		long int &number_of_AA_smatr_,
-		long int &smatr_min_);
-
-		static void smatr_min(
-		long int **smatr_,
-		long int number_of_AA_smatr_,
-		long int &smatr_min_);
-
-		static void remove_zero_probabilities(
-		double *&RR1_,
-		double *&RR1_sum_,
-		long int *&RR1_sum_elements_,
-		long int &alphabet_letters_number1_,
-		double *&RR2_,
-		double *&RR2_sum_,
-		long int *&RR2_sum_elements_,
-		long int &alphabet_letters_number2_,
-		long int **&smatr_,
-		long int &number_of_AA_smatr_,
-		long int &smatr_min_,
-
-		long int &number_of_letters1_,//number of letters for the sequence 1
-		long int &number_of_letters2_,//number of letters for the sequence 2
-
-		char *&alphabet1_,//alphabet letters for the sequence #1
-		char *&alphabet2_,//alphabet letters for the sequence #2
-
-		long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-		long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-		long int &codon_length_,//codon length 
-		long int *&codon_AA_);//<codon code,AA number>
-
-
-
-
-
-		static std::string long_to_string(//convert interer ot std::string
-		long int number_);
-
-		static char digit_to_string(//convert interer ot std::string
-		long int digit_);
-		
-
-		static bool the_value_is_double(
-		std::string str_,
-		double &val_);
-
-		static bool the_value_is_long(
-		std::string str_,
-		long int &val_);
-
-		static double sqrt_plus(
-		double x_);
-
-		static double error_of_the_sum(//v1_+v2_
-		double v1_error_,
-		double v2_error_);
-
-		static double error_of_the_product(//v1_*v2_
-		double v1_,
-		double v1_error_,
-		double v2_,
-		double v2_error_);
-
-		static double error_of_the_lg(//lg(v1_)
-		double v1_,
-		double v1_error_);
-
-		static double error_of_the_sqrt(//sqrt(v1_)
-		double v1_,
-		double v1_error_);
-
-		static double error_of_the_ratio(//v1_/v2_
-		double v1_,
-		double v1_error_,
-		double v2_,
-		double v2_error_);
-
-		static double error_of_the_sum_with_coeff(//c1_*v1_+c2_*v2_
-		double c1_,
-		double v1_error_,
-		double c2_,
-		double v2_error_);
-
-
-
-		static void read_alphabet(
-		std::string alphabet_file_name_,
-		long int &number_of_AA_alphabet_,
-		char* &alphabet_);
-
-		static void calculate_composition_frequencies(
-		double number_of_AA_alphabet_,
-		char* alphabet_,
-		std::string fasta_file_name_,
-		double *comp_frequencies_);
-
-		static long int convert_codon_into_AA(
-		long int codon_length_,//codon length 
-		long int *codon_AA_,//<codon code,AA number>
-		long int number_of_letters1_,//number of letters for the sequence 1
-		long int *codon_);
-
-		static long int convert_codon_into_code(
-		long int codon_length_,//codon length 
-		long int number_of_letters1_,//number of letters for the sequence 1
-		long int *codon_);//input codon
-
-
-		static void convert_code_into_codon(
-		long int code_,//the input code
-		long int codon_length_,//codon length 
-		long int number_of_letters1_,//number of letters for the sequence 1
-		long int *codon_);//must be allocated
-
-
-		static void read_codon_AA_file(
-		std::string file_name_,
-		long int &number_of_letters1_,//number of letters for the sequence 1
-		long int &number_of_letters2_,//number of letters for the sequence 2
-
-		char *&alphabet1_,//alphabet letters for the sequence #1
-		char *&alphabet2_,//alphabet letters for the sequence #2
-
-		long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
-		long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
-
-		long int &codon_length_,//codon length 
-		long int *&codon_AA_,//<codon code,AA number>
-		bool reverse_codons_flag_=false);//if true, then the codons are reversed
-
-		static void reverse_codons(
-		long int *codon_AA_,//<codon code,AA number>; original codons
-		long int alphabet_letters_number1_,//number of letters for the sequence #1
-		long int codon_length_,//codon length 
-		long int *&codon_AA_reversed_);//<codon code,AA number>; reversed codons
-
-
-		static void reverse_sequence(//reverse the letters of the sequence
-			long int *seq_,
-			long int seq_length_);
-
-		static void extract_AA_frequencies_for_DNA_sequence(
-			const long int *codon_AA_,//<codon code,AA number>
-			long int &codon_length_,//codon length 
-			long int number_of_letters1_,//number of letters for the sequence 1
-			long int number_of_letters2_,//number of letters for the sequence 2
-			const double *RR1_,//nucleotide probabilities
-			double *&RR1_AA_);//the resulted frequencies
-
-		static void read_sequences_for_alingment(
-
-			std::string input_file_name_,
-
-			long int &number_of_letters1_,//number of letters for the sequence 1
-			long int &number_of_letters2_,//number of letters for the sequence 2
-
-			char *&alphabet1_,//alphabet letters for the sequence #1
-			char *&alphabet2_,//alphabet letters for the sequence #2
-
-			long int& number_of_sequences_,
-
-			std::string *&headers_,
-			long int *&lengths1_,//lengths of the sequences #1
-			long int *&lengths2_,//lengths of the sequences #2
-			long int **&sequences1_,//the first index numerates sequences; the second - sequence letters
-			long int **&sequences2_);
-
-		static void read_string(
-			std::ifstream &f_,
-			std::string &st_,
-			bool &end_of_file_flag_);
-
-
-
-		inline static double ran2()//generates the next random value
-		{
-			return Njn::Uniform::variate <double> (0,1);
-			//double rand_C=(double)((double)rand()/(double)RAND_MAX);
-			//return rand_C;	
-		}
-
-		inline static void srand2(long int seed_)//initializes the seed
-		{
-			Njn::Random::seed(seed_);
-			//srand(seed_);
-		}
-
-		static void srand2_old(long int seed_);//initializes the seed
-
-		static double ran2_old();//generates the next random value
-
-		static void process_random_factor(
-			long int &random_factor_,
-			bool *rand_flag_=NULL);
-
-
-		static long int power_long(//returns a_^b_
-			long int a_,
-			long int b_);
-
-		static void convert_distr_into_sum(//convert distr_[0], distr_[1], distr_[2],... into distr_[0], distr_[0]+distr_[1], distr_[0]+distr_[1]+distr_[2],...
-			long int dim_,
-			double *distr_);
-
-		static bool Gauss(
-			std::vector<std::vector<double> > A_,//matrix n*(n+1)
-			std::vector<double> &x_,//solution
-			double inside_eps_,
-			std::vector<std::vector<double> > *inv_A_);
-
-		static void multiply_matrices(
-			const std::vector<std::vector<double> > &A_,
-			const std::vector<std::vector<double> > &B_,
-			std::vector<std::vector<double> > &res_);
-
-		static void multiply_matrix_and_vector(
-			const std::vector<std::vector<double> > &A_,
-			const std::vector<double> &y_,
-			std::vector<double> &res_);
-
-		static void transpose_matrix(
-			const std::vector<std::vector<double> > &A_,
-			std::vector<std::vector<double> > &res_);
-
-		static void print_matrix(
-			const std::vector<std::vector<double> > A_);
-
-		static double standard_deviation(//standard deviation for average of elements of vect_
-			long int dim_,
-			double *vect_);
-
-		static double average(//average of elements of vect_
-			long int dim_,
-			double *vect_);
-
-
-
-
-
-
-//----------------------------------
-
-		template<typename T>
-		static void get_memory_for_matrix(
-		long int dim1_,
-		long int dim2_,
-		T ** &matr_)
-		{
-			matr_=NULL;
-
-
-			try
-			{
-
-				long int i;
-				matr_=new T *[dim1_];
-				Sls::FSA_utils::assert_mem(matr_);
-
-				for(i=0;i<dim1_;i++)
-				{
-					matr_[i]=NULL;
-				};
-
-				for(i=0;i<dim1_;i++)
-				{
-					matr_[i]=new T [dim2_];
-					Sls::FSA_utils::assert_mem(matr_[i]);
-				};
-
-			}
-			catch (...)
-			{ 
-				if(matr_)
-				{
-					long int i;
-					for(i=0;i<dim1_;i++)
-					{
-						delete[]matr_[i];matr_[i]=NULL;
-					};
-					delete[]matr_;matr_=NULL;
-				};
-				throw;
-			};
-
-		}
-
-		template<typename T>
-		static void delete_memory_for_matrix(
-		long int dim1_,
-		T ** &matr_)
-		{
-			long int i;
-			if(matr_)
-			{
-				for(i=0;i<dim1_;i++)
-				{
-					delete []matr_[i];matr_[i]=NULL;
-				};
-				delete []matr_;matr_=NULL;
-			};
-
-		}
-
-		static long int random_long(
-		double value_,
-		long int dim_)
-		{
-			if(value_<0||value_>1.0||dim_<=0)
-			{
-				throw error("Unexpected error\n",4);
-			};
-
-			if(dim_==1)
-			{
-				return 0;
-			};
-
-			long int tmp=(long int)floor(value_*(double)dim_);
-			tmp=Tmin(tmp,dim_-1);
-			return tmp;
-		}
-
-		template<typename T>
-		static T random_long(
-		double value_,
-		long int dim_,
-		double *sum_distr_,
-		T* elements_=NULL)//sum_distr_[dim_-1] must be equal to 1
-		{
-			if(value_<0||value_>1)	
-			{
-				throw error("Unexpected error in q_elem importance_sampling::get_random_pair\n",4);
-			};
-
-			long int v1=0;
-			long int v2=dim_;
-
-			while(v2-v1>1)
-			{
-				long int v3=(long int)(Sls::FSA_utils::round(double(v2+v1)/2.0));
-				if(sum_distr_[v3-1]==value_)
-				{
-					v1=v3-1;
-					v2=v3;
-					break;
-				};
-
-				if(sum_distr_[v3-1]>value_)
-				{
-					v2=v3;
-				}
-				else
-				{
-					v1=v3;
-				};
-			};
-
-			if(elements_)
-			{
-				long int v2_1=v2-1;
-
-
-				long int v2_minus=-1;
-
-				long int j;
-				for(j=v2_1;j>=1;j--)
-				{
-					if(sum_distr_[j]!=sum_distr_[j-1])
-					{
-						v2_minus=j;
-						break;
-					};
-				};
-
-				if(v2_minus<0)
-				{
-					if(sum_distr_[0]>0)
-					{
-						v2_minus=0;
-					};
-				};
-
-				if(v2_minus>=0)
-				{
-					return elements_[v2_minus];
-				};
-
-				long int v2_plus=-1;
-				for(j=v2;j<dim_;j++)
-				{
-					if(sum_distr_[j]!=sum_distr_[j-1])
-					{
-						v2_plus=j;
-						break;
-					};
-				};
-
-				if(v2_minus<0)
-				{
-					throw error("Unexpected error in random_long\n",1);
-				}
-				else
-				{
-					return elements_[v2_plus];
-				};
-
-			}
-			else
-			{
-				return v2-1;
-			};
-
-		}
-
-		template<class T>
-		static void print_matrix(
-		std::string file_name_,
-		long int dim1_,
-		long int dim2_,
-		T** A_)
-		{
-			std::ofstream f(file_name_.data());
-			if(!f)
-			{
-				throw error("Error - the file "+file_name_+" is not found\n",3);
-			};
-
-			long int i,j;
-			for(i=0;i<dim1_;i++)
-			{
-				for(j=0;j<dim2_;j++)
-				{
-					if(j<dim2_-1)
-					{
-						f<<A_[i][j]<<"\t";
-					}
-					else
-					{
-						f<<A_[i][j]<<"\n";
-					};
-				};
-			};
-
-			f.close();
-		}
-
-
-
-
-
-		public:
-
-		long int d_tmpl;
-
-
-	};
-
-
-
-
-
-	template<typename T> class array_positive{
-	public:
-		array_positive(void *fsa_=NULL)// constructor
-		{ 
-			d_elem=NULL;
-			d_fsa=fsa_; 
-			if(!fsa_)
-			{
-				//throw error("Unexpected error\n",4);
-			};
-			d_dim=-1;
-			d_step=10;
-		}
-
-		void increment_array(long int ind_);
-
-		inline void set_elem(
-			long int ind_,
-			T elem_)
-		{
-			if(ind_>d_dim)
-			{
-				increment_array(ind_);
-			};
-
-			d_elem[ind_]=elem_;
-		}
-
-		inline T get_elem(
-			long int ind_)
-		{
-			if(ind_>d_dim)
-			{
-				increment_array(ind_);
-			};
-
-			return d_elem[ind_];
-		}
-
-
-		inline void increase_elem_by_1(
-			long int ind_)
-		{
-			if(ind_>d_dim)
-			{
-				increment_array(ind_);
-			};
-
-			d_elem[ind_]++;
-		}
-
-		inline void increase_elem_by_x(
-			long int ind_,
-			T x_)
-		{
-			if(ind_>d_dim)
-			{
-				increment_array(ind_);
-			};
-
-			d_elem[ind_]+=x_;
-		}
-
-		inline void divide_elem_by_x(
-			long int ind_,
-			T x_)
-		{
-			if(ind_>d_dim)
-			{
-				increment_array(ind_);
-			};
-
-			d_elem[ind_]/=x_;
-		}
-
-		~array_positive()
-		{
-			delete[]d_elem;d_elem=NULL;
-		}
-
-
-	public:
-			
-		long int d_step;
-		long int d_dim;//dimension of the array is d_dim+1
-		T * d_elem;
-		void *d_fsa;//initial data
-	};
-
-
-
-
-
-		
-
-
-
-//-------------------------------------------------------------------------------------------
-
-
-	template<typename T> class array_v{
-	public:
-		array_v(void *fsa_=NULL)// constructor
-		{ 
-			d_elem=NULL;
-			d_fsa=fsa_; 
-			d_dim=-1;
-			d_ind0=0;
-			d_step=10;
-			d_dim_plus_d_ind0=d_dim+d_ind0;
-		}
-
-		void clear()
-		{
-			d_dim=-1;
-			d_ind0=0;
-			d_dim_plus_d_ind0=d_dim+d_ind0;
-			delete[]d_elem;d_elem=NULL;
-		}
-
-		void increment_array_on_the_right(long int ind_);
-
-		void increment_array_on_the_left(long int ind_);
-
-		inline void set_elems(const array_v<T> *a_)
-		{
-			long int a0=a_->d_ind0;
-			long int a1=a_->d_dim_plus_d_ind0;
-
-			if(a0>a1)return;
-
-			while(a1>d_dim_plus_d_ind0)
-			{
-				d_dim_plus_d_ind0+=d_step;
-			};
-
-			while(a0<d_ind0)
-			{
-				d_ind0-=d_step;
-			};
-
-			d_dim=d_dim_plus_d_ind0-d_ind0;
-			d_elem=new T[d_dim+1];
-			sls_basic::assert_mem(d_elem);
-
-			long int i;
-			for(i=a0;i<=a1;i++)
-			{
-			  d_elem[i-d_ind0]=a_->d_elem[i-a0];
-			}
-		}
-
-		inline void set_elem(
-			long int ind_,
-			T elem_)
-		{
-			if(ind_>d_dim_plus_d_ind0)
-			{
-				increment_array_on_the_right(ind_);
-			};
-
-			if(ind_<d_ind0)
-			{
-				increment_array_on_the_left(ind_);
-			};
-
-			d_elem[ind_-d_ind0]=elem_;
-		}
-
-
-		T get_elem(
-			long int ind_)
-		{
-			if(ind_>d_dim_plus_d_ind0||ind_<d_ind0)
-			{
-				throw error("Error - the index ind_ in array_v::get_elem is out of range\n",1);
-			};
-
-			return d_elem[ind_-d_ind0];
-		}
-
-
-		inline void increase_elem_by_1(
-			long int ind_)
-		{
-			if(ind_>d_dim_plus_d_ind0)
-			{
-				increment_array_on_the_right(ind_);
-			};
-
-			if(ind_<d_ind0)
-			{
-				increment_array_on_the_left(ind_);
-			};
-
-			d_elem[ind_-d_ind0]++;
-		}
-
-
-		void increase_elem_by_x(
-			long int ind_,
-			double x_)
-		{
-			if(ind_>d_dim_plus_d_ind0)
-			{
-				increment_array_on_the_right(ind_);
-			};
-
-			if(ind_<d_ind0)
-			{
-				increment_array_on_the_left(ind_);
-			};
-
-			d_elem[ind_-d_ind0]+=x_;
-		}
-
-
-		void divide_elem_by_x(
-			long int ind_,
-			double x_)
-		{
-			if(ind_>d_dim_plus_d_ind0)
-			{
-				increment_array_on_the_right(ind_);
-			};
-
-			if(ind_<d_ind0)
-			{
-				increment_array_on_the_left(ind_);
-			};
-
-			d_elem[ind_-d_ind0]/=x_;
-		}
-
-
-
-
-		~array_v()
-		{
-			delete[]d_elem;d_elem=NULL;
-		}
-
-		static void copy_x2_into_x1(
-			array_v<T> &x1_,
-			array_v<T> &x2_)
-		{
-			x1_=x2_;
-			if(x2_.d_dim<0)
-			{
-				x1_.d_elem=NULL;
-				return;
-			};
-			x1_.d_elem=new T[x2_.d_dim+1];
-			FSA_utils::assert_mem(x1_.d_elem);
-			long int i;
-			for(i=0;i<=x2_.d_dim;i++)
-			{
-				x1_.d_elem[i]=x2_.d_elem[i];
-			};
-
-		}
-			
-
-
-
-	public:
-			
-		long int d_step;
-		long int d_dim;//dimension of the array is d_dim+1
-		long int d_ind0;//the leftmost index of the array
-		long int d_dim_plus_d_ind0;
-		T * d_elem;
-		void *d_fsa;//initial data
-	};
-
-
-//-------------------------------------------------------------------------------------------
-
-	template<typename T> class array_v2{
-
-
-	public:
-		array_v2(// constructor
-			long int subarray_length_,
-			bool assign_null_elem_=false,
-			T *null_elem_=NULL)
-		{ 
-			if(subarray_length_<=0)
-			{
-				throw error("Error - subarray_length_<=0 in array_v2::array_v2\n",1);
-			};
-			d_subarray_length=subarray_length_;
-			d_min_index=-1;
-			d_max_index=-1;
-			d_assign_null_elem=assign_null_elem_;
-			if(assign_null_elem_)
-			{
-				d_null_elem=*null_elem_;
-			};
-		}
-
-		~array_v2()
-		{
-			long int i;
-			for(i=0;i<(long int)d_vector_of_subarrays.size();i++)
-			{
-				delete[]d_vector_of_subarrays[i];
-			};
-		}
-
-		inline void clear()
-		{
-			deallocate_memory(d_max_index+1);
-			d_min_index=-1;
-			d_max_index=-1;
-			d_vector_of_subarrays.clear();
-
-		}
-
-		inline void allocate_memory(
-			long int ind_)//ind_ is not deleted
-		{
-			if(ind_>d_max_index)
-			{
-				long int ind_in_d_vector_of_subarrays=(long int)floor((double)ind_/(double)d_subarray_length);
-				long int old_size=(long int)d_vector_of_subarrays.size();
-				long int new_size=ind_in_d_vector_of_subarrays+1;
-				long int j;
-				for(j=old_size;j<new_size;j++)
-				{
-					T*pointer_tmp=new T[d_subarray_length];
-					FSA_utils::assert_mem(pointer_tmp);
-
-					d_vector_of_subarrays.push_back(pointer_tmp);
-					if(d_assign_null_elem)
-					{
-						long int i;
-						for(i=0;i<d_subarray_length;i++)
-						{
-							pointer_tmp[i]=d_null_elem;
-						};
-					};
-				};
-
-				d_max_index=d_subarray_length*new_size-1;
-			};
-
-		}
-
-
-		inline void set_elem(
-			long int ind_,
-			T elem_)
-		{
-			if(ind_<d_min_index)
-			{
-				throw error("Unexpected error - ind_<d_min_index in set_elem\n",1);
-			};
-
-			long int ind_in_d_vector_of_subarrays=(long int)floor((double)ind_/(double)d_subarray_length);
-			long int ind_in_subarray=(long int)(ind_%d_subarray_length);
-
-			if(ind_>d_max_index)
-			{
-				allocate_memory(ind_);
-			};
-
-			d_vector_of_subarrays[ind_in_d_vector_of_subarrays][ind_in_subarray]=elem_;
-		}
-
-
-		inline T &get_elem(
-			long int ind_)
-		{
-			if(ind_<d_min_index)
-			{
-				throw error("Unexpected error - ind_<d_min_index in get_elem\n",1);
-			};
-
-			if(ind_>d_max_index)
-			{
-				allocate_memory(ind_);
-			};
-
-			long int ind_in_d_vector_of_subarrays=(long int)floor((double)ind_/(double)d_subarray_length);
-			long int ind_in_subarray=(long int)(ind_%d_subarray_length);
-
-			return d_vector_of_subarrays[ind_in_d_vector_of_subarrays][ind_in_subarray];
-		}
-
-		inline void deallocate_memory(
-			long int ind_)//ind_ is not deleted
-		{
-			long int ind_in_d_vector_of_subarrays=(long int)FSA_utils::Tmin(floor((double)d_max_index/(double)d_subarray_length),floor((double)ind_/(double)d_subarray_length)-1);
-			long int ind_in_d_vector_of_subarrays_min=(long int)floor((double)d_min_index/(double)d_subarray_length);//always >=0
-			if(ind_in_d_vector_of_subarrays_min<0)
-			{
-				ind_in_d_vector_of_subarrays_min=0;
-			};
-
-
-			long int i;
-
-			for(i=ind_in_d_vector_of_subarrays_min;i<=ind_in_d_vector_of_subarrays;i++)
-			{
-				delete[]d_vector_of_subarrays[i];d_vector_of_subarrays[i]=NULL;
-			};
-
-			if(ind_in_d_vector_of_subarrays_min<ind_in_d_vector_of_subarrays+1)
-			{
-				d_min_index=(ind_in_d_vector_of_subarrays+1)*d_subarray_length;
-			};
-		}
-
-
-		
-	public:
-
-		long int d_subarray_length;
-		std::vector<T*> d_vector_of_subarrays;
-		long int d_min_index;
-		long int d_max_index;
-		bool d_assign_null_elem;
-		T d_null_elem;
-
-
-		
-	};
-
-	template<class T>
-	void array_positive<T>::increment_array(long int ind_)
-	{
-		T *d_elem_new=NULL;
-
-		try
-		{
-			long int o_dim=d_dim;
-			do{
-			  d_dim+=d_step;
-			}while(ind_>d_dim);
-
-			d_elem_new=new T[d_dim+1];
-			FSA_utils::assert_mem(d_elem_new);
-
-			long int i;
-			for(i=0;i<o_dim+1;i++)
-			{
-				d_elem_new[i]=d_elem[i];
-			};
-
-			for(i=o_dim+1;i<d_dim+1;i++)
-			{
-				d_elem_new[i]=0;
-			};
-
-
-			delete[]d_elem;d_elem=NULL;
-
-			d_elem=d_elem_new;d_elem_new=NULL;
-		}
-		catch (...)
-		{ 
-			delete[]d_elem_new;d_elem_new=NULL;
-			throw;
-		};
-		
-	}
-
-	template<class T>
-	void array_v<T>::increment_array_on_the_right(long int ind_)
-	{
-		bool ee_error_flag=false;
-		error ee_error("",0);
-		T *d_elem_new=NULL;
-
-		try
-		{
-		try
-		{
-
-
-			long int o_dim=d_dim;
-			do{
-			  d_dim+=d_step;
-			  d_dim_plus_d_ind0+=d_step;
-			}while(ind_>d_dim_plus_d_ind0);
-
-			d_elem_new=new T[d_dim+1];
-			FSA_utils::assert_mem(d_elem_new);
-
-			long int i;
-			for(i=0;i<o_dim+1;i++)
-			{
-				d_elem_new[i]=d_elem[i];
-			};
-
-			for(i=o_dim+1;i<d_dim+1;i++)
-			{
-				d_elem_new[i]=0;
-			};
-
-			delete[]d_elem;d_elem=NULL;
-			d_elem=d_elem_new;d_elem_new=NULL;
-
-
-		}
-		catch (error er)
-		{
-			ee_error_flag=true;
-			ee_error=er;		
-		};
-		}
-		catch (...)
-		{ 
-			ee_error_flag=true;
-			ee_error=error("Internal error in the program\n",4);
-		};
-
-		//memory release
-
-		if(ee_error_flag)
-		{
-			delete[]d_elem_new;d_elem_new=NULL;
-			throw error(ee_error.st,ee_error.error_code);
-		};
-
-	}
-
-	template<class T>
-		void array_v<T>::increment_array_on_the_left(long int ind_)
-	{
-		T *d_elem_new=NULL;
-
-		try
-		{
-			long int o_dim=d_dim;
-			do{
-			  d_dim+=d_step;
-			  d_ind0-=d_step;
-			}while(ind_<d_ind0);
-			long int jump=d_dim-o_dim;
-
-			d_elem_new=new T[d_dim+1];
-			FSA_utils::assert_mem(d_elem_new);
-
-			long int i;
-
-			for(i=0;i<jump;i++)
-			{
-				d_elem_new[i]=0;
-			};
-
-			for(i=0;i<o_dim+1;i++)
-			{
-				d_elem_new[i+jump]=d_elem[i];
-			};
-
-
-			delete[]d_elem;d_elem=NULL;
-			d_elem=d_elem_new;d_elem_new=NULL;
-
-		}
-		catch (...)
-		{
-			delete[]d_elem_new;d_elem_new=NULL;
-			throw;
-		};
-
-
-	}
-
-
-}
-
-
-#endif // GUMBEL_FSA1_UTILS
-
+#ifndef GUMBEL_FSA1_UTILS
+#define GUMBEL_FSA1_UTILS
+
+/* $Id: $
+* ===========================================================================
+*
+*							PUBLIC DOMAIN NOTICE
+*			   National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_fsa1_utils.hpp
+
+Author: Sergey Sheetlin, Martin Frith
+
+Contents: Frameshift alignment algorithms utilities
+
+******************************************************************************/
+#include "sls_basic.hpp"
+
+#include <vector>
+#include <complex>
+#include <iostream>
+#include <map>
+#include <vector>
+#include <fstream>
+#include <float.h> 
+#include <algorithm>
+#include <sstream>
+#include <ctime>
+#include <limits>
+#include <climits>
+#include <errno.h>
+
+#ifndef _MSC_VER //UNIX program
+#include <sys/time.h>
+#else
+#include <sys/timeb.h>
+#endif
+
+#include "njn_random.hpp"
+#include "njn_uniform.hpp"
+
+namespace Sls 
+{
+
+	class FSA_utils: public sls_basic//contains general functions
+	{
+		public:
+
+		static void read_RR(
+		std::string RR_file_name_,
+		double *&RR_,
+		double *&RR_sum_,
+		long int *&RR_sum_elements_,
+		long int &number_of_AA_RR_,
+		long int number_of_AA_RR_default_=0);
+
+		static void check_RR_sum(
+		double sum_tmp_,
+		long int number_of_AA_RR_,
+		std::string RR_file_name_);
+
+		static void calculate_RR_sum(
+		double *RR_,
+		long int number_of_AA_RR_,
+		double *&RR_sum_,
+		long int *&RR_sum_elements_);
+
+		static void read_RR(
+		std::string RR_file_name_,
+		double *&RR_,
+		long int &number_of_AA_RR_,
+		long int number_of_AA_RR_default_=0);
+
+		static void read_smatr(
+		std::string smatr_file_name_,
+		long int **&smatr_,
+		long int &number_of_AA_smatr_,
+		long int &smatr_min_);
+
+		static void smatr_min(
+		long int **smatr_,
+		long int number_of_AA_smatr_,
+		long int &smatr_min_);
+
+		static void remove_zero_probabilities(
+		double *&RR1_,
+		double *&RR1_sum_,
+		long int *&RR1_sum_elements_,
+		long int &alphabet_letters_number1_,
+		double *&RR2_,
+		double *&RR2_sum_,
+		long int *&RR2_sum_elements_,
+		long int &alphabet_letters_number2_,
+		long int **&smatr_,
+		long int &number_of_AA_smatr_,
+		long int &smatr_min_,
+
+		long int &number_of_letters1_,//number of letters for the sequence 1
+		long int &number_of_letters2_,//number of letters for the sequence 2
+
+		char *&alphabet1_,//alphabet letters for the sequence #1
+		char *&alphabet2_,//alphabet letters for the sequence #2
+
+		long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+		long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+		long int &codon_length_,//codon length 
+		long int *&codon_AA_);//<codon code,AA number>
+
+
+
+
+
+		static std::string long_to_string(//convert interer ot std::string
+		long int number_);
+
+		static char digit_to_string(//convert interer ot std::string
+		long int digit_);
+		
+
+		static bool the_value_is_double(
+		std::string str_,
+		double &val_);
+
+		static bool the_value_is_long(
+		std::string str_,
+		long int &val_);
+
+		static double sqrt_plus(
+		double x_);
+
+		static double error_of_the_sum(//v1_+v2_
+		double v1_error_,
+		double v2_error_);
+
+		static double error_of_the_product(//v1_*v2_
+		double v1_,
+		double v1_error_,
+		double v2_,
+		double v2_error_);
+
+		static double error_of_the_lg(//lg(v1_)
+		double v1_,
+		double v1_error_);
+
+		static double error_of_the_sqrt(//sqrt(v1_)
+		double v1_,
+		double v1_error_);
+
+		static double error_of_the_ratio(//v1_/v2_
+		double v1_,
+		double v1_error_,
+		double v2_,
+		double v2_error_);
+
+		static double error_of_the_sum_with_coeff(//c1_*v1_+c2_*v2_
+		double c1_,
+		double v1_error_,
+		double c2_,
+		double v2_error_);
+
+
+
+		static void read_alphabet(
+		std::string alphabet_file_name_,
+		long int &number_of_AA_alphabet_,
+		char* &alphabet_);
+
+		static void calculate_composition_frequencies(
+		double number_of_AA_alphabet_,
+		char* alphabet_,
+		std::string fasta_file_name_,
+		double *comp_frequencies_);
+
+		static long int convert_codon_into_AA(
+		long int codon_length_,//codon length 
+		long int *codon_AA_,//<codon code,AA number>
+		long int number_of_letters1_,//number of letters for the sequence 1
+		long int *codon_);
+
+		static long int convert_codon_into_code(
+		long int codon_length_,//codon length 
+		long int number_of_letters1_,//number of letters for the sequence 1
+		long int *codon_);//input codon
+
+
+		static void convert_code_into_codon(
+		long int code_,//the input code
+		long int codon_length_,//codon length 
+		long int number_of_letters1_,//number of letters for the sequence 1
+		long int *codon_);//must be allocated
+
+
+		static void read_codon_AA_file(
+		std::string file_name_,
+		long int &number_of_letters1_,//number of letters for the sequence 1
+		long int &number_of_letters2_,//number of letters for the sequence 2
+
+		char *&alphabet1_,//alphabet letters for the sequence #1
+		char *&alphabet2_,//alphabet letters for the sequence #2
+
+		long int *&alphabet1_to_long_,//d_alphabet1_to_long[c] returns order number of the letter c (for the sequence #1)
+		long int *&alphabet2_to_long_,//d_alphabet2_to_long[c] returns order number of the letter c (for the sequence #2)
+
+		long int &codon_length_,//codon length 
+		long int *&codon_AA_,//<codon code,AA number>
+		bool reverse_codons_flag_=false);//if true, then the codons are reversed
+
+		static void reverse_codons(
+		long int *codon_AA_,//<codon code,AA number>; original codons
+		long int alphabet_letters_number1_,//number of letters for the sequence #1
+		long int codon_length_,//codon length 
+		long int *&codon_AA_reversed_);//<codon code,AA number>; reversed codons
+
+
+		static void reverse_sequence(//reverse the letters of the sequence
+			long int *seq_,
+			long int seq_length_);
+
+		static void extract_AA_frequencies_for_DNA_sequence(
+			const long int *codon_AA_,//<codon code,AA number>
+			long int &codon_length_,//codon length 
+			long int number_of_letters1_,//number of letters for the sequence 1
+			long int number_of_letters2_,//number of letters for the sequence 2
+			const double *RR1_,//nucleotide probabilities
+			double *&RR1_AA_);//the resulted frequencies
+
+		static void read_sequences_for_alingment(
+
+			std::string input_file_name_,
+
+			long int &number_of_letters1_,//number of letters for the sequence 1
+			long int &number_of_letters2_,//number of letters for the sequence 2
+
+			char *&alphabet1_,//alphabet letters for the sequence #1
+			char *&alphabet2_,//alphabet letters for the sequence #2
+
+			long int& number_of_sequences_,
+
+			std::string *&headers_,
+			long int *&lengths1_,//lengths of the sequences #1
+			long int *&lengths2_,//lengths of the sequences #2
+			long int **&sequences1_,//the first index numerates sequences; the second - sequence letters
+			long int **&sequences2_);
+
+		static void read_string(
+			std::ifstream &f_,
+			std::string &st_,
+			bool &end_of_file_flag_);
+
+
+
+		inline static double ran2()//generates the next random value
+		{
+			return Njn::Uniform::variate <double> (0,1);
+			//double rand_C=(double)((double)rand()/(double)RAND_MAX);
+			//return rand_C;	
+		}
+
+		inline static void srand2(long int seed_)//initializes the seed
+		{
+			Njn::Random::seed(seed_);
+			//srand(seed_);
+		}
+
+		static void srand2_old(long int seed_);//initializes the seed
+
+		static double ran2_old();//generates the next random value
+
+		static void process_random_factor(
+			long int &random_factor_,
+			bool *rand_flag_=NULL);
+
+
+		static long int power_long(//returns a_^b_
+			long int a_,
+			long int b_);
+
+		static void convert_distr_into_sum(//convert distr_[0], distr_[1], distr_[2],... into distr_[0], distr_[0]+distr_[1], distr_[0]+distr_[1]+distr_[2],...
+			long int dim_,
+			double *distr_);
+
+		static bool Gauss(
+			std::vector<std::vector<double> > A_,//matrix n*(n+1)
+			std::vector<double> &x_,//solution
+			double inside_eps_,
+			std::vector<std::vector<double> > *inv_A_);
+
+		static void multiply_matrices(
+			const std::vector<std::vector<double> > &A_,
+			const std::vector<std::vector<double> > &B_,
+			std::vector<std::vector<double> > &res_);
+
+		static void multiply_matrix_and_vector(
+			const std::vector<std::vector<double> > &A_,
+			const std::vector<double> &y_,
+			std::vector<double> &res_);
+
+		static void transpose_matrix(
+			const std::vector<std::vector<double> > &A_,
+			std::vector<std::vector<double> > &res_);
+
+		static void print_matrix(
+			const std::vector<std::vector<double> > A_);
+
+		static double standard_deviation(//standard deviation for average of elements of vect_
+			long int dim_,
+			double *vect_);
+
+		static double average(//average of elements of vect_
+			long int dim_,
+			double *vect_);
+
+
+
+
+
+
+//----------------------------------
+
+		template<typename T>
+		static void get_memory_for_matrix(
+		long int dim1_,
+		long int dim2_,
+		T ** &matr_)
+		{
+			matr_=NULL;
+
+
+			try
+			{
+
+				long int i;
+				matr_=new T *[dim1_];
+				Sls::FSA_utils::assert_mem(matr_);
+
+				for(i=0;i<dim1_;i++)
+				{
+					matr_[i]=NULL;
+				};
+
+				for(i=0;i<dim1_;i++)
+				{
+					matr_[i]=new T [dim2_];
+					Sls::FSA_utils::assert_mem(matr_[i]);
+				};
+
+			}
+			catch (...)
+			{ 
+				if(matr_)
+				{
+					long int i;
+					for(i=0;i<dim1_;i++)
+					{
+						delete[]matr_[i];matr_[i]=NULL;
+					};
+					delete[]matr_;matr_=NULL;
+				};
+				throw;
+			};
+
+		}
+
+		template<typename T>
+		static void delete_memory_for_matrix(
+		long int dim1_,
+		T ** &matr_)
+		{
+			long int i;
+			if(matr_)
+			{
+				for(i=0;i<dim1_;i++)
+				{
+					delete []matr_[i];matr_[i]=NULL;
+				};
+				delete []matr_;matr_=NULL;
+			};
+
+		}
+
+		static long int random_long(
+		double value_,
+		long int dim_)
+		{
+			if(value_<0||value_>1.0||dim_<=0)
+			{
+				throw error("Unexpected error\n",4);
+			};
+
+			if(dim_==1)
+			{
+				return 0;
+			};
+
+			long int tmp=(long int)floor(value_*(double)dim_);
+			tmp=Tmin(tmp,dim_-1);
+			return tmp;
+		}
+
+		template<typename T>
+		static T random_long(
+		double value_,
+		long int dim_,
+		double *sum_distr_,
+		T* elements_=NULL)//sum_distr_[dim_-1] must be equal to 1
+		{
+			if(value_<0||value_>1)	
+			{
+				throw error("Unexpected error in q_elem importance_sampling::get_random_pair\n",4);
+			};
+
+			long int v1=0;
+			long int v2=dim_;
+
+			while(v2-v1>1)
+			{
+				long int v3=(long int)(Sls::FSA_utils::round(double(v2+v1)/2.0));
+				if(sum_distr_[v3-1]==value_)
+				{
+					v1=v3-1;
+					v2=v3;
+					break;
+				};
+
+				if(sum_distr_[v3-1]>value_)
+				{
+					v2=v3;
+				}
+				else
+				{
+					v1=v3;
+				};
+			};
+
+			if(elements_)
+			{
+				long int v2_1=v2-1;
+
+
+				long int v2_minus=-1;
+
+				long int j;
+				for(j=v2_1;j>=1;j--)
+				{
+					if(sum_distr_[j]!=sum_distr_[j-1])
+					{
+						v2_minus=j;
+						break;
+					};
+				};
+
+				if(v2_minus<0)
+				{
+					if(sum_distr_[0]>0)
+					{
+						v2_minus=0;
+					};
+				};
+
+				if(v2_minus>=0)
+				{
+					return elements_[v2_minus];
+				};
+
+				long int v2_plus=-1;
+				for(j=v2;j<dim_;j++)
+				{
+					if(sum_distr_[j]!=sum_distr_[j-1])
+					{
+						v2_plus=j;
+						break;
+					};
+				};
+
+				if(v2_minus<0)
+				{
+					throw error("Unexpected error in random_long\n",1);
+				}
+				else
+				{
+					return elements_[v2_plus];
+				};
+
+			}
+			else
+			{
+				return v2-1;
+			};
+
+		}
+
+		template<class T>
+		static void print_matrix(
+		std::string file_name_,
+		long int dim1_,
+		long int dim2_,
+		T** A_)
+		{
+			std::ofstream f(file_name_.data());
+			if(!f)
+			{
+				throw error("Error - the file "+file_name_+" is not found\n",3);
+			};
+
+			long int i,j;
+			for(i=0;i<dim1_;i++)
+			{
+				for(j=0;j<dim2_;j++)
+				{
+					if(j<dim2_-1)
+					{
+						f<<A_[i][j]<<"\t";
+					}
+					else
+					{
+						f<<A_[i][j]<<"\n";
+					};
+				};
+			};
+
+			f.close();
+		}
+
+
+
+
+
+		public:
+
+		long int d_tmpl;
+
+
+	};
+
+
+
+
+
+	template<typename T> class array_positive{
+	public:
+		array_positive(void *fsa_=NULL)// constructor
+		{ 
+			d_elem=NULL;
+			d_fsa=fsa_; 
+			if(!fsa_)
+			{
+				//throw error("Unexpected error\n",4);
+			};
+			d_dim=-1;
+			d_step=10;
+		}
+
+		void increment_array(long int ind_);
+
+		inline void set_elem(
+			long int ind_,
+			T elem_)
+		{
+			if(ind_>d_dim)
+			{
+				increment_array(ind_);
+			};
+
+			d_elem[ind_]=elem_;
+		}
+
+		inline T get_elem(
+			long int ind_)
+		{
+			if(ind_>d_dim)
+			{
+				increment_array(ind_);
+			};
+
+			return d_elem[ind_];
+		}
+
+
+		inline void increase_elem_by_1(
+			long int ind_)
+		{
+			if(ind_>d_dim)
+			{
+				increment_array(ind_);
+			};
+
+			d_elem[ind_]++;
+		}
+
+		inline void increase_elem_by_x(
+			long int ind_,
+			T x_)
+		{
+			if(ind_>d_dim)
+			{
+				increment_array(ind_);
+			};
+
+			d_elem[ind_]+=x_;
+		}
+
+		inline void divide_elem_by_x(
+			long int ind_,
+			T x_)
+		{
+			if(ind_>d_dim)
+			{
+				increment_array(ind_);
+			};
+
+			d_elem[ind_]/=x_;
+		}
+
+		~array_positive()
+		{
+			delete[]d_elem;d_elem=NULL;
+		}
+
+
+	public:
+			
+		long int d_step;
+		long int d_dim;//dimension of the array is d_dim+1
+		T * d_elem;
+		void *d_fsa;//initial data
+	};
+
+
+
+
+
+		
+
+
+
+//-------------------------------------------------------------------------------------------
+
+
+	template<typename T> class array_v{
+	public:
+		array_v(void *fsa_=NULL)// constructor
+		{ 
+			d_elem=NULL;
+			d_fsa=fsa_; 
+			d_dim=-1;
+			d_ind0=0;
+			d_step=10;
+			d_dim_plus_d_ind0=d_dim+d_ind0;
+		}
+
+		void clear()
+		{
+			d_dim=-1;
+			d_ind0=0;
+			d_dim_plus_d_ind0=d_dim+d_ind0;
+			delete[]d_elem;d_elem=NULL;
+		}
+
+		void increment_array_on_the_right(long int ind_);
+
+		void increment_array_on_the_left(long int ind_);
+
+		inline void set_elems(const array_v<T> *a_)
+		{
+			long int a0=a_->d_ind0;
+			long int a1=a_->d_dim_plus_d_ind0;
+
+			if(a0>a1)return;
+
+			while(a1>d_dim_plus_d_ind0)
+			{
+				d_dim_plus_d_ind0+=d_step;
+			};
+
+			while(a0<d_ind0)
+			{
+				d_ind0-=d_step;
+			};
+
+			d_dim=d_dim_plus_d_ind0-d_ind0;
+			d_elem=new T[d_dim+1];
+			sls_basic::assert_mem(d_elem);
+
+			long int i;
+			for(i=a0;i<=a1;i++)
+			{
+			  d_elem[i-d_ind0]=a_->d_elem[i-a0];
+			}
+		}
+
+		inline void set_elem(
+			long int ind_,
+			T elem_)
+		{
+			if(ind_>d_dim_plus_d_ind0)
+			{
+				increment_array_on_the_right(ind_);
+			};
+
+			if(ind_<d_ind0)
+			{
+				increment_array_on_the_left(ind_);
+			};
+
+			d_elem[ind_-d_ind0]=elem_;
+		}
+
+
+		T get_elem(
+			long int ind_)
+		{
+			if(ind_>d_dim_plus_d_ind0||ind_<d_ind0)
+			{
+				throw error("Error - the index ind_ in array_v::get_elem is out of range\n",1);
+			};
+
+			return d_elem[ind_-d_ind0];
+		}
+
+
+		inline void increase_elem_by_1(
+			long int ind_)
+		{
+			if(ind_>d_dim_plus_d_ind0)
+			{
+				increment_array_on_the_right(ind_);
+			};
+
+			if(ind_<d_ind0)
+			{
+				increment_array_on_the_left(ind_);
+			};
+
+			d_elem[ind_-d_ind0]++;
+		}
+
+
+		void increase_elem_by_x(
+			long int ind_,
+			double x_)
+		{
+			if(ind_>d_dim_plus_d_ind0)
+			{
+				increment_array_on_the_right(ind_);
+			};
+
+			if(ind_<d_ind0)
+			{
+				increment_array_on_the_left(ind_);
+			};
+
+			d_elem[ind_-d_ind0]+=x_;
+		}
+
+
+		void divide_elem_by_x(
+			long int ind_,
+			double x_)
+		{
+			if(ind_>d_dim_plus_d_ind0)
+			{
+				increment_array_on_the_right(ind_);
+			};
+
+			if(ind_<d_ind0)
+			{
+				increment_array_on_the_left(ind_);
+			};
+
+			d_elem[ind_-d_ind0]/=x_;
+		}
+
+
+
+
+		~array_v()
+		{
+			delete[]d_elem;d_elem=NULL;
+		}
+
+		static void copy_x2_into_x1(
+			array_v<T> &x1_,
+			array_v<T> &x2_)
+		{
+			x1_=x2_;
+			if(x2_.d_dim<0)
+			{
+				x1_.d_elem=NULL;
+				return;
+			};
+			x1_.d_elem=new T[x2_.d_dim+1];
+			FSA_utils::assert_mem(x1_.d_elem);
+			long int i;
+			for(i=0;i<=x2_.d_dim;i++)
+			{
+				x1_.d_elem[i]=x2_.d_elem[i];
+			};
+
+		}
+			
+
+
+
+	public:
+			
+		long int d_step;
+		long int d_dim;//dimension of the array is d_dim+1
+		long int d_ind0;//the leftmost index of the array
+		long int d_dim_plus_d_ind0;
+		T * d_elem;
+		void *d_fsa;//initial data
+	};
+
+
+//-------------------------------------------------------------------------------------------
+
+	template<typename T> class array_v2{
+
+
+	public:
+		array_v2(// constructor
+			long int subarray_length_,
+			bool assign_null_elem_=false,
+			T *null_elem_=NULL)
+		{ 
+			if(subarray_length_<=0)
+			{
+				throw error("Error - subarray_length_<=0 in array_v2::array_v2\n",1);
+			};
+			d_subarray_length=subarray_length_;
+			d_min_index=-1;
+			d_max_index=-1;
+			d_assign_null_elem=assign_null_elem_;
+			if(assign_null_elem_)
+			{
+				d_null_elem=*null_elem_;
+			};
+		}
+
+		~array_v2()
+		{
+			long int i;
+			for(i=0;i<(long int)d_vector_of_subarrays.size();i++)
+			{
+				delete[]d_vector_of_subarrays[i];
+			};
+		}
+
+		inline void clear()
+		{
+			deallocate_memory(d_max_index+1);
+			d_min_index=-1;
+			d_max_index=-1;
+			d_vector_of_subarrays.clear();
+
+		}
+
+		inline void allocate_memory(
+			long int ind_)//ind_ is not deleted
+		{
+			if(ind_>d_max_index)
+			{
+				long int ind_in_d_vector_of_subarrays=(long int)floor((double)ind_/(double)d_subarray_length);
+				long int old_size=(long int)d_vector_of_subarrays.size();
+				long int new_size=ind_in_d_vector_of_subarrays+1;
+				long int j;
+				for(j=old_size;j<new_size;j++)
+				{
+					T*pointer_tmp=new T[d_subarray_length];
+					FSA_utils::assert_mem(pointer_tmp);
+
+					d_vector_of_subarrays.push_back(pointer_tmp);
+					if(d_assign_null_elem)
+					{
+						long int i;
+						for(i=0;i<d_subarray_length;i++)
+						{
+							pointer_tmp[i]=d_null_elem;
+						};
+					};
+				};
+
+				d_max_index=d_subarray_length*new_size-1;
+			};
+
+		}
+
+
+		inline void set_elem(
+			long int ind_,
+			T elem_)
+		{
+			if(ind_<d_min_index)
+			{
+				throw error("Unexpected error - ind_<d_min_index in set_elem\n",1);
+			};
+
+			long int ind_in_d_vector_of_subarrays=(long int)floor((double)ind_/(double)d_subarray_length);
+			long int ind_in_subarray=(long int)(ind_%d_subarray_length);
+
+			if(ind_>d_max_index)
+			{
+				allocate_memory(ind_);
+			};
+
+			d_vector_of_subarrays[ind_in_d_vector_of_subarrays][ind_in_subarray]=elem_;
+		}
+
+
+		inline T &get_elem(
+			long int ind_)
+		{
+			if(ind_<d_min_index)
+			{
+				throw error("Unexpected error - ind_<d_min_index in get_elem\n",1);
+			};
+
+			if(ind_>d_max_index)
+			{
+				allocate_memory(ind_);
+			};
+
+			long int ind_in_d_vector_of_subarrays=(long int)floor((double)ind_/(double)d_subarray_length);
+			long int ind_in_subarray=(long int)(ind_%d_subarray_length);
+
+			return d_vector_of_subarrays[ind_in_d_vector_of_subarrays][ind_in_subarray];
+		}
+
+		inline void deallocate_memory(
+			long int ind_)//ind_ is not deleted
+		{
+			long int ind_in_d_vector_of_subarrays=(long int)FSA_utils::Tmin(floor((double)d_max_index/(double)d_subarray_length),floor((double)ind_/(double)d_subarray_length)-1);
+			long int ind_in_d_vector_of_subarrays_min=(long int)floor((double)d_min_index/(double)d_subarray_length);//always >=0
+			if(ind_in_d_vector_of_subarrays_min<0)
+			{
+				ind_in_d_vector_of_subarrays_min=0;
+			};
+
+
+			long int i;
+
+			for(i=ind_in_d_vector_of_subarrays_min;i<=ind_in_d_vector_of_subarrays;i++)
+			{
+				delete[]d_vector_of_subarrays[i];d_vector_of_subarrays[i]=NULL;
+			};
+
+			if(ind_in_d_vector_of_subarrays_min<ind_in_d_vector_of_subarrays+1)
+			{
+				d_min_index=(ind_in_d_vector_of_subarrays+1)*d_subarray_length;
+			};
+		}
+
+
+		
+	public:
+
+		long int d_subarray_length;
+		std::vector<T*> d_vector_of_subarrays;
+		long int d_min_index;
+		long int d_max_index;
+		bool d_assign_null_elem;
+		T d_null_elem;
+
+
+		
+	};
+
+	template<class T>
+	void array_positive<T>::increment_array(long int ind_)
+	{
+		T *d_elem_new=NULL;
+
+		try
+		{
+			long int o_dim=d_dim;
+			do{
+			  d_dim+=d_step;
+			}while(ind_>d_dim);
+
+			d_elem_new=new T[d_dim+1];
+			FSA_utils::assert_mem(d_elem_new);
+
+			long int i;
+			for(i=0;i<o_dim+1;i++)
+			{
+				d_elem_new[i]=d_elem[i];
+			};
+
+			for(i=o_dim+1;i<d_dim+1;i++)
+			{
+				d_elem_new[i]=0;
+			};
+
+
+			delete[]d_elem;d_elem=NULL;
+
+			d_elem=d_elem_new;d_elem_new=NULL;
+		}
+		catch (...)
+		{ 
+			delete[]d_elem_new;d_elem_new=NULL;
+			throw;
+		};
+		
+	}
+
+	template<class T>
+	void array_v<T>::increment_array_on_the_right(long int ind_)
+	{
+		bool ee_error_flag=false;
+		error ee_error("",0);
+		T *d_elem_new=NULL;
+
+		try
+		{
+		try
+		{
+
+
+			long int o_dim=d_dim;
+			do{
+			  d_dim+=d_step;
+			  d_dim_plus_d_ind0+=d_step;
+			}while(ind_>d_dim_plus_d_ind0);
+
+			d_elem_new=new T[d_dim+1];
+			FSA_utils::assert_mem(d_elem_new);
+
+			long int i;
+			for(i=0;i<o_dim+1;i++)
+			{
+				d_elem_new[i]=d_elem[i];
+			};
+
+			for(i=o_dim+1;i<d_dim+1;i++)
+			{
+				d_elem_new[i]=0;
+			};
+
+			delete[]d_elem;d_elem=NULL;
+			d_elem=d_elem_new;d_elem_new=NULL;
+
+
+		}
+		catch (error er)
+		{
+			ee_error_flag=true;
+			ee_error=er;		
+		};
+		}
+		catch (...)
+		{ 
+			ee_error_flag=true;
+			ee_error=error("Internal error in the program\n",4);
+		};
+
+		//memory release
+
+		if(ee_error_flag)
+		{
+			delete[]d_elem_new;d_elem_new=NULL;
+			throw error(ee_error.st,ee_error.error_code);
+		};
+
+	}
+
+	template<class T>
+		void array_v<T>::increment_array_on_the_left(long int ind_)
+	{
+		T *d_elem_new=NULL;
+
+		try
+		{
+			long int o_dim=d_dim;
+			do{
+			  d_dim+=d_step;
+			  d_ind0-=d_step;
+			}while(ind_<d_ind0);
+			long int jump=d_dim-o_dim;
+
+			d_elem_new=new T[d_dim+1];
+			FSA_utils::assert_mem(d_elem_new);
+
+			long int i;
+
+			for(i=0;i<jump;i++)
+			{
+				d_elem_new[i]=0;
+			};
+
+			for(i=0;i<o_dim+1;i++)
+			{
+				d_elem_new[i+jump]=d_elem[i];
+			};
+
+
+			delete[]d_elem;d_elem=NULL;
+			d_elem=d_elem_new;d_elem_new=NULL;
+
+		}
+		catch (...)
+		{
+			delete[]d_elem_new;d_elem_new=NULL;
+			throw;
+		};
+
+
+	}
+
+
+}
+
+
+#endif // GUMBEL_FSA1_UTILS
+
diff --git a/src/alp/sls_pvalues.cpp b/src/alp/sls_pvalues.cpp
index de5cedf..194d696 100644
--- a/src/alp/sls_pvalues.cpp
+++ b/src/alp/sls_pvalues.cpp
@@ -1,1347 +1,1347 @@
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_pvalues.cpp
-
-Author: Sergey Sheetlin
-
-Contents: Calculation of P-values using precalculated Gumbel parameters
-
-******************************************************************************/
-
-#include "sls_pvalues.hpp"
-#include "sls_alp_data.hpp"
-#include <iomanip>      // std::setprecision
-
-#include "sls_normal_distr_array.hpp"
-
-
-using namespace Sls;
-using namespace std;
-
-const double nat_cut_off_in_max=2.0;//nat cut-off in max used in FSC
-
-
-void pvalues::get_appr_tail_prob_with_cov(
-const ALP_set_of_parameters &par_,
-bool blast_,
-double y_,
-double m_,
-double n_,
-
-double &P_,
-double &P_error_,
-
-double &E_,
-double &E_error_,
-
-double &area_,
-
-double a_normal_,
-double b_normal_,
-double h_normal_,
-long int N_normal_,
-double *p_normal_,
-
-bool &area_is_1_flag_)
-{
-
-	//to optimize performance
-	blast_=false;
-
-	double lambda_=par_.lambda;
-	double lambda_error_=par_.lambda_error;
-	double k_=par_.K;
-	double k_error_=par_.K_error;
-
-	double ai_hat_=par_.a_I;
-	double ai_hat_error_=par_.a_I_error;
-	double bi_hat_; 
-	double bi_hat_error_; 
-	double alphai_hat_=par_.alpha_I;
-	double alphai_hat_error_=par_.alpha_I_error;
-	double betai_hat_;
-	double betai_hat_error_; 
-
-	double aj_hat_=par_.a_J;
-	double aj_hat_error_=par_.a_J_error;
-	double bj_hat_; 
-	double bj_hat_error_; 
-	double alphaj_hat_=par_.alpha_J;
-	double alphaj_hat_error_=par_.alpha_J_error;
-	double betaj_hat_; 
-	double betaj_hat_error_; 
-
-	double sigma_hat_=par_.sigma;
-	double sigma_hat_error_=par_.sigma_error;
-	double tau_hat_;
- 	double tau_hat_error_;
-
-	{
-		bi_hat_=par_.b_I;
-		bi_hat_error_=par_.b_I_error;
-		betai_hat_=par_.beta_I;
-		betai_hat_error_=par_.beta_I_error;
-
-		bj_hat_=par_.b_J;
-		bj_hat_error_=par_.b_J_error;
-		betaj_hat_=par_.beta_J;
-		betaj_hat_error_=par_.beta_J_error;
-
-		tau_hat_=par_.tau;
-		tau_hat_error_=par_.tau_error;
-	};
-
-
-	if(blast_)
-	{
-		alphai_hat_=0;
-		alphai_hat_error_=0;
-		betai_hat_=0;
-		betai_hat_error_=0;
-
-		alphaj_hat_=0;
-		alphaj_hat_error_=0;
-		betaj_hat_=0;
-		betaj_hat_error_=0;
-
-		sigma_hat_=0;
-		sigma_hat_error_=0;
-		tau_hat_=0;
-		tau_hat_error_=0;
-	};
-
-	double eps=0.000001;
-
-	double m_li_y_error=0;
-	double m_li_y=0;
-
-	double tmp=ai_hat_*y_+bi_hat_;
-
-	m_li_y_error=alp_data::error_of_the_sum(fabs(y_)*ai_hat_error_,bi_hat_error_);
-	m_li_y=m_-tmp;
-	
-	double vi_y_error=0;
-	double vi_y=0;
-
-	vi_y_error=alp_data::error_of_the_sum(fabs(y_)*alphai_hat_error_,betai_hat_error_);
-
-	vi_y=alp_data::Tmax(par_.vi_y_thr,alphai_hat_*y_+betai_hat_);
-
-	double sqrt_vi_y_error=alp_data::error_of_the_sqrt(vi_y,vi_y_error);
-
-	double sqrt_vi_y=sqrt(vi_y);
-
-	double m_F;
-	double m_F_error;
-
-	if(sqrt_vi_y==0.0||blast_)
-	{
-		m_F=1e100;
-		m_F_error=0.0;
-	}
-	else
-	{
-		m_F_error=alp_data::error_of_the_ratio(m_li_y,m_li_y_error,sqrt_vi_y,sqrt_vi_y_error);
-		m_F=m_li_y/sqrt_vi_y;
-	};
-
-
-	double P_m_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,m_F,eps);
-	double P_m_F_error=const_val*exp(-0.5*m_F*m_F)*m_F_error;
-
-	double E_m_F=-const_val*exp(-0.5*m_F*m_F);
-	double E_m_F_error=fabs(-E_m_F*m_F)*m_F_error;
-
-	double m_li_y_P_m_F_error=alp_data::error_of_the_product(m_li_y,m_li_y_error,P_m_F,P_m_F_error);
-	double m_li_y_P_m_F=m_li_y*P_m_F;
-
-	double sqrt_vi_y_E_m_F_error=alp_data::error_of_the_product(sqrt_vi_y,sqrt_vi_y_error,E_m_F,E_m_F_error);
-	double sqrt_vi_y_E_m_F=sqrt_vi_y*E_m_F;
-
-	double p1_error=alp_data::error_of_the_sum(m_li_y_P_m_F_error,sqrt_vi_y_E_m_F_error);
-	double p1=m_li_y_P_m_F-sqrt_vi_y_E_m_F;
-
-
-	double n_lj_y_error=0;
-	double n_lj_y=0;
-
-
-	tmp=aj_hat_*y_+bj_hat_;
-
-	n_lj_y_error=alp_data::error_of_the_sum(fabs(y_)*aj_hat_error_,bj_hat_error_);
-	n_lj_y=n_-tmp;
-
-	double vj_y_error=0;
-	double vj_y=0;
-
-	vj_y_error=alp_data::error_of_the_sum(fabs(y_)*alphaj_hat_error_,betaj_hat_error_);
-
-	vj_y=alp_data::Tmax(par_.vj_y_thr,alphaj_hat_*y_+betaj_hat_);
-
-	double sqrt_vj_y_error=alp_data::error_of_the_sqrt(vj_y,vj_y_error);
-
-	double sqrt_vj_y=sqrt(vj_y);
-
-	double n_F;
-	double n_F_error;
-
-	if(sqrt_vj_y==0.0||blast_)
-	{
-		n_F=1e100;
-		n_F_error=0.0;
-	}
-	else
-	{
-		n_F_error=alp_data::error_of_the_ratio(n_lj_y,n_lj_y_error,sqrt_vj_y,sqrt_vj_y_error);
-
-		n_F=n_lj_y/sqrt_vj_y;
-	};
-
-	double P_n_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,n_F,eps);
-	double P_n_F_error=const_val*exp(-0.5*n_F*n_F)*n_F_error;
-
-	double E_n_F=-const_val*exp(-0.5*n_F*n_F);
-	double E_n_F_error=fabs(-E_n_F*n_F)*n_F_error;
-
-	double n_lj_y_P_n_F_error=alp_data::error_of_the_product(n_lj_y,n_lj_y_error,P_n_F,P_n_F_error);
-	double n_lj_y_P_n_F=n_lj_y*P_n_F;
-
-	double sqrt_vj_y_E_n_F_error=alp_data::error_of_the_product(sqrt_vj_y,sqrt_vj_y_error,E_n_F,E_n_F_error);
-	double sqrt_vj_y_E_n_F=sqrt_vj_y*E_n_F;
-
-	double p2_error=alp_data::error_of_the_sum(n_lj_y_P_n_F_error,sqrt_vj_y_E_n_F_error);
-	double p2=n_lj_y_P_n_F-sqrt_vj_y_E_n_F;
-
-
-
-
-	double c_y_error=0;
-	double c_y=0;
-
-	c_y_error=alp_data::error_of_the_sum(sigma_hat_error_*y_,tau_hat_error_);
-
-	c_y=alp_data::Tmax(par_.c_y_thr,sigma_hat_*y_+tau_hat_);
-
-	double P_m_F_P_n_F_error=alp_data::error_of_the_product(P_m_F,P_m_F_error,P_n_F,P_n_F_error);
-	double P_m_F_P_n_F=P_m_F*P_n_F;
-
-	double c_y_P_m_F_P_n_F_error=alp_data::error_of_the_product(c_y,c_y_error,P_m_F_P_n_F,P_m_F_P_n_F_error);
-	double c_y_P_m_F_P_n_F=c_y*P_m_F_P_n_F;
-
-	double p1_p2_error=alp_data::error_of_the_product(p1,p1_error,p2,p2_error);
-	double p1_p2=p1*p2;
-
-
-	double area_error=alp_data::error_of_the_sum(p1_p2_error,c_y_P_m_F_P_n_F_error);
-	double area=p1_p2+c_y_P_m_F_P_n_F;
-
-
-
-
-	if(!blast_)
-	{
-		//area=alp_data::Tmax(area,1.0);
-	}
-	else
-	{
-		if(area<=1.0)
-		{
-			area_is_1_flag_=true;
-		};
-
-		if(area_is_1_flag_)
-		{
-			area=1.0;
-		};
-	};
-
-
-	double exp_lambda_y_error=fabs(lambda_error_*y_*exp(-lambda_*y_));
-	double exp_lambda_y=exp(-lambda_*y_);
-
-	double k_exp_lambda_y_error=alp_data::error_of_the_product(k_,k_error_,exp_lambda_y,exp_lambda_y_error);
-	double k_exp_lambda_y=k_*exp_lambda_y;
-
-	double area_k_exp_lambda_y_error=alp_data::error_of_the_product(area,area_error,k_exp_lambda_y,k_exp_lambda_y_error);
-	double area_k_exp_lambda_y=-area*k_exp_lambda_y;
-
-	E_=-area_k_exp_lambda_y;
-	E_error_=area_k_exp_lambda_y_error;
-
-	P_error_=exp(area_k_exp_lambda_y)*area_k_exp_lambda_y_error;
-
-	P_=sls_basic::one_minus_exp_function(area_k_exp_lambda_y);
-//	P_=1-exp(-k_*area*exp(-lambda_*y_));
-
-	area_=area;
-
-
-}
-
-void pvalues::compute_intercepts(
-ALP_set_of_parameters &par_)
-{
-	if(!par_.d_params_flag)
-	{
-		throw error("Unexpected error: pvalues::compute_intercepts is called for undefined parameters\n",1);
-	};
-
-	par_.b_I=2.0*par_.G*(par_.gapless_a-par_.a_I); 
-	par_.b_I_error=2.0*par_.G*alp_data::error_of_the_sum(par_.gapless_a_error,par_.a_I_error); 
-	par_.beta_I=2.0*par_.G*(par_.gapless_alpha-par_.alpha_I); 
-	par_.beta_I_error=2.0*par_.G*alp_data::error_of_the_sum(par_.gapless_alpha_error,par_.alpha_I_error); 
-
-	par_.b_J=2.0*par_.G*(par_.gapless_a-par_.a_J); 
-	par_.b_I_error=2.0*par_.G*alp_data::error_of_the_sum(par_.gapless_a_error,par_.a_J_error); 
-	par_.beta_J=2.0*par_.G*(par_.gapless_alpha-par_.alpha_J); 
-	par_.beta_J_error=2.0*par_.G*alp_data::error_of_the_sum(par_.gapless_alpha_error,par_.alpha_J_error); 
-
-	par_.tau=2.0*par_.G*(par_.gapless_alpha-par_.sigma);
-	par_.tau_error=2.0*par_.G*alp_data::error_of_the_sum(par_.gapless_alpha_error,par_.sigma_error);
-
-	long int vector_size=(long int)par_.m_LambdaSbs.size();
-
-	par_.m_BISbs.resize(vector_size);
-	par_.m_BJSbs.resize(vector_size);
-	par_.m_BetaISbs.resize(vector_size);
-	par_.m_BetaJSbs.resize(vector_size);
-	par_.m_TauSbs.resize(vector_size);
-
-	long int i;
-	for(i=0;i<vector_size;i++)
-	{
-		par_.m_BISbs[i]=2.0*par_.G*(par_.gapless_a-par_.m_AISbs[i]); 
-		par_.m_BetaISbs[i]=2.0*par_.G*(par_.gapless_alpha-par_.m_AlphaISbs[i]); 
-
-		par_.m_BJSbs[i]=2.0*par_.G*(par_.gapless_a-par_.m_AJSbs[i]); 
-		par_.m_BetaJSbs[i]=2.0*par_.G*(par_.gapless_alpha-par_.m_AlphaJSbs[i]); 
-
-		par_.m_TauSbs[i]=2.0*par_.G*(par_.gapless_alpha-par_.m_SigmaSbs[i]);
-	};
-
-	compute_tmp_values(par_);
-
-}
-
-void pvalues::compute_tmp_values(ALP_set_of_parameters &par_)
-{
-	if(!par_.d_params_flag)
-	{
-		throw error("Unexpected call of pvalues::compute_tmp_values\n",1);
-	};
-
-	//tmp values
-	if(par_.lambda>0)
-	{
-		par_.vi_y_thr=alp_data::Tmax(nat_cut_off_in_max*par_.alpha_I/par_.lambda,0.0);
-		par_.vj_y_thr=alp_data::Tmax(nat_cut_off_in_max*par_.alpha_J/par_.lambda,0.0);
-		par_.c_y_thr=alp_data::Tmax(nat_cut_off_in_max*par_.sigma/par_.lambda,0.0);
-	}
-	else
-	{
-		par_.vi_y_thr=0;
-		par_.vj_y_thr=0;
-		par_.c_y_thr=0;
-
-		par_.d_params_flag=false;
-	};
-}
-
-void pvalues::get_appr_tail_prob_with_cov_without_errors(
-const ALP_set_of_parameters &par_,
-bool blast_,
-double y_,
-double m_,
-double n_,
-
-double &P_,
-
-double &E_,
-
-double &area_,
-
-double a_normal_,
-double b_normal_,
-double h_normal_,
-long int N_normal_,
-double *p_normal_,
-
-bool &area_is_1_flag_,
-bool compute_only_area_)
-{
-
-	//to optimize performance
-	blast_=false;
-
-	double lambda_=par_.lambda;
-	double k_=par_.K;
-
-	double ai_hat_=par_.a_I;
-	double bi_hat_;
-	double alphai_hat_=par_.alpha_I;
-	double betai_hat_;
-
-	double aj_hat_=par_.a_J;
-	double bj_hat_;
-	double alphaj_hat_=par_.alpha_J;
-	double betaj_hat_;
-
-	double sigma_hat_=par_.sigma;
-	double tau_hat_;
-
-	{
-		bi_hat_=par_.b_I;
-		betai_hat_=par_.beta_I;
-
-		bj_hat_=par_.b_J;
-		betaj_hat_=par_.beta_J;
-
-		tau_hat_=par_.tau;
-	};
-
-	if(blast_)
-	{
-		alphai_hat_=0;
-		betai_hat_=0;
-
-		alphaj_hat_=0;
-		betaj_hat_=0;
-
-		sigma_hat_=0;
-		tau_hat_=0;
-	};
-
-	double eps=0.000001;
-
-	double m_li_y=0;
-
-	double tmp=ai_hat_*y_+bi_hat_;
-
-	m_li_y=m_-tmp;
-	
-	double vi_y=0;
-
-	vi_y=alp_data::Tmax(par_.vi_y_thr,alphai_hat_*y_+betai_hat_);
-
-	double sqrt_vi_y=sqrt(vi_y);
-
-
-	double m_F;
-
-	if(sqrt_vi_y==0.0||blast_)
-	{
-		m_F=1e100;
-	}
-	else
-	{
-		m_F=m_li_y/sqrt_vi_y;
-	};
-
-
-	double P_m_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,m_F,eps);
-
-	double E_m_F=-const_val*exp(-0.5*m_F*m_F);
-
-	double m_li_y_P_m_F=m_li_y*P_m_F;
-
-	double sqrt_vi_y_E_m_F=sqrt_vi_y*E_m_F;
-
-	double p1=m_li_y_P_m_F-sqrt_vi_y_E_m_F;
-
-
-	double n_lj_y=0;
-
-	tmp=aj_hat_*y_+bj_hat_;
-
-	n_lj_y=n_-tmp;
-
-	double vj_y=0;
-
-	vj_y=alp_data::Tmax(par_.vj_y_thr,alphaj_hat_*y_+betaj_hat_);
-
-	double sqrt_vj_y=sqrt(vj_y);
-
-	double n_F;
-
-	if(sqrt_vj_y==0.0||blast_)
-	{
-		n_F=1e100;
-	}
-	else
-	{
-		n_F=n_lj_y/sqrt_vj_y;
-	};
-
-	double P_n_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,n_F,eps);
-
-	double E_n_F=-const_val*exp(-0.5*n_F*n_F);
-
-	double n_lj_y_P_n_F=n_lj_y*P_n_F;
-
-	double sqrt_vj_y_E_n_F=sqrt_vj_y*E_n_F;
-
-	double p2=n_lj_y_P_n_F-sqrt_vj_y_E_n_F;
-
-
-
-
-	double c_y=0;
-
-	c_y=alp_data::Tmax(par_.c_y_thr,sigma_hat_*y_+tau_hat_);
-
-	double P_m_F_P_n_F=P_m_F*P_n_F;
-
-	double c_y_P_m_F_P_n_F=c_y*P_m_F_P_n_F;
-
-	double p1_p2=p1*p2;
-
-	double area=p1_p2+c_y_P_m_F_P_n_F;
-
-
-
-
-	if(!blast_)
-	{
-		//area=alp_data::Tmax(area,1.0);
-	}
-	else
-	{
-		if(area<=1.0)
-		{
-			area_is_1_flag_=true;
-		};
-
-		if(area_is_1_flag_)
-		{
-			area=1.0;
-		};
-	};
-
-	area_=area;
-
-	if(compute_only_area_)
-	{
-		return;
-	};
-
-	double exp_lambda_y=exp(-lambda_*y_);
-
-	double k_exp_lambda_y=k_*exp_lambda_y;
-
-	double area_k_exp_lambda_y=-area*k_exp_lambda_y;
-
-	E_=-area_k_exp_lambda_y;
-
-	P_=sls_basic::one_minus_exp_function(area_k_exp_lambda_y);
-//	P_=1-exp(-k_*area*exp(-lambda_*y_));
-
-}
-
-void pvalues::get_P_error_using_splitting_method(
-const ALP_set_of_parameters &par_,
-bool blast_,
-double y_,
-double m_,
-double n_,
-
-double &P_,
-double &P_error_,
-
-double &E_,
-double &E_error_,
-
-double a_normal_,
-double b_normal_,
-double h_normal_,
-long int N_normal_,
-double *p_normal_,
-
-bool &area_is_1_flag_)
-{
-	long int dim=par_.m_LambdaSbs.size();
-	if(dim==0)
-	{
-		throw error("Unexpected error in get_P_error_using_splitting_method\n",1);
-	};
-
-	P_=0;
-	P_error_=0;
-
-	E_=0;
-	E_error_=0;
-
-	double exp_E_values_aver=0;
-	double exp_E_values_error=0;
-
-
-	vector<double> P_values(dim);
-	vector<double> E_values(dim);
-	vector<double> exp_E_values(dim);
-
-
-	long int i;
-	for(i=0;i<dim;i++)
-	{
-		ALP_set_of_parameters par_tmp;
-
-		par_tmp.a_I=par_.m_AISbs[i];
-		par_tmp.a_I_error=0;
-
-		par_tmp.a_J=par_.m_AJSbs[i];
-		par_tmp.a_J_error=0;
-
-		
-
-		par_tmp.gapless_a=par_.gapless_a;
-		par_tmp.gapless_a_error=par_.gapless_a_error;
-
-		par_tmp.a=0.5*(par_tmp.a_I+par_tmp.a_J);
-		par_tmp.a_error=0;
-
-
-		par_tmp.sigma=par_.m_SigmaSbs[i];
-		par_tmp.sigma_error=0;
-
-		par_tmp.gapless_alpha=par_.gapless_alpha;
-		par_tmp.gapless_alpha_error=par_.gapless_alpha_error;
-
-
-		par_tmp.C=par_.m_CSbs[i];
-		par_tmp.C_error=0;
-
-		par_tmp.K=par_.m_KSbs[i];
-		par_tmp.K_error=0;
-
-
-		par_tmp.lambda=par_.m_LambdaSbs[i];
-		par_tmp.lambda_error=0;
-
-		par_tmp.alpha_I=par_.m_AlphaISbs[i];
-		par_tmp.alpha_I_error=0;
-
-		par_tmp.alpha_J=par_.m_AlphaJSbs[i];
-		par_tmp.alpha_J_error=0;
-
-		par_tmp.alpha=0.5*(par_tmp.alpha_I+par_tmp.alpha_J);
-		par_tmp.alpha_error=0;
-
-		par_tmp.G=par_.G;
-		par_tmp.G1=par_.G1;
-		par_tmp.G2=par_.G2;
-
-		//intercepts
-
-		{
-			par_tmp.b_I=par_.m_BISbs[i];
-			par_tmp.b_I_error=0;
-
-			par_tmp.b_J=par_.m_BJSbs[i];
-			par_tmp.b_J_error=0;
-
-			par_tmp.beta_I=par_.m_BetaISbs[i];
-			par_tmp.beta_I_error=0;
-
-			par_tmp.beta_J=par_.m_BetaJSbs[i];
-			par_tmp.beta_J_error=0;
-
-			par_tmp.tau=par_.m_TauSbs[i];
-			par_tmp.tau_error=0;
-
-			par_tmp.d_params_flag=true;
-
-			compute_tmp_values(par_tmp);
-
-		};
-
-
-		double P_tmp,area_tmp,E_tmp;
-
-		get_appr_tail_prob_with_cov_without_errors(
-		par_tmp,
-		blast_,
-		y_,
-		m_,
-		n_,
-
-		P_tmp,
-
-		E_tmp,
-
-		area_tmp,
-
-		a_normal_,
-		b_normal_,
-		h_normal_,
-		N_normal_,
-		p_normal_,
-
-		area_is_1_flag_);
-
-		P_values[i]=P_tmp;
-
-		P_+=P_tmp;
-
-		E_values[i]=E_tmp;
-
-		E_+=E_tmp;
-
-		double exp_E_tmp=exp(-E_tmp);
-		exp_E_values[i]=exp_E_tmp;
-		exp_E_values_aver+=exp_E_tmp;
-
-
-	};
-
-	if(dim<=1)
-	{
-		return;
-	};
-
-
-	if(P_<=0)
-	{
-		return;
-	};
-
-	if(E_<=0)
-	{
-		return;
-	};
-
-
-	P_/=(double)dim;
-	E_/=(double)dim;
-	exp_E_values_aver/=(double)dim;
-
-	for(i=0;i<dim;i++)
-	{
-		double tmp;
-		
-		if(P_>0)
-		{
-			tmp=P_values[i]/P_;
-			P_error_+=tmp*tmp;
-		};
-
-		if(E_>0)
-		{
-			tmp=E_values[i]/E_;
-			E_error_+=tmp*tmp;
-		};
-
-		if(exp_E_values_aver>0)
-		{
-			tmp=exp_E_values[i]/exp_E_values_aver;
-			exp_E_values_error+=tmp*tmp;
-		};
-
-	};
-
-	P_error_/=(double)dim;
-	P_error_-=1;
-	
-	E_error_/=(double)dim;
-	E_error_-=1;
-
-	exp_E_values_error/=(double)dim;
-	exp_E_values_error-=1;
-
-
-	if(P_<1e-4)
-	{
-		P_error_=P_*alp_reg::sqrt_for_errors(P_error_/(double)dim);
-	}
-	else
-	{
-		P_error_=exp_E_values_aver*alp_reg::sqrt_for_errors(exp_E_values_error/(double)dim);
-	};
-
-	E_error_=E_*alp_reg::sqrt_for_errors(E_error_/(double)dim);
-
-}
-
-
-pvalues::pvalues()
-{
-	blast=false;
-	eps=0.0001;
-	a_normal=-10;
-	b_normal=10;
-	N_normal=NORMAL_DISTR_ARRAY_DIM;
-	h_normal=(b_normal-a_normal)/(double)N_normal;
-	p_normal=normal_distr_array_for_P_values_calculation;
-}
-
-
-pvalues::~pvalues()
-{
-	
-}
-
-void pvalues::calculate_P_values(
-long int Score1,
-long int Score2,
-double Seq1Len,
-double Seq2Len,
-const ALP_set_of_parameters &ParametersSet,
-vector<double> &P_values,
-vector<double> &P_values_errors,
-vector<double> &E_values,
-vector<double> &E_values_errors)
-{
-	if(Score2<Score1)
-	{
-		throw error("Error - Score2<Score1\n",2);
-	};
-
-	if(Seq1Len<=0||Seq2Len<=0)
-	{
-		throw error("Error - Seq1Len<=0||Seq2Len<=0\n",2);
-	};
-
-	P_values.resize(Score2-Score1+1);
-	P_values_errors.resize(Score2-Score1+1);
-
-	E_values.resize(Score2-Score1+1);
-	E_values_errors.resize(Score2-Score1+1);
-
-
-	long int y;
-	for(y=Score1;y<=Score2;y++)
-	{
-		calculate_P_values(
-		y,
-		Seq1Len,
-		Seq2Len,
-		ParametersSet,
-		P_values[y-Score1],
-		P_values_errors[y-Score1],
-		E_values[y-Score1],
-		E_values_errors[y-Score1]);
-	};
-
-}
-
-void pvalues::calculate_P_values(
-double Score,
-double Seq1Len,
-double Seq2Len,
-const ALP_set_of_parameters &ParametersSet,
-double &P_value,
-double &P_value_error,
-double &E_value,
-double &E_value_error,
-bool read_Sbs_par_flag)
-{
-
-	if(Seq1Len<=0||Seq2Len<=0)
-	{
-		throw error("Error - Seq1Len<=0||Seq2Len<=0\n",2);
-	};
-
-	double P;
-	double P_error;
-	double E;
-	double E_error;
-	double area;
-	bool area_is_1_flag=false;
-
-
-	if(read_Sbs_par_flag)
-	{
-		
-
-		get_appr_tail_prob_with_cov_without_errors(
-		ParametersSet,
-		blast,
-		Score,
-		Seq1Len,
-		Seq2Len,
-
-		P,
-
-		E,
-
-		area,
-		a_normal,
-		b_normal,
-		h_normal,
-		N_normal,
-		p_normal,
-		area_is_1_flag);
-
-
-		
-		double P_tmp,E_tmp;
-
-		if(ParametersSet.m_LambdaSbs.size()>0)
-		{
-			get_P_error_using_splitting_method(
-			ParametersSet,
-			blast,
-			Score,
-			Seq1Len,
-			Seq2Len,
-
-			P_tmp,
-			P_error,
-
-			E_tmp,
-			E_error,
-
-			a_normal,
-			b_normal,
-			h_normal,
-			N_normal,
-			p_normal,
-			area_is_1_flag);
-
-
-			if(P_tmp>0)
-			{
-				P_error=P_error/P_tmp*P;
-			};
-
-			P_value_error=P_error;
-
-			if(E_tmp>0)
-			{
-				E_error=E_error/E_tmp*E;
-			};
-
-			E_value_error=E_error;
-
-		}
-		else
-		{
-			P_value_error=-DBL_MAX;
-			E_value_error=-DBL_MAX;
-		};
-
-		
-		
-	}
-	else
-	{
-		get_appr_tail_prob_with_cov(
-		ParametersSet,
-		blast,
-		Score,
-		Seq1Len,
-		Seq2Len,
-
-		P,
-		P_error,
-
-		E,
-		E_error,
-
-		area,
-		a_normal,
-		b_normal,
-		h_normal,
-		N_normal,
-		p_normal,
-		area_is_1_flag);
-
-		P_value_error=P_error;
-		E_value_error=E_error;
-	};
-
-	P_value=P;
-	E_value=E;
-}
-
-
-//input/output Gumbel parameters
-
-namespace Sls {
-
-std::ostream &operator<<(std::ostream &s_,
-const ALP_set_of_parameters &gumbel_params_)
-{
-
-
-	s_<<"Lambda\tLambda error\tK\tK error\tC\tC error\ta\ta error\ta_1\ta_1 error\ta_2\ta_2 error\tsigma\tsigma error\talpha\talpha error\talpha_1\talpha_1 error\talpha_2\talpha_2 error\tGapless a\tGapless a error\tGapless alpha\tGapless alpha error\tG\tCalculation time\tArrays for error calculation\n";
-	s_.precision(17);
-	s_<<
-		gumbel_params_.lambda<<"\t"<<gumbel_params_.lambda_error<<"\t"<<
-		gumbel_params_.K<<"\t"<<gumbel_params_.K_error<<"\t"<<
-		gumbel_params_.C<<"\t"<<gumbel_params_.C_error<<"\t"<<
-		gumbel_params_.a<<"\t"<<gumbel_params_.a_error<<"\t"<<
-		gumbel_params_.a_J<<"\t"<<gumbel_params_.a_J_error<<"\t"<<
-		gumbel_params_.a_I<<"\t"<<gumbel_params_.a_I_error<<"\t"<<
-		gumbel_params_.sigma<<"\t"<<gumbel_params_.sigma_error<<"\t"<<
-		gumbel_params_.alpha<<"\t"<<gumbel_params_.alpha_error<<"\t"<<
-		gumbel_params_.alpha_J<<"\t"<<gumbel_params_.alpha_J_error<<"\t"<<
-		gumbel_params_.alpha_I<<"\t"<<gumbel_params_.alpha_I_error<<"\t"<<
-		gumbel_params_.gapless_a<<"\t"<<gumbel_params_.gapless_a_error<<"\t"<<
-		gumbel_params_.gapless_alpha<<"\t"<<gumbel_params_.gapless_alpha_error<<"\t"<<
-		gumbel_params_.G<<"\t"<<
-		gumbel_params_.m_CalcTime<<"\t";
-
-	long int i;
-
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_LambdaSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_KSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_CSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_AJSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_AISbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_SigmaSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_AlphaJSbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-
-	{
-		const vector<double> &tmp=gumbel_params_.m_AlphaISbs;
-		s_<<tmp.size()<<"\t";
-		for(i=0;i<(long int)tmp.size();i++)
-		{
-			s_<<tmp[i]<<"\t";
-		};
-	};
-
-	s_<<endl;
-
-	return s_;
-
-}
-
-std::istream &operator>>(std::istream &s_,
-ALP_set_of_parameters &gumbel_params_)
-{
-
-	gumbel_params_.d_params_flag=false;
-	try
-	{
-
-		string st;
-		getline(s_,st);
-		s_>>
-			gumbel_params_.lambda>>gumbel_params_.lambda_error>>
-			gumbel_params_.K>>gumbel_params_.K_error>>
-			gumbel_params_.C>>gumbel_params_.C_error>>
-			gumbel_params_.a>>gumbel_params_.a_error>>
-			gumbel_params_.a_J>>gumbel_params_.a_J_error>>
-			gumbel_params_.a_I>>gumbel_params_.a_I_error>>
-			gumbel_params_.sigma>>gumbel_params_.sigma_error>>
-			gumbel_params_.alpha>>gumbel_params_.alpha_error>>
-			gumbel_params_.alpha_J>>gumbel_params_.alpha_J_error>>
-			gumbel_params_.alpha_I>>gumbel_params_.alpha_I_error>>
-			gumbel_params_.gapless_a>>gumbel_params_.gapless_a_error>>
-			gumbel_params_.gapless_alpha>>gumbel_params_.gapless_alpha_error>>
-			gumbel_params_.G>>
-			gumbel_params_.m_CalcTime;
-
-		long int i;
-
-
-		{
-			vector<double> &tmp=gumbel_params_.m_LambdaSbs;
-			long int tmp_size;
-			s_>>tmp_size;
-			if(tmp_size<=0)
-			{
-				throw error("Error in the input parameters\n",4);
-			};
-			tmp.resize(tmp_size);
-			for(i=0;i<tmp_size;i++)
-			{
-				s_>>tmp[i];
-			};
-		};
-
-		{
-			vector<double> &tmp=gumbel_params_.m_KSbs;
-			long int tmp_size;
-			s_>>tmp_size;
-			if(tmp_size<=0)
-			{
-				throw error("Error in the input parameters\n",4);
-			};
-			tmp.resize(tmp_size);
-			for(i=0;i<tmp_size;i++)
-			{
-				s_>>tmp[i];
-			};
-		};
-
-
-		{
-			vector<double> &tmp=gumbel_params_.m_CSbs;
-			long int tmp_size;
-			s_>>tmp_size;
-			if(tmp_size<=0)
-			{
-				throw error("Error in the input parameters\n",4);
-			};
-			tmp.resize(tmp_size);
-			for(i=0;i<tmp_size;i++)
-			{
-				s_>>tmp[i];
-			};
-		};
-
-
-
-		{
-			vector<double> &tmp=gumbel_params_.m_AJSbs;
-			long int tmp_size;
-			s_>>tmp_size;
-			if(tmp_size<=0)
-			{
-				throw error("Error in the input parameters\n",4);
-			};
-			tmp.resize(tmp_size);
-			for(i=0;i<tmp_size;i++)
-			{
-				s_>>tmp[i];
-			};
-		};
-
-		{
-			vector<double> &tmp=gumbel_params_.m_AISbs;
-			long int tmp_size;
-			s_>>tmp_size;
-			if(tmp_size<=0)
-			{
-				throw error("Error in the input parameters\n",4);
-			};
-			tmp.resize(tmp_size);
-			for(i=0;i<tmp_size;i++)
-			{
-				s_>>tmp[i];
-			};
-		};
-
-
-
-		{
-			vector<double> &tmp=gumbel_params_.m_SigmaSbs;
-			long int tmp_size;
-			s_>>tmp_size;
-			if(tmp_size<=0)
-			{
-				throw error("Error in the input parameters\n",4);
-			};
-			tmp.resize(tmp_size);
-			for(i=0;i<tmp_size;i++)
-			{
-				s_>>tmp[i];
-			};
-		};
-
-
-		{
-			vector<double> &tmp=gumbel_params_.m_AlphaJSbs;
-			long int tmp_size;
-			s_>>tmp_size;
-			if(tmp_size<=0)
-			{
-				throw error("Error in the input parameters\n",4);
-			};
-			tmp.resize(tmp_size);
-			for(i=0;i<tmp_size;i++)
-			{
-				s_>>tmp[i];
-			};
-		};
-
-		{
-			vector<double> &tmp=gumbel_params_.m_AlphaISbs;
-			long int tmp_size;
-			s_>>tmp_size;
-			if(tmp_size<=0)
-			{
-				throw error("Error in the input parameters\n",4);
-			};
-			tmp.resize(tmp_size);
-			for(i=0;i<tmp_size;i++)
-			{
-				s_>>tmp[i];
-			};
-		};
-
-		gumbel_params_.d_params_flag=true;
-		return s_;
-	}
-	catch (...)
-	{ 
-		gumbel_params_.d_params_flag=false;
-		throw;
-	};
-
-}
-
-//returns "true" if the Gumbel parameters are properly defined and "false" otherwise
-bool pvalues::assert_Gumbel_parameters(
-const ALP_set_of_parameters &par_)//a set of Gumbel parameters
-{
-		if(par_.lambda<=0||
-		par_.lambda_error<0||
-
-		//the parameters C and K_C are not necessary for the P-value calculation
-		//par_.C<0||
-		//par_.C_error<0||
-
-		par_.K<=0||
-		par_.K_error<0||
-
-		par_.a_I<0||
-		par_.a_I_error<0||
-
-		par_.a_J<0||
-		par_.a_J_error<0||
-
-		par_.sigma<0||
-		par_.sigma_error<0||
-
-		par_.alpha_I<0||
-		par_.alpha_I_error<0||
-
-		par_.alpha_J<0||
-		par_.alpha_J_error<0||
-
-		par_.gapless_a<0||
-		par_.gapless_a_error<0||
-
-		par_.gapless_alpha<0||
-		par_.gapless_alpha_error<0||
-
-		par_.G<0||
-		par_.G1<0||
-		par_.G2<0||
-
-		//intercepts
-		par_.b_I_error<0||
-
-		par_.b_J_error<0||
-
-		par_.beta_I_error<0||
-
-		par_.beta_J_error<0||
-
-		par_.tau_error<0
-
-		)
-		{
-			return false;
-		};
-
-
-
-		size_t size_tmp=par_.m_LambdaSbs.size();
-		if(
-		par_.m_KSbs.size()!=size_tmp||
-		//par_.m_CSbs.size()!=size_tmp||
-
-		par_.m_SigmaSbs.size()!=size_tmp||
-
-		par_.m_AlphaISbs.size()!=size_tmp||
-		par_.m_AlphaJSbs.size()!=size_tmp||
-
-		par_.m_AISbs.size()!=size_tmp||
-		par_.m_AJSbs.size()!=size_tmp||
-
-		par_.m_BISbs.size()!=size_tmp||
-		par_.m_BJSbs.size()!=size_tmp||
-
-		par_.m_BetaISbs.size()!=size_tmp||
-		par_.m_BetaJSbs.size()!=size_tmp||
-
-		par_.m_TauSbs.size()!=size_tmp)
-		{
-			return false;
-		};
-
-
-		return true;
-
-}
-
-
-
-}
-
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_pvalues.cpp
+
+Author: Sergey Sheetlin
+
+Contents: Calculation of P-values using precalculated Gumbel parameters
+
+******************************************************************************/
+
+#include "sls_pvalues.hpp"
+#include "sls_alp_data.hpp"
+#include <iomanip>      // std::setprecision
+
+#include "sls_normal_distr_array.hpp"
+
+
+using namespace Sls;
+using namespace std;
+
+const double nat_cut_off_in_max=2.0;//nat cut-off in max used in FSC
+
+
+void pvalues::get_appr_tail_prob_with_cov(
+const ALP_set_of_parameters &par_,
+bool blast_,
+double y_,
+double m_,
+double n_,
+
+double &P_,
+double &P_error_,
+
+double &E_,
+double &E_error_,
+
+double &area_,
+
+double a_normal_,
+double b_normal_,
+double h_normal_,
+long int N_normal_,
+double *p_normal_,
+
+bool &area_is_1_flag_)
+{
+
+	//to optimize performance
+	blast_=false;
+
+	double lambda_=par_.lambda;
+	double lambda_error_=par_.lambda_error;
+	double k_=par_.K;
+	double k_error_=par_.K_error;
+
+	double ai_hat_=par_.a_I;
+	double ai_hat_error_=par_.a_I_error;
+	double bi_hat_; 
+	double bi_hat_error_; 
+	double alphai_hat_=par_.alpha_I;
+	double alphai_hat_error_=par_.alpha_I_error;
+	double betai_hat_;
+	double betai_hat_error_; 
+
+	double aj_hat_=par_.a_J;
+	double aj_hat_error_=par_.a_J_error;
+	double bj_hat_; 
+	double bj_hat_error_; 
+	double alphaj_hat_=par_.alpha_J;
+	double alphaj_hat_error_=par_.alpha_J_error;
+	double betaj_hat_; 
+	double betaj_hat_error_; 
+
+	double sigma_hat_=par_.sigma;
+	double sigma_hat_error_=par_.sigma_error;
+	double tau_hat_;
+ 	double tau_hat_error_;
+
+	{
+		bi_hat_=par_.b_I;
+		bi_hat_error_=par_.b_I_error;
+		betai_hat_=par_.beta_I;
+		betai_hat_error_=par_.beta_I_error;
+
+		bj_hat_=par_.b_J;
+		bj_hat_error_=par_.b_J_error;
+		betaj_hat_=par_.beta_J;
+		betaj_hat_error_=par_.beta_J_error;
+
+		tau_hat_=par_.tau;
+		tau_hat_error_=par_.tau_error;
+	};
+
+
+	if(blast_)
+	{
+		alphai_hat_=0;
+		alphai_hat_error_=0;
+		betai_hat_=0;
+		betai_hat_error_=0;
+
+		alphaj_hat_=0;
+		alphaj_hat_error_=0;
+		betaj_hat_=0;
+		betaj_hat_error_=0;
+
+		sigma_hat_=0;
+		sigma_hat_error_=0;
+		tau_hat_=0;
+		tau_hat_error_=0;
+	};
+
+	double eps=0.000001;
+
+	double m_li_y_error=0;
+	double m_li_y=0;
+
+	double tmp=ai_hat_*y_+bi_hat_;
+
+	m_li_y_error=alp_data::error_of_the_sum(fabs(y_)*ai_hat_error_,bi_hat_error_);
+	m_li_y=m_-tmp;
+	
+	double vi_y_error=0;
+	double vi_y=0;
+
+	vi_y_error=alp_data::error_of_the_sum(fabs(y_)*alphai_hat_error_,betai_hat_error_);
+
+	vi_y=alp_data::Tmax(par_.vi_y_thr,alphai_hat_*y_+betai_hat_);
+
+	double sqrt_vi_y_error=alp_data::error_of_the_sqrt(vi_y,vi_y_error);
+
+	double sqrt_vi_y=sqrt(vi_y);
+
+	double m_F;
+	double m_F_error;
+
+	if(sqrt_vi_y==0.0||blast_)
+	{
+		m_F=1e100;
+		m_F_error=0.0;
+	}
+	else
+	{
+		m_F_error=alp_data::error_of_the_ratio(m_li_y,m_li_y_error,sqrt_vi_y,sqrt_vi_y_error);
+		m_F=m_li_y/sqrt_vi_y;
+	};
+
+
+	double P_m_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,m_F,eps);
+	double P_m_F_error=const_val*exp(-0.5*m_F*m_F)*m_F_error;
+
+	double E_m_F=-const_val*exp(-0.5*m_F*m_F);
+	double E_m_F_error=fabs(-E_m_F*m_F)*m_F_error;
+
+	double m_li_y_P_m_F_error=alp_data::error_of_the_product(m_li_y,m_li_y_error,P_m_F,P_m_F_error);
+	double m_li_y_P_m_F=m_li_y*P_m_F;
+
+	double sqrt_vi_y_E_m_F_error=alp_data::error_of_the_product(sqrt_vi_y,sqrt_vi_y_error,E_m_F,E_m_F_error);
+	double sqrt_vi_y_E_m_F=sqrt_vi_y*E_m_F;
+
+	double p1_error=alp_data::error_of_the_sum(m_li_y_P_m_F_error,sqrt_vi_y_E_m_F_error);
+	double p1=m_li_y_P_m_F-sqrt_vi_y_E_m_F;
+
+
+	double n_lj_y_error=0;
+	double n_lj_y=0;
+
+
+	tmp=aj_hat_*y_+bj_hat_;
+
+	n_lj_y_error=alp_data::error_of_the_sum(fabs(y_)*aj_hat_error_,bj_hat_error_);
+	n_lj_y=n_-tmp;
+
+	double vj_y_error=0;
+	double vj_y=0;
+
+	vj_y_error=alp_data::error_of_the_sum(fabs(y_)*alphaj_hat_error_,betaj_hat_error_);
+
+	vj_y=alp_data::Tmax(par_.vj_y_thr,alphaj_hat_*y_+betaj_hat_);
+
+	double sqrt_vj_y_error=alp_data::error_of_the_sqrt(vj_y,vj_y_error);
+
+	double sqrt_vj_y=sqrt(vj_y);
+
+	double n_F;
+	double n_F_error;
+
+	if(sqrt_vj_y==0.0||blast_)
+	{
+		n_F=1e100;
+		n_F_error=0.0;
+	}
+	else
+	{
+		n_F_error=alp_data::error_of_the_ratio(n_lj_y,n_lj_y_error,sqrt_vj_y,sqrt_vj_y_error);
+
+		n_F=n_lj_y/sqrt_vj_y;
+	};
+
+	double P_n_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,n_F,eps);
+	double P_n_F_error=const_val*exp(-0.5*n_F*n_F)*n_F_error;
+
+	double E_n_F=-const_val*exp(-0.5*n_F*n_F);
+	double E_n_F_error=fabs(-E_n_F*n_F)*n_F_error;
+
+	double n_lj_y_P_n_F_error=alp_data::error_of_the_product(n_lj_y,n_lj_y_error,P_n_F,P_n_F_error);
+	double n_lj_y_P_n_F=n_lj_y*P_n_F;
+
+	double sqrt_vj_y_E_n_F_error=alp_data::error_of_the_product(sqrt_vj_y,sqrt_vj_y_error,E_n_F,E_n_F_error);
+	double sqrt_vj_y_E_n_F=sqrt_vj_y*E_n_F;
+
+	double p2_error=alp_data::error_of_the_sum(n_lj_y_P_n_F_error,sqrt_vj_y_E_n_F_error);
+	double p2=n_lj_y_P_n_F-sqrt_vj_y_E_n_F;
+
+
+
+
+	double c_y_error=0;
+	double c_y=0;
+
+	c_y_error=alp_data::error_of_the_sum(sigma_hat_error_*y_,tau_hat_error_);
+
+	c_y=alp_data::Tmax(par_.c_y_thr,sigma_hat_*y_+tau_hat_);
+
+	double P_m_F_P_n_F_error=alp_data::error_of_the_product(P_m_F,P_m_F_error,P_n_F,P_n_F_error);
+	double P_m_F_P_n_F=P_m_F*P_n_F;
+
+	double c_y_P_m_F_P_n_F_error=alp_data::error_of_the_product(c_y,c_y_error,P_m_F_P_n_F,P_m_F_P_n_F_error);
+	double c_y_P_m_F_P_n_F=c_y*P_m_F_P_n_F;
+
+	double p1_p2_error=alp_data::error_of_the_product(p1,p1_error,p2,p2_error);
+	double p1_p2=p1*p2;
+
+
+	double area_error=alp_data::error_of_the_sum(p1_p2_error,c_y_P_m_F_P_n_F_error);
+	double area=p1_p2+c_y_P_m_F_P_n_F;
+
+
+
+
+	if(!blast_)
+	{
+		//area=alp_data::Tmax(area,1.0);
+	}
+	else
+	{
+		if(area<=1.0)
+		{
+			area_is_1_flag_=true;
+		};
+
+		if(area_is_1_flag_)
+		{
+			area=1.0;
+		};
+	};
+
+
+	double exp_lambda_y_error=fabs(lambda_error_*y_*exp(-lambda_*y_));
+	double exp_lambda_y=exp(-lambda_*y_);
+
+	double k_exp_lambda_y_error=alp_data::error_of_the_product(k_,k_error_,exp_lambda_y,exp_lambda_y_error);
+	double k_exp_lambda_y=k_*exp_lambda_y;
+
+	double area_k_exp_lambda_y_error=alp_data::error_of_the_product(area,area_error,k_exp_lambda_y,k_exp_lambda_y_error);
+	double area_k_exp_lambda_y=-area*k_exp_lambda_y;
+
+	E_=-area_k_exp_lambda_y;
+	E_error_=area_k_exp_lambda_y_error;
+
+	P_error_=exp(area_k_exp_lambda_y)*area_k_exp_lambda_y_error;
+
+	P_=sls_basic::one_minus_exp_function(area_k_exp_lambda_y);
+//	P_=1-exp(-k_*area*exp(-lambda_*y_));
+
+	area_=area;
+
+
+}
+
+void pvalues::compute_intercepts(
+ALP_set_of_parameters &par_)
+{
+	if(!par_.d_params_flag)
+	{
+		throw error("Unexpected error: pvalues::compute_intercepts is called for undefined parameters\n",1);
+	};
+
+	par_.b_I=2.0*par_.G*(par_.gapless_a-par_.a_I); 
+	par_.b_I_error=2.0*par_.G*alp_data::error_of_the_sum(par_.gapless_a_error,par_.a_I_error); 
+	par_.beta_I=2.0*par_.G*(par_.gapless_alpha-par_.alpha_I); 
+	par_.beta_I_error=2.0*par_.G*alp_data::error_of_the_sum(par_.gapless_alpha_error,par_.alpha_I_error); 
+
+	par_.b_J=2.0*par_.G*(par_.gapless_a-par_.a_J); 
+	par_.b_I_error=2.0*par_.G*alp_data::error_of_the_sum(par_.gapless_a_error,par_.a_J_error); 
+	par_.beta_J=2.0*par_.G*(par_.gapless_alpha-par_.alpha_J); 
+	par_.beta_J_error=2.0*par_.G*alp_data::error_of_the_sum(par_.gapless_alpha_error,par_.alpha_J_error); 
+
+	par_.tau=2.0*par_.G*(par_.gapless_alpha-par_.sigma);
+	par_.tau_error=2.0*par_.G*alp_data::error_of_the_sum(par_.gapless_alpha_error,par_.sigma_error);
+
+	long int vector_size=(long int)par_.m_LambdaSbs.size();
+
+	par_.m_BISbs.resize(vector_size);
+	par_.m_BJSbs.resize(vector_size);
+	par_.m_BetaISbs.resize(vector_size);
+	par_.m_BetaJSbs.resize(vector_size);
+	par_.m_TauSbs.resize(vector_size);
+
+	long int i;
+	for(i=0;i<vector_size;i++)
+	{
+		par_.m_BISbs[i]=2.0*par_.G*(par_.gapless_a-par_.m_AISbs[i]); 
+		par_.m_BetaISbs[i]=2.0*par_.G*(par_.gapless_alpha-par_.m_AlphaISbs[i]); 
+
+		par_.m_BJSbs[i]=2.0*par_.G*(par_.gapless_a-par_.m_AJSbs[i]); 
+		par_.m_BetaJSbs[i]=2.0*par_.G*(par_.gapless_alpha-par_.m_AlphaJSbs[i]); 
+
+		par_.m_TauSbs[i]=2.0*par_.G*(par_.gapless_alpha-par_.m_SigmaSbs[i]);
+	};
+
+	compute_tmp_values(par_);
+
+}
+
+void pvalues::compute_tmp_values(ALP_set_of_parameters &par_)
+{
+	if(!par_.d_params_flag)
+	{
+		throw error("Unexpected call of pvalues::compute_tmp_values\n",1);
+	};
+
+	//tmp values
+	if(par_.lambda>0)
+	{
+		par_.vi_y_thr=alp_data::Tmax(nat_cut_off_in_max*par_.alpha_I/par_.lambda,0.0);
+		par_.vj_y_thr=alp_data::Tmax(nat_cut_off_in_max*par_.alpha_J/par_.lambda,0.0);
+		par_.c_y_thr=alp_data::Tmax(nat_cut_off_in_max*par_.sigma/par_.lambda,0.0);
+	}
+	else
+	{
+		par_.vi_y_thr=0;
+		par_.vj_y_thr=0;
+		par_.c_y_thr=0;
+
+		par_.d_params_flag=false;
+	};
+}
+
+void pvalues::get_appr_tail_prob_with_cov_without_errors(
+const ALP_set_of_parameters &par_,
+bool blast_,
+double y_,
+double m_,
+double n_,
+
+double &P_,
+
+double &E_,
+
+double &area_,
+
+double a_normal_,
+double b_normal_,
+double h_normal_,
+long int N_normal_,
+double *p_normal_,
+
+bool &area_is_1_flag_,
+bool compute_only_area_)
+{
+
+	//to optimize performance
+	blast_=false;
+
+	double lambda_=par_.lambda;
+	double k_=par_.K;
+
+	double ai_hat_=par_.a_I;
+	double bi_hat_;
+	double alphai_hat_=par_.alpha_I;
+	double betai_hat_;
+
+	double aj_hat_=par_.a_J;
+	double bj_hat_;
+	double alphaj_hat_=par_.alpha_J;
+	double betaj_hat_;
+
+	double sigma_hat_=par_.sigma;
+	double tau_hat_;
+
+	{
+		bi_hat_=par_.b_I;
+		betai_hat_=par_.beta_I;
+
+		bj_hat_=par_.b_J;
+		betaj_hat_=par_.beta_J;
+
+		tau_hat_=par_.tau;
+	};
+
+	if(blast_)
+	{
+		alphai_hat_=0;
+		betai_hat_=0;
+
+		alphaj_hat_=0;
+		betaj_hat_=0;
+
+		sigma_hat_=0;
+		tau_hat_=0;
+	};
+
+	double eps=0.000001;
+
+	double m_li_y=0;
+
+	double tmp=ai_hat_*y_+bi_hat_;
+
+	m_li_y=m_-tmp;
+	
+	double vi_y=0;
+
+	vi_y=alp_data::Tmax(par_.vi_y_thr,alphai_hat_*y_+betai_hat_);
+
+	double sqrt_vi_y=sqrt(vi_y);
+
+
+	double m_F;
+
+	if(sqrt_vi_y==0.0||blast_)
+	{
+		m_F=1e100;
+	}
+	else
+	{
+		m_F=m_li_y/sqrt_vi_y;
+	};
+
+
+	double P_m_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,m_F,eps);
+
+	double E_m_F=-const_val*exp(-0.5*m_F*m_F);
+
+	double m_li_y_P_m_F=m_li_y*P_m_F;
+
+	double sqrt_vi_y_E_m_F=sqrt_vi_y*E_m_F;
+
+	double p1=m_li_y_P_m_F-sqrt_vi_y_E_m_F;
+
+
+	double n_lj_y=0;
+
+	tmp=aj_hat_*y_+bj_hat_;
+
+	n_lj_y=n_-tmp;
+
+	double vj_y=0;
+
+	vj_y=alp_data::Tmax(par_.vj_y_thr,alphaj_hat_*y_+betaj_hat_);
+
+	double sqrt_vj_y=sqrt(vj_y);
+
+	double n_F;
+
+	if(sqrt_vj_y==0.0||blast_)
+	{
+		n_F=1e100;
+	}
+	else
+	{
+		n_F=n_lj_y/sqrt_vj_y;
+	};
+
+	double P_n_F=sls_basic::normal_probability(a_normal_,b_normal_,h_normal_,N_normal_,p_normal_,n_F,eps);
+
+	double E_n_F=-const_val*exp(-0.5*n_F*n_F);
+
+	double n_lj_y_P_n_F=n_lj_y*P_n_F;
+
+	double sqrt_vj_y_E_n_F=sqrt_vj_y*E_n_F;
+
+	double p2=n_lj_y_P_n_F-sqrt_vj_y_E_n_F;
+
+
+
+
+	double c_y=0;
+
+	c_y=alp_data::Tmax(par_.c_y_thr,sigma_hat_*y_+tau_hat_);
+
+	double P_m_F_P_n_F=P_m_F*P_n_F;
+
+	double c_y_P_m_F_P_n_F=c_y*P_m_F_P_n_F;
+
+	double p1_p2=p1*p2;
+
+	double area=p1_p2+c_y_P_m_F_P_n_F;
+
+
+
+
+	if(!blast_)
+	{
+		//area=alp_data::Tmax(area,1.0);
+	}
+	else
+	{
+		if(area<=1.0)
+		{
+			area_is_1_flag_=true;
+		};
+
+		if(area_is_1_flag_)
+		{
+			area=1.0;
+		};
+	};
+
+	area_=area;
+
+	if(compute_only_area_)
+	{
+		return;
+	};
+
+	double exp_lambda_y=exp(-lambda_*y_);
+
+	double k_exp_lambda_y=k_*exp_lambda_y;
+
+	double area_k_exp_lambda_y=-area*k_exp_lambda_y;
+
+	E_=-area_k_exp_lambda_y;
+
+	P_=sls_basic::one_minus_exp_function(area_k_exp_lambda_y);
+//	P_=1-exp(-k_*area*exp(-lambda_*y_));
+
+}
+
+void pvalues::get_P_error_using_splitting_method(
+const ALP_set_of_parameters &par_,
+bool blast_,
+double y_,
+double m_,
+double n_,
+
+double &P_,
+double &P_error_,
+
+double &E_,
+double &E_error_,
+
+double a_normal_,
+double b_normal_,
+double h_normal_,
+long int N_normal_,
+double *p_normal_,
+
+bool &area_is_1_flag_)
+{
+	long int dim=par_.m_LambdaSbs.size();
+	if(dim==0)
+	{
+		throw error("Unexpected error in get_P_error_using_splitting_method\n",1);
+	};
+
+	P_=0;
+	P_error_=0;
+
+	E_=0;
+	E_error_=0;
+
+	double exp_E_values_aver=0;
+	double exp_E_values_error=0;
+
+
+	vector<double> P_values(dim);
+	vector<double> E_values(dim);
+	vector<double> exp_E_values(dim);
+
+
+	long int i;
+	for(i=0;i<dim;i++)
+	{
+		ALP_set_of_parameters par_tmp;
+
+		par_tmp.a_I=par_.m_AISbs[i];
+		par_tmp.a_I_error=0;
+
+		par_tmp.a_J=par_.m_AJSbs[i];
+		par_tmp.a_J_error=0;
+
+		
+
+		par_tmp.gapless_a=par_.gapless_a;
+		par_tmp.gapless_a_error=par_.gapless_a_error;
+
+		par_tmp.a=0.5*(par_tmp.a_I+par_tmp.a_J);
+		par_tmp.a_error=0;
+
+
+		par_tmp.sigma=par_.m_SigmaSbs[i];
+		par_tmp.sigma_error=0;
+
+		par_tmp.gapless_alpha=par_.gapless_alpha;
+		par_tmp.gapless_alpha_error=par_.gapless_alpha_error;
+
+
+		par_tmp.C=par_.m_CSbs[i];
+		par_tmp.C_error=0;
+
+		par_tmp.K=par_.m_KSbs[i];
+		par_tmp.K_error=0;
+
+
+		par_tmp.lambda=par_.m_LambdaSbs[i];
+		par_tmp.lambda_error=0;
+
+		par_tmp.alpha_I=par_.m_AlphaISbs[i];
+		par_tmp.alpha_I_error=0;
+
+		par_tmp.alpha_J=par_.m_AlphaJSbs[i];
+		par_tmp.alpha_J_error=0;
+
+		par_tmp.alpha=0.5*(par_tmp.alpha_I+par_tmp.alpha_J);
+		par_tmp.alpha_error=0;
+
+		par_tmp.G=par_.G;
+		par_tmp.G1=par_.G1;
+		par_tmp.G2=par_.G2;
+
+		//intercepts
+
+		{
+			par_tmp.b_I=par_.m_BISbs[i];
+			par_tmp.b_I_error=0;
+
+			par_tmp.b_J=par_.m_BJSbs[i];
+			par_tmp.b_J_error=0;
+
+			par_tmp.beta_I=par_.m_BetaISbs[i];
+			par_tmp.beta_I_error=0;
+
+			par_tmp.beta_J=par_.m_BetaJSbs[i];
+			par_tmp.beta_J_error=0;
+
+			par_tmp.tau=par_.m_TauSbs[i];
+			par_tmp.tau_error=0;
+
+			par_tmp.d_params_flag=true;
+
+			compute_tmp_values(par_tmp);
+
+		};
+
+
+		double P_tmp,area_tmp,E_tmp;
+
+		get_appr_tail_prob_with_cov_without_errors(
+		par_tmp,
+		blast_,
+		y_,
+		m_,
+		n_,
+
+		P_tmp,
+
+		E_tmp,
+
+		area_tmp,
+
+		a_normal_,
+		b_normal_,
+		h_normal_,
+		N_normal_,
+		p_normal_,
+
+		area_is_1_flag_);
+
+		P_values[i]=P_tmp;
+
+		P_+=P_tmp;
+
+		E_values[i]=E_tmp;
+
+		E_+=E_tmp;
+
+		double exp_E_tmp=exp(-E_tmp);
+		exp_E_values[i]=exp_E_tmp;
+		exp_E_values_aver+=exp_E_tmp;
+
+
+	};
+
+	if(dim<=1)
+	{
+		return;
+	};
+
+
+	if(P_<=0)
+	{
+		return;
+	};
+
+	if(E_<=0)
+	{
+		return;
+	};
+
+
+	P_/=(double)dim;
+	E_/=(double)dim;
+	exp_E_values_aver/=(double)dim;
+
+	for(i=0;i<dim;i++)
+	{
+		double tmp;
+		
+		if(P_>0)
+		{
+			tmp=P_values[i]/P_;
+			P_error_+=tmp*tmp;
+		};
+
+		if(E_>0)
+		{
+			tmp=E_values[i]/E_;
+			E_error_+=tmp*tmp;
+		};
+
+		if(exp_E_values_aver>0)
+		{
+			tmp=exp_E_values[i]/exp_E_values_aver;
+			exp_E_values_error+=tmp*tmp;
+		};
+
+	};
+
+	P_error_/=(double)dim;
+	P_error_-=1;
+	
+	E_error_/=(double)dim;
+	E_error_-=1;
+
+	exp_E_values_error/=(double)dim;
+	exp_E_values_error-=1;
+
+
+	if(P_<1e-4)
+	{
+		P_error_=P_*alp_reg::sqrt_for_errors(P_error_/(double)dim);
+	}
+	else
+	{
+		P_error_=exp_E_values_aver*alp_reg::sqrt_for_errors(exp_E_values_error/(double)dim);
+	};
+
+	E_error_=E_*alp_reg::sqrt_for_errors(E_error_/(double)dim);
+
+}
+
+
+pvalues::pvalues()
+{
+	blast=false;
+	eps=0.0001;
+	a_normal=-10;
+	b_normal=10;
+	N_normal=NORMAL_DISTR_ARRAY_DIM;
+	h_normal=(b_normal-a_normal)/(double)N_normal;
+	p_normal=normal_distr_array_for_P_values_calculation;
+}
+
+
+pvalues::~pvalues()
+{
+	
+}
+
+void pvalues::calculate_P_values(
+long int Score1,
+long int Score2,
+double Seq1Len,
+double Seq2Len,
+const ALP_set_of_parameters &ParametersSet,
+vector<double> &P_values,
+vector<double> &P_values_errors,
+vector<double> &E_values,
+vector<double> &E_values_errors)
+{
+	if(Score2<Score1)
+	{
+		throw error("Error - Score2<Score1\n",2);
+	};
+
+	if(Seq1Len<=0||Seq2Len<=0)
+	{
+		throw error("Error - Seq1Len<=0||Seq2Len<=0\n",2);
+	};
+
+	P_values.resize(Score2-Score1+1);
+	P_values_errors.resize(Score2-Score1+1);
+
+	E_values.resize(Score2-Score1+1);
+	E_values_errors.resize(Score2-Score1+1);
+
+
+	long int y;
+	for(y=Score1;y<=Score2;y++)
+	{
+		calculate_P_values(
+		y,
+		Seq1Len,
+		Seq2Len,
+		ParametersSet,
+		P_values[y-Score1],
+		P_values_errors[y-Score1],
+		E_values[y-Score1],
+		E_values_errors[y-Score1]);
+	};
+
+}
+
+void pvalues::calculate_P_values(
+double Score,
+double Seq1Len,
+double Seq2Len,
+const ALP_set_of_parameters &ParametersSet,
+double &P_value,
+double &P_value_error,
+double &E_value,
+double &E_value_error,
+bool read_Sbs_par_flag)
+{
+
+	if(Seq1Len<=0||Seq2Len<=0)
+	{
+		throw error("Error - Seq1Len<=0||Seq2Len<=0\n",2);
+	};
+
+	double P;
+	double P_error;
+	double E;
+	double E_error;
+	double area;
+	bool area_is_1_flag=false;
+
+
+	if(read_Sbs_par_flag)
+	{
+		
+
+		get_appr_tail_prob_with_cov_without_errors(
+		ParametersSet,
+		blast,
+		Score,
+		Seq1Len,
+		Seq2Len,
+
+		P,
+
+		E,
+
+		area,
+		a_normal,
+		b_normal,
+		h_normal,
+		N_normal,
+		p_normal,
+		area_is_1_flag);
+
+
+		
+		double P_tmp,E_tmp;
+
+		if(ParametersSet.m_LambdaSbs.size()>0)
+		{
+			get_P_error_using_splitting_method(
+			ParametersSet,
+			blast,
+			Score,
+			Seq1Len,
+			Seq2Len,
+
+			P_tmp,
+			P_error,
+
+			E_tmp,
+			E_error,
+
+			a_normal,
+			b_normal,
+			h_normal,
+			N_normal,
+			p_normal,
+			area_is_1_flag);
+
+
+			if(P_tmp>0)
+			{
+				P_error=P_error/P_tmp*P;
+			};
+
+			P_value_error=P_error;
+
+			if(E_tmp>0)
+			{
+				E_error=E_error/E_tmp*E;
+			};
+
+			E_value_error=E_error;
+
+		}
+		else
+		{
+			P_value_error=-DBL_MAX;
+			E_value_error=-DBL_MAX;
+		};
+
+		
+		
+	}
+	else
+	{
+		get_appr_tail_prob_with_cov(
+		ParametersSet,
+		blast,
+		Score,
+		Seq1Len,
+		Seq2Len,
+
+		P,
+		P_error,
+
+		E,
+		E_error,
+
+		area,
+		a_normal,
+		b_normal,
+		h_normal,
+		N_normal,
+		p_normal,
+		area_is_1_flag);
+
+		P_value_error=P_error;
+		E_value_error=E_error;
+	};
+
+	P_value=P;
+	E_value=E;
+}
+
+
+//input/output Gumbel parameters
+
+namespace Sls {
+
+std::ostream &operator<<(std::ostream &s_,
+const ALP_set_of_parameters &gumbel_params_)
+{
+
+
+	s_<<"Lambda\tLambda error\tK\tK error\tC\tC error\ta\ta error\ta_1\ta_1 error\ta_2\ta_2 error\tsigma\tsigma error\talpha\talpha error\talpha_1\talpha_1 error\talpha_2\talpha_2 error\tGapless a\tGapless a error\tGapless alpha\tGapless alpha error\tG\tCalculation time\tArrays for error calculation\n";
+	s_.precision(17);
+	s_<<
+		gumbel_params_.lambda<<"\t"<<gumbel_params_.lambda_error<<"\t"<<
+		gumbel_params_.K<<"\t"<<gumbel_params_.K_error<<"\t"<<
+		gumbel_params_.C<<"\t"<<gumbel_params_.C_error<<"\t"<<
+		gumbel_params_.a<<"\t"<<gumbel_params_.a_error<<"\t"<<
+		gumbel_params_.a_J<<"\t"<<gumbel_params_.a_J_error<<"\t"<<
+		gumbel_params_.a_I<<"\t"<<gumbel_params_.a_I_error<<"\t"<<
+		gumbel_params_.sigma<<"\t"<<gumbel_params_.sigma_error<<"\t"<<
+		gumbel_params_.alpha<<"\t"<<gumbel_params_.alpha_error<<"\t"<<
+		gumbel_params_.alpha_J<<"\t"<<gumbel_params_.alpha_J_error<<"\t"<<
+		gumbel_params_.alpha_I<<"\t"<<gumbel_params_.alpha_I_error<<"\t"<<
+		gumbel_params_.gapless_a<<"\t"<<gumbel_params_.gapless_a_error<<"\t"<<
+		gumbel_params_.gapless_alpha<<"\t"<<gumbel_params_.gapless_alpha_error<<"\t"<<
+		gumbel_params_.G<<"\t"<<
+		gumbel_params_.m_CalcTime<<"\t";
+
+	long int i;
+
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_LambdaSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_KSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_CSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_AJSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_AISbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_SigmaSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_AlphaJSbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+
+	{
+		const vector<double> &tmp=gumbel_params_.m_AlphaISbs;
+		s_<<tmp.size()<<"\t";
+		for(i=0;i<(long int)tmp.size();i++)
+		{
+			s_<<tmp[i]<<"\t";
+		};
+	};
+
+	s_<<endl;
+
+	return s_;
+
+}
+
+std::istream &operator>>(std::istream &s_,
+ALP_set_of_parameters &gumbel_params_)
+{
+
+	gumbel_params_.d_params_flag=false;
+	try
+	{
+
+		string st;
+		getline(s_,st);
+		s_>>
+			gumbel_params_.lambda>>gumbel_params_.lambda_error>>
+			gumbel_params_.K>>gumbel_params_.K_error>>
+			gumbel_params_.C>>gumbel_params_.C_error>>
+			gumbel_params_.a>>gumbel_params_.a_error>>
+			gumbel_params_.a_J>>gumbel_params_.a_J_error>>
+			gumbel_params_.a_I>>gumbel_params_.a_I_error>>
+			gumbel_params_.sigma>>gumbel_params_.sigma_error>>
+			gumbel_params_.alpha>>gumbel_params_.alpha_error>>
+			gumbel_params_.alpha_J>>gumbel_params_.alpha_J_error>>
+			gumbel_params_.alpha_I>>gumbel_params_.alpha_I_error>>
+			gumbel_params_.gapless_a>>gumbel_params_.gapless_a_error>>
+			gumbel_params_.gapless_alpha>>gumbel_params_.gapless_alpha_error>>
+			gumbel_params_.G>>
+			gumbel_params_.m_CalcTime;
+
+		long int i;
+
+
+		{
+			vector<double> &tmp=gumbel_params_.m_LambdaSbs;
+			long int tmp_size;
+			s_>>tmp_size;
+			if(tmp_size<=0)
+			{
+				throw error("Error in the input parameters\n",4);
+			};
+			tmp.resize(tmp_size);
+			for(i=0;i<tmp_size;i++)
+			{
+				s_>>tmp[i];
+			};
+		};
+
+		{
+			vector<double> &tmp=gumbel_params_.m_KSbs;
+			long int tmp_size;
+			s_>>tmp_size;
+			if(tmp_size<=0)
+			{
+				throw error("Error in the input parameters\n",4);
+			};
+			tmp.resize(tmp_size);
+			for(i=0;i<tmp_size;i++)
+			{
+				s_>>tmp[i];
+			};
+		};
+
+
+		{
+			vector<double> &tmp=gumbel_params_.m_CSbs;
+			long int tmp_size;
+			s_>>tmp_size;
+			if(tmp_size<=0)
+			{
+				throw error("Error in the input parameters\n",4);
+			};
+			tmp.resize(tmp_size);
+			for(i=0;i<tmp_size;i++)
+			{
+				s_>>tmp[i];
+			};
+		};
+
+
+
+		{
+			vector<double> &tmp=gumbel_params_.m_AJSbs;
+			long int tmp_size;
+			s_>>tmp_size;
+			if(tmp_size<=0)
+			{
+				throw error("Error in the input parameters\n",4);
+			};
+			tmp.resize(tmp_size);
+			for(i=0;i<tmp_size;i++)
+			{
+				s_>>tmp[i];
+			};
+		};
+
+		{
+			vector<double> &tmp=gumbel_params_.m_AISbs;
+			long int tmp_size;
+			s_>>tmp_size;
+			if(tmp_size<=0)
+			{
+				throw error("Error in the input parameters\n",4);
+			};
+			tmp.resize(tmp_size);
+			for(i=0;i<tmp_size;i++)
+			{
+				s_>>tmp[i];
+			};
+		};
+
+
+
+		{
+			vector<double> &tmp=gumbel_params_.m_SigmaSbs;
+			long int tmp_size;
+			s_>>tmp_size;
+			if(tmp_size<=0)
+			{
+				throw error("Error in the input parameters\n",4);
+			};
+			tmp.resize(tmp_size);
+			for(i=0;i<tmp_size;i++)
+			{
+				s_>>tmp[i];
+			};
+		};
+
+
+		{
+			vector<double> &tmp=gumbel_params_.m_AlphaJSbs;
+			long int tmp_size;
+			s_>>tmp_size;
+			if(tmp_size<=0)
+			{
+				throw error("Error in the input parameters\n",4);
+			};
+			tmp.resize(tmp_size);
+			for(i=0;i<tmp_size;i++)
+			{
+				s_>>tmp[i];
+			};
+		};
+
+		{
+			vector<double> &tmp=gumbel_params_.m_AlphaISbs;
+			long int tmp_size;
+			s_>>tmp_size;
+			if(tmp_size<=0)
+			{
+				throw error("Error in the input parameters\n",4);
+			};
+			tmp.resize(tmp_size);
+			for(i=0;i<tmp_size;i++)
+			{
+				s_>>tmp[i];
+			};
+		};
+
+		gumbel_params_.d_params_flag=true;
+		return s_;
+	}
+	catch (...)
+	{ 
+		gumbel_params_.d_params_flag=false;
+		throw;
+	};
+
+}
+
+//returns "true" if the Gumbel parameters are properly defined and "false" otherwise
+bool pvalues::assert_Gumbel_parameters(
+const ALP_set_of_parameters &par_)//a set of Gumbel parameters
+{
+		if(par_.lambda<=0||
+		par_.lambda_error<0||
+
+		//the parameters C and K_C are not necessary for the P-value calculation
+		//par_.C<0||
+		//par_.C_error<0||
+
+		par_.K<=0||
+		par_.K_error<0||
+
+		par_.a_I<0||
+		par_.a_I_error<0||
+
+		par_.a_J<0||
+		par_.a_J_error<0||
+
+		par_.sigma<0||
+		par_.sigma_error<0||
+
+		par_.alpha_I<0||
+		par_.alpha_I_error<0||
+
+		par_.alpha_J<0||
+		par_.alpha_J_error<0||
+
+		par_.gapless_a<0||
+		par_.gapless_a_error<0||
+
+		par_.gapless_alpha<0||
+		par_.gapless_alpha_error<0||
+
+		par_.G<0||
+		par_.G1<0||
+		par_.G2<0||
+
+		//intercepts
+		par_.b_I_error<0||
+
+		par_.b_J_error<0||
+
+		par_.beta_I_error<0||
+
+		par_.beta_J_error<0||
+
+		par_.tau_error<0
+
+		)
+		{
+			return false;
+		};
+
+
+
+		size_t size_tmp=par_.m_LambdaSbs.size();
+		if(
+		par_.m_KSbs.size()!=size_tmp||
+		//par_.m_CSbs.size()!=size_tmp||
+
+		par_.m_SigmaSbs.size()!=size_tmp||
+
+		par_.m_AlphaISbs.size()!=size_tmp||
+		par_.m_AlphaJSbs.size()!=size_tmp||
+
+		par_.m_AISbs.size()!=size_tmp||
+		par_.m_AJSbs.size()!=size_tmp||
+
+		par_.m_BISbs.size()!=size_tmp||
+		par_.m_BJSbs.size()!=size_tmp||
+
+		par_.m_BetaISbs.size()!=size_tmp||
+		par_.m_BetaJSbs.size()!=size_tmp||
+
+		par_.m_TauSbs.size()!=size_tmp)
+		{
+			return false;
+		};
+
+
+		return true;
+
+}
+
+
+
+}
+
diff --git a/src/alp/sls_pvalues.hpp b/src/alp/sls_pvalues.hpp
index 04216ff..c47dd37 100644
--- a/src/alp/sls_pvalues.hpp
+++ b/src/alp/sls_pvalues.hpp
@@ -1,326 +1,326 @@
-#ifndef INCLUDED_SLS_PVALUES
-#define INCLUDED_SLS_PVALUES
-
-/* $Id: $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's offical duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================*/
-
-/*****************************************************************************
-
-File name: sls_pvalues.hpp
-
-Author: Sergey Sheetlin
-
-Contents: P-values calculation routines
-
-******************************************************************************/
-
-#include "sls_basic.hpp"
-
-#include <vector>
-#include <string>
-#include <math.h>
-#include <cstdlib>
-
-#include <cmath>
-#include <iostream>
-
-namespace Sls {
-
-	struct ALP_set_of_parameters
-	{
-		ALP_set_of_parameters()
-		{
-			d_params_flag=false;
-
-			b_I=0;
-			b_I_error=0;
-
-			b_J=0;
-			b_J_error=0;
-
-			beta_I=0;
-			beta_I_error=0;
-
-			beta_J=0;
-			beta_J_error=0;
-
-			tau=0;
-			tau_error=0;
-
-		};
-
-		double lambda;
-		double lambda_error;
-
-		double C;
-		double C_error;
-
-
-		double K;
-		double K_error;
-
-		double a_I;
-		double a_I_error;
-
-		double a_J;
-		double a_J_error;
-
-		double sigma;
-		double sigma_error;
-
-		double alpha_I;
-		double alpha_I_error;
-
-		double alpha_J;
-		double alpha_J_error;
-
-		double a;
-		double a_error;
-
-		double alpha;
-		double alpha_error;
-
-		double gapless_a;
-		double gapless_a_error;
-
-		double gapless_alpha;
-		double gapless_alpha_error;
-
-		long int G;
-		long int G1;
-		long int G2;
-
-		std::vector<double > m_LambdaSbs;
-		std::vector<double > m_KSbs;
-		std::vector<double > m_CSbs;
-
-		std::vector<double > m_SigmaSbs;
-
-		std::vector<double > m_AlphaISbs;
-		std::vector<double > m_AlphaJSbs;
-
-		std::vector<double > m_AISbs;
-		std::vector<double > m_AJSbs;
-
-		double m_CalcTime;
-
-		bool d_params_flag;//if true, then the parameters are defined and P-values can be calculated
-
-		//intercepts
-		double b_I;
-		double b_I_error;
-
-		double b_J;
-		double b_J_error;
-
-		double beta_I;
-		double beta_I_error;
-
-		double beta_J;
-		double beta_J_error;
-
-		double tau;
-		double tau_error;
-
-		std::vector<double > m_BISbs;
-		std::vector<double > m_BJSbs;
-
-		std::vector<double > m_BetaISbs;
-		std::vector<double > m_BetaJSbs;
-
-		std::vector<double > m_TauSbs;
-
-		//tmp values
-		double vi_y_thr;
-		double vj_y_thr;
-		double c_y_thr;
-	};
-
-	std::ostream &operator<<(std::ostream &s_,
-	const ALP_set_of_parameters &gumbel_params_);
-
-	std::istream &operator>>(std::istream &s_,
-	ALP_set_of_parameters &gumbel_params_);
-
-	class pvalues{
-
-		public:
-
-
-		pvalues();
-
-		~pvalues();
-
-
-		public:
-
-		static void get_appr_tail_prob_with_cov(
-		const ALP_set_of_parameters &par_,
-		bool blast_,
-		double y_,
-		double m_,
-		double n_,
-
-		double &P_,
-		double &P_error_,
-
-		double &E_,
-		double &E_error_,
-
-		double &area_,
-
-		double a_normal_,
-		double b_normal_,
-		double h_normal_,
-		long int N_normal_,
-		double *p_normal_,
-
-		bool &area_is_1_flag_);
-
-		static void compute_tmp_values(ALP_set_of_parameters &par_);
-
-		static void get_appr_tail_prob_with_cov_without_errors(
-		const ALP_set_of_parameters &par_,
-		bool blast_,
-		double y_,
-		double m_,
-		double n_,
-
-		double &P_,
-
-		double &E_,
-
-		double &area_,
-
-		double a_normal_,
-		double b_normal_,
-		double h_normal_,
-		long int N_normal_,
-		double *p_normal_,
-
-		bool &area_is_1_flag_,
-		bool compute_only_area_=false);
-
-		static void get_P_error_using_splitting_method(
-		const ALP_set_of_parameters &par_,
-		bool blast_,
-		double y_,
-		double m_,
-		double n_,
-
-		double &P_,
-		double &P_error_,
-
-		double &E_,
-		double &E_error_,
-
-		double a_normal_,
-		double b_normal_,
-		double h_normal_,
-		long int N_normal_,
-		double *p_normal_,
-
-		bool &area_is_1_flag_);
-
-
-		public:
-
-		static void compute_intercepts(
-		ALP_set_of_parameters &par_);
-
-		void calculate_P_values(
-		long int Score1,
-		long int Score2,
-		double Seq1Len,
-		double Seq2Len,
-		const ALP_set_of_parameters &ParametersSet,
-		std::vector<double> &P_values,
-		std::vector<double> &P_values_errors,
-		std::vector<double> &E_values,
-		std::vector<double> &E_values_errors);
-
-		void calculate_P_values(
-		double Score,
-		double Seq1Len,
-		double Seq2Len,
-		const ALP_set_of_parameters &ParametersSet,
-		double &P_value,
-		double &P_value_error,
-		double &E_value,
-		double &E_value_error,
-		bool read_Sbs_par_flag=true);
-
-		static inline double ran3()//generates the next random value
-		{
-			double rand_C=(double)((double)rand()/(double)RAND_MAX);
-			return rand_C;	
-		};
-
-		static inline double standard_normal()//generates standard normal random value using the Box�Muller transform
-		{
-			double r1=0;
-			while(r1==0)
-			{
-				r1=ran3();
-			};
-			double r2=0;
-			while(r2==0)
-			{
-				r2=ran3();
-			};
-
-			double v1=-2*log(r1);
-			if(v1<0)
-			{
-				v1=0;
-			};
-			return sqrt(v1)*cos(2*pi*r2);
-		};
-
-		static //returns "true" if the Gumbel parameters are properly defined and "false" otherwise
-		bool assert_Gumbel_parameters(
-		const ALP_set_of_parameters &par_);//a set of Gumbel parameters
-
-
-
-
-
-		public:
-
-
-		bool blast;
-		double eps;
-		double a_normal;
-		double b_normal;
-		long int N_normal;
-		double h_normal;
-		double *p_normal;
-
-
-	};
-}
-
-#endif //! INCLUDED
-
+#ifndef INCLUDED_SLS_PVALUES
+#define INCLUDED_SLS_PVALUES
+
+/* $Id: $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's offical duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+
+/*****************************************************************************
+
+File name: sls_pvalues.hpp
+
+Author: Sergey Sheetlin
+
+Contents: P-values calculation routines
+
+******************************************************************************/
+
+#include "sls_basic.hpp"
+
+#include <vector>
+#include <string>
+#include <math.h>
+#include <cstdlib>
+
+#include <cmath>
+#include <iostream>
+
+namespace Sls {
+
+	struct ALP_set_of_parameters
+	{
+		ALP_set_of_parameters()
+		{
+			d_params_flag=false;
+
+			b_I=0;
+			b_I_error=0;
+
+			b_J=0;
+			b_J_error=0;
+
+			beta_I=0;
+			beta_I_error=0;
+
+			beta_J=0;
+			beta_J_error=0;
+
+			tau=0;
+			tau_error=0;
+
+		};
+
+		double lambda;
+		double lambda_error;
+
+		double C;
+		double C_error;
+
+
+		double K;
+		double K_error;
+
+		double a_I;
+		double a_I_error;
+
+		double a_J;
+		double a_J_error;
+
+		double sigma;
+		double sigma_error;
+
+		double alpha_I;
+		double alpha_I_error;
+
+		double alpha_J;
+		double alpha_J_error;
+
+		double a;
+		double a_error;
+
+		double alpha;
+		double alpha_error;
+
+		double gapless_a;
+		double gapless_a_error;
+
+		double gapless_alpha;
+		double gapless_alpha_error;
+
+		long int G;
+		long int G1;
+		long int G2;
+
+		std::vector<double > m_LambdaSbs;
+		std::vector<double > m_KSbs;
+		std::vector<double > m_CSbs;
+
+		std::vector<double > m_SigmaSbs;
+
+		std::vector<double > m_AlphaISbs;
+		std::vector<double > m_AlphaJSbs;
+
+		std::vector<double > m_AISbs;
+		std::vector<double > m_AJSbs;
+
+		double m_CalcTime;
+
+		bool d_params_flag;//if true, then the parameters are defined and P-values can be calculated
+
+		//intercepts
+		double b_I;
+		double b_I_error;
+
+		double b_J;
+		double b_J_error;
+
+		double beta_I;
+		double beta_I_error;
+
+		double beta_J;
+		double beta_J_error;
+
+		double tau;
+		double tau_error;
+
+		std::vector<double > m_BISbs;
+		std::vector<double > m_BJSbs;
+
+		std::vector<double > m_BetaISbs;
+		std::vector<double > m_BetaJSbs;
+
+		std::vector<double > m_TauSbs;
+
+		//tmp values
+		double vi_y_thr;
+		double vj_y_thr;
+		double c_y_thr;
+	};
+
+	std::ostream &operator<<(std::ostream &s_,
+	const ALP_set_of_parameters &gumbel_params_);
+
+	std::istream &operator>>(std::istream &s_,
+	ALP_set_of_parameters &gumbel_params_);
+
+	class pvalues{
+
+		public:
+
+
+		pvalues();
+
+		~pvalues();
+
+
+		public:
+
+		static void get_appr_tail_prob_with_cov(
+		const ALP_set_of_parameters &par_,
+		bool blast_,
+		double y_,
+		double m_,
+		double n_,
+
+		double &P_,
+		double &P_error_,
+
+		double &E_,
+		double &E_error_,
+
+		double &area_,
+
+		double a_normal_,
+		double b_normal_,
+		double h_normal_,
+		long int N_normal_,
+		double *p_normal_,
+
+		bool &area_is_1_flag_);
+
+		static void compute_tmp_values(ALP_set_of_parameters &par_);
+
+		static void get_appr_tail_prob_with_cov_without_errors(
+		const ALP_set_of_parameters &par_,
+		bool blast_,
+		double y_,
+		double m_,
+		double n_,
+
+		double &P_,
+
+		double &E_,
+
+		double &area_,
+
+		double a_normal_,
+		double b_normal_,
+		double h_normal_,
+		long int N_normal_,
+		double *p_normal_,
+
+		bool &area_is_1_flag_,
+		bool compute_only_area_=false);
+
+		static void get_P_error_using_splitting_method(
+		const ALP_set_of_parameters &par_,
+		bool blast_,
+		double y_,
+		double m_,
+		double n_,
+
+		double &P_,
+		double &P_error_,
+
+		double &E_,
+		double &E_error_,
+
+		double a_normal_,
+		double b_normal_,
+		double h_normal_,
+		long int N_normal_,
+		double *p_normal_,
+
+		bool &area_is_1_flag_);
+
+
+		public:
+
+		static void compute_intercepts(
+		ALP_set_of_parameters &par_);
+
+		void calculate_P_values(
+		long int Score1,
+		long int Score2,
+		double Seq1Len,
+		double Seq2Len,
+		const ALP_set_of_parameters &ParametersSet,
+		std::vector<double> &P_values,
+		std::vector<double> &P_values_errors,
+		std::vector<double> &E_values,
+		std::vector<double> &E_values_errors);
+
+		void calculate_P_values(
+		double Score,
+		double Seq1Len,
+		double Seq2Len,
+		const ALP_set_of_parameters &ParametersSet,
+		double &P_value,
+		double &P_value_error,
+		double &E_value,
+		double &E_value_error,
+		bool read_Sbs_par_flag=true);
+
+		static inline double ran3()//generates the next random value
+		{
+			double rand_C=(double)((double)rand()/(double)RAND_MAX);
+			return rand_C;	
+		};
+
+		static inline double standard_normal()//generates standard normal random value using the Box�Muller transform
+		{
+			double r1=0;
+			while(r1==0)
+			{
+				r1=ran3();
+			};
+			double r2=0;
+			while(r2==0)
+			{
+				r2=ran3();
+			};
+
+			double v1=-2*log(r1);
+			if(v1<0)
+			{
+				v1=0;
+			};
+			return sqrt(v1)*cos(2*pi*r2);
+		};
+
+		static //returns "true" if the Gumbel parameters are properly defined and "false" otherwise
+		bool assert_Gumbel_parameters(
+		const ALP_set_of_parameters &par_);//a set of Gumbel parameters
+
+
+
+
+
+		public:
+
+
+		bool blast;
+		double eps;
+		double a_normal;
+		double b_normal;
+		long int N_normal;
+		double h_normal;
+		double *p_normal;
+
+
+	};
+}
+
+#endif //! INCLUDED
+
diff --git a/src/fileMap.cc b/src/fileMap.cc
index fe2a994..9122658 100644
--- a/src/fileMap.cc
+++ b/src/fileMap.cc
@@ -24,10 +24,10 @@ static void err( const std::string& s ) {
 // loaded into memory, by reading it sequentially.  Without this,
 // random access can be horribly slow (at least on two Linux 2.6
 // systems).
-static void primeMemory( void* begin, std::size_t bytes ){
+static void primeMemory( void* begin, size_t bytes ){
   // use "static" to stop the compiler optimizing the whole function away:
   static unsigned z = 0;
-  std::size_t stepSize = 1024;
+  size_t stepSize = 1024;
   const char* x = static_cast<char*>(begin);
   const char* y = x + (bytes / stepSize) * stepSize;
   while( x < y ){
@@ -38,7 +38,7 @@ static void primeMemory( void* begin, std::size_t bytes ){
 
 namespace cbrc{
 
-void* openFileMap( const std::string& fileName, std::size_t bytes ){
+void* openFileMap( const std::string& fileName, size_t bytes ){
   if( bytes == 0 ) return 0;
 
   int f = open( fileName.c_str(), O_RDONLY );
@@ -55,7 +55,7 @@ void* openFileMap( const std::string& fileName, std::size_t bytes ){
   return m;
 }
 
-void closeFileMap( void* begin, std::size_t bytes ){
+void closeFileMap( void* begin, size_t bytes ){
   if( bytes == 0 ) return;
   int e = munmap( begin, bytes );
   if( e < 0 ) err( "failed to \"munmap\" " + stringify(bytes) + " bytes" );
diff --git a/src/fileMap.hh b/src/fileMap.hh
index 7ff216c..ebbcd3b 100644
--- a/src/fileMap.hh
+++ b/src/fileMap.hh
@@ -5,7 +5,7 @@
 #ifndef FILE_MAP_HH
 #define FILE_MAP_HH
 
-#include <cstddef>  // size_t
+#include <stddef.h>  // size_t
 #include <string>
 
 namespace cbrc{
@@ -13,11 +13,11 @@ namespace cbrc{
 // Maps a file into memory, read-only, and returns a pointer to the
 // start of the mapping.  If it fails, it throws a runtime_error.  If
 // bytes is zero, it does nothing and returns 0.
-void* openFileMap( const std::string& fileName, std::size_t bytes );
+void* openFileMap( const std::string& fileName, size_t bytes );
 
 // Releases a file mapping.  If bytes is zero, it does nothing.  If it
 // fails, it throws a runtime_error.
-void closeFileMap( void* begin, std::size_t bytes );
+void closeFileMap( void* begin, size_t bytes );
 
 }
 
diff --git a/src/lastal.cc b/src/lastal.cc
index 155a4c5..29b08d2 100644
--- a/src/lastal.cc
+++ b/src/lastal.cc
@@ -10,6 +10,7 @@
 #include "LambdaCalculator.hh"
 #include "LastEvaluer.hh"
 #include "GeneticCode.hh"
+#include "SubsetMinimizerFinder.hh"
 #include "SubsetSuffixArray.hh"
 #include "Centroid.hh"
 #include "GappedXdropAligner.hh"
@@ -28,19 +29,19 @@
 #include "gaplessTwoQualityXdrop.hh"
 #include "io.hh"
 #include "stringify.hh"
+#include "threadUtil.hh"
 #include <iomanip>  // setw
 #include <iostream>
 #include <fstream>
 #include <stdexcept>
 #include <cstdlib>  // EXIT_SUCCESS, EXIT_FAILURE
 
-#include <thread>
-
 #define ERR(x) throw std::runtime_error(x)
-#define LOG(x) if( args.verbosity > 0 ) std::cerr << "lastal: " << x << '\n'
+#define LOG(x) if( args.verbosity > 0 ) std::cerr << args.programName << ": " << x << '\n'
+#define LOG2(x) if( args.verbosity > 1 ) std::cerr << args.programName << ": " << x << '\n'
 
-static void warn( const char* s ){
-  std::cerr << "lastal: " << s << '\n';
+static void warn( const char* programName, const char* s ){
+  std::cerr << programName << ": " << s << '\n';
 }
 
 using namespace cbrc;
@@ -132,7 +133,8 @@ void permuteComplement(const double *from, double *to) {
 void makeQualityScorers(){
   if( args.isTranslated() )
     if( isQuality( args.inputFormat ) || isQuality( referenceFormat ) )
-      return warn( "quality data not used for DNA-versus-protein alignment" );
+      return warn( args.programName,
+		   "quality data not used for DNA-versus-protein alignment" );
 
   const ScoreMatrixRow* m = scoreMatrix.caseSensitive;  // case isn't relevant
   double lambda = lambdaCalculator.lambda();
@@ -217,7 +219,8 @@ void makeQualityScorers(){
       }
     }
     else{
-      warn("quality data not used for non-fastq query versus fastq reference");
+      warn(args.programName,
+	   "quality data not used for non-fastq query versus fastq reference");
     }
   }
 }
@@ -282,7 +285,7 @@ void calculateScoreStatistics( const std::string& matrixName,
 
 // Read the .prj file for the whole database
 void readOuterPrj( const std::string& fileName, unsigned& volumes,
-                   indexT& minSeedLimit,
+                   indexT& refMinimizerWindow, indexT& minSeedLimit,
 		   bool& isKeepRefLowercase, int& refTantanSetting,
                    countT& refSequences, countT& refLetters ){
   std::ifstream f( fileName.c_str() );
@@ -307,6 +310,7 @@ void readOuterPrj( const std::string& fileName, unsigned& volumes,
     if( word == "tantansetting" ) iss >> refTantanSetting;
     if( word == "masklowercase" ) iss >> isCaseSensitiveSeeds;
     if( word == "sequenceformat" ) iss >> referenceFormat;
+    if( word == "minimizerwindow" ) iss >> refMinimizerWindow;
     if( word == "volumes" ) iss >> volumes;
     if( word == "numofindexes" ) iss >> numOfIndexes;
   }
@@ -346,8 +350,6 @@ void readInnerPrj( const std::string& fileName,
 
 // Write match counts for each query sequence
 void writeCounts( std::ostream& out ){
-  LOG( "writing..." );
-
   for( indexT i = 0; i < matchCounts.size(); ++i ){
     out << query.seqName(i) << '\n';
 
@@ -361,8 +363,6 @@ void writeCounts( std::ostream& out ){
 
 // Count all matches, of all sizes, of a query sequence against a suffix array
 void countMatches( size_t queryNum, const uchar* querySeq ){
-  LOG( "counting..." );
-
   indexT loopBeg = query.seqBeg(queryNum) - query.padBeg(queryNum);
   indexT loopEnd = query.seqEnd(queryNum) - query.padBeg(queryNum);
   if( args.minHitDepth > 1 )
@@ -490,7 +490,8 @@ struct Dispatcher{
 };
 
 static bool isCollatedAlignments() {
-  return args.outputFormat == 'b' || args.cullingLimitForFinalAlignments;
+  return args.outputFormat == 'b' || args.outputFormat == 'B' ||
+    args.cullingLimitForFinalAlignments;
 }
 
 static void printAndDelete(char *text) {
@@ -522,13 +523,21 @@ void alignGapless( LastAligner& aligner, SegmentPairPot& gaplessAlns,
   if( args.minHitDepth > 1 )
     loopEnd -= std::min( args.minHitDepth - 1, loopEnd );
 
+  std::vector< SubsetMinimizerFinder > minFinders( numOfIndexes );
+  for( unsigned x = 0; x < numOfIndexes; ++x ){
+    minFinders[x].init( suffixArrays[x].getSeed(), dis.b, loopBeg, loopEnd );
+  }
+
   for( indexT i = loopBeg; i < loopEnd; i += args.queryStep ){
     for( unsigned x = 0; x < numOfIndexes; ++x ){
+      const SubsetSuffixArray& sax = suffixArrays[x];
+      if( args.minimizerWindow > 1 &&
+	  !minFinders[x].isMinimizer( sax.getSeed(), dis.b, i, loopEnd,
+				      args.minimizerWindow ) ) continue;
       const indexT* beg;
       const indexT* end;
-      suffixArrays[x].match( beg, end, dis.b + i, dis.a,
-			     args.oneHitMultiplicity,
-			     args.minHitDepth, args.maxHitDepth );
+      sax.match( beg, end, dis.b + i, dis.a,
+		 args.oneHitMultiplicity, args.minHitDepth, args.maxHitDepth );
       matchCount += end - beg;
 
       // Tried: if we hit a delimiter when using contiguous seeds, then
@@ -577,9 +586,9 @@ void alignGapless( LastAligner& aligner, SegmentPairPot& gaplessAlns,
     }
   }
 
-  LOG( "initial matches=" << matchCount );
-  LOG( "gapless extensions=" << gaplessExtensionCount );
-  LOG( "gapless alignments=" << gaplessAlignmentCount );
+  LOG2( "initial matches=" << matchCount );
+  LOG2( "gapless extensions=" << gaplessExtensionCount );
+  LOG2( "gapless alignments=" << gaplessAlignmentCount );
 }
 
 // Shrink the SegmentPair to its longest run of identical matches.
@@ -624,7 +633,7 @@ void alignGapped( LastAligner& aligner,
   gaplessAlns.cull( args.cullingLimitForGaplessAlignments );
   gaplessAlns.sort();  // sort by score descending, and remove duplicates
 
-  LOG( "redone gapless alignments=" << gaplessAlns.size() );
+  LOG2( "redone gapless alignments=" << gaplessAlns.size() );
 
   for( size_t i = 0; i < gaplessAlns.size(); ++i ){
     SegmentPair& sp = gaplessAlns.get(i);
@@ -663,8 +672,8 @@ void alignGapped( LastAligner& aligner,
     ++gappedAlignmentCount;
   }
 
-  LOG( "gapped extensions=" << gappedExtensionCount );
-  LOG( "gapped alignments=" << gappedAlignmentCount );
+  LOG2( "gapped extensions=" << gappedExtensionCount );
+  LOG2( "gapped alignments=" << gappedAlignmentCount );
 }
 
 // Print the gapped alignments, after optionally calculating match
@@ -677,7 +686,6 @@ void alignFinish( LastAligner& aligner, const AlignmentPot& gappedAlns,
 
   if( args.outputType > 3 ){
     if( dis.p ){
-      LOG( "exponentiating PSSM..." );
       centroid.setPssm( dis.p, query.padLen(queryNum), args.temperature,
                         getOneQualityExpMatrix(strand), dis.b, dis.j );
     }
@@ -687,8 +695,6 @@ void alignFinish( LastAligner& aligner, const AlignmentPot& gappedAlns,
     centroid.setOutputType( args.outputType );
   }
 
-  LOG( "finishing..." );
-
   for( size_t i = 0; i < gappedAlns.size(); ++i ){
     const Alignment& aln = gappedAlns.items[i];
     if( args.outputType < 4 ){
@@ -764,7 +770,6 @@ void makeQualityPssm( LastAligner& aligner,
   if( !isQuality( args.inputFormat ) || isQuality( referenceFormat ) ) return;
   if( args.isTranslated() ) return;
 
-  LOG( "making PSSM..." );
   std::vector<int> &qualityPssm = aligner.qualityPssm;
   size_t queryLen = query.padLen(queryNum);
   qualityPssm.resize(queryLen * scoreMatrixRowSize);
@@ -795,8 +800,6 @@ void scan( LastAligner& aligner,
   bool isMask = (args.maskLowercase > 0);
   makeQualityPssm( aligner, queryNum, strand, querySeq, isMask );
 
-  LOG( "scanning..." );
-
   SegmentPairPot gaplessAlns;
   alignGapless( aligner, gaplessAlns, queryNum, strand, querySeq );
   if( args.outputType == 1 ) return;  // we just want gapless alignments
@@ -820,7 +823,7 @@ void scan( LastAligner& aligner,
 
   if( args.outputType > 2 ){  // we want non-redundant alignments
     gappedAlns.eraseSuboptimal();
-    LOG( "nonredundant gapped alignments=" << gappedAlns.size() );
+    LOG2( "nonredundant gapped alignments=" << gappedAlns.size() );
   }
 
   if( !isCollatedAlignments() ) gappedAlns.sort();  // sort by score
@@ -855,17 +858,14 @@ void translateAndScan( LastAligner& aligner, size_t queryNum, char strand ){
   size_t size = query.padLen(queryNum);
 
   if( args.isTranslated() ){
-    LOG( "translating..." );
     modifiedQuery.resize( size );
     geneticCode.translate( querySeq, querySeq + size, &modifiedQuery[0] );
     if( args.tantanSetting ){
-      LOG( "masking..." );
       tantanMaskTranslatedQuery( queryNum, &modifiedQuery[0] );
     }
     querySeq = &modifiedQuery[0];
   }else{
     if( args.tantanSetting ){
-      LOG( "masking..." );
       modifiedQuery.assign( querySeq, querySeq + size );
       tantanMaskOneQuery( queryNum, &modifiedQuery[0] );
       querySeq = &modifiedQuery[0];
@@ -892,7 +892,6 @@ static void reverseComplementPssm( size_t queryNum ){
 }
 
 static void reverseComplementQuery( size_t queryNum ){
-  LOG( "reverse complementing..." );
   size_t b = query.seqBeg(queryNum);
   size_t e = query.seqEnd(queryNum);
   queryAlph.rc( query.seqWriter() + b, query.seqWriter() + e );
@@ -919,67 +918,47 @@ static void alignOneQuery(LastAligner &aligner,
     translateAndScan(aligner, queryNum, '-');
 }
 
-static size_t firstQuerySequenceInChunk(size_t chunkNum) {
-  size_t numOfQueries = query.finishedSequences();
-  size_t numOfChunks = aligners.size();
-  size_t beg = query.seqBeg(0);
-  size_t end = query.padEnd(numOfQueries - 1) - 1;
-  countT len = end - beg;  // try to avoid overflow
-  size_t pos = beg + len * chunkNum / numOfChunks;
-  size_t seqNum = query.whichSequence(pos);
-  size_t begDistance = pos - query.seqBeg(seqNum);
-  size_t endDistance = query.padEnd(seqNum) - pos;
-  return (begDistance < endDistance) ? seqNum : seqNum + 1;
-}
-
 static void alignSomeQueries(size_t chunkNum,
 			     unsigned volume, unsigned volumeCount) {
+  size_t numOfChunks = aligners.size();
   LastAligner &aligner = aligners[chunkNum];
   std::vector<AlignmentText> &textAlns = aligner.textAlns;
-  size_t beg = firstQuerySequenceInChunk(chunkNum);
-  size_t end = firstQuerySequenceInChunk(chunkNum + 1);
+  size_t beg = firstSequenceInChunk(query, numOfChunks, chunkNum);
+  size_t end = firstSequenceInChunk(query, numOfChunks, chunkNum + 1);
   bool isMultiVolume = (volumeCount > 1);
   bool isFirstVolume = (volume == 0);
   bool isFinalVolume = (volume + 1 == volumeCount);
-  bool isMultiThread = (aligners.size() > 1);
+  bool isFirstThread = (chunkNum == 0);
+  bool isSort = isCollatedAlignments();
+  bool isSortPerQuery = (isSort && !isMultiVolume);
+  bool isPrintPerQuery = (isFirstThread && !(isSort && isMultiVolume));
   for (size_t i = beg; i < end; ++i) {
     size_t oldNumOfAlns = textAlns.size();
     alignOneQuery(aligner, i, isFirstVolume);
-    if (!isMultiVolume && isCollatedAlignments()) {
-      sort(textAlns.begin() + oldNumOfAlns, textAlns.end());
-      if (!isMultiThread) printAndClear(textAlns);
-    }
+    if (isSortPerQuery) sort(textAlns.begin() + oldNumOfAlns, textAlns.end());
+    if (isPrintPerQuery) printAndClear(textAlns);
   }
   if (isFinalVolume && isMultiVolume) {
     cullFinalAlignments(textAlns, 0);
-    if (isCollatedAlignments()) sort(textAlns.begin(), textAlns.end());
+    if (isSort) sort(textAlns.begin(), textAlns.end());
+    if (isFirstThread) printAndClear(textAlns);
   }
 }
 
 static void scanOneVolume(unsigned volume, unsigned volumeCount) {
+#ifdef HAS_CXX_THREADS
   size_t numOfChunks = aligners.size();
-  if (numOfChunks == 1) {
-    alignSomeQueries(0, volume, volumeCount);
-  } else {
-    std::vector<std::thread> threads(numOfChunks);
-    for (size_t i = 0; i < numOfChunks; ++i)
-      threads[i] = std::thread(alignSomeQueries, i, volume, volumeCount);
-    // Exceptions from threads are not handled nicely, but I don't
-    // think it matters much.
-    for (size_t i = 0; i < numOfChunks; ++i)
-      threads[i].join();
-  }
-}
-
-static unsigned decideNumOfThreads() {
-  if (args.numOfThreads) return args.numOfThreads;
-  unsigned x = std::thread::hardware_concurrency();
-  if (x) {
-    LOG("threads=" << x);
-    return x;
-  }
-  warn("can't determine how many threads to use: falling back to 1 thread");
-  return 1;
+  std::vector<std::thread> threads(numOfChunks - 1);
+  for (size_t i = 1; i < numOfChunks; ++i)
+    threads[i - 1] = std::thread(alignSomeQueries, i, volume, volumeCount);
+  // Exceptions from threads are not handled nicely, but I don't
+  // think it matters much.
+#endif
+  alignSomeQueries(0, volume, volumeCount);
+#ifdef HAS_CXX_THREADS
+  for (size_t i = 1; i < numOfChunks; ++i)
+    threads[i - 1].join();
+#endif
 }
 
 void readIndex( const std::string& baseName, indexT seqCount ) {
@@ -1023,7 +1002,6 @@ void scanAllVolumes( unsigned volumes, std::ostream& out ){
 
   if( args.outputType == 0 ) writeCounts( out );
   printAndClearAll();
-  LOG( "query batch done!" );
 }
 
 void writeHeader( countT refSequences, countT refLetters, std::ostream& out ){
@@ -1049,7 +1027,7 @@ void writeHeader( countT refSequences, countT refLetters, std::ostream& out ){
       out << "#\n";
     }
 
-    if( args.outputFormat != 'b' ) {
+    if( args.outputFormat != 'b' && args.outputFormat != 'B' ) {
       out << "# Coordinates are 0-based.  For - strand matches, coordinates\n";
       out << "# in the reverse complement of the 2nd sequence are used.\n";
       out << "#\n";
@@ -1063,10 +1041,12 @@ void writeHeader( countT refSequences, countT refLetters, std::ostream& out ){
       out << "# name start alnSize strand seqSize alignment\n"
 	  << "#\n";
     }
-    if( args.outputFormat == 'b' ){
+    if( args.outputFormat == 'b' || args.outputFormat == 'B' ){
       out << "# Fields: query id, subject id, % identity, alignment length, "
-	  << "mismatches, gap opens, q. start, q. end, s. start, s. end, "
-	  << "evalue, bit score\n";
+	  << "mismatches, gap opens, q. start, q. end, s. start, s. end";
+      if( evaluer.isGood() ) out << ", evalue, bit score";
+      if( args.outputFormat == 'B' ) out << ", query length, subject length";
+      out << '\n';
     }
   }
 }
@@ -1110,12 +1090,14 @@ void lastal( int argc, char** argv ){
   args.resetCumulativeOptions();  // because we will do fromArgs again
 
   unsigned volumes = unsigned(-1);
+  indexT refMinimizerWindow = 1;  // assume this value, if not specified
   indexT minSeedLimit = 0;
   countT refSequences = -1;
   countT refLetters = -1;
   bool isKeepRefLowercase = true;
   int refTantanSetting = 0;
-  readOuterPrj( args.lastdbName + ".prj", volumes, minSeedLimit,
+  readOuterPrj( args.lastdbName + ".prj", volumes,
+		refMinimizerWindow, minSeedLimit,
 		isKeepRefLowercase, refTantanSetting,
 		refSequences, refLetters );
   bool isDna = (alph.letters == alph.dna);
@@ -1143,12 +1125,13 @@ void lastal( int argc, char** argv ){
       ERR( "can't use option -l > 1: need to re-run lastdb with i <= 1" );
   }
 
-  aligners.resize( decideNumOfThreads() );
+  aligners.resize( decideNumberOfThreads( args.numOfThreads,
+					  args.programName, args.verbosity ) );
   bool isMultiVolume = (volumes+1 > 0 && volumes > 1);
   args.setDefaultsFromAlphabet( isDna, isProtein, refLetters,
 				isKeepRefLowercase, refTantanSetting,
                                 isCaseSensitiveSeeds, isMultiVolume,
-				aligners.size() );
+				refMinimizerWindow, aligners.size() );
   if( args.tantanSetting )
     tantanMasker.init( isProtein, args.tantanSetting > 1,
 		       alph.letters, alph.encode );
@@ -1226,11 +1209,11 @@ try{
   return EXIT_SUCCESS;
 }
 catch( const std::bad_alloc& e ) {  // bad_alloc::what() may be unfriendly
-  std::cerr << "lastal: out of memory\n";
+  std::cerr << argv[0] << ": out of memory\n";
   return EXIT_FAILURE;
 }
 catch( const std::exception& e ) {
-  std::cerr << "lastal: " << e.what() << '\n';
+  std::cerr << argv[0] << ": " << e.what() << '\n';
   return EXIT_FAILURE;
 }
 catch( int i ) {
diff --git a/src/lastdb.cc b/src/lastdb.cc
index 868f6e1..57cf321 100644
--- a/src/lastdb.cc
+++ b/src/lastdb.cc
@@ -11,6 +11,7 @@
 #include "io.hh"
 #include "qualityScoreUtil.hh"
 #include "stringify.hh"
+#include "threadUtil.hh"
 #include <stdexcept>
 #include <fstream>
 #include <iostream>
@@ -18,7 +19,7 @@
 #include <numeric>  // accumulate
 
 #define ERR(x) throw std::runtime_error(x)
-#define LOG(x) if( args.verbosity > 0 ) std::cerr << "lastdb: " << x << '\n'
+#define LOG(x) if( args.verbosity > 0 ) std::cerr << args.programName << ": " << x << '\n'
 
 using namespace cbrc;
 
@@ -47,52 +48,49 @@ bool isDubiousDna( const Alphabet& alph, const MultiSequence& multi ){
   else return false;
 }
 
-const unsigned maxNumOfIndexes = 16;
-
-static void addSeeds( SubsetSuffixArray indexes[], unsigned& numOfIndexes,
-		      const std::string& subsetSeeds,
+static void addSeeds( std::vector< CyclicSubsetSeed >& seeds,
+		      const std::string& seedText,
 		      const LastdbArguments& args, const Alphabet& alph ){
-  std::istringstream iss( subsetSeeds );
+  std::istringstream iss( seedText );
   std::vector< std::string > seedAlphabet;
   std::string pattern;
   while( CyclicSubsetSeed::nextPattern( iss, seedAlphabet, pattern ) ){
-    if( numOfIndexes >= maxNumOfIndexes ) ERR( "too many seed patterns" );
-    CyclicSubsetSeed& seed = indexes[ numOfIndexes++ ].getSeed();
-    seed.init( seedAlphabet, pattern, args.isCaseSensitive, alph.encode );
+    CyclicSubsetSeed s;
+    s.init( seedAlphabet, pattern, args.isCaseSensitive, alph.encode );
+    seeds.push_back(s);
   }
 }
 
-// Set up the seed pattern(s), and return how many of them there are
-unsigned makeSubsetSeeds( SubsetSuffixArray indexes[],
-			  const std::string& subsetSeeds,
-			  const LastdbArguments& args, const Alphabet& alph ){
-  unsigned numOfIndexes = 0;
+// Set up the seed pattern(s)
+static void makeSubsetSeeds( std::vector< CyclicSubsetSeed >& seeds,
+			     const std::string& seedText,
+			     const LastdbArguments& args,
+			     const Alphabet& alph ){
   const std::string& a = alph.letters;
 
   if( !args.subsetSeedFile.empty() ){
-    addSeeds( indexes, numOfIndexes, subsetSeeds, args, alph );
+    addSeeds( seeds, seedText, args, alph );
   }
   else if( !args.seedPatterns.empty() ){
     for( unsigned x = 0; x < args.seedPatterns.size(); ++x ){
       const std::string& p = args.seedPatterns[x];
       std::string s = CyclicSubsetSeed::stringFromPatterns( p, a );
-      addSeeds( indexes, numOfIndexes, s, args, alph );
+      addSeeds( seeds, s, args, alph );
     }
   }
   else{
     std::string s = (alph.letters == alph.dna)
       ? CyclicSubsetSeed::stringFromName( "YASS" )
       : CyclicSubsetSeed::stringFromPatterns( "1", a );
-    addSeeds( indexes, numOfIndexes, s, args, alph );
+    addSeeds( seeds, s, args, alph );
   }
 
-  if( !numOfIndexes ) ERR( "no seed patterns" );
-  return numOfIndexes;
+  if( seeds.empty() ) ERR( "no seed patterns" );
 }
 
-void writeLastalOptions( std::ostream& out, const std::string& subsetSeeds ){
+void writeLastalOptions( std::ostream& out, const std::string& seedText ){
   std::string trigger = "#lastal";
-  std::istringstream iss( subsetSeeds );
+  std::istringstream iss( seedText );
   std::string line;
   while( getline( iss, line ) )
     if( line.compare( 0, trigger.size(), trigger ) == 0 )
@@ -103,7 +101,7 @@ void writePrjFile( const std::string& fileName, const LastdbArguments& args,
 		   const Alphabet& alph, countT sequenceCount,
 		   const std::vector<countT>& letterCounts,
 		   unsigned volumes, unsigned numOfIndexes,
-		   const std::string& subsetSeeds ){
+		   const std::string& seedText ){
   countT letterTotal = std::accumulate( letterCounts.begin(),
                                         letterCounts.end(), countT(0) );
 
@@ -131,47 +129,99 @@ void writePrjFile( const std::string& fileName, const LastdbArguments& args,
     if( args.inputFormat != sequenceFormat::fasta ){
       f << "sequenceformat=" << args.inputFormat << '\n';
     }
+    if( args.minimizerWindow > 1 ){
+      // Maybe this should be written (and read) by the indexes, so
+      // each index can have a different window?
+      f << "minimizerwindow=" << args.minimizerWindow << '\n';
+    }
     if( volumes+1 > 0 ){
       f << "volumes=" << volumes << '\n';
     }
     else{
       f << "numofindexes=" << numOfIndexes << '\n';
     }
-    writeLastalOptions( f, subsetSeeds );
+    writeLastalOptions( f, seedText );
   }
 
   f.close();
   if( !f ) ERR( "can't write file: " + fileName );
 }
 
+static void preprocessSomeSeqs(MultiSequence *multi,
+			       const TantanMasker *masker,
+			       const uchar *maskTable,
+			       size_t numOfChunks,
+			       size_t chunkNum) {
+  size_t beg = firstSequenceInChunk(*multi, numOfChunks, chunkNum);
+  size_t end = firstSequenceInChunk(*multi, numOfChunks, chunkNum + 1);
+  uchar *w = multi->seqWriter();
+  for (size_t i = beg; i < end; ++i)
+    masker->mask(w + multi->seqBeg(i), w + multi->seqEnd(i), maskTable);
+}
+
+static void preprocessSeqs(MultiSequence &multi,
+			   const TantanMasker &masker,
+			   const uchar *maskTable,
+			   size_t numOfChunks) {
+#ifdef HAS_CXX_THREADS
+  std::vector<std::thread> threads(numOfChunks - 1);
+  for (size_t i = 1; i < numOfChunks; ++i)
+    threads[i - 1] = std::thread(preprocessSomeSeqs,
+				 &multi, &masker, maskTable, numOfChunks, i);
+#endif
+  preprocessSomeSeqs(&multi, &masker, maskTable, numOfChunks, 0);
+#ifdef HAS_CXX_THREADS
+  for (size_t i = 1; i < numOfChunks; ++i)
+    threads[i - 1].join();
+#endif
+}
+
 // Make one database volume, from one batch of sequences
-void makeVolume( SubsetSuffixArray indexes[], unsigned numOfIndexes,
-		 const MultiSequence& multi, const LastdbArguments& args,
+void makeVolume( std::vector< CyclicSubsetSeed >& seeds,
+		 MultiSequence& multi, const LastdbArguments& args,
 		 const Alphabet& alph, const std::vector<countT>& letterCounts,
-		 const std::string& subsetSeeds, const std::string& baseName ){
+		 const TantanMasker& masker, unsigned numOfThreads,
+		 const std::string& seedText, const std::string& baseName ){
+  size_t numOfIndexes = seeds.size();
+  size_t numOfSequences = multi.finishedSequences();
+  size_t textLength = multi.finishedSize();
+
+  if( args.tantanSetting ){
+    LOG( "masking..." );
+    preprocessSeqs( multi, masker, alph.numbersToLowercase, numOfThreads );
+  }
+
   LOG( "writing..." );
-  writePrjFile( baseName + ".prj", args, alph, multi.finishedSequences(),
-		letterCounts, -1, numOfIndexes, subsetSeeds );
+  writePrjFile( baseName + ".prj", args, alph, numOfSequences,
+		letterCounts, -1, numOfIndexes, seedText );
   multi.toFiles( baseName );
+  const uchar* seq = multi.seqReader();
 
   for( unsigned x = 0; x < numOfIndexes; ++x ){
+    SubsetSuffixArray myIndex;
+    seeds[x].swap( myIndex.getSeed() );
+
+    LOG( "gathering..." );
+    for( size_t i = 0; i < numOfSequences; ++i ){
+      myIndex.addPositions( seq, multi.seqBeg(i), multi.seqEnd(i),
+			    args.indexStep, args.minimizerWindow );
+    }
+
     LOG( "sorting..." );
-    indexes[x].sortIndex( multi.seqReader(),
-			  args.minSeedLimit, args.childTableType );
+    myIndex.sortIndex( seq, args.minSeedLimit, args.childTableType );
 
     LOG( "bucketing..." );
-    indexes[x].makeBuckets( multi.seqReader(), args.bucketDepth );
+    myIndex.makeBuckets( seq, args.bucketDepth );
 
     LOG( "writing..." );
-    indexT textLength = multi.finishedSize();
     if( numOfIndexes > 1 ){
-      indexes[x].toFiles( baseName + char('a' + x), false, textLength );
+      myIndex.toFiles( baseName + char('a' + x), false, textLength );
     }
     else{
-      indexes[x].toFiles( baseName, true, textLength );
+      myIndex.toFiles( baseName, true, textLength );
     }
 
-    indexes[x].clearPositions();
+    seeds[x].swap( myIndex.getSeed() );
   }
 
   LOG( "done!" );
@@ -228,23 +278,25 @@ void lastdb( int argc, char** argv ){
   LastdbArguments args;
   args.fromArgs( argc, argv );
 
-  std::string subsetSeeds;
+  std::string seedText;
   if( !args.subsetSeedFile.empty() ){
-    subsetSeeds = CyclicSubsetSeed::stringFromName( args.subsetSeedFile );
+    seedText = CyclicSubsetSeed::stringFromName( args.subsetSeedFile );
     args.resetCumulativeOptions();
-    args.fromString( subsetSeeds );  // read options from the seed file
+    args.fromString( seedText );  // read options from the seed file
     args.fromArgs( argc, argv );  // command line overrides seed file
   }
 
+  unsigned numOfThreads =
+    decideNumberOfThreads(args.numOfThreads, args.programName, args.verbosity);
   Alphabet alph;
   MultiSequence multi;
-  SubsetSuffixArray indexes[maxNumOfIndexes];
+  std::vector< CyclicSubsetSeed > seeds;
   makeAlphabet( alph, args );
   TantanMasker tantanMasker;
   if( args.tantanSetting )
     tantanMasker.init( alph.isProtein(), args.tantanSetting > 1,
 		       alph.letters, alph.encode );
-  unsigned numOfIndexes = makeSubsetSeeds( indexes, subsetSeeds, args, alph );
+  makeSubsetSeeds( seeds, seedText, args, alph );
   multi.initForAppending(1);
   alph.tr( multi.seqWriter(), multi.seqWriter() + multi.unfinishedSize() );
   unsigned volumeNumber = 0;
@@ -261,10 +313,10 @@ void lastdb( int argc, char** argv ){
     std::istream& in = openIn( *i, inFileStream );
     LOG( "reading " << *i << "..." );
 
-    while( appendFromFasta( multi, numOfIndexes, args, alph, in ) ){
+    while( appendFromFasta( multi, seeds.size(), args, alph, in ) ){
       if( !args.isProtein && args.userAlphabet.empty() &&
           sequenceCount == 0 && isDubiousDna( alph, multi ) ){
-        std::cerr << "lastdb: that's some funny-lookin DNA\n";
+        std::cerr << args.programName << ": that's some funny-lookin DNA\n";
       }
 
       if( multi.isFinished() ){
@@ -277,20 +329,12 @@ void lastdb( int argc, char** argv ){
 	if( args.isCountsOnly ){
 	  // memory-saving, which seems to be important on 32-bit systems:
 	  multi.reinitForAppending();
-	}else{
-	  if( args.tantanSetting ){
-	    uchar* w = multi.seqWriter();
-	    tantanMasker.mask( w + beg, w + end, alph.numbersToLowercase );
-	  }
-	  for( unsigned x = 0; x < numOfIndexes; ++x ){
-	    indexes[x].addPositions( seq, beg, end, args.indexStep );
-	  }
 	}
       }
       else{
 	std::string baseName = args.lastdbName + stringify(volumeNumber++);
-	makeVolume( indexes, numOfIndexes, multi, args, alph, letterCounts,
-		    subsetSeeds, baseName );
+	makeVolume( seeds, multi, args, alph, letterCounts,
+		    tantanMasker, numOfThreads, seedText, baseName );
 	for( unsigned c = 0; c < alph.size; ++c )
 	  letterTotals[c] += letterCounts[c];
 	letterCounts.assign( alph.size, 0 );
@@ -301,19 +345,19 @@ void lastdb( int argc, char** argv ){
 
   if( multi.finishedSequences() > 0 ){
     if( volumeNumber == 0 ){
-      makeVolume( indexes, numOfIndexes, multi, args, alph, letterCounts,
-		  subsetSeeds, args.lastdbName );
+      makeVolume( seeds, multi, args, alph, letterCounts,
+		  tantanMasker, numOfThreads, seedText, args.lastdbName );
       return;
     }
     std::string baseName = args.lastdbName + stringify(volumeNumber++);
-    makeVolume( indexes, numOfIndexes, multi, args, alph, letterCounts,
-		subsetSeeds, baseName );
+    makeVolume( seeds, multi, args, alph, letterCounts,
+		tantanMasker, numOfThreads, seedText, baseName );
   }
 
   for( unsigned c = 0; c < alph.size; ++c ) letterTotals[c] += letterCounts[c];
 
   writePrjFile( args.lastdbName + ".prj", args, alph, sequenceCount,
-		letterTotals, volumeNumber, numOfIndexes, subsetSeeds );
+		letterTotals, volumeNumber, seeds.size(), seedText );
 }
 
 int main( int argc, char** argv )
@@ -322,11 +366,11 @@ try{
   return EXIT_SUCCESS;
 }
 catch( const std::bad_alloc& e ) {  // bad_alloc::what() may be unfriendly
-  std::cerr << "lastdb: out of memory\n";
+  std::cerr << argv[0] << ": out of memory\n";
   return EXIT_FAILURE;
 }
 catch( const std::exception& e ) {
-  std::cerr << "lastdb: " << e.what() << '\n';
+  std::cerr << argv[0] << ": " << e.what() << '\n';
   return EXIT_FAILURE;
 }
 catch( int i ) {
diff --git a/src/makefile b/src/makefile
index 64f6143..ea6e797 100644
--- a/src/makefile
+++ b/src/makefile
@@ -2,7 +2,7 @@ CXX = g++
 CC  = gcc
 
 CXXFLAGS = -O3 -Wall -Wextra -Wcast-qual -Wswitch-enum -Wundef	\
--Wcast-align -pedantic -g -std=c++11 -pthread
+-Wcast-align -pedantic -g -std=c++11 -pthread -DHAS_CXX_THREADS
 # -Wconversion
 # -fomit-frame-pointer ?
 
@@ -10,18 +10,18 @@ CFLAGS = -Wall -O2
 
 DBOBJ = Alphabet.o MultiSequence.o CyclicSubsetSeed.o			\
 SubsetSuffixArray.o LastdbArguments.o io.o fileMap.o TantanMasker.o	\
-ScoreMatrix.o LambdaCalculator.o tantan.o SubsetSuffixArraySort.o	\
-MultiSequenceQual.o lastdb.o
+ScoreMatrix.o SubsetMinimizerFinder.o LambdaCalculator.o tantan.o	\
+SubsetSuffixArraySort.o MultiSequenceQual.o lastdb.o
 
 ALOBJ = Alphabet.o MultiSequence.o CyclicSubsetSeed.o			\
 SubsetSuffixArray.o LastalArguments.o io.o fileMap.o TantanMasker.o	\
-ScoreMatrix.o tantan.o DiagonalTable.o SegmentPair.o Alignment.o	\
-GappedXdropAligner.o SegmentPairPot.o AlignmentPot.o			\
-GeneralizedAffineGapCosts.o Centroid.o LambdaCalculator.o		\
-TwoQualityScoreMatrix.o OneQualityScoreMatrix.o QualityPssmMaker.o	\
-GeneticCode.o LastEvaluer.o gaplessXdrop.o gaplessPssmXdrop.o		\
-gaplessTwoQualityXdrop.o SubsetSuffixArraySearch.o AlignmentWrite.o	\
-MultiSequenceQual.o GappedXdropAlignerPssm.o				\
+ScoreMatrix.o SubsetMinimizerFinder.o tantan.o DiagonalTable.o		\
+SegmentPair.o Alignment.o GappedXdropAligner.o SegmentPairPot.o		\
+AlignmentPot.o GeneralizedAffineGapCosts.o Centroid.o			\
+LambdaCalculator.o TwoQualityScoreMatrix.o OneQualityScoreMatrix.o	\
+QualityPssmMaker.o GeneticCode.o LastEvaluer.o gaplessXdrop.o		\
+gaplessPssmXdrop.o gaplessTwoQualityXdrop.o SubsetSuffixArraySearch.o	\
+AlignmentWrite.o MultiSequenceQual.o GappedXdropAlignerPssm.o		\
 GappedXdropAligner2qual.o GappedXdropAligner3frame.o lastal.o		\
 alp/sls_alignment_evaluer.o alp/sls_pvalues.o alp/sls_alp_sim.o		\
 alp/sls_alp_regression.o alp/sls_alp_data.o alp/sls_alp.o		\
@@ -155,9 +155,11 @@ QualityPssmMaker.o: QualityPssmMaker.cc QualityPssmMaker.hh \
 ScoreMatrix.o: ScoreMatrix.cc ScoreMatrix.hh ScoreMatrixData.hh io.hh
 SegmentPair.o: SegmentPair.cc SegmentPair.hh
 SegmentPairPot.o: SegmentPairPot.cc SegmentPairPot.hh SegmentPair.hh
+SubsetMinimizerFinder.o: SubsetMinimizerFinder.cc \
+ SubsetMinimizerFinder.hh CyclicSubsetSeed.hh
 SubsetSuffixArray.o: SubsetSuffixArray.cc SubsetSuffixArray.hh \
  CyclicSubsetSeed.hh VectorOrMmap.hh Mmap.hh fileMap.hh stringify.hh \
- io.hh
+ SubsetMinimizerFinder.hh io.hh
 SubsetSuffixArraySearch.o: SubsetSuffixArraySearch.cc \
  SubsetSuffixArray.hh CyclicSubsetSeed.hh VectorOrMmap.hh Mmap.hh \
  fileMap.hh stringify.hh
@@ -184,17 +186,19 @@ lastal.o: lastal.cc LastalArguments.hh SequenceFormat.hh \
  TwoQualityScoreMatrix.hh qualityScoreUtil.hh stringify.hh \
  LambdaCalculator.hh LastEvaluer.hh alp/sls_alignment_evaluer.hpp \
  alp/sls_pvalues.hpp alp/sls_basic.hpp alp/sls_falp_alignment_evaluer.hpp \
- alp/sls_fsa1_pvalues.hpp GeneticCode.hh SubsetSuffixArray.hh \
- CyclicSubsetSeed.hh VectorOrMmap.hh Mmap.hh fileMap.hh Centroid.hh \
- GappedXdropAligner.hh GeneralizedAffineGapCosts.hh SegmentPair.hh \
- AlignmentPot.hh Alignment.hh SegmentPairPot.hh ScoreMatrix.hh \
- Alphabet.hh MultiSequence.hh TantanMasker.hh tantan.hh DiagonalTable.hh \
- gaplessXdrop.hh gaplessPssmXdrop.hh gaplessTwoQualityXdrop.hh io.hh \
+ alp/sls_fsa1_pvalues.hpp GeneticCode.hh SubsetMinimizerFinder.hh \
+ SubsetSuffixArray.hh CyclicSubsetSeed.hh VectorOrMmap.hh Mmap.hh \
+ fileMap.hh Centroid.hh GappedXdropAligner.hh \
+ GeneralizedAffineGapCosts.hh SegmentPair.hh AlignmentPot.hh Alignment.hh \
+ SegmentPairPot.hh ScoreMatrix.hh Alphabet.hh MultiSequence.hh \
+ TantanMasker.hh tantan.hh DiagonalTable.hh gaplessXdrop.hh \
+ gaplessPssmXdrop.hh gaplessTwoQualityXdrop.hh io.hh threadUtil.hh \
  version.hh
 lastdb.o: lastdb.cc LastdbArguments.hh SequenceFormat.hh \
  SubsetSuffixArray.hh CyclicSubsetSeed.hh VectorOrMmap.hh Mmap.hh \
  fileMap.hh stringify.hh Alphabet.hh MultiSequence.hh ScoreMatrixRow.hh \
- TantanMasker.hh tantan.hh io.hh qualityScoreUtil.hh version.hh
+ TantanMasker.hh tantan.hh io.hh qualityScoreUtil.hh threadUtil.hh \
+ version.hh
 tantan.o: tantan.cc tantan.hh
 last-merge-batches.o: last-merge-batches.c version.hh
 alp/njn_dynprogprob.o: alp/njn_dynprogprob.cpp alp/njn_dynprogprob.hpp \
diff --git a/src/threadUtil.hh b/src/threadUtil.hh
new file mode 100644
index 0000000..c3b6da0
--- /dev/null
+++ b/src/threadUtil.hh
@@ -0,0 +1,38 @@
+// Copyright 2016 Martin C. Frith
+
+#ifndef THREAD_UTIL_HH
+#define THREAD_UTIL_HH
+
+#include <iostream>
+#include <stdexcept>
+
+#ifdef HAS_CXX_THREADS
+#include <thread>
+#endif
+
+namespace cbrc {
+
+inline unsigned decideNumberOfThreads(unsigned request,
+				      const char *programName,
+				      bool isVerbose) {
+#ifdef HAS_CXX_THREADS
+  if (request) return request;
+  unsigned x = std::thread::hardware_concurrency();
+  if (x) {
+    if (isVerbose) std::cerr << programName << ": threads=" << x << '\n';
+    return x;
+  }
+  std::cerr
+    << programName
+    << ": can't determine how many threads to use: falling back to 1 thread\n";
+#else
+  if (request != 1)
+    throw
+      std::runtime_error("I was installed here with multi-threading disabled");
+#endif
+  return 1;
+}
+
+}
+
+#endif
diff --git a/src/version.hh b/src/version.hh
index e0933c3..5d61001 100644
--- a/src/version.hh
+++ b/src/version.hh
@@ -1 +1 @@
-"712"
+"731"

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/last-align.git



More information about the debian-med-commit mailing list