source: cpp/frams/genetics/fT/fTest_oper.cpp @ 896

Last change on this file since 896 was 896, checked in by Maciej Komosinski, 12 days ago

Replaced #defined macros for popular random-related operations with functions

  • Property svn:eol-style set to native
File size: 3.8 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2019  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include "fTest_oper.h"
6#include <common/nonstd.h> //randomN, rnd01
7
8/**
9Sample output (simple examples of various genetic operations) produced by genooper_test_fTest.cpp:
10$ ./genooper_test_fTest.exe
11GATCGATTACA   [mutated 0.0%]
12GATCCATTACA   [mutated 9.1%]
13GATCCTGTACA   [mutated 27.3%]
14GATCCTGTACA   [mutated 0.0%]
15GATCCTGTACA   [mutated 0.0%]
16GATCCTGTATA   [mutated 9.1%]
17GATCCTGTATA   [mutated 0.0%]
18GATACTGTATA   [mutated 9.1%]
19GATACTGTATA   [mutated 9.1%]
20GATACTGTATA   [mutated 0.0%]
21
22Crossing over the last mutant,
23GATACTGTATA
24and the simplest genotype
25GATCGATTACA
26:
27Offspring 1:
28GATACTCGATTACA  (35.7% genes from parent1)
29Offspring 2:
30GATGTATA  (25.0% genes from parent2)
31
32Checking genotype:
33ATGsomethingCG... error at position 4.
34After validation:
35ATGCG
36...and how about YOUR genotype?
37*/
38
39
40// To test this genetic format, you can also use the general genooper_test app that supports all genetic formats:
41// $ ./genooper_test.exe /*T*/AAAAAAAAAAA
42
43
44
45#define FIELDSTRUCT GenoOper_fTest
46static ParamEntry GENOtestparam_tab[] =   //external access to ftest genetic parameters
47{
48        { "Genetics: fTest", 1, 1, },
49        { "fTest_mut", 0, 0, "Mutation probability", "f 0 1", FIELD(prob), "How many genes should be mutated during single mutation (1=all genes, 0.1=ten percent)", },
50        { 0, },
51};
52#undef FIELDSTRUCT
53
54GenoOper_fTest::GenoOper_fTest()
55{
56        par.setParamTab(GENOtestparam_tab);
57        par.select(this);
58        supported_format = 'T'; //'0' for f0, '1' for f1, 'F' for fF, etc.
59        prob = 0.1;
60}
61
62///The only letters allowed are A,T,G,C
63int GenoOper_fTest::checkValidity(const char* gene)
64{
65        if (!gene[0]) return 1; //empty is not valid
66        bool ok = true;
67        size_t i;
68        for (i = 0; i < strlen(gene); i++) if (!strchr("ATGC", gene[i])) { ok = false; break; }
69        return ok ? GENOPER_OK : i + 1;
70}
71
72///Remove all invalid letters from the genotype
73int GenoOper_fTest::validate(char *&gene)
74{
75        SString validated; //new genotype (everything except ATGC is skipped)
76        for (size_t i = 0; i < strlen(gene); i++)
77                if (strchr("ATGC", gene[i])) validated += gene[i];  //validated contains only ATGC
78        free(gene);
79        gene = strdup(validated.c_str()); //reallocate
80        return GENOPER_OK;
81}
82
83///Very simple mutation; should be improved to guarantee at least one gene changed
84int GenoOper_fTest::mutate(char *&geno, float &chg, int &method)
85{
86        static char a[] = "ATGC";
87        method = 0;
88        int changes = 0, len = strlen(geno);
89        for (int i = 0; i < len; i++)
90                if (rndDouble(1) < prob) //normalize prob with length of genotype
91                {
92                        geno[i] = a[rndUint(4)];
93                        changes++;
94                }
95        chg = (float)changes / len;
96        return GENOPER_OK;
97}
98
99///A simple one-point crossover
100int GenoOper_fTest::crossOver(char *&g1, char *&g2, float& chg1, float& chg2)
101{
102        int len1 = strlen(g1), len2 = strlen(g2);
103        int p1 = rndUint(len1);  //random cut point for first genotype
104        int p2 = rndUint(len2);  //random cut point for second genotype
105        char *child1 = (char*)malloc(p1 + len2 - p2 + 1);
106        char *child2 = (char*)malloc(p2 + len1 - p1 + 1);
107        strncpy(child1, g1, p1);   strcpy(child1 + p1, g2 + p2);
108        strncpy(child2, g2, p2);   strcpy(child2 + p2, g1 + p1);
109        free(g1); g1 = child1;
110        free(g2); g2 = child2;
111        chg1 = (float)p1 / strlen(child1);
112        chg2 = (float)p2 / strlen(child2);
113        return GENOPER_OK;
114}
115
116///Applying some colors and font styles...
117uint32_t GenoOper_fTest::style(const char *g, int pos)
118{
119        char ch = g[pos];
120        uint32_t style = GENSTYLE_CS(0, GENSTYLE_INVALID); //default, should be changed below
121        if (ch == 'A') style = GENSTYLE_RGBS(200, 0, 0, GENSTYLE_BOLD);
122        if (ch == 'T') style = GENSTYLE_RGBS(0, 200, 0, GENSTYLE_BOLD);
123        if (ch == 'G') style = GENSTYLE_RGBS(0, 0, 200, GENSTYLE_NONE);
124        if (ch == 'C') style = GENSTYLE_RGBS(200, 200, 0, GENSTYLE_NONE);
125        return style;
126}
Note: See TracBrowser for help on using the repository browser.