source: cpp/frams/_demos/neuro_layout_test.cpp @ 1229

Last change on this file since 1229 was 999, checked in by Maciej Komosinski, 4 years ago

More consistent usage of "shapetype" (vs. "shape")

  • Property svn:eol-style set to native
File size: 4.1 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include <common/virtfile/stdiofile.h>
6#include <frams/util/sstringutils.h>
7#include <frams/genetics/preconfigured.h>
8#include <frams/model/model.h>
9#include <common/loggers/loggertostdout.h>
10#include <frams/canvas/nn_layout_model.h>
11
12#include <algorithm>
13
14/**
15 @file
16 Sample code: Neuron layout tester
17
18 Hint: Use loader_test to extract genotypes from Framsticks *.gen files:
19 loader_test "data/walking.gen" "Walking Lizard" | neuro_layout_test -
20*/
21
22// stl is fun? ;-) ForwardIterator implementation for element coordinates (required by min_element/max_element)
23template <int MEMBER> struct NNIter : public std::iterator<std::forward_iterator_tag, int> //MEMBER: 0..3=x/y/w/h
24{
25        NNLayoutState *nn; int index;
26        NNIter() {}
27        NNIter(NNLayoutState *_nn, int _index) :nn(_nn), index(_index) {}
28        int operator*() { return nn->GetXYWH(index)[MEMBER]; }
29        NNIter& operator++() { index++; return *this; }
30        bool operator!=(const NNIter& it) { return index != it.index; }
31        bool operator==(const NNIter& it) { return index == it.index; }
32
33        static NNIter begin(NNLayoutState *_nn) { return NNIter(_nn, 0); }
34        static NNIter end(NNLayoutState *_nn) { return NNIter(_nn, _nn->GetElements()); }
35};
36
37class Screen
38{
39        int min_x, max_x, min_y, max_y, scale_x, scale_y;
40        int rows, columns;
41        char* screen;
42
43public:
44
45        Screen(int _min_x, int _max_x, int _min_y, int _max_y, int _scale_x, int _scale_y)
46                :min_x(_min_x), max_x(_max_x), min_y(_min_y), max_y(_max_y), scale_x(_scale_x), scale_y(_scale_y)
47        {
48                columns = (max_x - min_x + scale_x - 1) / scale_x;
49                rows = (max_y - min_y + scale_y - 1) / scale_y;
50                screen = new char[rows * columns];
51                memset(screen, ' ', rows * columns);
52        }
53
54        ~Screen()
55        {
56                delete[] screen;
57        }
58
59        void put(int x, int y, const char *str)
60        {
61                x = (x - min_x) / scale_x;
62                y = (y - min_y) / scale_y;
63                if (x < 0) return;
64                if (y < 0) return;
65                if (y >= rows) return;
66                for (; *str; str++, x++)
67                {
68                        if (x >= columns) return;
69                        screen[columns * y + x] = *str;
70                }
71        }
72
73        void print()
74        {
75                for (int y = 0; y < rows; y++)
76                {
77                        fwrite(&screen[columns * y], 1, columns, stdout);
78                        printf("\n");
79                }
80        }
81};
82
83int main(int argc, char*argv[])
84{
85        LoggerToStdout messages_to_stdout(LoggerBase::Enable);
86        PreconfiguredGenetics genetics;
87
88        if (argc <= 1)
89        {
90                puts("Parameters:\n"
91                        " 1. Genotype (or - character indicating the genotype will be read from stdin)\n"
92                        " 2. (Optional) layout type (the only useful layout is 2, which is the default, see nn_simple_layout.cpp");
93                return 10;
94        }
95        SString gen(argv[1]);
96        if (!strcmp(gen.c_str(), "-"))
97        {
98                gen = 0;
99                StdioFILEDontClose in(stdin);
100                loadSString(&in, gen);
101        }
102        int layout_type = 2;
103        if (argc > 2) layout_type = atol(argv[2]);
104        Geno g(gen);
105        if (!g.isValid()) { puts("invalid genotype"); return 5; }
106        Model m(g, Model::SHAPETYPE_UNKNOWN);
107        if (!m.getNeuroCount()) { puts("no neural network"); return 1; }
108        printf("%d neurons,", m.getNeuroCount());
109
110        NNLayoutState_Model nn_layout(&m);
111        struct NNLayoutFunction &nnfun = nn_layout_functions[layout_type];
112        printf(" using layout type=%d (%s)\n", layout_type, nnfun.name);
113        nnfun.doLayout(&nn_layout);
114
115        for (int i = 0; i < nn_layout.GetElements(); i++)
116        {
117                int *xywh = nn_layout.GetXYWH(i);
118                printf("#%-3d %s\t%d,%d\t%dx%d\n", i, m.getNeuro(i)->getClassName().c_str(),
119                        xywh[0], xywh[1], xywh[2], xywh[3]);
120        }
121
122        Screen screen(*std::min_element(NNIter<0>::begin(&nn_layout), NNIter<0>::end(&nn_layout)) - 30,
123                *std::max_element(NNIter<0>::begin(&nn_layout), NNIter<0>::end(&nn_layout)) + 70,
124                *std::min_element(NNIter<1>::begin(&nn_layout), NNIter<1>::end(&nn_layout)),
125                *std::max_element(NNIter<1>::begin(&nn_layout), NNIter<1>::end(&nn_layout)) + 30,
126                10, 35);
127
128        printf("===========================================\n");
129        for (int i = 0; i < nn_layout.GetElements(); i++)
130        {
131                int *xywh = nn_layout.GetXYWH(i);
132                SString label = SString::sprintf("%d:%s", i, m.getNeuro(i)->getClassName().c_str());
133                screen.put(xywh[0], xywh[1], label.c_str());
134        }
135        screen.print();
136        printf("===========================================\n");
137
138}
Note: See TracBrowser for help on using the repository browser.