experiments/evorobot/src/displaycontroller.cpp

00001 /********************************************************************************
00002  *  FARSA Experiments Library                                                   *
00003  *  Copyright (C) 2007-2012                                                     *
00004  *  Stefano Nolfi <stefano.nolfi@istc.cnr.it>                                   *
00005  *  Onofrio Gigliotta <onofrio.gigliotta@istc.cnr.it>                           *
00006  *  Gianluca Massera <emmegian@yahoo.it>                                        *
00007  *  Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it>                         *
00008  *                                                                              *
00009  *  This program is free software; you can redistribute it and/or modify        *
00010  *  it under the terms of the GNU General Public License as published by        *
00011  *  the Free Software Foundation; either version 2 of the License, or           *
00012  *  (at your option) any later version.                                         *
00013  *                                                                              *
00014  *  This program is distributed in the hope that it will be useful,             *
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of              *
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
00017  *  GNU General Public License for more details.                                *
00018  *                                                                              *
00019  *  You should have received a copy of the GNU General Public License           *
00020  *  along with this program; if not, write to the Free Software                 *
00021  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *
00022  ********************************************************************************/
00023 
00024 #include "displaycontroller.h"
00025 
00026 #include <QtGui>        // Widget
00027 #include <QKeyEvent>    // Dialog
00028 #include <QFileDialog>  // Dialog
00029 #include <QMessageBox>  // Dialog
00030 #include <QImage>       // the background image of the controller
00031 #include "logger.h"
00032 
00033 // All the suff below is to avoid warnings on Windows about the use of unsafe
00034 // functions. This should be only a temporary workaround, the solution is stop
00035 // using C string and file functions...
00036 #if defined(_MSC_VER)
00037     #pragma warning(push)
00038     #pragma warning(disable:4996)
00039 #endif
00040 
00041 #define MAXFREEP 10000
00042 
00043 namespace farsa {
00044 
00045 NetworkDialog::NetworkDialog(Evonet* net, QWidget* parent, Qt::WindowFlags flags) : QWidget( parent, flags )
00046 {
00047     this->enet=net;
00048 
00049     drawblocks = 0;          // whether we display or not the list of block  
00050     cneuronn=0;              // n. of selected cneurons
00051     cscalex=1.0;             // x scale for the controller rendering
00052     cscaley=1.0;             // y scale for the controller rendering
00053     pseudomode=0;            // the display modality (0=label 1=delta, 2=weight, 3=biases, 4=gain)
00054     enet->nselected=0;       // number of currently extracted parameters
00055     grid=0;                  // no grid
00056 
00057     // Creating the main layout. Direction is BottomToTop so that m_layout (added first)
00058     // is at bottom, while the toolbar (added last) is on top
00059     m_mainLayout = new QVBoxLayout(this);
00060     //m_mainLayout->setContentsMargins(0, 0, 0, 0);
00061 
00062     createActions();
00063     // Creating toolbar and adding it to the main layout
00064     m_toolBar = new QToolBar(this);
00065     m_mainLayout->addWidget(m_toolBar);
00066     createToolBars();
00067 
00068     //enet->wrange=5.0;        // debug: this variable has to be taken from parameters
00069     //enet->grange=5.0;        // debug: this variable has to be taken from parameters
00070     this->enet->neuronlesions = 0; // debug: this variable has to be taken from parameters
00071     
00072     freep=enet->freep;
00073     /*
00074     freep=new float[MAXFREEP];
00075     for(i=0, p=freep; i < MAXFREEP; i++, p++)
00076         *p = 0.0;
00077      
00078     if (this->load_net_blocks("evorobot.net", 1) != 1)
00079     {
00080       Logger::error("error: file robot.net not found");
00081       exit(1);
00082     }
00083  
00084     for(i=0;i< enet->nneurons;i++)   // debug: we create labels here manually for the moment, but we should use the evonet class variables
00085     {
00086      sprintf(enet->neuronl[i],"N%d",i);
00087      sprintf(neuroncl[i],"N%d",i);
00088 
00089     }
00090     */
00091     rendNetwork = new RendNetwork( this );
00092     m_mainLayout->addWidget( rendNetwork, 4 );
00093 }
00094 
00095 
00096 NetworkDialog::~NetworkDialog()
00097 {
00098 }
00099 
00100 /*
00101 void NetworkDialog::keyReleaseEvent(QKeyEvent* event)
00102 {
00103    
00104     if (event->matches(QKeySequence::Print)) {
00105         // Taking a screenshow of the widget
00106         shotWidget();
00107     } else {
00108         // Calling parent function
00109         QDialog::keyReleaseEvent(event);
00110     }
00111 }
00112 */
00113 
00114 void NetworkDialog::shotWidget()
00115 {
00116     /*
00117     // Taking a screenshot of this widget
00118     QPixmap shot(size());
00119     render(&shot);
00120 
00121     // Asking the user where to save the shot
00122     QString fileName = QFileDialog::getSaveFileName(this, tr("Save Shot"), "./widget.png", tr("Images (*.png *.xpm *.jpg)"));
00123     if (!fileName.isEmpty()) {
00124         shot.save(fileName);
00125 
00126         QMessageBox::information(this, QString("File Saved"), QString("The widget shot has been saved"));
00127     }*/
00128 }
00129 
00130 
00131 void NetworkDialog::error(const char *emessage)
00132 {
00133    QMessageBox::about(this, "ERROR", emessage);
00134 }
00135 
00136 void NetworkDialog::warning(const char *emessage)
00137 {
00138    QMessageBox::about(this, "WARNING", emessage);
00139 }
00140 
00141 void NetworkDialog::createToolBars()
00142 {
00143     m_toolBar->addAction(openAct);
00144     m_toolBar->addAction(saveAct);
00145     m_toolBar->addAction(randomfreepAct);
00146     m_toolBar->addAction(set_neurontypeAct);
00147     m_toolBar->addAction(set_neurongainAct);
00148     m_toolBar->addAction(set_neuronbiasAct);
00149     m_toolBar->addAction(set_lesionAct);
00150     m_toolBar->addAction(mixerAct);
00151     m_toolBar->addAction(set_neurondisplayAct);
00152     m_toolBar->addAction(display_labelAct);
00153     m_toolBar->addAction(display_weightAct);
00154     m_toolBar->addAction(display_deltaAct);
00155     m_toolBar->addAction(display_biasAct);
00156     m_toolBar->addAction(display_gainAct);
00157     m_toolBar->addAction(display_blocksAct);
00158     m_toolBar->addAction(erase_netAct);
00159     m_toolBar->addAction(add_ublockAct);
00160     m_toolBar->addAction(add_cblockAct);
00161     m_toolBar->addAction(add_gblockAct);
00162 }
00163 
00164 void NetworkDialog::createActions()
00165 {
00166 
00167     
00168     openAct = new QAction(QIcon(":/evorobot/open.png"), tr("&Open"), this);
00169     
00170     
00171     openAct->setStatusTip(tr("Open a network architecture or a phenotype file"));
00172     connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
00173 
00174     saveAct = new QAction(QIcon(":/evorobot/save.png"), tr("&Save"), this);
00175     saveAct->setStatusTip(tr("Save the network architecture or the phenotype from a file"));
00176     connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
00177 
00178     randomfreepAct = new QAction(QIcon(":/evorobot/light.png"), tr("&Randomize"), this);
00179     randomfreepAct->setStatusTip(tr("Randomize thee free parameters (population and individual)"));
00180     connect(randomfreepAct, SIGNAL(triggered()), this, SLOT(randomfreep()));
00181 
00182     set_neurondisplayAct = new QAction(QIcon(":/evorobot/show.png"), tr("&Set/Unset neurons to be displayed as graph"), this);
00183     set_neurondisplayAct->setShortcut(tr("Ctrl+N"));
00184     set_neurondisplayAct->setStatusTip(tr("Select/Deselect neurons to be displayed as graph"));
00185     connect(set_neurondisplayAct, SIGNAL(triggered()), this, SLOT(set_neurondisplay()));
00186 
00187     set_neurontypeAct = new QAction(QIcon(":/evorobot/delta.png"), tr("&change neurons type"), this);
00188     set_neurontypeAct->setShortcut(tr("Ctrl+W"));
00189     set_neurontypeAct->setStatusTip(tr("change neurons type"));
00190     connect(set_neurontypeAct, SIGNAL(triggered()), this, SLOT(set_neurontype()));
00191 
00192     set_neurongainAct = new QAction(QIcon(":/evorobot/gain.png"), tr("&Add/Remove neurons gain"), this);
00193     set_neurongainAct->setShortcut(tr("Ctrl+G"));
00194     set_neurongainAct->setStatusTip(tr("Add/Remove neurons gain"));
00195     connect(set_neurongainAct, SIGNAL(triggered()), this, SLOT(set_neurongain()));
00196 
00197     set_neuronbiasAct = new QAction(QIcon(":/evorobot/bias.png"), tr("&Add/Remove neurons biases"), this);
00198     set_neuronbiasAct->setShortcut(tr("Ctrl+B"));
00199     set_neuronbiasAct->setStatusTip(tr("Add/Remove neurons bias"));
00200     connect(set_neuronbiasAct, SIGNAL(triggered()), this, SLOT(set_neuronbias()));
00201 
00202     set_lesionAct = new QAction(QIcon(":/evorobot/lesion.png"), tr("&Lesion/Restore neurons"), this);
00203     set_lesionAct->setShortcut(tr("Ctrl+B"));
00204     set_lesionAct->setStatusTip(tr("Lesion/Restore neurons"));
00205     connect(set_lesionAct, SIGNAL(triggered()), this, SLOT(set_lesion()));
00206 
00207     mixerAct = new QAction(QIcon(":/evorobot/mix.png"), tr("&Lesion/Restore neurons"), this);
00208     mixerAct->setShortcut(tr("Ctrl+M"));
00209     mixerAct->setStatusTip(tr("Mixer to change Lesioned neurons' values"));
00210     connect(mixerAct, SIGNAL(triggered()), this, SLOT(openMixer()));
00211 
00212     display_labelAct = new QAction(QIcon(":/evorobot/label.png"), tr("&Display/Undisplay neuron labels"), this);
00213     display_labelAct->setShortcut(tr("Ctrl+L"));
00214     display_labelAct->setStatusTip(tr("Display neuron labels"));
00215     connect(display_labelAct, SIGNAL(triggered()), this, SLOT(display_label()));
00216 
00217     display_weightAct = new QAction(QIcon(":/evorobot/weight.png"), tr("&Display/Undisplay weights"), this);
00218     display_weightAct->setShortcut(tr("Ctrl+W"));
00219     display_weightAct->setStatusTip(tr("Display the incoming and outcoming weight of a neuron"));
00220     connect(display_weightAct, SIGNAL(triggered()), this, SLOT(display_weight()));
00221 
00222     display_deltaAct = new QAction(QIcon(":/evorobot/ddelta.png"), tr("&Display/Undisplay neurons delta"), this);
00223     display_deltaAct->setShortcut(tr("Ctrl+Y"));
00224     display_deltaAct->setStatusTip(tr("Display neurons delta"));
00225     connect(display_deltaAct, SIGNAL(triggered()), this, SLOT(display_delta()));
00226 
00227     display_biasAct = new QAction(QIcon(":/evorobot/dbias.png"), tr("&Display/Undisplay biases"), this);
00228     display_biasAct->setShortcut(tr("Ctrl+Z"));
00229     display_biasAct->setStatusTip(tr("Display neurons biases"));
00230     connect(display_biasAct, SIGNAL(triggered()), this, SLOT(display_bias()));
00231 
00232     display_gainAct = new QAction(QIcon(":/evorobot/dgain.png"), tr("&Display/Undisplay gains"), this);
00233     display_gainAct->setShortcut(tr("Ctrl+G"));
00234     display_gainAct->setStatusTip(tr("Display neurons gains"));
00235     connect(display_gainAct, SIGNAL(triggered()), this, SLOT(display_gain()));
00236 
00237     display_blocksAct = new QAction(QIcon(":/evorobot/displayblocks.png"), tr("&Display/Undisplay blocks"), this);
00238     display_blocksAct->setShortcut(tr("Ctrl+B"));
00239     display_blocksAct->setStatusTip(tr("Display blocks description"));
00240     connect(display_blocksAct, SIGNAL(triggered()), this, SLOT(display_blocks()));
00241 
00242     erase_netAct = new QAction(QIcon(":/evorobot/erase.png"), tr("&Erase network"), this);
00243     erase_netAct->setShortcut(tr("Ctrl+E"));
00244     erase_netAct->setStatusTip(tr("Erase selected/all connections and update blocks"));
00245     connect(erase_netAct, SIGNAL(triggered()), this, SLOT(erase_net()));
00246 
00247     add_ublockAct = new QAction(QIcon(":/evorobot/addublock.png"), tr("&Add Update Block"), this);
00248     add_ublockAct->setShortcut(tr("Ctrl+A"));
00249     add_ublockAct->setStatusTip(tr("add an update block"));
00250     connect(add_ublockAct, SIGNAL(triggered()), this, SLOT(add_ublock()));
00251 
00252     add_cblockAct = new QAction(QIcon(":/evorobot/addblock.png"), tr("&Add Connection Block"), this);
00253     add_cblockAct->setShortcut(tr("Ctrl+A"));
00254     add_cblockAct->setStatusTip(tr("add a connection block"));
00255     connect(add_cblockAct, SIGNAL(triggered()), this, SLOT(add_cblock()));
00256 
00257     add_gblockAct = new QAction(QIcon(":/evorobot/gainblock.png"), tr("&Add a gain block"), this);
00258     add_gblockAct->setShortcut(tr("Ctrl+G"));
00259     add_gblockAct->setStatusTip(tr("add a gain block"));
00260     connect(add_gblockAct, SIGNAL(triggered()), this, SLOT(add_gblock()));
00261     
00262     increasevAct = new QShortcut(tr("+"), this); 
00263     connect(increasevAct, SIGNAL(activated()), this, SLOT(increasev()));
00264     
00265     decreasevAct = new QShortcut(tr("-"), this);
00266     connect(decreasevAct, SIGNAL(activated()), this, SLOT(decreasev()));
00267     
00268 
00269 }
00270 
00271 
00272 // Randomize the free parameters 
00273 void NetworkDialog::randomfreep()
00274 {
00275 
00276     // debug: randomization of parameters to be implemented here
00277     rendNetwork->update();
00278 
00279 }
00280 
00281 // define or undefine neurons to be displayed
00282 void NetworkDialog::set_neurondisplay()
00283 {
00284    int i;
00285 
00286    if (cneuronn == 1)
00287    {
00288      if (enet->neurondisplay[cneuron[0]] == 1)
00289        enet->neurondisplay[cneuron[0]] = 0;
00290       else
00291        enet->neurondisplay[cneuron[0]] = 1;
00292    }
00293    if (cneuronn == 2)
00294    {
00295      if (enet->neurondisplay[cneuron[0]] == 1)
00296       for (i=cneuron[0]; i <= cneuron[1]; i++)
00297        enet->neurondisplay[i] = 0;
00298      else
00299       for (i=cneuron[0]; i <= cneuron[1]; i++)
00300        enet->neurondisplay[i] = 1;
00301    }
00302    if (cneuronn < 1 || cneuronn > 2)
00303      warning("you should select one neuron or one block of neurons first");
00304 
00305    cneuronn = 0;
00306    rendNetwork->update();
00307 
00308 }
00309 // change neurons' type
00310 void NetworkDialog::set_neurontype()
00311 {
00312     int i;
00313     
00314     if (cneuronn == 1)
00315     {
00316         enet->neurontype[cneuron[0]] += 1;
00317         if (enet->neurontype[cneuron[0]] > 3)
00318             enet->neurontype[cneuron[0]] = 0;
00319     }
00320     if (cneuronn == 2)
00321     {
00322         for (i=cneuron[0]; i <= cneuron[1]; i++)
00323         {  
00324             enet->neurontype[i] += 1;
00325             if (enet->neurontype[i] > 3) 
00326                 enet->neurontype[i] = 0;
00327         }
00328     }
00329     if (cneuronn < 1 || cneuronn > 2)
00330         warning("you should select one neuron or one block of neurons first");
00331     
00332     rendNetwork->update();
00333 
00334 }
00335 
00336 
00337 // define or undefine neurons gain
00338 void NetworkDialog::set_neurongain()
00339 {
00340    int i;
00341 
00342    if (cneuronn == 1)
00343    {
00344      if (enet->neurongain[cneuron[0]] == 1)
00345        enet->neurongain[cneuron[0]] = 0;
00346       else
00347        enet->neurongain[cneuron[0]] = 1;
00348    }
00349    if (cneuronn == 2)
00350    {
00351      if (enet->neurongain[cneuron[0]] == 1)
00352       for (i=cneuron[0]; i <= cneuron[1]; i++)
00353        enet->neurongain[i] = 0;
00354      else
00355       for (i=cneuron[0]; i <= cneuron[1]; i++)
00356        enet->neurongain[i] = 1;
00357    }
00358    if (cneuronn < 1 || cneuronn > 2)
00359      warning("you should select one neuron or one block of neurons first");
00360 
00361     cneuronn = 0;
00362     rendNetwork->update();
00363 
00364 }
00365 
00366 
00367 // define or undefine neurons bias
00368 void NetworkDialog::set_neuronbias()
00369 {
00370    int i;
00371 
00372    if (cneuronn == 1)
00373    {
00374      if (enet->neuronbias[cneuron[0]] == 1)
00375        enet->neuronbias[cneuron[0]] = 0;
00376       else
00377        enet->neuronbias[cneuron[0]] = 1;
00378    }
00379    if (cneuronn == 2)
00380    {
00381      if (enet->neuronbias[cneuron[0]] == 1)
00382       for (i=cneuron[0]; i <= cneuron[1]; i++)
00383        enet->neuronbias[i] = 0;
00384      else
00385       for (i=cneuron[0]; i <= cneuron[1]; i++)
00386        enet->neuronbias[i] = 1;
00387    }
00388    if (cneuronn < 1 || cneuronn > 2)
00389      warning("you should select one neuron or one block of neurons first");
00390 
00391    cneuronn = 0;
00392    rendNetwork->update();
00393 }
00394 
00395 /*
00396  * Lesion/Restore neurons
00397  */
00398 void NetworkDialog::set_lesion()
00399 {
00400     if (cneuronn == 1) {
00401         enet->neuronlesion[cneuron[0]]=!enet->neuronlesion[cneuron[0]];
00402         cneuronn = 0;
00403         rendNetwork->update();
00404     } else if (cneuronn == 2) {
00405         for(int ls = cneuron[0]; ls <= cneuron[1]; ls++) {
00406             enet->neuronlesion[ls] = !enet->neuronlesion[ls];
00407         }
00408         cneuronn = 0;
00409         rendNetwork->update();
00410     } else {
00411         warning("you should select one neuron or one block of neurons first");
00412     }
00413 }
00414 
00415 
00416 // Display neurons label
00417 void NetworkDialog::display_label()
00418 {
00419 
00420    pseudomode = 0;
00421    pseudo_activate_net(0);
00422    rendNetwork->update();
00423 
00424 }
00425 
00426 
00427 
00428 // Display/Undisplay neurons delta
00429 void NetworkDialog::display_delta()
00430 {
00431 
00432    pseudomode = 1;
00433    pseudo_activate_net(1);
00434    rendNetwork->update();
00435 
00436 }
00437 
00438 
00439 // Display/Undisplay the weights of a neuron
00440 void NetworkDialog::display_weight()
00441 {
00442 
00443 
00444    if (cneuronn == 1 || cneuronn == 2)
00445      {
00446       pseudomode = 2;
00447       pseudo_activate_net(2);
00448       rendNetwork->update();
00449      }
00450      else
00451      {
00452       warning("you should first select one or two (receiving and sending) neurons");
00453      }
00454 }
00455 
00456 // Display/Undisplay neurons biases
00457 void NetworkDialog::display_bias()
00458 {
00459 
00460    pseudomode = 3;
00461    pseudo_activate_net(3);
00462    rendNetwork->update();
00463 
00464 }
00465 
00466 // Display/Undisplay neurons gains
00467 void NetworkDialog::display_gain()
00468 {
00469 
00470    pseudomode = 4;
00471    pseudo_activate_net(4);
00472    rendNetwork->update();
00473 
00474 }
00475 
00476 // Display/Undisplay blocks description
00477 void NetworkDialog::display_blocks()
00478 {
00479 
00480   if (drawblocks == 0)
00481     drawblocks = 1;
00482   else
00483     drawblocks = 0;
00484   rendNetwork->update();
00485 
00486 }
00487 
00488 // Erase selected/all connections and update blocks
00489 // gain-block removal not implemented yet
00490 void NetworkDialog::erase_net()
00491 {
00492 
00493    int i,ii;
00494    int b,bb;
00495 
00496    if (cneuronn == 0)
00497    {
00498     enet->net_nblocks = 0;
00499     for(i=0;i < enet->nneurons; i++)
00500        {
00501          enet->neuronbias[i] = 0;
00502          enet->neurontype[i] = 0;
00503          enet->neurondisplay[i] = 1;
00504        }
00505     }
00506    if (cneuronn == 4)
00507    {
00508      for (b=0; b < enet->net_nblocks; b++)
00509       {
00510        if (enet->net_block[b][0] == 0 && enet->net_block[b][1] == cneuron[0]  && enet->net_block[b][2] == (cneuron[1] - cneuron[0] + 1) && enet->net_block[b][3] == cneuron[2] && enet->net_block[b][4] == (cneuron[3] - cneuron[2] + 1) )
00511         {
00512          for (bb=b; bb < (enet->net_nblocks - 1); bb++)
00513            for (ii=0; ii < 5; ii++)
00514              enet->net_block[bb][ii] = enet->net_block[bb+1][ii];
00515          enet->net_nblocks--;
00516         }
00517       }
00518     }
00519    if (cneuronn == 2)
00520    {
00521      for (b=0; b < enet->net_nblocks; b++)
00522       {
00523        if (enet->net_block[b][0] == 1 && enet->net_block[b][1] == cneuron[0] && enet->net_block[b][2] == (cneuron[1] - cneuron[0] + 1))
00524         {
00525          for (bb=b; bb < (enet->net_nblocks - 1); bb++)
00526            for (ii=0; ii < 5; ii++)
00527              enet->net_block[bb][ii] = enet->net_block[bb+1][ii];
00528            enet->net_nblocks--;
00529         }
00530        if (enet->net_block[b][0] == 0 && enet->net_block[b][1] == cneuron[0] && enet->net_block[b][2] == 1 && enet->net_block[b][3] == cneuron[1] && enet->net_block[b][4] == 1)
00531         {
00532          for (bb=b; bb < (enet->net_nblocks - 1); bb++)
00533            for (ii=0; ii < 5; ii++)
00534              enet->net_block[bb][ii] = enet->net_block[bb+1][ii];
00535            enet->net_nblocks--;
00536         }
00537       }
00538     }
00539    rendNetwork->update();
00540 }
00541 
00542 
00543 // Add an update block
00544 void NetworkDialog::add_ublock()
00545 {
00546 
00547   int i;
00548 
00549   i = enet->net_nblocks;
00550 
00551   if (cneuronn != 1 && cneuronn != 2)
00552     {
00553       warning("this command require to select 1 or 2 neurons");
00554       return;
00555     }
00556 
00557   if (cneuronn == 1)
00558     {
00559      enet->net_block[i][0] = 1;
00560      enet->net_block[i][1] = cneuron[0];
00561      enet->net_block[i][2] = 1;
00562      enet->net_block[i][3] = 0;
00563      enet->net_block[i][4] = 0;
00564      enet->net_nblocks++;
00565      cneuronn = 0;
00566     }
00567 
00568   if (cneuronn == 2)
00569     {
00570      enet->net_block[i][0] = 1;
00571      enet->net_block[i][1] = cneuron[0];
00572      enet->net_block[i][2] = cneuron[1] - cneuron[0] + 1;
00573      enet->net_block[i][3] = 0;
00574      enet->net_block[i][4] = 0;
00575      enet->net_nblocks++;
00576      cneuronn = 0;
00577     }
00578 
00579    rendNetwork->update();
00580 }
00581 
00582 
00583 // Add a connection block (at the end of the list but before the block that activate the corresponding neurons, if present)
00584 void NetworkDialog::add_cblock()
00585 {
00586 
00587   int i;
00588   int ii;
00589   int v;
00590   int b;
00591 
00592   if (cneuronn != 2 && cneuronn != 4)
00593     {
00594       warning("this command require to select 2 or 4 neurons");
00595       return;
00596     }
00597 
00598   b = enet->net_nblocks;
00599   for(i=0; i < enet->net_nblocks; i++)
00600     {
00601       if (enet->net_block[i][0] == 1 && (cneuron[0] >= enet->net_block[i][1]) && (cneuron[0] <= (enet->net_block[i][1] + enet->net_block[i][2] - 1)) )
00602        {
00603         b = i;
00604         for(ii=enet->net_nblocks; ii > b; ii--)
00605          {
00606           for(v=0; v < 5; v++)
00607            enet->net_block[ii][v] = enet->net_block[ii-1][v];
00608          }
00609        }
00610     }
00611 
00612   if (cneuronn == 2)
00613    {
00614     enet->net_block[b][0] = 0;
00615     enet->net_block[b][1] = cneuron[0];
00616     enet->net_block[b][2] = 1;
00617     enet->net_block[b][3] = cneuron[1];
00618     enet->net_block[b][4] = 1;
00619     enet->net_nblocks++;
00620     cneuronn = 0;
00621    }
00622 
00623   if (cneuronn == 4)
00624     {
00625      enet->net_block[b][0] = 0;
00626      enet->net_block[b][1] = cneuron[0];
00627      enet->net_block[b][2] = cneuron[1] - cneuron[0] + 1;
00628      enet->net_block[b][3] = cneuron[2];
00629      enet->net_block[b][4] = cneuron[3] - cneuron[2] + 1;
00630      enet->net_nblocks++;
00631      cneuronn = 0;
00632     }
00633 
00634    rendNetwork->update();
00635 }
00636 
00637 // Add a gain block
00638 void NetworkDialog::add_gblock()
00639 {
00640 
00641   int i;
00642 
00643   i = enet->net_nblocks;
00644 
00645   if (cneuronn != 2 && cneuronn != 3)
00646     {
00647       warning("this command require to select 2 or 3 neurons");
00648       return;
00649     }
00650 
00651   // a type-2 block operate by making the gain of a block of neurons
00652   // all equal to the gain of the first neuron
00653   if (cneuronn == 2)
00654     {
00655      enet->net_block[i][0] = 2;
00656      enet->net_block[i][1] = cneuron[0];
00657      enet->net_block[i][2] = cneuron[1] - cneuron[0] + 1;
00658      enet->net_block[i][3] = 0;
00659      enet->net_block[i][4] = 0;
00660      enet->net_nblocks++;
00661      cneuronn = 0;
00662     }
00663   // a type-3 block operate by making the gain of a block of neurons
00664   // all equal to activation state of the 3rd neuron
00665   if (cneuronn == 3)
00666     {
00667      enet->net_block[i][0] = 3;
00668      enet->net_block[i][1] = cneuron[0];
00669      enet->net_block[i][2] = cneuron[1] - cneuron[0] + 1;
00670      enet->net_block[i][3] = cneuron[2];
00671      enet->net_block[i][4] = 0;
00672      enet->net_nblocks++;
00673      cneuronn = 0;
00674     }
00675 
00676    rendNetwork->update();
00677 }
00678 
00679 
00680 /*
00681  * open a .net or .phe file
00682  */
00683 void NetworkDialog::open()
00684 {
00685 
00686     char *f;
00687     QByteArray filen;
00688     char filename[256];
00689 
00690 
00691     QString fileName = QFileDialog::getOpenFileName(this,
00692             "Choose a filename to open",
00693                     "",
00694                     "*.net *.phe");
00695 
00696 
00697     if (fileName.endsWith("net"))
00698     {
00699       filen = fileName.toAscii();
00700       f = filen.data();
00701       strcpy(filename, f);
00702       enet->load_net_blocks(filename, 0);
00703     }
00704     else
00705      if (fileName.endsWith("phe"))
00706      {
00707       filen = fileName.toAscii();
00708       f = filen.data();
00709       strcpy(filename, f);
00710       enet->load_net_blocks(filename, 1);
00711      }
00712 
00713 }
00714 
00715 /*
00716  * save a .net or .phe file
00717  */
00718 void NetworkDialog::save()
00719 {
00720 
00721     char *f;
00722     QByteArray filen;
00723     char filename[256];
00724 
00725 
00726     QString fileName = QFileDialog::getSaveFileName(this,
00727             "Choose a filename to save",
00728                     "",
00729                     "*.net *.phe");
00730 
00731 
00732     if (fileName.endsWith("net"))
00733     {
00734       filen = fileName.toAscii();
00735       f = filen.data();
00736       strcpy(filename, f);
00737       enet->save_net_blocks(filename, 0);
00738     }
00739     else
00740      if (fileName.endsWith("phe"))
00741      {
00742       filen = fileName.toAscii();
00743       f = filen.data();
00744       strcpy(filename, f);
00745       enet->save_net_blocks(filename, 1);
00746      }
00747 
00748 }
00749 
00750 // Increase a selected value
00751 void NetworkDialog::increasev()
00752 {
00753    float **gp;
00754    float *v;
00755 
00756 
00757    // when 2 neurons are selected we assume that the user want to change a connection weight
00758    if (cneuronn == 2)
00759      {
00760       pseudomode = 2;
00761       pseudo_activate_net(-1);
00762       if (enet->nselected == 1)
00763       {
00764        gp = enet->selectedp;
00765        v = *gp;
00766        *v += ((enet->wrange * 2.0f) / 256.0f);
00767        pseudo_activate_net(-1);
00768        rendNetwork->update();
00769       }
00770      }
00771    // when 1 neuron is selected we modify the bias of the neuron, 
00772    // or the delta or the gain of the neuron (if the user previously pushed the delta or gain buttons, respectively) 
00773    if (cneuronn == 1)
00774      {
00775       if (pseudomode != 1 && pseudomode != 4)
00776         pseudomode = 3;
00777       pseudo_activate_net(-1);
00778       if (enet->nselected == 1)
00779       {
00780        gp = enet->selectedp;
00781        v = *gp;
00782        *v += ((enet->wrange * 2.0f) / 256.0f);
00783        pseudo_activate_net(-1);
00784        rendNetwork->update();
00785       }
00786      }
00787 
00788 }
00789 
00790 // Decrease a selected value
00791 void NetworkDialog::decreasev()
00792 {
00793 
00794     float **gp;
00795     float *v;
00796 
00797 
00798    // when 2 neurons are selected we assume that the user want to change a connection weight
00799    if (cneuronn == 2)
00800      {
00801       pseudomode = 2;
00802       pseudo_activate_net(-1);
00803       if (enet->nselected == 1)
00804       {
00805        gp = enet->selectedp;
00806        v = *gp;
00807        *v -= ((enet->wrange * 2.0f) / 256.0f);
00808        pseudo_activate_net(-1);
00809        rendNetwork->update();
00810       }
00811      }
00812    // when 1 neuron is selected we modify the bias of the neuron, 
00813    // or the delta or the gain of the neuron (if the user previously pushed the delta or gain buttons, respectively) 
00814    if (cneuronn == 1)
00815      {
00816       if (pseudomode != 1 && pseudomode != 4)
00817         pseudomode = 3;
00818       pseudo_activate_net(-1);
00819       if (enet->nselected == 1)
00820       {
00821        gp = enet->selectedp;
00822        v = *gp;
00823        *v -= ((enet->wrange * 2.0f) / 256.0f);
00824        pseudo_activate_net(-1);
00825        rendNetwork->update();
00826       }
00827      }
00828 
00829 }
00830 
00831 
00832 /*
00833  * This function copy delta, or weight, or biases, or label into neurons clabels
00834  * and into the graphicp parameter vector (debug: this second feature has to be reimplemented)
00835  */
00836 void
00837 NetworkDialog::pseudo_activate_net(int /*dmode*/)
00838 
00839 {
00840     int i;
00841     int t;
00842     int b;
00843     float delta;
00844     float gain;
00845     float bias;
00846     float **gp;
00847 //     int dlabel=0;
00848     int ddelta=0;
00849     int dweight=0; 
00850     int dbias=0;
00851     int dgain=0;
00852     float *p;
00853 
00854     switch(pseudomode)
00855      {
00856        case 0:
00857 //          dlabel = 1;
00858          break;
00859        case 1:
00860          ddelta = 1;
00861          break;
00862        case 2:
00863          dweight = 1;
00864          break;
00865        case 3:
00866          dbias = 1;
00867          break;
00868        case 4:
00869          dgain = 1;
00870          break;
00871      }
00872 
00873      p = freep;
00874      gp = enet->selectedp;
00875      enet->nselected = 0;
00876 
00877      for(i=0;i < enet->nneurons;i++)
00878       strcpy(neuroncl[i],enet->neuronl[i]); 
00879 
00880      for(i=0;i < enet->nneurons;i++)
00881       updated[i] = 0;
00882 
00883      // gain
00884      for(i=0;i < enet->nneurons;i++)
00885      {
00886        if (enet->neurongain[i] == 1)
00887        {
00888          if (dgain > 0 && (cneuronn != 1 || cneuron[0] == i))
00889           {
00890            gain = (fabs((double) *p) / enet->wrange) * enet->grange;
00891            sprintf(neuroncl[i],"%.1f",gain);
00892            *gp = p;
00893            gp++;
00894            enet->nselected++;
00895           }
00896           p++;
00897        }
00898      }
00899 
00900      // biases
00901      for(i=0;i < enet->nneurons;i++)
00902      {
00903        if (enet->neuronbias[i] == 1)
00904        {
00905          if (dbias > 0 && (cneuronn != 1 || cneuron[0] == i))
00906           {
00907             bias = (fabs((double) *p) / enet->wrange) * enet->brange;
00908             sprintf(neuroncl[i],"%.1f",bias);
00909            *gp = p;
00910            gp++;
00911            enet->nselected++;
00912           }
00913           p++;
00914        }
00915      }
00916 
00917      // blocks
00918      for (b=0; b < enet->net_nblocks; b++)
00919      {      
00920        // connection block
00921        if (enet->net_block[b][0] == 0)
00922        {
00923          for(t=enet->net_block[b][1]; t < enet->net_block[b][1] + enet->net_block[b][2];t++)
00924           for(i=enet->net_block[b][3]; i < enet->net_block[b][3] + enet->net_block[b][4];i++)
00925           {
00926            // extract the weights
00927            if (dweight == 1 && ((cneuronn == 1 && cneuron[0] == t) || (cneuronn == 2 && cneuron[0] == t && cneuron[1] == i))) 
00928              {
00929               sprintf(neuroncl[i],"%.1f",*p);
00930               *gp = p;
00931               gp++;
00932               enet->nselected++;
00933              }
00934             p++;
00935           }
00936        } 
00937        // update block
00938        if (enet->net_block[b][0] == 1)
00939        {
00940          for(t=enet->net_block[b][1]; t < (enet->net_block[b][1] + enet->net_block[b][2]); t++)
00941           {
00942           updated[t] +=1;
00943           if (enet->neurontype[t] != 1)
00944            {
00945             ;
00946            }
00947            else
00948            {
00949             delta = (float) (fabs((double) *p) / enet->wrange);
00950             if (ddelta > 0 && (cneuronn != 1 || cneuron[0] == t))
00951              {
00952               sprintf(neuroncl[t],"%.1f",delta);
00953               *gp = p;
00954               gp++;
00955               enet->nselected++;
00956              }
00957             p++;
00958            }
00959           }
00960        }
00961      }
00962 
00963    
00964 }
00965 
00966 /*
00967  * Mixer for lesioned or freezed neurons
00968  */
00969 void NetworkDialog::openMixer()
00970 {
00971 
00972     mixerDialog=new MixerDialog(this->enet);
00973     rendNetwork->update();
00974 
00975 }
00976 
00977 
00978 
00979 // -----------------------------------------------------
00980 // Widget RendNetwork
00981 // -----------------------------------------------------
00982 
00983 RendNetwork::RendNetwork( NetworkDialog* networkDialog, QWidget *parent)
00984     : QWidget(parent)
00985 {
00986     shape = Polygon;
00987     antialiased = false;
00988     pixmap.load(":/evorobot/qt-logo.png");
00989 
00990     setBackgroundRole(QPalette::Base);
00991     this->networkDialog = networkDialog;
00992 
00993     rnmousex = 20000;
00994     rnmousey = 30000;
00995 }
00996 
00997 QSize RendNetwork::minimumSizeHint() const
00998 {
00999     return QSize(250, 250);
01000 }
01001 
01002 QSize RendNetwork::sizeHint() const
01003 {
01004    return QSize(550, 500);
01005 }
01006 
01007 void RendNetwork::setShape(Shape shape)
01008 {
01009     this->shape = shape;
01010     update();
01011 }
01012 
01013 void RendNetwork::setPen(const QPen &pen)
01014 {
01015     this->pen = pen;
01016     update();
01017 }
01018 
01019 
01020 
01021 void RendNetwork::setBrush(const QBrush &brush)
01022 {
01023     this->brush = brush;
01024     update();
01025 }
01026 
01027 void RendNetwork::setAntialiased(bool antialiased)
01028 {
01029     this->antialiased = antialiased;
01030     update();
01031 }
01032 
01033 void RendNetwork::setTransformed(bool transformed)
01034 {
01035     this->transformed = transformed;
01036     update();
01037 }
01038 
01039 
01040 void RendNetwork::paintEvent(QPaintEvent *)
01041 {
01042  
01043 
01044    int    i;
01045    int    t,b;
01046    int    sx,sy,dx,dy;
01047    char   message[64];
01048    float  *p;
01049    int     cr,cb,cg;
01050    int     wid = 1;
01051    float   w;
01052    QPainter painter(this);
01053 
01054    QRect labelxy(0,0,30,20);          // neuron labels 
01055    QPoint pxy;
01056    painter.setPen(pen);
01057    QPen pen(Qt::black, 1);                 // black solid line, 1 pixels wide
01058    painter.setPen(pen);
01059 
01060    // draw neural architecture
01061    if (networkDialog->enet->drawnxmax > 0 && networkDialog->enet->drawnymax > 0)
01062     {
01063      networkDialog->cscaley = height() / (float) networkDialog->enet->drawnymax;
01064      networkDialog->cscalex = width() / (float) networkDialog->enet->drawnxmax;
01065      painter.scale(networkDialog->cscalex, networkDialog->cscaley);
01066     }
01067     else
01068     {
01069      painter.scale(1.0,1.0);
01070     }
01071     painter.setPen(Qt::gray);
01072     p  = networkDialog->enet->freep;
01073     for(i=0;i < networkDialog->enet->nneurons;i++)
01074      {
01075       if (networkDialog->enet->neurongain[i] == 1)
01076        p++;
01077      }
01078     for(i=0;i < networkDialog->enet->nneurons;i++)
01079      {
01080       if (networkDialog->enet->neuronbias[i] == 1)
01081        {
01082         networkDialog->biases[i] = *p;
01083         p++;
01084        }
01085      }
01086     for (i=0; i < networkDialog->enet->net_nblocks; i++)
01087     {
01088       if (networkDialog->enet->net_block[i][0] == 0)
01089         for (t=networkDialog->enet->net_block[i][1]; t < (networkDialog->enet->net_block[i][1] + networkDialog->enet->net_block[i][2]); t++)
01090           for (b=networkDialog->enet->net_block[i][3]; b < (networkDialog->enet->net_block[i][3] + networkDialog->enet->net_block[i][4]); b++)
01091            {
01092              if (networkDialog->cneuronn == 2 && networkDialog->cneuron[0] == t && networkDialog->cneuron[1] == b)
01093                wid = 2;
01094               else
01095                wid = 1;
01096              w = *p;
01097              if (w > networkDialog->enet->wrange)
01098                w = networkDialog->enet->wrange;
01099              if (w < (0.0 - networkDialog->enet->wrange))
01100                w = 0.0 - networkDialog->enet->wrange;
01101              cr = cg = cb = 255;
01102              if (w > 0)
01103               {
01104                cg -= ((w / networkDialog->enet->wrange) * 255);
01105                cb -= ((w / networkDialog->enet->wrange) * 255);
01106               } 
01107              else
01108               {
01109                cg += ((w / networkDialog->enet->wrange) * 255);
01110                cr += ((w / networkDialog->enet->wrange) * 255);
01111               } 
01112  
01113             painter.setPen(QPen(QColor(cr,cg,cb,255), wid, Qt::SolidLine));
01114             p++;
01115             if (abs(networkDialog->enet->neuronxy[b][1] - networkDialog->enet->neuronxy[t][1]) > 20) 
01116               painter.drawLine((float) networkDialog->enet->neuronxy[t][0], (float) networkDialog->enet->neuronxy[t][1], (float) networkDialog->enet->neuronxy[b][0], (float) networkDialog->enet->neuronxy[b][1]);
01117              else
01118              {
01119               dx = abs(networkDialog->enet->neuronxy[t][0] - networkDialog->enet->neuronxy[b][0]);
01120               dy = abs(networkDialog->enet->neuronxy[t][1] - networkDialog->enet->neuronxy[b][1]);
01121               if (networkDialog->enet->neuronxy[t][0] < networkDialog->enet->neuronxy[b][0])
01122                 sx = networkDialog->enet->neuronxy[t][0];
01123                else
01124                 sx = networkDialog->enet->neuronxy[b][0];
01125               if (networkDialog->enet->neuronxy[t][1] < networkDialog->enet->neuronxy[b][1])
01126                 sy = networkDialog->enet->neuronxy[t][1];
01127                else
01128                 sy = networkDialog->enet->neuronxy[b][1];
01129               painter.drawArc((float) sx,(float) (sy-20),(float) dx, (float) (dy+40), 0 * 16, 180 * 16); 
01130              }
01131           }
01132       if (networkDialog->enet->net_block[i][0] == 1)
01133        {
01134          for(t=networkDialog->enet->net_block[i][1]; t < (networkDialog->enet->net_block[i][1] + networkDialog->enet->net_block[i][2]); t++)
01135            if (networkDialog->enet->neurontype[t] == 1)
01136              p++;
01137        }
01138     }
01139     for (i=0; i < networkDialog->enet->nneurons; i++)
01140      {
01141       if (networkDialog->enet->neuronbias[i] == 1)
01142       {
01143        wid = 2;
01144        w = networkDialog->biases[i];
01145        if (w > networkDialog->enet->wrange)
01146          w = networkDialog->enet->wrange;
01147        if (w < (0.0 - networkDialog->enet->wrange))
01148          w = 0.0 - networkDialog->enet->wrange;
01149        cr = cg = cb = 255;
01150        if (w > 0)
01151          {
01152            cg -= ((w / networkDialog->enet->wrange) * 255);
01153            cb -= ((w / networkDialog->enet->wrange) * 255);
01154          } 
01155          else
01156          {
01157            cg += ((w / networkDialog->enet->wrange) * 255);
01158            cr += ((w / networkDialog->enet->wrange) * 255);
01159          } 
01160        painter.setPen(QPen(QColor(cr,cg,cb,255), wid, Qt::SolidLine));
01161        }         
01162       else
01163        {
01164         painter.setPen(Qt::black);
01165        }        
01166 
01167      if (networkDialog->enet->neurontype[i] == 0)
01168          painter.setBrush(QBrush(QColor(75, 75, 75, 255), Qt::SolidPattern));       // standard logistic in dark-gray 
01169             else
01170              if (networkDialog->enet->neurontype[i] == 1)
01171                painter.setBrush(QBrush(QColor(255, 0, 0, 255), Qt::SolidPattern));      // dynamic with timeconstant in red
01172               else
01173                if (networkDialog->enet->neurontype[i] == 2)
01174                  painter.setBrush(QBrush(QColor(0, 0, 255, 255), Qt::SolidPattern));        // binary in blue
01175                 else
01176                   painter.setBrush(QBrush(QColor(150, 150, 150, 255), Qt::SolidPattern));   // logistic 20% in light-gray
01177 
01178       painter.drawEllipse((float) (networkDialog->enet->neuronxy[i][0] - 5), (float) (networkDialog->enet->neuronxy[i][1] - 5), 10.0, 10.0);
01179 
01180       // for neurons with gain parameters we display an additional white point in the centre of the circle
01181       if (networkDialog->enet->neurongain[i] == 1)
01182         {
01183           painter.setPen(QPen(QColor(255,255,255,255), wid, Qt::SolidLine));
01184           painter.setBrush(QBrush(QColor(255, 255, 255, 255), Qt::SolidPattern));
01185           painter.drawEllipse((float) (networkDialog->enet->neuronxy[i][0] - 1), (float) (networkDialog->enet->neuronxy[i][1] - 1), 2.0, 2.0);
01186         }
01187 
01188       }
01189 
01190     painter.setPen(Qt::black);
01191     for (i=0; i < networkDialog->enet->nneurons; i++)
01192       {
01193         if (networkDialog->enet->neurondisplay[i] == 1)
01194           painter.setPen(Qt::black);
01195          else
01196           painter.setPen(Qt::red);
01197         if (i < networkDialog->ninputs)
01198           labelxy.setRect((float) (networkDialog->enet->neuronxy[i][0] - 5), (float) (networkDialog->enet->neuronxy[i][1] + 5), 30, 30);
01199          else
01200           labelxy.setRect((float) (networkDialog->enet->neuronxy[i][0] - 5), (float) (networkDialog->enet->neuronxy[i][1] - 18), 30, 30);
01201         painter.drawText(labelxy, networkDialog->neuroncl[i]);
01202 
01203         painter.setPen(Qt::darkRed);
01204         if (networkDialog->enet->neuronlesion[i]) painter.drawText(networkDialog->enet->neuronxy[i][0]-5,networkDialog->enet->neuronxy[i][1]-5,"X");//onofrio
01205       }
01206 
01207     painter.setBrush(Qt::black);
01208     if (networkDialog->cneuronn == 1)
01209        painter.drawEllipse((float) (networkDialog->enet->neuronxy[networkDialog->cneuron[0]][0] - 5), (float) (networkDialog->enet->neuronxy[networkDialog->cneuron[0]][1] - 5), 10.0, 10.0);
01210     if (networkDialog->cneuronn >= 2)
01211      {
01212      if (networkDialog->cneuron[0] <= networkDialog->cneuron[1])
01213       {
01214        for (i=networkDialog->cneuron[0]; i <= networkDialog->cneuron[1]; i++)
01215           painter.drawEllipse((float) (networkDialog->enet->neuronxy[i][0] - 5), (float) (networkDialog->enet->neuronxy[i][1] - 5), 10.0, 10.0);
01216       }
01217       else
01218       {
01219        painter.drawEllipse((float) (networkDialog->enet->neuronxy[networkDialog->cneuron[0]][0] - 5), (float) (networkDialog->enet->neuronxy[networkDialog->cneuron[0]][1] - 5), 10.0, 10.0);
01220        painter.drawEllipse((float) (networkDialog->enet->neuronxy[networkDialog->cneuron[1]][0] - 5), (float) (networkDialog->enet->neuronxy[networkDialog->cneuron[1]][1] - 5), 10.0, 10.0);
01221       }
01222      }
01223     painter.setBrush(Qt::blue);
01224     if (networkDialog->cneuronn == 3)
01225           painter.drawEllipse((float) (networkDialog->enet->neuronxy[networkDialog->cneuron[2]][0] - 5), (float) (networkDialog->enet->neuronxy[networkDialog->cneuron[2]][1] - 5), 10.0, 10.0);
01226     if (networkDialog->cneuronn == 4 && networkDialog->cneuron[2] <= networkDialog->cneuron[3])
01227       for (i=networkDialog->cneuron[2]; i <= networkDialog->cneuron[3]; i++)
01228           painter.drawEllipse((float) (networkDialog->enet->neuronxy[i][0] - 5), (float) (networkDialog->enet->neuronxy[i][1] - 5), 10.0, 10.0);
01229 
01230    // display connection and update blocks
01231    if (networkDialog->drawblocks > 0)
01232    {
01233      pxy.setY(20);
01234      pxy.setX(0);
01235      sprintf(message,"%d neurons (%d %d %d), blocks:", networkDialog->enet->nneurons, networkDialog->ninputs, networkDialog->nhiddens, networkDialog->noutputs);
01236      painter.drawText(pxy, message);
01237      painter.setPen(Qt::black);
01238      for (b=0; b < networkDialog->enet->net_nblocks; b++)
01239      {
01240        if (networkDialog->enet->net_block[b][0] == 0)
01241              sprintf(message,"c) %s-%s  %s-%s", networkDialog->enet->neuronl[networkDialog->enet->net_block[b][1]], networkDialog->enet->neuronl[networkDialog->enet->net_block[b][1]+networkDialog->enet->net_block[b][2]-1],networkDialog->enet->neuronl[networkDialog->enet->net_block[b][3]],networkDialog->enet->neuronl[networkDialog->enet->net_block[b][3]+networkDialog->enet->net_block[b][4]-1]);
01242        if (networkDialog->enet->net_block[b][0] == 1)
01243              sprintf(message,"u) %s-%s", networkDialog->enet->neuronl[networkDialog->enet->net_block[b][1]], networkDialog->enet->neuronl[networkDialog->enet->net_block[b][1]+networkDialog->enet->net_block[b][2]-1]);
01244        if (networkDialog->enet->net_block[b][0] == 2)
01245              sprintf(message,"g) %s-%s", networkDialog->enet->neuronl[networkDialog->enet->net_block[b][1]], networkDialog->enet->neuronl[networkDialog->enet->net_block[b][1]+networkDialog->enet->net_block[b][2]-1]);
01246        if (networkDialog->enet->net_block[b][0] == 3)
01247              sprintf(message,"g) %s-%s  %s", networkDialog->enet->neuronl[networkDialog->enet->net_block[b][1]], networkDialog->enet->neuronl[networkDialog->enet->net_block[b][1]+networkDialog->enet->net_block[b][2]-1],networkDialog->enet->neuronl[networkDialog->enet->net_block[b][3]]);
01248        pxy.setY(b*20+40);
01249        pxy.setX(0);
01250        painter.drawText(pxy, message);
01251      }
01252 
01253 
01254    }
01255 
01256 }
01257 
01258 
01259 /*
01260  * handle mouse buttons
01261  */
01262 void 
01263 RendNetwork::mousePressEvent(QMouseEvent *event)
01264 {
01265         
01266     int x,y,b;
01267     int i,t;
01268     int mode;
01269     double cdist, dist;
01270     
01271     x=event->x();
01272     y=event->y();
01273     b=event->button();
01274 
01275 
01276     if (b == 2)
01277     {
01278       // right button has been pressed 
01279     }
01280     else
01281     {
01282      // left button
01283      if (b == 1)
01284      {
01285       mode = 0;
01286       rnmousex = x;
01287       rnmousey = y;
01288 
01289       //   on a neuron: select the neuron (eventually as part of a block)
01290       if (mode == 0)
01291        for(i=0; i < networkDialog->enet->nneurons; i++)
01292        {
01293         if (mdist((float) x,(float) y, (float) networkDialog->enet->neuronxy[i][0] * networkDialog->cscalex, (float) networkDialog->enet->neuronxy[i][1] * networkDialog->cscaley) < 10.0)
01294         {
01295           if (networkDialog->cneuronn < 4)
01296           {
01297            networkDialog->cneuron[networkDialog->cneuronn] = i;
01298            networkDialog->cneuronn++;
01299           }
01300           else
01301           {
01302            networkDialog->cneuronn = 0;
01303           }
01304           mode = 2;
01305         }
01306        }
01307       //   on a connection: select the receiving and sending neuron 
01308       if (mode == 0) 
01309        {
01310        dist = 999.99;
01311        for (i=0; i < networkDialog->enet->net_nblocks; i++)
01312         {
01313          if (networkDialog->enet->net_block[i][0] == 0)
01314            for (t=networkDialog->enet->net_block[i][1]; t < (networkDialog->enet->net_block[i][1] + networkDialog->enet->net_block[i][2]); t++)
01315             for (b=networkDialog->enet->net_block[i][3]; b < (networkDialog->enet->net_block[i][3] + networkDialog->enet->net_block[i][4]); b++)
01316              {
01317               cdist = segmentdist((float) x, (float) y, (float) networkDialog->enet->neuronxy[t][0] * networkDialog->cscalex, (float) networkDialog->enet->neuronxy[t][1] * networkDialog->cscaley, (float) networkDialog->enet->neuronxy[b][0] * networkDialog->cscalex, (float) networkDialog->enet->neuronxy[b][1] * networkDialog->cscaley);
01318               {
01319                if (cdist < 1 && cdist < dist)
01320                 {
01321                  dist = cdist;
01322                  networkDialog->cneuron[0] = t;
01323                  networkDialog->cneuron[1] = b;
01324                  networkDialog->cneuronn = 2;
01325                  mode = 1;
01326                 }
01327               }
01328              }
01329          }
01330         }
01331       // otherwise remove selected neurons 
01332       // and reset the display modality to label
01333       if (mode == 0)
01334         {
01335          networkDialog->cneuronn = 0;
01336          networkDialog->pseudomode = 0; 
01337          networkDialog->pseudo_activate_net(0);
01338         }
01339       update();
01340      }
01341    }
01342 
01343 
01344 }
01345 
01346 
01347 /*
01348  * handle mouse move events
01349  */
01350 void 
01351 RendNetwork::mouseMoveEvent(QMouseEvent *event)
01352 {
01353 
01354     int x,y;
01355     int i;
01356     int mode;
01357     QPoint xy;
01358     int   cn;
01359 
01360 
01361     x=event->x();
01362     y=event->y();
01363 
01364     mode = 0;
01365 
01366     // move current neuron
01367     networkDialog->cneuronn = 0;
01368     if (mode == 0)
01369       {
01370        for(i=0, cn=-1; i < networkDialog->enet->nneurons; i++)
01371          if (mdist((float) rnmousex,(float) rnmousey, (float) networkDialog->enet->neuronxy[i][0] * networkDialog->cscalex, (float) networkDialog->enet->neuronxy[i][1] * networkDialog->cscaley) < 10.0)
01372            cn = i;
01373        if (cn >= 0)
01374           {
01375             networkDialog->enet->neuronxy[cn][0] = (float) x / networkDialog->cscalex;
01376             networkDialog->enet->neuronxy[cn][1] = (float) y / networkDialog->cscaley;
01377             update();
01378             rnmousex = x;
01379             rnmousey = y;
01380             mode = 1;
01381             //sprintf(sbuffer,"neuron #%d moved to %d %d", cn, enet->neuronxy[cn][0], enet->neuronxy[cn][1]);
01382             //display_stat_message(sbuffer);
01383           }
01384       }
01385 
01386 }
01387 
01388 
01389 /*
01390  * handle mouse release events by constraints movements to the grid (if any)
01391  */
01392 void 
01393 RendNetwork::mouseReleaseEvent(QMouseEvent *event)
01394 {
01395 
01396     int i;
01397     int mode;
01398     QPoint xy;
01399     float *o = NULL;
01400     float oldp1,oldp2;
01401     int   cn;
01402 
01403 
01404     if (networkDialog->grid > 0)
01405     {
01406 
01407     rnmousex=event->x();
01408     rnmousey=event->y();
01409 
01410     mode = 0;
01411 
01412     // move current neuron    
01413     if (mode == 0)
01414      for(i=0, cn=-1; i < networkDialog->enet->nneurons; i++)
01415        if (mdist((float) rnmousex,(float) rnmousey, networkDialog->enet->neuronxy[i][0], networkDialog->enet->neuronxy[i][1]) < 10.0)
01416          cn = i;
01417      if (cn >= 0)
01418        {
01419         oldp1 = networkDialog->enet->neuronxy[cn][0];
01420         oldp2 = networkDialog->enet->neuronxy[cn][1];
01421         networkDialog->enet->neuronxy[cn][0] = (float) (((int) networkDialog->enet->neuronxy[cn][0]) / networkDialog->grid * networkDialog->grid);
01422         networkDialog->enet->neuronxy[cn][1] = (float) (((int) networkDialog->enet->neuronxy[cn][1]) / networkDialog->grid * networkDialog->grid);
01423         if ((oldp1 - networkDialog->enet->neuronxy[cn][0]) > (networkDialog->grid / 2))
01424           networkDialog->enet->neuronxy[cn][0] += networkDialog->grid;
01425         if ((oldp2 - networkDialog->enet->neuronxy[cn][1]) > (networkDialog->grid / 2))
01426           networkDialog->enet->neuronxy[cn][1] += networkDialog->grid;
01427         update();
01428         //sprintf(sbuffer,"neuron #%d released to %d %d", cn, enet->neuronxy[cn][0], enet->neuronxy[cn][1]);
01429         //display_stat_message(sbuffer);
01430         mode = 1;
01431        }
01432 
01433     if (mode == 3)
01434         {
01435         oldp1 = *o;
01436         oldp2 = *(o + 1);
01437         *o = (float) (((int) *o) / networkDialog->grid * networkDialog->grid);
01438         *(o + 1) = (float) (((int) *(o + 1)) / networkDialog->grid * networkDialog->grid);
01439         if ((oldp1 - *o) > (networkDialog->grid / 2))
01440           *o += networkDialog->grid;
01441         if ((oldp2 - *(o + 1)) > (networkDialog->grid / 2))
01442           *(o + 1) += networkDialog->grid;
01443         //sprintf(sbuffer,"object %s #%d released to %.1f %.1f", nobject, idobject, *o, *(o + 1));
01444         //display_stat_message(sbuffer);
01445         update();
01446         }
01447 
01448     }
01449 
01450 
01451 }
01452 
01453 /*
01454  * handle mouse buttons
01455  */
01456 void 
01457 RendNetwork::mouseDoubleClickEvent(QMouseEvent* /*event*/)
01458 {
01459     
01460 }
01461 
01462 
01463 
01464 double
01465 RendNetwork::mdist(float x, float y, float x1, float y1)
01466 
01467 {
01468    double qdist;
01469 
01470    qdist = ((x-x1)*(x-x1)) + ((y-y1)*(y-y1));
01471    return(sqrt(qdist));
01472 }
01473 
01474 /*
01475 * estimate the distance between a point (p) and a segment (a-b) 
01476 * by computing dist(p,a) + dist(p,b) - dist(a,b)
01477 * if one of the two distances are greater than the segment
01478 * assume that the point is too far or is outside the segment
01479 */
01480 double
01481 RendNetwork::segmentdist(float px,float py,float ax,float ay,float bx,float by) 
01482 {
01483   double dab,dpa,dpb; 
01484 
01485   dab = sqrt(((ax-bx)*(ax-bx)) + ((ay-by)*(ay-by)));
01486   dpa = sqrt(((px-ax)*(px-ax)) + ((py-ay)*(py-ay)));
01487   dpb = sqrt(((px-bx)*(px-bx)) + ((py-by)*(py-by)));
01488 
01489   if (dpa < dab && dpb < dab)
01490     return((dpa+dpb)-dab);
01491   else
01492     return(99999.999);
01493 }
01494 
01495 /* EvoSlider */
01496 EvoSlider::EvoSlider(double *ref, double rangemin , double rangemax, QWidget * /*parent*/)
01497 {
01498 vref=ref;
01499 setRange((int)(rangemin*100),(int)(rangemax*100));
01500 setOrientation(Qt::Vertical);
01501 connect(this,SIGNAL(valueChanged(int)),this, SLOT(updateValue(int)));
01502 }
01503 
01504 void EvoSlider::updateValue(int ival)
01505 {
01506     *vref=(double)ival/100.0;
01507 }
01508 
01509 /* Mixer */
01510 MixerDialog::MixerDialog(Evonet *enet)
01511 {
01512     evonet=enet;
01513     trialRef=0.0;
01514     //now check ho lesion we have
01515     for(int i=0;i<enet->getNoNeurons();i++)
01516         if(enet->neuronlesion[i])
01517         {
01518             Logger::info(QString("Neuron no.%1 is lesioned\n").arg(i));
01519         }
01520         setUpMixer();
01521     setWindowTitle("Mixer for lesioned or freezed neurons");
01522     //setGeometry(50,50,400,400);
01523     //setVisible(true);
01524     
01525 }
01526 
01527 void MixerDialog::setUpMixer()
01528 {
01529     //QHBoxLayout *layout= new QHBoxLayout;
01530     QGridLayout *layout=new QGridLayout();  
01531     for(int i=0;i<evonet->getNoNeurons();i++)
01532         if(evonet->neuronlesion[i])
01533         {
01534             layout->addWidget(new QLabel(evonet->neuronl[i]),0,i);
01535             layout->addWidget(new EvoSlider(&evonet->neuronlesionVal[i],evonet->neuronrange[i][0],evonet->neuronrange[i][1]),1,i);
01536         }
01537     setLayout(layout);
01538     setVisible(true);
01539 
01540 }
01541 
01542 } //end namespace farsa
01543 
01544 // All the suff below is to restore the warning state on Windows
01545 #if defined(_MSC_VER)
01546     #pragma warning(pop)
01547 #endif