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

Last change on this file since 1311 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
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
[972]2// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
[286]3// See LICENSE.txt for details.
[135]4
[382]5#include <common/virtfile/stdiofile.h>
[135]6#include <frams/util/sstringutils.h>
[145]7#include <frams/genetics/preconfigured.h>
[135]8#include <frams/model/model.h>
[391]9#include <common/loggers/loggertostdout.h>
[135]10#include <frams/canvas/nn_layout_model.h>
11
12#include <algorithm>
13
14/**
15 @file
16 Sample code: Neuron layout tester
17
[408]18 Hint: Use loader_test to extract genotypes from Framsticks *.gen files:
[135]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)
[972]23template <int MEMBER> struct NNIter : public std::iterator<std::forward_iterator_tag, int> //MEMBER: 0..3=x/y/w/h
[135]24{
[972]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; }
[135]32
[972]33        static NNIter begin(NNLayoutState *_nn) { return NNIter(_nn, 0); }
34        static NNIter end(NNLayoutState *_nn) { return NNIter(_nn, _nn->GetElements()); }
[135]35};
36
37class Screen
38{
[972]39        int min_x, max_x, min_y, max_y, scale_x, scale_y;
40        int rows, columns;
41        char* screen;
[135]42
43public:
44
[972]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        }
[135]53
[972]54        ~Screen()
55        {
[135]56                delete[] screen;
[972]57        }
[135]58
[972]59        void put(int x, int y, const char *str)
[135]60        {
[972]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++)
[135]67                {
[972]68                        if (x >= columns) return;
69                        screen[columns * y + x] = *str;
[135]70                }
71        }
72
[972]73        void print()
[135]74        {
[972]75                for (int y = 0; y < rows; y++)
[135]76                {
[972]77                        fwrite(&screen[columns * y], 1, columns, stdout);
78                        printf("\n");
[135]79                }
80        }
81};
82
[972]83int main(int argc, char*argv[])
[135]84{
[972]85        LoggerToStdout messages_to_stdout(LoggerBase::Enable);
86        PreconfiguredGenetics genetics;
[145]87
[972]88        if (argc <= 1)
[135]89        {
90                puts("Parameters:\n"
[972]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;
[135]94        }
[972]95        SString gen(argv[1]);
96        if (!strcmp(gen.c_str(), "-"))
[135]97        {
[972]98                gen = 0;
99                StdioFILEDontClose in(stdin);
100                loadSString(&in, gen);
[135]101        }
[972]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; }
[999]106        Model m(g, Model::SHAPETYPE_UNKNOWN);
[972]107        if (!m.getNeuroCount()) { puts("no neural network"); return 1; }
108        printf("%d neurons,", m.getNeuroCount());
[135]109
[972]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);
[135]114
[972]115        for (int i = 0; i < nn_layout.GetElements(); i++)
[135]116        {
[972]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]);
[135]120        }
121
[972]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);
[135]127
[972]128        printf("===========================================\n");
129        for (int i = 0; i < nn_layout.GetElements(); i++)
[135]130        {
[972]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());
[135]134        }
[972]135        screen.print();
136        printf("===========================================\n");
[135]137
138}
Note: See TracBrowser for help on using the repository browser.