// 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 #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] Parameters: name of a file with genotypes (only f1 format) weight of the difference in the number of parts weight of the difference in degrees of matched parts weight of the difference in neurons of matched parts 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: (columns in a row are separated by TABs) ... 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] \n\n"); printf("Parameters:\n"); printf(" name of a file with genotypes (only f1 format is allowed)\n"); printf(" weight of the difference in the number of parts\n"); printf(" weight of the difference in degrees of matched parts\n"); printf(" weight of the difference in neurons of matched parts\n"); printf(" 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(" (columns in a row are separated by TABs)\n"); printf(" ...\n"); printf(" \n"); return -1; } // prepare output parameters from .gen file vector *pvGenos = new vector(); vector *pvNames = new vector(); // 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 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; } const char *params[] = {"", "", "", ""}; for (int i = 0; i < M.GetNOFactors(); i++) { iCurrParam++; szCurrParam = argv[ iCurrParam ]; nResult = sscanf(szCurrParam, " %lf ", & M.m_adFactors[ i ]); if (nResult != 1) { // is not a number -- error printf("%s", params[i]); printf(" should be a number\n"); return -1; } else { // 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 (int k = 0; k < (int) pvGenos->size(); k++) { aaSimil[k] = new double [pvGenos->size()]; for (int l = 0; l < (int) pvGenos->size(); l++) aaSimil[k][l] = 0.0; } // compute and remember similarities int i, j; for (i = 0; i < (int) pvGenos->size(); i++) { for (j = 0; j < (int) 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()); int iGen; for (iGen = 0; iGen < (int) pvNames->size(); iGen++) { printf("%s\n", pvNames->at(iGen)); } } // if (bPrintNames) // print out the matrix of similarities for (i = 0; i < (int) pvGenos->size(); i++) { for (j = 0; j < (int) pvGenos->size(); j++) { printf("%.2lf\t", aaSimil[i][j]); } printf("\n"); } // delete vectors and arrays for (i = 0; i < (int) pvGenos->size(); i++) { delete pvGenos->operator[](i); delete [] pvNames->operator[](i); delete [] aaSimil[i]; } delete pvGenos; delete pvNames; delete [] aaSimil; return 0; }