Index: cpp/frams/_demos/simil_match_test.cpp
===================================================================
--- cpp/frams/_demos/simil_match_test.cpp	(revision 349)
+++ cpp/frams/_demos/simil_match_test.cpp	(revision 349)
@@ -0,0 +1,425 @@
+// This file is a part of Framsticks SDK.  http://www.framsticks.com/
+// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// See LICENSE.txt for details.
+
+#include "frams/model/similarity/simil_match.h"
+
+/** Runs unit tests of classes used in computation of similarity.
+ */
+#include <stdio.h>
+#include <assert.h>
+
+/** Prints out (standard output) the ERROR message.
+ */
+void PrintErrorMessage()
+{
+    printf("There were ERRORS during tests!\n");
+}
+
+/** Prints out (standard output) the OK message.
+ */
+void PrintPassedMessage()
+{
+    printf("Tests passed OK!\n");
+}
+
+/** Test construction of the SimilMatching objects and whether they are empty at
+    the beginning.
+        @return 0 if OK. Errors break execution (assert())
+ */
+int TestConstruction()
+{
+    const int nSize1 = 10;
+    const int nSize2 = 200;
+
+    // check symmetric matching
+    SimilMatching match1(nSize1, nSize1);
+
+    // test if all elements are unmatched yet
+    int i, j;
+    for (j = 0; j < 2; j++)
+    {
+        for (i = 0; i < nSize1; i++)
+        {
+            assert(match1.IsMatched(j, i) == false);
+        }
+    }
+
+    // test if all are unmatched - new method
+    assert(match1.IsEmpty() == true);
+
+    // check assymetric matching
+    SimilMatching match2(nSize1, nSize2);
+
+    // check if all elements are unmatched yet in object 0
+    for (i = 0; i < nSize1; i++)
+    {
+        assert(match2.IsMatched(0, i) == false);
+    }
+    // check if all elements are unmatched yet in object 1
+    for (i = 0; i < nSize2; i++)
+    {
+        assert(match2.IsMatched(1, i) == false);
+    }
+
+    // test if all are unmatched - new method
+    assert(match2.IsEmpty() == true);
+
+    return 0;
+}
+
+/** Tests if sizes of matching are appropriate.
+        @return 0 if OK. Errors break execution (assert()).
+ */
+int TestSizes()
+{
+    const int nSizeMax = 100;
+    SimilMatching *pMatching = NULL;
+
+    // construct objects of different size and check their sizes
+    int i, j;
+    for (i = 1; i < nSizeMax; i++)
+    {
+        for (j = 1; j < nSizeMax; j++)
+        {
+
+            // create a matching of size (i,j)
+            pMatching = new SimilMatching(i, j);
+            assert(pMatching != NULL);
+
+            // check size of both objects
+            assert(pMatching->GetObjectSize(0) == i);
+            assert(pMatching->GetObjectSize(1) == j);
+
+            // delete disused object
+            delete pMatching;
+        }
+    }
+    return 0;
+}
+
+/** Tests the copying constructor of 4 different, deterministic matchings:
+        empty, straight, reverse, sparse.
+        Also tests the method Empty().
+        @return 0 if OK. Errors break execution (assert())
+ */
+int TestCopyConstructor()
+{
+    // define the size used for creating matchings
+    const int iSize = 1000;
+    int iObj; // a counter of objects in matchings
+
+    {
+        // 1st test: create an empty matching, copy it, and check the copy
+        SimilMatching Source(iSize, iSize);
+        // check if it is empty
+        assert(Source.IsEmpty() == true);
+        // check sizes of objects
+        assert(Source.GetObjectSize(0) == iSize);
+        assert(Source.GetObjectSize(1) == iSize);
+        // create a copy of this matching
+        SimilMatching Dest(Source);
+        // check the copy:
+        // - sizes of matched object
+        assert(Dest.GetObjectSize(0) == Source.GetObjectSize(0));
+        assert(Dest.GetObjectSize(1) == Source.GetObjectSize(1));
+        // - the copy should be empty, too
+        assert(Dest.IsEmpty() == true);
+        // make it empty once again
+        Dest.Empty();
+        // and check once more
+        assert(Dest.IsEmpty() == true);
+    }
+
+    {
+        // 2nd test: create a straight matching (i, i), copy it, and check the copy
+        SimilMatching Source(iSize, iSize);
+        // check if it is empty
+        assert(Source.IsEmpty() == true);
+        // check sizes of objects
+        assert(Source.GetObjectSize(0) == iSize);
+        assert(Source.GetObjectSize(1) == iSize);
+        // match objects (iObj, iObj)
+        for (iObj = 0; iObj < iSize; iObj++)
+        {
+            Source.Match(0, iObj, 1, iObj);
+        }
+        // check if the matching is full
+        assert(Source.IsFull() == true);
+        // now create a copy of the matching
+        SimilMatching Dest(Source);
+        // check the copy
+        // - sizes of matched object
+        assert(Dest.GetObjectSize(0) == Source.GetObjectSize(0));
+        assert(Dest.GetObjectSize(1) == Source.GetObjectSize(1));
+        // - the copy should be full, too
+        assert(Dest.IsFull() == true);
+        // - the copy should have exactly the same assignments in matching
+        for (iObj = 0; iObj < iSize; iObj++)
+        {
+            // all object should be matched!
+            // check both directions: 0 -> 1
+            assert(Dest.IsMatched(0, iObj) == true);
+            assert(iObj == Dest.GetMatchedIndex(0, iObj));
+            // and: 1 -> 0
+            assert(Dest.IsMatched(1, iObj) == true);
+            assert(iObj == Dest.GetMatchedIndex(1, iObj));
+        }
+        // make it empty
+        Dest.Empty();
+        // and check once more
+        assert(Dest.IsEmpty() == true);
+    }
+
+    {
+        // 3rd test: create a reverse matching (i, N - i - 1), copy it, and check the copy
+        SimilMatching Source(iSize, iSize);
+        // check if it is empty
+        assert(Source.IsEmpty() == true);
+        // check sizes of objects
+        assert(Source.GetObjectSize(0) == iSize);
+        assert(Source.GetObjectSize(1) == iSize);
+        // match objects (iObj, N - iObj - 1)
+        for (iObj = 0; iObj < iSize; iObj++)
+        {
+            Source.Match(0, iObj, 1, iSize - iObj - 1);
+        }
+        // check if the matching is full
+        assert(Source.IsFull() == true);
+        // now create a copy of the matching
+        SimilMatching Dest(Source);
+        // check the copy
+        // - sizes of matched object
+        assert(Dest.GetObjectSize(0) == Source.GetObjectSize(0));
+        assert(Dest.GetObjectSize(1) == Source.GetObjectSize(1));
+        // - the copy should be full, too
+        assert(Dest.IsFull() == true);
+        // - the copy should have exactly the same assignments in matching
+        for (iObj = 0; iObj < iSize; iObj++)
+        {
+            // all object should be matched!
+            // check both directions: 0 -> 1
+            assert(Dest.IsMatched(0, iObj) == true);
+            assert((iSize - iObj - 1) == Dest.GetMatchedIndex(0, iObj));
+            // and: 1 -> 0
+            assert(Dest.IsMatched(1, iObj) == true);
+            assert((iSize - iObj - 1) == Dest.GetMatchedIndex(1, iObj));
+        }
+        // make it empty
+        Dest.Empty();
+        // and check once more
+        assert(Dest.IsEmpty() == true);
+    }
+
+    {
+        // 4th test: create a sparse matching (i, 2*i), copy it and check the copy
+        SimilMatching Source(iSize, 2 * iSize);
+        // check if it is empty
+        assert(Source.IsEmpty() == true);
+        // check sizes of objects
+        assert(Source.GetObjectSize(0) == iSize);
+        assert(Source.GetObjectSize(1) == 2 * iSize);
+        // match objects (iObj, 2 * iObj)
+        for (iObj = 0; iObj < iSize; iObj++)
+        {
+            Source.Match(0, iObj, 1, 2 * iObj);
+        }
+        // check if the matching is full (should be, as the smaller set is completely matched
+        assert(Source.IsFull() == true);
+        // now create a copy of the matching
+        SimilMatching Dest(Source);
+        // check the copy
+        // - sizes of matched object
+        assert(Dest.GetObjectSize(0) == Source.GetObjectSize(0));
+        assert(Dest.GetObjectSize(1) == Source.GetObjectSize(1));
+        // - the copy should be full, too
+        assert(Dest.IsFull() == true);
+        // - the copy should have exactly the same assignments in matching
+        for (iObj = 0; iObj < iSize; iObj++)
+        {
+            // check both directions: 0 -> 1
+            // (all matched, (iObj, 2 * iObj))
+            assert(Dest.IsMatched(0, iObj) == true);
+            assert((2 * iObj) == Dest.GetMatchedIndex(0, iObj));
+            // and direction; 1 -> 0
+            // (only even are matched, ( 2 * iObj, iObj))
+            // for 2 * iObj (which are even): matched
+            assert(Dest.IsMatched(1, 2 * iObj) == true);
+            assert(iObj == Dest.GetMatchedIndex(1, 2 * iObj));
+            // for 2 * iObj + 1 (which are odd): unmatched
+            assert(Dest.IsMatched(1, 2 * iObj + 1) == false);
+        }
+        // make it empty
+        Dest.Empty();
+        // and check once more
+        assert(Dest.IsEmpty() == true);
+    }
+
+    return 0;
+}
+
+/** Tests different matchings.
+        @return 0 if OK. Errors break execution (assert())
+ */
+int TestMatching()
+{
+    // define size used by method
+    const int nSize1 = 10;
+    // some loop counters
+    int i;
+
+    // first check some symmetric matching
+    SimilMatching match1(nSize1, nSize1);
+
+    // matching is empty
+    assert(match1.IsEmpty() == true);
+
+    // create matching - (i,i)
+    for (i = 0; i < nSize1; i++)
+    {
+
+        // matching is not full
+        assert(match1.IsFull() == false);
+
+        // these are not matched yet
+        assert(match1.IsMatched(0, i) == false);
+        assert(match1.IsMatched(1, i) == false);
+
+        // now - match!
+        match1.Match(0, i, 1, i);
+
+        // matching is not empty
+        assert(match1.IsEmpty() == false);
+
+        // now they are matched
+        assert(match1.IsMatched(0, i) == true);
+        assert(match1.IsMatched(1, i) == true);
+
+        // check the matched index for object 0 and 1
+        assert(match1.GetMatchedIndex(0, i) == i);
+        assert(match1.GetMatchedIndex(1, i) == i);
+    }
+
+    // now matching have to be full
+    assert(match1.IsFull() == true);
+
+    // check some symmetric matching
+    SimilMatching match2(nSize1, nSize1);
+
+    // matching is empty
+    assert(match2.IsEmpty() == true);
+
+    // create matching - (i, nSize1 - 1 - i)
+    for (i = 0; i < nSize1; i++)
+    {
+
+        // matching is not full
+        assert(match2.IsFull() == false);
+
+        // these are not matched yet
+        assert(match2.IsMatched(0, i) == false);
+        assert(match2.IsMatched(1, nSize1 - 1 - i) == false);
+
+        // now - match (but use the opposite syntax)!
+        match2.Match(1, nSize1 - 1 - i, 0, i);
+
+        // matching is not empty
+        assert(match2.IsEmpty() == false);
+
+        // now they are matched
+        assert(match2.IsMatched(0, i) == true);
+        assert(match2.IsMatched(1, nSize1 - 1 - i) == true);
+
+        // check the matched index for object 0 and 1
+        assert(match2.GetMatchedIndex(0, i) == (nSize1 - 1 - i));
+        assert(match2.GetMatchedIndex(1, nSize1 - 1 - i) == i);
+    }
+
+    // now matching have to be full
+    assert(match2.IsFull() == true);
+
+    // check some asymmnetic matching, too
+    SimilMatching match3(nSize1, 2 * nSize1);
+
+    // matching is empty
+    assert(match3.IsEmpty() == true);
+
+    // create matching - (i, 2 * i)
+    for (i = 0; i < nSize1; i++)
+    {
+
+        // matching is not full
+        assert(match3.IsFull() == false);
+
+        // these are not matched yet
+        assert(match3.IsMatched(0, i) == false);
+        assert(match3.IsMatched(1, 2 * i) == false);
+
+        // now - match (but use the opposite syntax)!
+        match3.Match(1, 2 * i, 0, i);
+
+        // matching is not empty
+        assert(match3.IsEmpty() == false);
+
+        // now they are matched
+        assert(match3.IsMatched(0, i) == true);
+        assert(match3.IsMatched(1, 2 * i) == true);
+
+        // but the odd elements of object 1 are not matched
+        assert(match3.IsMatched(1, 2 * i + 1) == false);
+
+        // check the matched index for object 0 and 1
+        assert(match3.GetMatchedIndex(0, i) == 2 * i);
+        assert(match3.GetMatchedIndex(1, 2 * i) == i);
+    }
+
+    // now matching have to be full (because the smallest object has all elements matched).
+    assert(match3.IsFull() == true);
+
+    return 0;
+}
+
+/** Defines all tests of SimilMatching class.
+        @return 0 if tests passed, (-1) if there were errors.
+ */
+int main(int argc, char *argv[])
+{
+    // assume that the result of tests is OK
+    bool bResultOK = true;
+
+    // run construction test
+    if (TestConstruction() != 0)
+    {
+        bResultOK = false;
+    }
+
+    // run sizes test
+    if (TestSizes() != 0)
+    {
+        bResultOK = false;
+    }
+
+    // run matching test
+    if (TestMatching() != 0)
+    {
+        bResultOK = false;
+    }
+
+    // run a copy constructor test
+    if (TestCopyConstructor() != 0)
+    {
+        bResultOK = false;
+    }
+
+    // print proper message about tests status and return
+    if (bResultOK)
+    {
+        PrintPassedMessage();
+        return 0;
+    }
+    else
+    {
+        PrintErrorMessage();
+        return (-1);
+    }
+}
Index: cpp/frams/_demos/simil_test.cpp
===================================================================
--- cpp/frams/_demos/simil_test.cpp	(revision 349)
+++ cpp/frams/_demos/simil_test.cpp	(revision 349)
@@ -0,0 +1,215 @@
+// This file is a part of Framsticks SDK.  http://www.framsticks.com/
+// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// See LICENSE.txt for details.
+
+
+#include <vector>
+#include "frams/errmgr/stdouterr.h"
+#include "frams/_demos/genotypeloader.h"
+#include "frams/genetics/preconfigured.h"
+#include "frams/virtfile/stdiofile.h"
+#include "frams/model/similarity/simil_model.h"
+
+
+
+using namespace std;
+
+/** Computes a matrix of distances between all genotypes in the specified
+    .gen file, using the matching and measure weights as specified in the
+    command line.
+
+    Command line parameters: [-names] <genotypesFile> <w_dP> <w_dDEG> <w_dNEU> <w_dGEO>
+
+    Parameters:
+      <genotypesFile> name of a file with genotypes (only f1 format)
+      <w_dP> weight of the difference in the number of parts
+      <w_dDEG> weight of the difference in degrees of matched parts
+      <w_dNEU> weight of the difference in neurons of matched parts
+      <w_dGEO> weight of the distance of matched parts
+
+    Switches:
+      -names specifies that the number and names of genotypes are to be printed to output
+        before the distance matrix; by default the number and names are not printed
+
+    Outputs a distance matrix in the format:
+    <row_1> (columns in a row are separated by TABs)
+    ...
+    <row_n>
+
+    Last modified: 2015-04-16
+ */
+int main(int argc, char *argv[])
+{
+    //StdoutErrorHandler err; //?TODO
+    typedef double *pDouble;
+    int iCurrParam = 0; // index of the currently processed parameter
+    char *szCurrParam = NULL;
+    ModelSimil M; // similarity computing object
+    bool bPrintNames = false; // specifies if names of genotypes are to be printed
+    int nResult = 0; // a temporary result
+
+    if (argc < 6)
+    {
+        // too few parameters
+        printf("Too few parameters!\n");
+        printf("Command line: [-names] <genotypesFile> <matchType> <w_dP> <w_dDEG> <w_dNEU> <w_dGEO> <ifFUZZY>\n\n");
+        printf("Parameters:\n");
+        printf(" <genotypesFile> name of a file with genotypes (only f1 format is allowed)\n");
+        printf(" <w_dP> weight of the difference in the number of parts\n");
+        printf(" <w_dDEG> weight of the difference in degrees of matched parts\n");
+        printf(" <w_dNEU> weight of the difference in neurons of matched parts\n");
+        printf(" <w_dGEO> weight of the distance of matched parts\n\n");
+        printf("Switches:\n");
+        printf(" -names specifies that the number and names of genotypes are to be printed to output\n");
+        printf("   before the distance matrix; by default the number and names are not printed\n\n");
+
+        printf("Outputs a symmetric distance matrix in the format:\n");
+        printf(" <row_1> (columns in a row are separated by TABs)\n");
+        printf(" ...\n");
+        printf(" <row_n>\n");
+
+        return -1;
+    }
+
+    // prepare output parameters from .gen file
+    vector<Geno *> *pvGenos = new vector<Geno *>();
+    vector<char *> *pvNames = new vector<char *>();
+
+    // check if there is a switch
+    iCurrParam = 1;
+    szCurrParam = argv[ iCurrParam ];
+    if (strcmp(szCurrParam, "-names") == 0)
+    {
+        // switch "-names" was given; print names also
+        bPrintNames = true;
+        // pass to the next parameter
+        iCurrParam++;
+    }
+
+    // check the parameters
+    // get <genotypesFile> name from command line
+    char *szFileName = argv[ iCurrParam ];
+
+    // initially set measure components' weights to invalid values (negative)
+    for (int i = 0; i < M.GetNOFactors(); i++)
+    {
+        M.m_adFactors[i] = -1.0;
+    }
+
+    char *params[] = {"<w_dP>", "<w_dDEG>", "<w_dNEU>", "<w_dGEO>"};
+    for (int i = 0; i < M.GetNOFactors(); i++)
+    {
+        iCurrParam++;
+        szCurrParam = argv[ iCurrParam ];
+        nResult = sscanf(szCurrParam, " %lf ", & M.m_adFactors[ i ]);
+        if (nResult != 1)
+        {
+            // <w_dP> is not a number -- error
+            printf("%s", params[i]);
+            printf(" should be a number\n");
+            return -1;
+        }
+        else
+        {
+            // <w_dP> is a number; check if nonnegative
+            if (M.m_adFactors[ i ] < 0.0)
+            {
+                printf("%s", params[i]);
+                printf(" should be a nonnegative number\n");
+                return -1;
+            }
+        }
+    }
+
+    // read the input file
+    // prepare loading of genotypes from a .gen file
+    // create some basic genotype converters
+    PreconfiguredGenetics genetics;
+    StdioFileSystem_autoselect stdiofilesys;
+
+    long count = 0, totalsize = 0;
+    MiniGenotypeLoader loader(szFileName);
+    MiniGenotype *loaded;
+    while (loaded = loader.loadNextGenotype())
+    {
+        // while a valid genotype was loaded
+        count++;
+        totalsize += loaded->genotype.len();
+        // create a Geno object based on the MiniGenotype
+        Geno *pNextGenotype = new Geno(loaded->genotype);
+        if ((pNextGenotype != NULL) && (pNextGenotype->isValid()))
+        {
+            pvGenos->push_back(pNextGenotype);
+            char *szNewName = new char [ loaded->name.len() + 1];
+            strcpy(szNewName, loaded->name.c_str());
+            pvNames->push_back(szNewName);
+        }
+        else
+        {
+            printf("Genotype %2li is not valid\n", count);
+        }
+    }
+    if (loader.getStatus() == MiniGenotypeLoader::OnError)
+    {
+        printf("Error: %s", loader.getError().c_str());
+    }
+
+    double dSimilarity = 0.0;
+    double **aaSimil = NULL; // array of similarities
+
+    // create the empty array of similarities
+    aaSimil = new pDouble [pvGenos->size()];
+    for (unsigned int k = 0; k < pvGenos->size(); k++)
+    {
+        aaSimil[k] = new double [pvGenos->size()];
+        for (unsigned int l = 0; l < pvGenos->size(); l++)
+            aaSimil[k][l] = 0.0;
+    }
+
+    // compute and remember similarities
+    unsigned int i, j;
+    for (i = 0; i < pvGenos->size(); i++)
+    {
+        for (j = 0; j < pvGenos->size(); j++)
+        {
+            dSimilarity = M.EvaluateDistance(pvGenos->operator[](i), pvGenos->operator[](j));
+            aaSimil[i][j] = dSimilarity;
+        }
+    }
+
+    if (bPrintNames)
+    {
+        // if "-names" switch was given,
+        // print the number of genotypes and their names
+        printf("%li\n", pvGenos->size());
+        unsigned int iGen;
+        for (iGen = 0; iGen < pvNames->size(); iGen++)
+        {
+            printf("%s\n", pvNames->at(iGen));
+        }
+    } // if (bPrintNames)
+
+    // print out the matrix of similarities
+    for (i = 0; i < pvGenos->size(); i++)
+    {
+        for (j = 0; j < pvGenos->size(); j++)
+        {
+            printf("%.2lf\t", aaSimil[i][j]);
+        }
+        printf("\n");
+    }
+
+    // delete vectors and arrays
+    for (i = 0; i < pvGenos->size(); i++)
+    {
+        delete pvGenos->operator[](i);
+        delete [] pvNames->operator[](i);
+        delete [] aaSimil[i];
+    }
+
+    delete pvGenos;
+    delete pvNames;
+    delete [] aaSimil;
+
+    return 0;
+}
