REMOVED: the DrawModel function from classifierInterface (they all do exactly the...
[mldemos:baraks-mldemos.git] / MLDemos / mlsaving.cpp
1 /*********************************************************************
2 MLDemos: A User-Friendly visualization toolkit for machine learning
3 Copyright (C) 2010  Basilio Noris
4 Contact: mldemos@b4silio.com
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free
18 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *********************************************************************/
20 #include "mldemos.h"
21 #include <QDebug>
22 #include <fstream>
23 #include <QPixmap>
24 #include <QBitmap>
25 #include <QSettings>
26 #include <QFileDialog>
27 #include <QTextStream>
28 #include "classifier.h"
29 #include "regressor.h"
30 #include <fstream>
31
32 using namespace std;
33
34 void MLDemos::SaveLayoutOptions()
35 {
36     QCoreApplication::setOrganizationDomain("b4silio");
37     QCoreApplication::setOrganizationName("b4silio");
38     QCoreApplication::setApplicationName("MLDemos");
39
40     QSettings settings;
41     settings.beginGroup("Gui");
42     settings.setValue("geometry", saveGeometry());
43     settings.setValue("windowState", saveState());
44     settings.setValue("algoGeometry", algorithmWidget->saveGeometry());
45     settings.setValue("drawGeometry", drawToolbarWidget->saveGeometry());
46     settings.setValue("displayGeometry", displayDialog->saveGeometry());
47     settings.setValue("statsGeometry", statsDialog->saveGeometry());
48     settings.setValue("compareGeometry", compareWidget->saveGeometry());
49     settings.setValue("generatorGeometry", generator->saveGeometry());
50
51     settings.setValue("algoTab", algorithmOptions->tabWidget->currentIndex());
52     settings.setValue("ShowAlgoOptions", algorithmWidget->isVisible());
53     settings.setValue("ShowCompare", compareWidget->isVisible());
54     settings.setValue("ShowDrawOptions", drawToolbarWidget->isVisible());
55     settings.setValue("ShowDisplayOptions", displayDialog->isVisible());
56     settings.setValue("ShowStatsOptions", statsDialog->isVisible());
57     settings.setValue("ShowToolbar", ui.actionShow_Toolbar->isChecked());
58     settings.setValue("SmallIcons", ui.actionSmall_Icons->isChecked());
59     settings.setValue("ShowGenerator", generator->isVisible());
60     //    settings.setValue("canvasType", ui.canvasTypeCombo->currentIndex());
61     settings.endGroup();
62
63     settings.beginGroup("displayOptions");
64     settings.setValue("infoCheck", displayOptions->infoCheck->isChecked());
65     settings.setValue("mapCheck", displayOptions->mapCheck->isChecked());
66     settings.setValue("modelCheck", displayOptions->modelCheck->isChecked());
67     settings.setValue("samplesCheck", displayOptions->samplesCheck->isChecked());
68     settings.setValue("gridCheck", displayOptions->gridCheck->isChecked());
69     settings.setValue("spinZoom", displayOptions->spinZoom->value());
70     settings.setValue("legendCheck", displayOptions->legendCheck->isChecked());
71     settings.setValue("check3DSamples", displayOptions->check3DSamples->isChecked());
72     settings.setValue("check3DWireframe", displayOptions->check3DWireframe->isChecked());
73     settings.setValue("check3DSurfaces", displayOptions->check3DSurfaces->isChecked());
74     settings.setValue("check3DTransparency", displayOptions->check3DTransparency->isChecked());
75     settings.setValue("check3DBlurry", displayOptions->check3DBlurry->isChecked());
76     settings.setValue("check3DRotate", displayOptions->check3DRotate->isChecked());
77     settings.endGroup();
78
79     settings.beginGroup("drawingOptions");
80     settings.setValue("infoCheck", drawToolbarContext1->randCombo->currentIndex());
81     settings.setValue("spinCount", drawToolbarContext1->spinCount->value());
82     settings.setValue("spinSize", drawToolbar->radiusSpin->value());
83     settings.setValue("spinAngle", drawToolbarContext2->spinAngle->value());
84     settings.setValue("spinSigmaX", drawToolbarContext2->spinSigmaX->value());
85     settings.setValue("spinSigmaY", drawToolbarContext2->spinSigmaY->value());
86     settings.setValue("spinObsAngle", drawToolbarContext3->spinAngle->value());
87     settings.setValue("spinObsSigmaX", drawToolbarContext3->spinSigmaX->value());
88     settings.setValue("spinObsSigmaY", drawToolbarContext3->spinSigmaY->value());
89     settings.setValue("spinObsPowerX", drawToolbarContext3->spinPowerX->value());
90     settings.setValue("spinObsPowerY", drawToolbarContext3->spinPowerY->value());
91     settings.setValue("spinObsRepulsionX", drawToolbarContext3->spinRepulsionX->value());
92     settings.setValue("spinObsRepulsionY", drawToolbarContext3->spinRepulsionY->value());
93     settings.setValue("spinRadius", drawToolbarContext4->spinRadius->value());
94     settings.setValue("spinAlpha", drawToolbarContext4->spinAlpha->value());
95     settings.setValue("eraseCheck", drawToolbar->eraseButton->isChecked());
96     settings.setValue("sprayCheck", drawToolbar->sprayButton->isChecked());
97     settings.setValue("spray3DCheck", drawToolbar->spray3DButton->isChecked());
98     settings.setValue("singleCheck", drawToolbar->singleButton->isChecked());
99     settings.setValue("ellipseCheck", drawToolbar->ellipseButton->isChecked());
100     settings.setValue("lineCheck", drawToolbar->lineButton->isChecked());
101     settings.setValue("trajectoryCheck", drawToolbar->trajectoryButton->isChecked());
102     settings.setValue("obstacleCheck", drawToolbar->obstacleButton->isChecked());
103     settings.setValue("paintCheck", drawToolbar->paintButton->isChecked());
104     settings.setValue("infoCheck", drawToolbarContext1->randCombo->currentIndex());
105     settings.endGroup();
106
107     settings.beginGroup("classificationOptions");
108     settings.setValue("positiveClass", optionsClassify->positiveSpin->value());
109     settings.setValue("trainRatio", optionsClassify->traintestRatioCombo->currentIndex());
110     settings.setValue("tab", optionsClassify->algoList->currentIndex());
111     settings.endGroup();
112
113     settings.beginGroup("regressionOptions");
114     settings.setValue("trainRatio", optionsRegress->traintestRatioCombo->currentIndex());
115     settings.setValue("tab", optionsRegress->algoList->currentIndex());
116     settings.endGroup();
117
118     settings.beginGroup("dynamicalOptions");
119     settings.setValue("centerType", optionsDynamic->centerCombo->currentIndex());
120     settings.setValue("zeroCheck", optionsDynamic->zeroCheck->isChecked());
121     settings.setValue("resampleType", optionsDynamic->resampleCombo->currentIndex());
122     settings.setValue("resampleCount", optionsDynamic->resampleSpin->value());
123     settings.setValue("obstacleType", optionsDynamic->obstacleCombo->currentIndex());
124     settings.setValue("dT", optionsDynamic->dtSpin->value());
125     settings.setValue("tab", optionsDynamic->algoList->currentIndex());
126     settings.setValue("colorCheck", optionsDynamic->colorCheck->isChecked());
127     settings.endGroup();
128
129     settings.beginGroup("compareOptions");
130     settings.setValue("foldCount", optionsCompare->foldCountSpin->value());
131     settings.setValue("trainRatio", optionsCompare->traintestRatioCombo->currentIndex());
132     settings.endGroup();
133
134     settings.beginGroup("clusterOptions");
135     settings.setValue("tab", optionsCluster->algoList->currentIndex());
136     settings.setValue("trainRatio", optionsCluster->trainRatioCombo->currentIndex());
137     settings.setValue("trainTestCombo", optionsCluster->trainTestCombo->currentIndex());
138     settings.setValue("optimizeCombo", optionsCluster->optimizeCombo->currentIndex());
139     settings.setValue("rangeStart", optionsCluster->rangeStartSpin->value());
140     settings.setValue("rangeStop", optionsCluster->rangeStopSpin->value());
141     settings.endGroup();
142
143     settings.beginGroup("maximizeOptions");
144     settings.setValue("tab", optionsMaximize->algoList->currentIndex());
145     settings.setValue("varianceSpin", optionsMaximize->varianceSpin->value());
146     settings.setValue("iterationsSpin", optionsMaximize->iterationsSpin->value());
147     settings.setValue("stoppingSpin", optionsMaximize->stoppingSpin->value());
148     settings.setValue("benchmarkCombo", optionsMaximize->benchmarkCombo->currentIndex());
149     settings.endGroup();
150
151     settings.beginGroup("reinforceOptions");
152     settings.setValue("tab", optionsReinforcement->algoList->currentIndex());
153     settings.setValue("varianceSpin", optionsReinforcement->varianceSpin->value());
154     settings.setValue("iterationsSpin", optionsReinforcement->iterationsSpin->value());
155     settings.setValue("displayIterationSpin", optionsReinforcement->displayIterationSpin->value());
156     settings.setValue("problemCombo", optionsReinforcement->problemCombo->currentIndex());
157     settings.setValue("rewardCombo", optionsReinforcement->rewardCombo->currentIndex());
158     settings.setValue("policyCombo", optionsReinforcement->policyCombo->currentIndex());
159     settings.setValue("quantizeCombo", optionsReinforcement->quantizeCombo->currentIndex());
160     settings.setValue("resolutionSpin", optionsReinforcement->resolutionSpin->value());
161     settings.setValue("benchmarkCombo", optionsReinforcement->benchmarkCombo->currentIndex());
162     settings.endGroup();
163
164     settings.beginGroup("projectOptions");
165     settings.setValue("tab", optionsProject->algoList->currentIndex());
166     settings.setValue("fitCheck", optionsProject->fitCheck->isChecked());
167     settings.endGroup();
168
169     settings.beginGroup("statsOptions");
170     settings.setValue("tab", showStats->tabWidget->currentIndex());
171     settings.endGroup();
172
173     settings.beginGroup("generatorOptions");
174     settings.setValue("generatorCombo", generator->ui->generatorCombo->currentIndex());
175     settings.setValue("countSpin", generator->ui->countSpin->value());
176     settings.setValue("dimSpin", generator->ui->dimSpin->value());
177     settings.setValue("gridCountSpin", generator->ui->gridCountSpin->value());
178     settings.setValue("classesCount", generator->ui->classesCount->value());
179     settings.setValue("radiusSpin", generator->ui->radiusSpin->value());
180     settings.endGroup();
181
182     FOR(i,classifiers.size())
183     {
184         if(!classifiers[i]) continue;
185         settings.beginGroup(QString("plugins::classifiers::") + classifiers[i]->GetName());
186         classifiers[i]->SaveOptions(settings);
187         settings.endGroup();
188     }
189     FOR(i,clusterers.size())
190     {
191         if(!clusterers[i]) continue;
192         settings.beginGroup(QString("plugins::clusterers::") + clusterers[i]->GetName());
193         clusterers[i]->SaveOptions(settings);
194         settings.endGroup();
195     }
196     FOR(i,regressors.size())
197     {
198         if(!regressors[i]) continue;
199         settings.beginGroup(QString("plugins::regressors::") + regressors[i]->GetName());
200         regressors[i]->SaveOptions(settings);
201         settings.endGroup();
202     }
203     FOR(i,dynamicals.size())
204     {
205         if(!dynamicals[i]) continue;
206         settings.beginGroup(QString("plugins::dynamicals::") + dynamicals[i]->GetName());
207         dynamicals[i]->SaveOptions(settings);
208         settings.endGroup();
209     }
210     FOR(i,maximizers.size())
211     {
212         if(!maximizers[i]) continue;
213         settings.beginGroup(QString("plugins::maximizers::") + maximizers[i]->GetName());
214         maximizers[i]->SaveOptions(settings);
215         settings.endGroup();
216     }
217     FOR(i,reinforcements.size())
218     {
219         if(!reinforcements[i]) continue;
220         settings.beginGroup(QString("plugins::reinforcements::") + reinforcements[i]->GetName());
221         reinforcements[i]->SaveOptions(settings);
222         settings.endGroup();
223     }
224     FOR(i,projectors.size())
225     {
226         if(!projectors[i]) continue;
227         settings.beginGroup(QString("plugins::projectors::") + projectors[i]->GetName());
228         projectors[i]->SaveOptions(settings);
229         settings.endGroup();
230     }
231 }
232
233 void MLDemos::LoadLayoutOptions()
234 {
235     QCoreApplication::setOrganizationDomain("b4silio");
236     QCoreApplication::setOrganizationName("b4silio");
237     QCoreApplication::setApplicationName("MLDemos");
238
239     QSettings settings;
240     settings.beginGroup("Gui");
241     if(settings.contains("geometry")) restoreGeometry(settings.value("geometry").toByteArray());
242     if(settings.contains("windowState")) restoreState(settings.value("windowState").toByteArray());
243     if(settings.contains("algoGeometry")) algorithmWidget->restoreGeometry(settings.value("algoGeometry").toByteArray());
244     if(settings.contains("drawGeometry")) drawToolbarWidget->restoreGeometry(settings.value("drawGeometry").toByteArray());
245     if(settings.contains("displayGeometry")) displayDialog->restoreGeometry(settings.value("displayGeometry").toByteArray());
246     if(settings.contains("statsGeometry")) statsDialog->restoreGeometry(settings.value("statsGeometry").toByteArray());
247     if(settings.contains("compareGeometry")) compareWidget->restoreGeometry(settings.value("compareGeometry").toByteArray());
248     if(settings.contains("generatorGeometry")) generator->restoreGeometry(settings.value("generatorGeometry").toByteArray());
249 #ifdef MACX // ugly hack to avoid resizing problems on the mac
250     if(height() < 400) resize(width(),400);
251     if(algorithmWidget->height() < 220) algorithmWidget->resize(636,220);
252 #endif // MACX
253
254     if(settings.contains("algoTab")) algorithmOptions->tabWidget->setCurrentIndex(settings.value("algoTab").toInt());
255     if(settings.contains("ShowAlgoOptions")) algorithmWidget->setVisible(settings.value("ShowAlgoOptions").toBool());
256     if(settings.contains("ShowCompare")) compareWidget->setVisible(settings.value("ShowCompare").toBool());
257     if(settings.contains("ShowDrawOptions")) drawToolbarWidget->setVisible(settings.value("ShowDrawOptions").toBool());
258     if(settings.contains("ShowDisplayOptions")) displayDialog->setVisible(settings.value("ShowDisplayOptions").toBool());
259     if(settings.contains("ShowStatsOptions")) statsDialog->setVisible(settings.value("ShowStatsOptions").toBool());
260     if(settings.contains("ShowToolbar")) ui.actionShow_Toolbar->setChecked(settings.value("ShowToolbar").toBool());
261     if(settings.contains("SmallIcons")) ui.actionSmall_Icons->setChecked(settings.value("SmallIcons").toBool());
262     if(settings.contains("ShowGenerator")) generator->setVisible(settings.value("ShowGenerator").toBool());
263     //    if(settings.contains("canvasType")) ui.canvasTypeCombo->setCurrentIndex(settings.value("canvasType").toInt());
264     settings.endGroup();
265
266     actionAlgorithms->setChecked(algorithmWidget->isVisible());
267     actionCompare->setChecked(compareWidget->isVisible());
268     actionDrawSamples->setChecked(drawToolbarWidget->isVisible());
269     actionDisplayOptions->setChecked(displayDialog->isVisible());
270     actionShowStats->setChecked(statsDialog->isVisible());
271     actionAddData->setChecked(generator->isVisible());
272
273     settings.beginGroup("displayOptions");
274     if(settings.contains("infoCheck")) displayOptions->infoCheck->setChecked(settings.value("infoCheck").toBool());
275     if(settings.contains("mapCheck")) displayOptions->mapCheck->setChecked(settings.value("mapCheck").toBool());
276     if(settings.contains("modelCheck")) displayOptions->modelCheck->setChecked(settings.value("modelCheck").toBool());
277     if(settings.contains("samplesCheck")) displayOptions->samplesCheck->setChecked(settings.value("samplesCheck").toBool());
278     if(settings.contains("gridCheck")) displayOptions->gridCheck->setChecked(settings.value("gridCheck").toBool());
279     if(settings.contains("spinZoom")) displayOptions->spinZoom->setValue(settings.value("spinZoom").toFloat());
280     if(settings.contains("legendCheck")) displayOptions->legendCheck->setChecked(settings.value("legendCheck").toBool());
281     if(settings.contains("check3DSamples")) displayOptions->check3DSamples->setChecked(settings.value("check3DSamples").toBool());
282     if(settings.contains("check3DWireframe")) displayOptions->check3DWireframe->setChecked(settings.value("check3DWireframe").toBool());
283     if(settings.contains("check3DSurfaces")) displayOptions->check3DSurfaces->setChecked(settings.value("check3DSurfaces").toBool());
284     if(settings.contains("check3DTransparency")) displayOptions->check3DTransparency->setChecked(settings.value("check3DTransparency").toBool());
285     if(settings.contains("check3DBlurry")) displayOptions->check3DBlurry->setChecked(settings.value("check3DBlurry").toBool());
286     if(settings.contains("check3DRotate")) displayOptions->check3DRotate->setChecked(settings.value("check3DRotate").toBool());
287
288     //if(settings.contains("xDimIndex")) displayOptions->xDimIndex->setValue(settings.value("xDimIndex").toInt());
289     //if(settings.contains("yDimIndex")) displayOptions->yDimIndex->setValue(settings.value("yDimIndex").toInt());
290     settings.endGroup();
291
292     settings.beginGroup("drawingOptions");
293     if(settings.contains("infoCheck")) drawToolbarContext1->randCombo->setCurrentIndex(settings.value("infoCheck").toInt());
294     if(settings.contains("spinAngle")) drawToolbarContext2->spinAngle->setValue(settings.value("spinAngle").toFloat());
295     if(settings.contains("spinCount")) drawToolbarContext1->spinCount->setValue(settings.value("spinCount").toFloat());
296     if(settings.contains("spinSigmaX")) drawToolbarContext2->spinSigmaX->setValue(settings.value("spinSigmaX").toFloat());
297     if(settings.contains("spinSigmaY")) drawToolbarContext2->spinSigmaY->setValue(settings.value("spinSigmaY").toFloat());
298     if(settings.contains("spinObsAngle")) drawToolbarContext3->spinAngle->setValue(settings.value("spinObsAngle").toFloat());
299     if(settings.contains("spinObsSigmaX")) drawToolbarContext3->spinSigmaX->setValue(settings.value("spinObsSigmaX").toFloat());
300     if(settings.contains("spinObsSigmaY")) drawToolbarContext3->spinSigmaY->setValue(settings.value("spinObsSigmaY").toFloat());
301     if(settings.contains("spinObsPowerX")) drawToolbarContext3->spinPowerX->setValue(settings.value("spinObsPowerX").toInt());
302     if(settings.contains("spinObsPowerY")) drawToolbarContext3->spinPowerY->setValue(settings.value("spinObsPowerY").toInt());
303     if(settings.contains("spinObsRepulsionX")) drawToolbarContext3->spinRepulsionX->setValue(settings.value("spinObsRepulsionX").toFloat());
304     if(settings.contains("spinObsRepulsionY")) drawToolbarContext3->spinRepulsionY->setValue(settings.value("spinObsRepulsionY").toFloat());
305     if(settings.contains("spinRadius")) drawToolbarContext4->spinRadius->setValue(settings.value("spinRadius").toFloat());
306     if(settings.contains("spinAlpha")) drawToolbarContext4->spinAlpha->setValue(settings.value("spinAlpha").toFloat());
307     if(settings.contains("spinSize")) drawToolbar->radiusSpin->setValue(settings.value("spinSize").toFloat());
308     if(settings.contains("eraseCheck")) drawToolbar->eraseButton->setChecked(settings.value("eraseCheck").toBool());
309     if(settings.contains("sprayCheck")) drawToolbar->sprayButton->setChecked(settings.value("sprayCheck").toBool());
310     if(settings.contains("spray3DCheck")) drawToolbar->spray3DButton->setChecked(settings.value("spray3DCheck").toBool());
311     if(settings.contains("singleCheck")) drawToolbar->singleButton->setChecked(settings.value("singleCheck").toBool());
312     if(settings.contains("ellipseCheck")) drawToolbar->ellipseButton->setChecked(settings.value("ellipseCheck").toBool());
313     if(settings.contains("lineCheck")) drawToolbar->lineButton->setChecked(settings.value("lineCheck").toBool());
314     if(settings.contains("trajectoryCheck")) drawToolbar->trajectoryButton->setChecked(settings.value("trajectoryCheck").toBool());
315     if(settings.contains("obstacleCheck")) drawToolbar->obstacleButton->setChecked(settings.value("obstacleCheck").toBool());
316     if(settings.contains("paintCheck")) drawToolbar->paintButton->setChecked(settings.value("paintCheck").toBool());
317     settings.endGroup();
318
319     settings.beginGroup("classificationOptions");
320     if(settings.contains("positiveClass")) optionsClassify->positiveSpin->setValue(settings.value("positiveClass").toFloat());
321     if(settings.contains("trainRatio")) optionsClassify->traintestRatioCombo->setCurrentIndex(settings.value("trainRatio").toInt());
322     if(settings.contains("tab")) optionsClassify->algoList->setCurrentIndex(settings.value("tab").toInt());
323     settings.endGroup();
324
325     settings.beginGroup("regressionOptions");
326     if(settings.contains("trainRatio")) optionsRegress->traintestRatioCombo->setCurrentIndex(settings.value("trainRatio").toInt());
327     if(settings.contains("tab")) optionsRegress->algoList->setCurrentIndex(settings.value("tab").toInt());
328     settings.endGroup();
329
330     settings.beginGroup("dynamicalOptions");
331     if(settings.contains("centerType")) optionsDynamic->centerCombo->setCurrentIndex(settings.value("centerType").toInt());
332     if(settings.contains("zeroCheck")) optionsDynamic->zeroCheck->setChecked(settings.value("zeroCheck").toBool());
333     if(settings.contains("resampleType")) optionsDynamic->resampleCombo->setCurrentIndex(settings.value("resampleType").toInt());
334     if(settings.contains("resampleCount")) optionsDynamic->resampleSpin->setValue(settings.value("resampleCount").toFloat());
335     if(settings.contains("obstacleType")) optionsDynamic->obstacleCombo->setCurrentIndex(settings.value("obstacleType").toInt());
336     if(settings.contains("dT")) optionsDynamic->dtSpin->setValue(settings.value("dT").toFloat());
337     if(settings.contains("tab")) optionsDynamic->algoList->setCurrentIndex(settings.value("tab").toInt());
338     if(settings.contains("colorCheck")) optionsDynamic->colorCheck->setChecked(settings.value("colorCheck").toBool());
339     settings.endGroup();
340
341     settings.beginGroup("compareOptions");
342     if(settings.contains("foldCount")) optionsCompare->foldCountSpin->setValue(settings.value("foldCount").toFloat());
343     if(settings.contains("trainRatio")) optionsCompare->traintestRatioCombo->setCurrentIndex(settings.value("trainRatio").toInt());
344     settings.endGroup();
345
346     settings.beginGroup("clusterOptions");
347     if(settings.contains("tab")) optionsCluster->algoList->setCurrentIndex(settings.value("tab").toInt());
348     if(settings.contains("trainRatio")) optionsCluster->trainRatioCombo->setCurrentIndex(settings.value("trainRatio").toInt());
349     if(settings.contains("trainTestCombo")) optionsCluster->trainTestCombo->setCurrentIndex(settings.value("trainTestCombo").toInt());
350     if(settings.contains("optimizeCombo")) optionsCluster->optimizeCombo->setCurrentIndex(settings.value("optimizeCombo").toInt());
351     if(settings.contains("rangeStart")) optionsCluster->rangeStartSpin->setValue(settings.value("rangeStart").toInt());
352     if(settings.contains("rangeStop")) optionsCluster->rangeStopSpin->setValue(settings.value("rangeStop").toInt());
353     settings.endGroup();
354
355     settings.beginGroup("maximizeOptions");
356     if(settings.contains("tab")) optionsMaximize->algoList->setCurrentIndex(settings.value("tab").toInt());
357     if(settings.contains("varianceSpin")) optionsMaximize->varianceSpin->setValue(settings.value("varianceSpin").toDouble());
358     if(settings.contains("iterationsSpin")) optionsMaximize->iterationsSpin->setValue(settings.value("iterationsSpin").toInt());
359     if(settings.contains("stoppingSpin")) optionsMaximize->stoppingSpin->setValue(settings.value("stoppingSpin").toDouble());
360     if(settings.contains("benchmarkCombo")) optionsMaximize->benchmarkCombo->setCurrentIndex(settings.value("benchmarkCombo").toInt());
361     settings.endGroup();
362
363     settings.beginGroup("reinforceOptions");
364     if(settings.contains("tab")) optionsReinforcement->algoList->setCurrentIndex(settings.value("tab").toInt());
365     if(settings.contains("varianceSpin")) optionsReinforcement->varianceSpin->setValue(settings.value("varianceSpin").toDouble());
366     if(settings.contains("iterationsSpin")) optionsReinforcement->iterationsSpin->setValue(settings.value("iterationsSpin").toInt());
367     if(settings.contains("displayIterationSpin")) optionsReinforcement->displayIterationSpin->setValue(settings.value("displayIterationSpin").toInt());
368     if(settings.contains("problemCombo")) optionsReinforcement->problemCombo->setCurrentIndex(settings.value("problemCombo").toInt());
369     if(settings.contains("rewardCombo")) optionsReinforcement->rewardCombo->setCurrentIndex(settings.value("rewardCombo").toInt());
370     if(settings.contains("policyCombo")) optionsReinforcement->policyCombo->setCurrentIndex(settings.value("policyCombo").toInt());
371     if(settings.contains("quantizeCombo")) optionsReinforcement->quantizeCombo->setCurrentIndex(settings.value("quantizeCombo").toInt());
372     if(settings.contains("resolutionSpin")) optionsReinforcement->resolutionSpin->setValue(settings.value("resolutionSpin").toInt());
373     if(settings.contains("benchmarkCombo")) optionsReinforcement->benchmarkCombo->setCurrentIndex(settings.value("benchmarkCombo").toInt());
374     settings.endGroup();
375
376     settings.beginGroup("projectOptions");
377     if(settings.contains("tab")) optionsProject->algoList->setCurrentIndex(settings.value("tab").toInt());
378     if(settings.contains("fitCheck")) optionsProject->fitCheck->setChecked(settings.value("fitCheck").toBool());
379     settings.endGroup();
380
381     settings.beginGroup("statsOptions");
382     if(settings.contains("tab")) showStats->tabWidget->setCurrentIndex(settings.value("tab").toInt());
383     settings.endGroup();
384
385     settings.beginGroup("generatorOptions");
386     if(settings.contains("generatorCombo")) generator->ui->generatorCombo->setCurrentIndex(settings.value("generatorCombo").toInt());
387     if(settings.contains("countSpin")) generator->ui->countSpin->setValue(settings.value("countSpin").toInt());
388     if(settings.contains("dimSpin")) generator->ui->dimSpin->setValue(settings.value("dimSpin").toInt());
389     if(settings.contains("gridCountSpin")) generator->ui->gridCountSpin->setValue(settings.value("gridCountSpin").toInt());
390     if(settings.contains("classesCount")) generator->ui->classesCount->setValue(settings.value("classesCount").toInt());
391     if(settings.contains("radiusSpin")) generator->ui->radiusSpin->setValue(settings.value("radiusSpin").toFloat());
392     settings.endGroup();
393
394     FOR(i,classifiers.size())
395     {
396         if(!classifiers[i]) continue;
397         settings.beginGroup(QString("plugins::classifiers::") + classifiers[i]->GetName());
398         classifiers[i]->LoadOptions(settings);
399         settings.endGroup();
400     }
401     FOR(i,clusterers.size())
402     {
403         if(!clusterers[i]) continue;
404         settings.beginGroup(QString("plugins::clusterers::") + clusterers[i]->GetName());
405         clusterers[i]->LoadOptions(settings);
406         settings.endGroup();
407     }
408     FOR(i,regressors.size())
409     {
410         if(!regressors[i]) continue;
411         settings.beginGroup(QString("plugins::regressors::") + regressors[i]->GetName());
412         regressors[i]->LoadOptions(settings);
413         settings.endGroup();
414     }
415     FOR(i,dynamicals.size())
416     {
417         if(!dynamicals[i]) continue;
418         settings.beginGroup(QString("plugins::dynamicals::") + dynamicals[i]->GetName());
419         dynamicals[i]->LoadOptions(settings);
420         settings.endGroup();
421     }
422     FOR(i,maximizers.size())
423     {
424         if(!maximizers[i]) continue;
425         settings.beginGroup(QString("plugins::maximizers::") + maximizers[i]->GetName());
426         maximizers[i]->LoadOptions(settings);
427         settings.endGroup();
428     }
429     FOR(i,reinforcements.size())
430     {
431         if(!reinforcements[i]) continue;
432         settings.beginGroup(QString("plugins::reinforcements::") + reinforcements[i]->GetName());
433         reinforcements[i]->LoadOptions(settings);
434         settings.endGroup();
435     }
436     FOR(i,projectors.size())
437     {
438         if(!projectors[i]) continue;
439         settings.beginGroup(QString("plugins::projectors::") + projectors[i]->GetName());
440         projectors[i]->LoadOptions(settings);
441         settings.endGroup();
442     }
443     canvas->repaint();
444 }
445
446
447 void MLDemos::SaveParams( QString filename )
448 {
449     if(!classifier && !regressor && !clusterer && !dynamical && !maximizer) return;
450     QFile file(filename);
451     file.open(QFile::WriteOnly | QFile::Append);
452     QTextStream out(&file);
453     if(!file.isOpen()) return;
454
455     if(!canvas->data->GetCount()) out << "0 2\n";
456     char groupName[255];
457
458     if(canvas->dimNames.size())
459     {
460         out << "headers" << " " << canvas->dimNames.size();
461         FOR(i, canvas->dimNames.size())
462         {
463             QString header = canvas->dimNames.at(i);
464             // we take out all spaces as they're really not nice for parsing the headers afterwards
465             header.replace("\n", "_");
466             header.replace(" ", "_");
467             header.replace("\t", "_");
468             out << " " << header;
469         }
470         out << "\n";
471     }
472     if(classifier)
473     {
474         int tab = optionsClassify->algoList->currentIndex();
475         sprintf(groupName,"classificationOptions");
476         out << groupName << ":" << "tab" << " " << optionsClassify->algoList->currentIndex() << "\n";
477         out << groupName << ":" << "positiveClass" << " " << optionsClassify->positiveSpin->value() << "\n";
478         if(tab < classifiers.size() && classifiers[tab])
479         {
480             classifiers[tab]->SaveParams(out);
481         }
482     }
483     if(regressor)
484     {
485         int tab = optionsRegress->algoList->currentIndex();
486         sprintf(groupName,"regressionOptions");
487         out << groupName << ":" << "tab" << " " << optionsRegress->algoList->currentIndex() << "\n";
488         out << groupName << ":" << "outputDimCombo" << " " << optionsRegress->outputDimCombo->currentIndex() << "\n";
489         if(tab < regressors.size() && regressors[tab])
490         {
491             regressors[tab]->SaveParams(out);
492         }
493     }
494     if(dynamical)
495     {
496         int tab = optionsDynamic->algoList->currentIndex();
497         sprintf(groupName,"dynamicalOptions");
498         out << groupName << ":" << "centerType" << " " << optionsDynamic->centerCombo->currentIndex() << "\n";
499         out << groupName << ":" << "zeroCheck" << " " << optionsDynamic->zeroCheck->isChecked() << "\n";
500         out << groupName << ":" << "resampleType" << " " << optionsDynamic->resampleCombo->currentIndex() << "\n";
501         out << groupName << ":" << "resampleCount" << " " << optionsDynamic->resampleSpin->value() << "\n";
502         out << groupName << ":" << "obstacleType" << " " << optionsDynamic->obstacleCombo->currentIndex() << "\n";
503         out << groupName << ":" << "dT" << " " << optionsDynamic->dtSpin->value() << "\n";
504         out << groupName << ":" << "colorCheck" << " " << optionsDynamic->colorCheck->isChecked() << "\n";
505         out << groupName << ":" << "tab" << " " << optionsDynamic->algoList->currentIndex() << "\n";
506         if(tab < dynamicals.size() && dynamicals[tab])
507         {
508             dynamicals[tab]->SaveParams(out);
509         }
510     }
511     if(clusterer)
512     {
513         int tab = optionsCluster->algoList->currentIndex();
514         sprintf(groupName,"clusterOptions");
515         out << groupName << ":" << "tab" << " " << optionsCluster->algoList->currentIndex() << "\n";
516         out << groupName << ":" << "trainRatio" << " " << optionsCluster->trainRatioCombo->currentIndex() << "\n";
517         out << groupName << ":" << "trainTestCombo" << " " << optionsCluster->trainTestCombo->currentIndex() << "\n";
518         out << groupName << ":" << "optimizeCombo" << " " << optionsCluster->optimizeCombo->currentIndex() << "\n";
519         out << groupName << ":" << "rangeStart" << " " << optionsCluster->rangeStartSpin->value() << "\n";
520         out << groupName << ":" << "rangeStop" << " " << optionsCluster->rangeStopSpin->value() << "\n";
521         if(tab < clusterers.size() && clusterers[tab])
522         {
523             clusterers[tab]->SaveParams(out);
524         }
525     }
526     if(maximizer)
527     {
528         int tab = optionsMaximize->algoList->currentIndex();
529         double variance = optionsMaximize->varianceSpin->value();
530         sprintf(groupName,"maximizationOptions");
531         out << groupName << ":" << "tab" << " " << optionsMaximize->algoList->currentIndex() << "\n";
532         out << groupName << ":" << "gaussVarianceSpin" << " " << optionsMaximize->varianceSpin->value() << "\n";
533         out << groupName << ":" << "iterationsSpin" << " " << optionsMaximize->iterationsSpin->value() << "\n";
534         out << groupName << ":" << "stoppingSpin" << " " << optionsMaximize->stoppingSpin->value() << "\n";
535         out << groupName << ":" << "benchmarkCombo" << " " << optionsMaximize->benchmarkCombo->currentIndex() << "\n";
536         if(tab < maximizers.size() && maximizers[tab])
537         {
538             maximizers[tab]->SaveParams(out);
539         }
540     }
541     if(reinforcement)
542     {
543         int tab = optionsReinforcement->algoList->currentIndex();
544         double variance = optionsReinforcement->varianceSpin->value();
545         sprintf(groupName,"reinforcementOptions");
546         out << groupName << ":" << "tab" << " " << optionsReinforcement->algoList->currentIndex() << "\n";
547         out << groupName << ":" << "gaussVarianceSpin" << " " << optionsReinforcement->varianceSpin->value() << "\n";
548         out << groupName << ":" << "iterationsSpin" << " " << optionsReinforcement->iterationsSpin->value() << "\n";
549         out << groupName << ":" << "displayIterationSpin" << " " << optionsReinforcement->displayIterationSpin->value() << "\n";
550         out << groupName << ":" << "problemCombo" << " " << optionsReinforcement->problemCombo->currentIndex() << "\n";
551         out << groupName << ":" << "rewardCombo" << " " << optionsReinforcement->rewardCombo->currentIndex() << "\n";
552         out << groupName << ":" << "policyCombo" << " " << optionsReinforcement->policyCombo->currentIndex() << "\n";
553         out << groupName << ":" << "quantizeCombo" << " " << optionsReinforcement->quantizeCombo->currentIndex() << "\n";
554         out << groupName << ":" << "resolutionSpin" << " " << optionsReinforcement->resolutionSpin->value() << "\n";
555         out << groupName << ":" << "benchmarkCombo" << " " << optionsReinforcement->benchmarkCombo->currentIndex() << "\n";
556
557         if(tab < reinforcements.size() && reinforcements[tab])
558         {
559             reinforcements[tab]->SaveParams(out);
560         }
561     }
562     if(projector)
563     {
564         int tab = optionsProject->algoList->currentIndex();
565         sprintf(groupName,"projectOptions");
566         out << groupName << ":" << "tab" << " " << optionsProject->algoList->currentIndex() << "\n";
567         out << groupName << ":" << "fitCheck" << " " << optionsProject->fitCheck->isChecked() << "\n";
568         if(tab < projectors.size() && projectors[tab])
569         {
570             projectors[tab]->SaveParams(out);
571         }
572     }
573 }
574
575 bool startsWith(char *a, char *b)
576 {
577     bool yeah = true;
578     for (int i=0; i<strlen(b); i++)
579     {
580         yeah &= a[i] == b[i];
581     }
582     return yeah;
583 }
584
585 void MLDemos::LoadParams( QString filename )
586 {
587     QFile file(filename);
588     file.open(QFile::ReadOnly);
589     QTextStream in(&file);
590     if(!file.isOpen()) return;
591
592     int sampleCnt, size;
593     in >> sampleCnt;
594     in >> size;
595     QString line;
596     //char line[255];
597     float value;
598
599     char classGroup[255];
600     char regrGroup[255];
601     char dynGroup[255];
602     char clustGroup[255];
603     char maximGroup[255];
604     char reinfGroup[255];
605     char projGroup[255];
606     sprintf(classGroup,"classificationOptions");
607     sprintf(regrGroup,"regressionOptions");
608     sprintf(dynGroup,"dynamicalOptions");
609     sprintf(clustGroup,"clusteringOptions");
610     sprintf(maximGroup,"maximizationOptions");
611     sprintf(reinfGroup,"reinforcementOptions");
612     sprintf(projGroup,"projectOptions");
613
614     // we skip the samples themselves
615     //qDebug() << "Skipping "<< sampleCnt <<" samples" << endl;
616     FOR(i, sampleCnt) line = in.readLine();
617     bool bClass = false, bRegr = false, bDyn = false, bClust = false, bMaxim = false, bReinf = false, bProj = false;
618     //qDebug() << "Loading parameter list" << endl;
619     int tab = 0;
620     while(!in.atEnd())
621     {
622         in >> line;
623         in >> value;
624         //              qDebug() << line << " " << value << endl;
625         if(line.startsWith("headers"))
626         {
627             int headerCount = value;
628             canvas->dimNames.clear();
629             FOR(i, headerCount)
630             {
631                 QString header;
632                 in >> header;
633                 canvas->dimNames << header;
634             }
635             //qDebug() << "dimensions: " << dimensionNames;
636         }
637         if(line.startsWith(classGroup))
638         {
639             bClass = true;
640             algorithmOptions->tabWidget->setCurrentWidget(algorithmOptions->tabClass);
641             if(line.endsWith("tab")) optionsClassify->algoList->setCurrentIndex(tab = (int)value);
642             if(line.endsWith("positiveClass")) optionsClassify->positiveSpin->setValue((int)value);
643             if(tab < classifiers.size() && classifiers[tab]) classifiers[tab]->LoadParams(line,value);
644         }
645         if(line.startsWith(regrGroup))
646         {
647             bRegr = true;
648             algorithmOptions->tabWidget->setCurrentWidget(algorithmOptions->tabRegr);
649             if(line.endsWith("tab")) optionsRegress->algoList->setCurrentIndex(tab = (int)value);
650             if(line.endsWith("outputDimCombo")) optionsRegress->outputDimCombo->setCurrentIndex((int)value);
651             if(tab < regressors.size() && regressors[tab]) regressors[tab]->LoadParams(line,value);
652         }
653         if(line.startsWith(dynGroup))
654         {
655             bDyn = true;
656             algorithmOptions->tabWidget->setCurrentWidget(algorithmOptions->tabDyn);
657             if(line.endsWith("centerType")) optionsDynamic->centerCombo->setCurrentIndex((int)value);
658             if(line.endsWith("zeroCheck")) optionsDynamic->zeroCheck->setChecked((int)value);
659             if(line.endsWith("resampleType")) optionsDynamic->resampleCombo->setCurrentIndex((int)value);
660             if(line.endsWith("resampleCount")) optionsDynamic->resampleSpin->setValue((int)value);
661             if(line.endsWith("obstacleType")) optionsDynamic->obstacleCombo->setCurrentIndex((int)value);
662             if(line.endsWith("dT")) optionsDynamic->dtSpin->setValue((float)value);
663             if(line.endsWith("colorCheck")) optionsDynamic->colorCheck->setChecked((int)value);
664             if(line.endsWith("tab")) optionsDynamic->algoList->setCurrentIndex(tab = (int)value);
665             if(tab < dynamicals.size() && dynamicals[tab]) dynamicals[tab]->LoadParams(line,value);
666         }
667         if(line.startsWith(clustGroup))
668         {
669             bClust = true;
670             algorithmOptions->tabWidget->setCurrentWidget(algorithmOptions->tabClust);
671             if(line.endsWith("tab")) optionsCluster->algoList->setCurrentIndex(tab = (int)value);
672             if(line.endsWith("trainRatio")) optionsCluster->trainRatioCombo->setCurrentIndex((int)value);
673             if(line.endsWith("trainTestCombo")) optionsCluster->trainTestCombo->setCurrentIndex((int)value);
674             if(line.endsWith("optimizeCombo")) optionsCluster->optimizeCombo->setCurrentIndex((int)value);
675             if(line.endsWith("rangeStart")) optionsCluster->rangeStartSpin->setValue((int)value);
676             if(line.endsWith("rangeStop")) optionsCluster->rangeStopSpin->setValue((int)value);
677             if(tab < clusterers.size() && clusterers[tab]) clusterers[tab]->LoadParams(line,value);
678         }
679         if(line.startsWith(maximGroup))
680         {
681             bMaxim = true;
682             algorithmOptions->tabWidget->setCurrentWidget(algorithmOptions->tabMax);
683             if(line.endsWith("tab")) optionsMaximize->algoList->setCurrentIndex(tab = (int)value);
684             if(line.endsWith("gaussVarianceSpin")) optionsMaximize->varianceSpin->setValue((double)value);
685             if(line.endsWith("iterationsSpin")) optionsMaximize->iterationsSpin->setValue((int)value);
686             if(line.endsWith("stoppingSpin")) optionsMaximize->stoppingSpin->setValue((double)value);
687             if(line.endsWith("benchmarkCombo")) optionsMaximize->benchmarkCombo->setCurrentIndex((int)value);
688             if(tab < maximizers.size() && maximizers[tab]) maximizers[tab]->LoadParams(line,value);
689         }
690         if(line.startsWith(reinfGroup))
691         {
692             bReinf = true;
693             algorithmOptions->tabWidget->setCurrentWidget(algorithmOptions->tabReinf);
694             if(line.endsWith("tab")) optionsReinforcement->algoList->setCurrentIndex(tab = (int)value);
695             if(line.endsWith("gaussVarianceSpin")) optionsReinforcement->varianceSpin->setValue((double)value);
696             if(line.endsWith("iterationsSpin")) optionsReinforcement->iterationsSpin->setValue((int)value);
697             if(line.endsWith("displayIterationSpin")) optionsReinforcement->displayIterationSpin->setValue((int)value);
698             if(line.endsWith("problemCombo")) optionsReinforcement->problemCombo->setCurrentIndex((int)value);
699             if(line.endsWith("rewardCombo")) optionsReinforcement->rewardCombo->setCurrentIndex((int)value);
700             if(line.endsWith("policyCombo")) optionsReinforcement->policyCombo->setCurrentIndex((int)value);
701             if(line.endsWith("quantizeCombo")) optionsReinforcement->quantizeCombo->setCurrentIndex((int)value);
702             if(line.endsWith("resolutionSpin")) optionsReinforcement->resolutionSpin->setValue((int)value);
703             if(line.endsWith("benchmarkCombo")) optionsReinforcement->benchmarkCombo->setCurrentIndex((int)value);
704             if(tab < reinforcements.size() && reinforcements[tab]) reinforcements[tab]->LoadParams(line,value);
705
706         }
707         if(line.startsWith(projGroup))
708         {
709             bProj = true;
710             algorithmOptions->tabWidget->setCurrentWidget(algorithmOptions->tabProj);
711             if(line.endsWith("tab")) optionsProject->algoList->setCurrentIndex(tab = (int)value);
712             if(line.endsWith("fitCheck")) optionsProject->fitCheck->setChecked((int)value);
713             if(tab < projectors.size() && projectors[tab]) projectors[tab]->LoadParams(line,value);
714         }
715     }
716     ResetPositiveClass();
717     ManualSelectionUpdated();
718     InputDimensionsUpdated();
719     if(bClass) Classify();
720     if(bRegr) Regression();
721     if(bDyn) Dynamize();
722     if(bClust) Cluster();
723     if(bProj) Project();
724     actionAlgorithms->setChecked(algorithmWidget->isVisible());
725 }
726
727 void MLDemos::ExportOutput()
728 {
729     if(!classifier && !regressor && !clusterer && !projector) return;
730     QString filename = QFileDialog::getSaveFileName(this, tr("Save Output Data"), "", tr("Data (*.txt *.csv)"));
731     if(filename.isEmpty()) return;
732     if(!filename.endsWith(".txt") && !filename.endsWith(".csv")) filename += ".txt";
733
734     QFile file(filename);
735     file.open(QFile::WriteOnly);
736     QTextStream out(&file);
737     if(!file.isOpen()) return;
738
739     if(classifier || clusterer || regressor)
740     {
741         out << "#Sample(n-dims) TrueClass ComputedValue(s)\n";
742         vector<fvec> samples = canvas->data->GetSamples();
743         ivec labels = canvas->data->GetLabels();
744         FOR(i, samples.size())
745         {
746             fvec &sample = samples[i];
747             fvec res;
748             if(classifier) res = classifier->TestMulti(sample);
749             else if (clusterer) res = clusterer->Test(sample);
750             else if (regressor) res = regressor->Test(sample);
751             FOR(d, sample.size()) out << QString("%1\t").arg(sample[d]);
752             out << QString("%1\t").arg(labels[i]);
753             FOR(d, res.size()) out << QString("%1\t").arg(res[d], 0, 'f', 3);
754             out << "\n";
755         }
756     }
757     else if(projector)
758     {
759         out << "#Sample(n-dims) TrueClass Projected(m-dims)\n";
760         vector<fvec> samples = canvas->data->GetSamples();
761         ivec labels = canvas->data->GetLabels();
762         FOR(i, samples.size())
763         {
764             fvec &sample = samples[i];
765             fvec projected;
766             projected = projector->Project(sample);
767             FOR(d, sample.size()) out << QString("%1\t").arg(sample[d]);
768             out << QString("%1\t").arg(labels[i]);
769             FOR(d, projected.size()) out << QString("%1\t").arg(projected[d], 0, 'f', 3);
770             out << "\n";
771         }
772     }
773     file.close();
774 }
775
776 void MLDemos::LoadClassifier()
777 {
778     QString filename = QFileDialog::getOpenFileName(this, tr("Load Model"), "", tr("Model (*.model)"));
779     if(filename.isEmpty()) return;
780     int tab = optionsClassify->algoList->currentIndex();
781     if(tab >= classifiers.size() || !classifiers[tab]) return;
782     Classifier *classifier = classifiers[tab]->GetClassifier();
783     bool ok = classifier->LoadModel(filename.toStdString());
784     if(ok)
785     {
786         if(!classifierMulti.size()) DEL(this->classifier);
787         classifier = 0;
788         FOR(i,classifierMulti.size()) DEL(classifierMulti[i]); classifierMulti.clear();
789         this->classifier = classifier;
790         tabUsedForTraining = tab;
791         classifiers[tab]->Draw(canvas, classifier);
792         DrawClassifiedSamples(canvas, classifier, classifierMulti);
793         if(drawTimer->isRunning()) drawTimer->Stop();
794         drawTimer->Clear();
795         drawTimer->start(QThread::NormalPriority);
796     }
797     else DEL(classifier);
798 }
799
800 void MLDemos::SaveClassifier()
801 {
802     if(!classifier) return;
803     QString filename = QFileDialog::getSaveFileName(this, tr("Save Model"), "", tr("Model (*.model)"));
804     if(filename.isEmpty()) return;
805     if(!filename.endsWith(".model")) filename += ".model";
806     classifier->SaveModel(filename.toStdString());
807 }
808
809 void MLDemos::LoadRegressor()
810 {
811     QString filename = QFileDialog::getOpenFileName(this, tr("Load Model"), "", tr("Model (*.model)"));
812     if(filename.isEmpty()) return;
813     int tab = optionsRegress->algoList->currentIndex();
814     if(tab >= regressors.size() || !regressors[tab]) return;
815     Regressor *regressor = regressors[tab]->GetRegressor();
816     bool ok = regressor->LoadModel(filename.toStdString());
817     if(ok)
818     {
819         DEL(this->regressor);
820         this->regressor = regressor;
821         tabUsedForTraining = tab;
822         regressors[tab]->Draw(canvas, regressor);
823         if(drawTimer->isRunning()) drawTimer->Stop();
824         drawTimer->Clear();
825         drawTimer->start(QThread::NormalPriority);
826     }
827     else DEL(regressor);
828 }
829
830 void MLDemos::SaveRegressor()
831 {
832     if(!regressor) return;
833     QString filename = QFileDialog::getSaveFileName(this, tr("Save Model"), "", tr("Model (*.model)"));
834     if(filename.isEmpty()) return;
835     if(!filename.endsWith(".model")) filename += ".model";
836     regressor->SaveModel(filename.toStdString());
837 }
838
839 void MLDemos::LoadDynamical()
840 {
841     QString filename = QFileDialog::getOpenFileName(this, tr("Load Model"), "", tr("Model (*.model)"));
842     if(filename.isEmpty()) return;
843     int tab = optionsDynamic->algoList->currentIndex();
844     if(tab >= dynamicals.size() || !dynamicals[tab]) return;
845     Dynamical *dynamical = dynamicals[tab]->GetDynamical();
846     bool ok = dynamical->LoadModel(filename.toStdString());
847     if(ok)
848     {
849         DEL(this->dynamical);
850         this->dynamical = dynamical;
851         tabUsedForTraining = tab;
852         dynamicals[tab]->Draw(canvas, dynamical);
853         if(dynamicals[tab]->UsesDrawTimer())
854         {
855             if(drawTimer->isRunning()) drawTimer->Stop();
856             drawTimer->Clear();
857             drawTimer->bColorMap = optionsDynamic->colorCheck->isChecked();
858             drawTimer->start(QThread::NormalPriority);
859         }
860     }
861     else DEL(dynamical);
862 }
863
864 void MLDemos::SaveDynamical()
865 {
866     if(!dynamical) return;
867     QString filename = QFileDialog::getSaveFileName(this, tr("Save Model"), "", tr("Model (*.model)"));
868     if(filename.isEmpty()) return;
869     if(!filename.endsWith(".model")) filename += ".model";
870     dynamical->SaveModel(filename.toStdString());
871 }
872
873 void MLDemos::MapFromReward()
874 {
875     RewardMap *reward = canvas->data->GetReward();
876     if(!reward || reward->Empty() || reward->dim < 2) return;
877     int w = reward->size[0];
878     int h = reward->size[1];
879     QImage image(w,h,QImage::Format_RGB32);
880     FOR(y, h)
881     {
882         FOR(x, w)
883         {
884             double value = reward->rewards[y*w + x];
885             value = min(max(value*255.,0.),255.);
886             image.setPixel(x,y,qRgb(255,255-value,255-value));
887         }
888     }
889     int W = canvas->width();
890     int H = canvas->height();
891     canvas->maps.reward = QPixmap::fromImage(image).scaled(W, H, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
892     canvas->repaint();
893 }
894
895 void MLDemos::RewardFromMap(QImage rewardMap)
896 {
897     QRgb *pixels = (QRgb*) rewardMap.bits();
898     int w = rewardMap.width();
899     int h = rewardMap.height();
900
901     double *data = new double[w*h];
902     double maxData = 0;
903     FOR(i, w*h)
904     {
905         data[i] = 1. - qBlue(pixels[i])/255.; // all data is in a 0-1 range
906         maxData = max(maxData, data[i]);
907     }
908     if(maxData > 0)
909     {
910         FOR(i, w*h) data[i] /= maxData; // we ensure that the data is normalized
911     }
912     ivec size;
913     size.push_back(w);
914     size.push_back(h);
915     fvec low(2,0.f);
916     fvec high(2,1.f);
917     canvas->data->GetReward()->SetReward(data, size, low, high);
918     delete [] data;
919 }