File indexing completed on 2021-12-21 12:17:51

0001 /***************************************************************************
0002 *   Kartesio is a program for calculating best fit curves with            * 
0003 *   experimental points using regression algorithms or neural networks.   *
0004 *                                                                         *
0005 *                   Kartesio has been created by                          *
0006 *                Luca Tringali, TRINGALINVENT@libero.it                   *
0007 *                                                                         *
0008 *                    Copyright 2011-2013 Luca Tringali                    *
0009 *                                                                         *
0010 *   This program is free software; you can redistribute it and/or modify  *
0011 *   it under the terms of the GNU General Public License as published by  *
0012 *   the Free Software Foundation; either version 2 of the License, or     *
0013 *   (at your option) any later version.                                   *
0014 *                                                                         *
0015 *   This program is distributed in the hope that it will be useful,       *
0016 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0017 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0018 *   GNU General Public License for more details.                          *
0019 *                                                                         *
0020 *   You should have received a copy of the GNU General Public License     *
0021 *   along with this program; if not, write to the                         *
0022 *   Free Software Foundation, Inc.,                                       *
0023 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
0024 ***************************************************************************/
0025 
0026 #include "calculations.h"
0027 
0028 Calculations::Calculations()
0029 {
0030     //
0031 }
0032 
0033 Calculations::~Calculations()
0034 {
0035     //
0036 }
0037 
0038 double Calculations::rmsError(QTableWidget *table,  QString func) {
0039     double rms=0.0;
0040     
0041     if (!table->item(0,0) || table->item(0,0)->text().isEmpty())
0042     {
0043         //go on
0044     } else {
0045         
0046         
0047         for (int i=0; i<table->rowCount() ; i++) {
0048             if (!table->item(i,0) || table->item(i,0)->text().isEmpty()) {
0049                 break;
0050             } else {
0051                 QScriptEngine myEngine;
0052                 QByteArray ban = func.toLatin1();
0053                 char *tmreporto = ban.data();
0054                 
0055                 QString istr;
0056                 istr.append(QString("%1").arg((table->item(i,0)->data(Qt::DisplayRole).toDouble())));
0057                 QString myscript = solvex(tmreporto,istr);
0058                 QScriptValue three = myEngine.evaluate(myscript);
0059                 
0060                 double tvalue = three.toNumber();
0061                 double diff = table->item(i,1)->data(Qt::DisplayRole).toDouble() - tvalue;
0062                 rms+= std::pow(diff, 2);
0063             }
0064         }
0065     }
0066     
0067     return std::pow((rms/table->rowCount()),0.5);
0068 }
0069 
0070 QString Calculations::calculate(QTableWidget *table,  QLineEdit *func) {
0071     //this function calculates the best fit curve from some points and a generic function
0072     m_resultFunction = "";
0073     m_myReport=QString("Values obtained by maxima:")+QString("\n");
0074     m_width = int(m_xmax - m_xmin);
0075     int totalcoeff=0;
0076     QStringList coeff;
0077     QString myfunz;
0078     std::vector < std::vector <double> > allcoeffs;
0079     
0080     
0081     //uid.tableWidget->sortItems(1, Qt::AscendingOrder); //seems that the sorting doesn't work correctly
0082     if (!table->item(0,0) || table->item(0,0)->text().isEmpty())
0083     {
0084         //go on
0085     } else {
0086         //now we can plot the values
0087         QVarLengthArray<double, 64> px(table->rowCount());
0088         QVarLengthArray<double, 64> py(table->rowCount());
0089         int totaldata=0;
0090         for (int i=0; i<table->rowCount() ; i++) {
0091             if (!table->item(i,0) || table->item(i,0)->text().isEmpty()) {
0092                 break;
0093             } else {
0094                 totaldata++;
0095                 py[i] = table->item(i,1)->data(Qt::DisplayRole).toDouble();
0096                 px[i] = table->item(i,0)->data(Qt::DisplayRole).toDouble();
0097             }
0098         }
0099         //now in the arrays px and py are stored the values of the points
0100         //we need to read the function and find a way to invert it
0101         
0102         //first of all we need to create an array of the coefficients
0103         //then, for every coefficient (e.g.: "a") we force the passage for one point
0104         //then we must solve the system
0105         //example of a correct system: solve([7=(a*(2^2))+(b*2)+c,13=(a*(3^2))+(b*3)+c,21=(a*(4^2))+(b*4)+c],[a,b,c]);
0106         //this procedure is replicated until every point has been used. Then we make the medium between the coefficient values
0107         //We will use the following command: maxima --batch-string="solve([7=(a*(2^2))+(b*2)+c,13=(a*(3^2))+(b*3)+c,21=(a*(4^2))+(b*4)+c],[a,b,c]);"
0108         
0109         //Try to fill the coeff list with all the coefficients and totalcoeff with the number of coefficients if there is a generic equation
0110         if (func->text()=="") return 0;
0111         QString yvalue = func->text();
0112         QString tempy;
0113         QString tempyn = "";
0114         tempy = "";
0115         if (check(yvalue)==false) return "";
0116         for (int i=0; i<yvalue.length()+1;i++) {
0117             if (yvalue[i]=='q' or yvalue[i]=='w' or yvalue[i]=='e' or yvalue[i]=='r' or yvalue[i]=='t' or yvalue[i]=='y' or yvalue[i]=='u' or yvalue[i]=='i' or yvalue[i]=='o' or yvalue[i]=='p' or yvalue[i]=='a' or yvalue[i]=='s' or yvalue[i]=='d' or yvalue[i]=='f' or yvalue[i]=='g' or yvalue[i]=='h' or yvalue[i]=='j' or yvalue[i]=='k' or yvalue[i]=='l' or yvalue[i]=='z' or yvalue[i]=='x' or yvalue[i]=='c' or yvalue[i]=='v' or yvalue[i]=='b' or yvalue[i]=='n' or yvalue[i]=='m' or yvalue[i]=='Q' or yvalue[i]=='W' or yvalue[i]=='E' or yvalue[i]=='R' or yvalue[i]=='T' or yvalue[i]=='Y' or yvalue[i]=='U' or yvalue[i]=='I' or yvalue[i]=='O' or yvalue[i]=='P' or yvalue[i]=='A' or yvalue[i]=='S' or yvalue[i]=='D' or yvalue[i]=='F' or yvalue[i]=='G' or yvalue[i]=='H' or yvalue[i]=='J' or yvalue[i]=='K' or yvalue[i]=='L' or yvalue[i]=='Z' or yvalue[i]=='X' or yvalue[i]=='C' or yvalue[i]=='V' or yvalue[i]=='B' or yvalue[i]=='N' or yvalue[i]=='M') tempyn = tempyn + yvalue[i];
0118             // every letter will be added in the variable tempyn so we can study it
0119             tempy = "";
0120             if  (yvalue[i]=='=' or yvalue[i]=='+' or yvalue[i]=='-' or yvalue[i]=='*' or yvalue[i]=='/' or yvalue[i]=='(' or yvalue[i]==')' or yvalue[i]=='1' or yvalue[i]=='2' or yvalue[i]=='3' or yvalue[i]=='4' or yvalue[i]=='5' or yvalue[i]=='6' or yvalue[i]=='7' or yvalue[i]=='8' or yvalue[i]=='9' or yvalue[i]=='0' or yvalue[i]=='.' or yvalue[i]==',' ) tempyn = "";
0121             //use the correct functions
0122             if (!(tempyn.isEmpty() or tempyn=="cos" or tempyn=="sin" or tempyn=="y" or tempyn=="x" or tempyn=="tan" or tempyn=="cot" or tempyn=="exp" or tempyn=="abs" or tempyn=="acos" or tempyn=="atan" or tempyn=="atan2" or tempyn=="asin" or tempyn=="ceil" or tempyn=="floor" or tempyn=="log" or tempyn=="ln" or tempyn=="max" or tempyn=="min" or tempyn=="random" or tempyn=="round" or tempyn=="sqrt")) {
0123                 if  ((yvalue[i+1]=='+' or yvalue[i+1]=='=' or yvalue[i+1]=='-' or yvalue[i+1]=='*' or yvalue[i+1]=='^' or yvalue[i+1]=='/' or yvalue[i+1]=='(' or yvalue[i+1]==')' or yvalue[i+1]=='1' or yvalue[i+1]=='2' or yvalue[i+1]=='3' or yvalue[i+1]=='4' or yvalue[i+1]=='5' or yvalue[i+1]=='6' or yvalue[i+1]=='7' or yvalue[i+1]=='8' or yvalue[i+1]=='9' or yvalue[i+1]=='0' or yvalue[i+1]=='.' or yvalue[i+1]==' ' or yvalue[i+1]==',' or yvalue[i+1]=='=' or (i+1)==(yvalue.length())) ) {
0124                     coeff.append(tempyn);
0125                     totalcoeff++;
0126                 }
0127             }
0128         }
0129         
0130         m_tryNumber = 0;
0131         
0132         allcoeffs.resize(totalcoeff);
0133         for (int j=0; j<(totalcoeff);j++) {
0134             allcoeffs[j].resize(1);
0135         }
0136         
0137         //run the procedure until every point has been used
0138         for (int f=0; f<(totaldata);f++) {
0139             //we try to prepare the command line for maxima
0140             QString cmd = maximap + " --batch-string=\"numer:true;solve([";
0141             int fir = 1;
0142             int i = f;
0143             //now i'm using the value of the points to fit the curve
0144             //REMEMBER that coeff.at(u) is the actual coefficient px[i] and py[i] are the x,y values of the point used
0145             for (int u=0; u<totalcoeff; u++) {
0146                 QByteArray banf = func->text().toLatin1();
0147                 char *tmfn = banf.data();
0148                 QString xtmp;
0149                 xtmp.setNum(px[i%totaldata]).replace(QString(","), QString("."));
0150                 QString eqa = replacevar(tmfn,xtmp,QString("x"));
0151                 QByteArray banfn = eqa.toLatin1();
0152                 char *tmfns = banfn.data();
0153                 xtmp.setNum(py[i%totaldata]).replace(QString(","), QString("."));
0154                 QString eq = replacevar(tmfns,xtmp,QString("y"));
0155                 if (fir==0) cmd = cmd + ','+ eq;
0156                 if (fir==1) {
0157                     cmd = cmd + eq;
0158                     fir = 0;
0159                 }
0160                 i++;
0161             }
0162             
0163             cmd = cmd+"],[";
0164             fir= 1;
0165             for (int u=0; u<totalcoeff; u++) {
0166                 if (fir==0) cmd = cmd + ','+coeff.at(u);
0167                 if (fir==1) {
0168                     cmd = cmd + coeff.at(u);
0169                     fir = 0;
0170                 }
0171             }
0172 
0173             QString tmpfilename = "";
0174             QTemporaryFile file;
0175             if (file.open()) {
0176                 tmpfilename = file.fileName();
0177             }
0178             tmpfilename = tmpfilename +"1";
0179             cmd = cmd+"]);\" >> \"" + tmpfilename + "\"";
0180             
0181             //run cmd in a linux shell
0182             QByteArray banfc = cmd.toLatin1();
0183             char *tmc = banfc.data();
0184             QFile::remove(tmpfilename);
0185             int go = system(tmc);
0186             // if go is not 0, then it means that maxima died
0187             if  (go!=0) return QString("died");
0188             qDebug()<<tmpfilename;
0189 
0190             QByteArray banfcf = tmpfilename.toLatin1();
0191             char *tmf = banfcf.data();
0192             char tmpchr;
0193             ifstream texto(tmf);
0194             if (texto) {
0195                 do {
0196                     texto >> tmpchr;
0197                     myfunz = myfunz + tmpchr;
0198                 } while (!texto.eof());
0199             }
0200             texto.close();
0201             
0202             //now we have a string like this "...solve([1=a3+b3+c,2=a4+b4+c,3=a5+b5+c],[a,b,c])(%o2)[[a=0,b=1,c=-2]]]"
0203             //and we must read the values of the coefficients to store them in a list then we create the function
0204             //replacing the correct coefficient values into the original function written by user
0205             
0206             if (myfunz.indexOf("(%o2)")==-1) return 0;
0207             QString tempstr = myfunz.split("(%o2)").at(1);
0208             //we must delete [ and ]
0209             QString cancstr = tempstr.replace("[","");
0210             cancstr = cancstr.replace("]","");
0211             if (myfunz.indexOf(",")==-1 and totalcoeff>1) return 0;
0212             QStringList cmvalue = cancstr.split(',');
0213             m_myReport = m_myReport + cancstr+ '\n';
0214             //ignore the result if it is not a correct number
0215             int good = 1;
0216             for (int u=0; u<totalcoeff; u++) {
0217                 for (int n=0; n<cmvalue.count() ; n++) {
0218                     if (cmvalue.at(n).indexOf("=")==-1) {
0219                         break;
0220                         good = 0;
0221                     }
0222                     QStringList mnval = cmvalue.at(n).split('=');
0223                     QScriptEngine myEnginee;
0224                     QScriptValue isreal = myEnginee.evaluate(mnval.at(1)+"*0");
0225                     if (isreal.toString()!="0") good = 0;
0226                 }
0227             }
0228             
0229             //at this point, cmvalue contains the values of coefficients, for example the first element could be a=0
0230             
0231             myfunz = func->text();
0232             
0233             if (good == 1) {
0234                 for (int u=0; u<totalcoeff; u++) {
0235                     int r = 0;
0236                     for (int n=0; n<cmvalue.count() ; n++) {
0237                         if (cmvalue.at(n).indexOf("=")!=-1) {
0238                             QStringList mnval = cmvalue.at(n).split('=');
0239                             if (mnval.at(0)==coeff.at(u)) {
0240                                 //now we must sum the new value to the others
0241                                 if (m_resultFunction=="") m_resultFunction = myfunz;
0242                                 if (f!=0 and m_tryNumber!=0) {  //remember that f begins with 0
0243                                     allcoeffs.at(u).resize(r+1);
0244                                     allcoeffs.at(u).at(r) = mnval.at(1).toDouble();
0245                                     r++;
0246                                 }
0247                                 m_tryNumber++;
0248                             }
0249                         }
0250                     }
0251                 }
0252                 m_oldValue = cmvalue;
0253             }
0254         } //here ends the search for coefficients values
0255         
0256         if (m_resultFunction=="") m_resultFunction = myfunz;
0257         //mean for every coeff
0258         for (int u=0; u<totalcoeff; u++) {
0259             double mean = 0;
0260             for (int r=0; r<allcoeffs.at(u).size(); r++) {
0261                 mean += allcoeffs.at(u).at(r);
0262             }
0263             mean = (mean/allcoeffs.at(u).size());
0264             QByteArray banf = m_resultFunction.toLatin1();
0265             char *tmfnz = banf.data();
0266             m_resultFunction = replacevar(tmfnz,QString::number(mean), coeff.at(u));
0267         }
0268         
0269     } //here ends the "else"
0270     return m_resultFunction;
0271 }
0272 
0273 
0274 QString Calculations::trainNN(QTableWidget *table,  QComboBox *func, bool backprop, bool genalg)
0275 {
0276     //this function calculates the best fit curve from some points and a generic function
0277     m_resultFunction = "";
0278     //m_myReport="Values obtained by maxima:\n";
0279     m_width = int(m_xmax - m_xmin);
0280     int totalcoeff=0;
0281     //QStringList coeff;
0282     QString myfunz;
0283     std::vector<int> lSzV;
0284     int layers = 2;
0285     QString myresult = "";
0286     
0287     
0288     std::vector < std::vector <double> > dataV;
0289     
0290     //now we need to know which function has been selected
0291     
0292     //uid.tableWidget->sortItems(1, Qt::AscendingOrder); //seems that the sorting doesn't work correctly
0293     if (!table->item(0,0) || table->item(0,0)->text().isEmpty())
0294     {
0295         //go on
0296     } else {
0297         
0298         if (func->currentText() == "y=m*x+q") {
0299             totalcoeff = 2;
0300             dataV.resize(table->rowCount());
0301             for (int j=0; j<(table->rowCount());j++) {
0302                 dataV[j].resize(totalcoeff+1);
0303             }
0304             for (int i=0; i<table->rowCount() ; i++) {
0305                 if (!table->item(i,0) || table->item(i,0)->text().isEmpty()) {
0306                     break;
0307                 } else {
0308                     dataV[i][0] = table->item(i,0)->data(Qt::DisplayRole).toDouble();  //x
0309                     dataV[i][1] = 1;
0310                     dataV[i][2] = table->item(i,1)->data(Qt::DisplayRole).toDouble();  //y
0311                 }
0312             }
0313         }
0314         
0315         if (func->currentText() == "y=a*(x^2)+b*x+c") {
0316             totalcoeff = 3;
0317             dataV.resize(table->rowCount());
0318             for (int j=0; j<(table->rowCount());j++) {
0319                 dataV[j].resize(totalcoeff+1);
0320             }
0321             for (int i=0; i<table->rowCount() ; i++) {
0322                 if (!table->item(i,0) || table->item(i,0)->text().isEmpty()) {
0323                     break;
0324                 } else {
0325                     dataV[i][0] = pow(table->item(i,0)->data(Qt::DisplayRole).toDouble(), 2);  //x^2
0326                     dataV[i][1] = table->item(i,0)->data(Qt::DisplayRole).toDouble();  //x
0327                     dataV[i][2] = 1;
0328                     dataV[i][3] = table->item(i,1)->data(Qt::DisplayRole).toDouble();  //y
0329                 }
0330             }
0331         }
0332         
0333         if (func->currentText() == "y=a*(x^3)+b*(x^2)+c*x+d") {
0334             totalcoeff = 4;
0335             dataV.resize(table->rowCount());
0336             for (int j=0; j<(table->rowCount());j++) {
0337                 dataV[j].resize(totalcoeff+1);
0338             }
0339             for (int i=0; i<table->rowCount() ; i++) {
0340                 if (!table->item(i,0) || table->item(i,0)->text().isEmpty()) {
0341                     break;
0342                 } else {
0343                     dataV[i][0] = pow(table->item(i,0)->data(Qt::DisplayRole).toDouble(), 3);  //x^3
0344                     dataV[i][1] = pow(table->item(i,0)->data(Qt::DisplayRole).toDouble(), 2);  //x^2
0345                     dataV[i][2] = table->item(i,0)->data(Qt::DisplayRole).toDouble();  //x
0346                     dataV[i][3] = 1;
0347                     dataV[i][4] = table->item(i,1)->data(Qt::DisplayRole).toDouble();  //y
0348                 }
0349             }
0350         }
0351         
0352         if (func->currentText() == "y=a*(x^4)+b*(x^3)+c*(x^2)+d*x+e") {
0353             totalcoeff = 5;
0354             dataV.resize(table->rowCount());
0355             for (int j=0; j<(table->rowCount());j++) {
0356                 dataV[j].resize(totalcoeff+1);
0357             }
0358             for (int i=0; i<table->rowCount() ; i++) {
0359                 if (!table->item(i,0) || table->item(i,0)->text().isEmpty()) {
0360                     break;
0361                 } else {
0362                     dataV[i][0] = pow(table->item(i,0)->data(Qt::DisplayRole).toDouble(), 4);  //x^4
0363                     dataV[i][1] = pow(table->item(i,0)->data(Qt::DisplayRole).toDouble(), 3);  //x^3
0364                     dataV[i][2] = pow(table->item(i,0)->data(Qt::DisplayRole).toDouble(), 2);  //x^2
0365                     dataV[i][3] = table->item(i,0)->data(Qt::DisplayRole).toDouble();  //x
0366                     dataV[i][4] = 1;
0367                     dataV[i][5] = table->item(i,1)->data(Qt::DisplayRole).toDouble();  //y
0368                 }
0369             }
0370         }
0371         
0372         if (func->currentText() == "y=a*(e^x)+c") {
0373             totalcoeff = 2;
0374             dataV.resize(table->rowCount());
0375             for (int j=0; j<(table->rowCount());j++) {
0376                 dataV[j].resize(totalcoeff+1);
0377             }
0378             for (int i=0; i<table->rowCount() ; i++) {
0379                 if (!table->item(i,0) || table->item(i,0)->text().isEmpty()) {
0380                     break;
0381                 } else {
0382                     dataV[i][0] = exp(table->item(i,0)->data(Qt::DisplayRole).toDouble());  //exp(x)
0383                     dataV[i][1] = 1;
0384                     dataV[i][2] = table->item(i,1)->data(Qt::DisplayRole).toDouble();  //y
0385                 }
0386             }
0387         }
0388         
0389         if (func->currentText() == "y=a*ln(x)+c") {
0390             totalcoeff = 2;
0391             dataV.resize(table->rowCount());
0392             for (int j=0; j<(table->rowCount());j++) {
0393                 dataV[j].resize(totalcoeff+1);
0394             }
0395             for (int i=0; i<table->rowCount() ; i++) {
0396                 if (!table->item(i,0) || table->item(i,0)->text().isEmpty()) {
0397                     break;
0398                 } else {
0399                     dataV[i][0] = log(table->item(i,0)->data(Qt::DisplayRole).toDouble());  //ln(x)
0400                     dataV[i][1] = 1;
0401                     dataV[i][2] = table->item(i,1)->data(Qt::DisplayRole).toDouble();  //y
0402                 }
0403             }
0404         }
0405         
0406         
0407         if (func->currentText() == "y=(a/x)+b") {
0408             totalcoeff = 2;
0409             dataV.resize(table->rowCount());
0410             for (int j=0; j<(table->rowCount());j++) {
0411                 dataV[j].resize(totalcoeff+1);
0412             }
0413             for (int i=0; i<table->rowCount() ; i++) {
0414                 if (!table->item(i,0) || table->item(i,0)->text().isEmpty()) {
0415                     break;
0416                 } else {
0417                     dataV[i][0] = (1/(table->item(i,0)->data(Qt::DisplayRole).toDouble()));  //1/x
0418                     dataV[i][1] = 1;
0419                     dataV[i][2] = table->item(i,1)->data(Qt::DisplayRole).toDouble();  //y
0420                 }
0421             }
0422         }
0423         
0424         lSzV.resize(layers);
0425         lSzV[0] = (totalcoeff-1);
0426         lSzV[1] = 1;
0427         
0428         //this is the common zorba neural network definition
0429         
0430         double learningRate = 0.1;
0431         double momentum = 0.1;
0432         int maxCrossoverNumber = 200;
0433 
0434         ZorbaNN *myNet = new ZorbaNN(layers, lSzV, learningRate, momentum);
0435         myNet->minAcceptableError = pow(10,-4);
0436         QByteArray banfc = weightssavename.toLatin1();
0437         char *tmcf = banfc.data();
0438         myNet->fileviewweights = tmcf;
0439         myNet->viewweights = viewweights;
0440 
0441         if (loadnetwork != "") {
0442             std::cout << "Actual weights:";
0443             myNet->printWeights();
0444             QByteArray banfcn = loadnetwork.toLatin1();
0445             char *tmcfn = banfcn.data();
0446             myNet->setNetwork(tmcfn);
0447             loadnetwork = "";
0448             std::cout << "Loaded weights:";
0449             myNet->printWeights();
0450         }
0451 
0452         if (backprop==true) myNet->recursiveTrainBackProp(dataV, m_maxIters);
0453         if (genalg==true) myNet->recursiveTrainGenAlg(dataV, m_maxIters, maxCrossoverNumber);
0454         
0455         myresult = "y=";
0456         
0457         for (int f = 0; f<totalcoeff; f++) {
0458             //print the result: the number of weights is totalcoeff
0459             double temp = (1/(1+exp(-(myNet->getWeight(1,0,f)))));
0460             std::ostringstream strs;
0461             strs << std::fixed << std::setprecision(6) << temp;
0462             myresult = myresult + QString(strs.str().c_str());
0463             QString vars = "";
0464             if (func->currentText() == "y=m*x+q" && f == 0) vars = "*x+";
0465             
0466             if (func->currentText() == "y=a*(x^2)+b*x+c" && f == 0) vars = "*(x^2)+";
0467             if (func->currentText() == "y=a*(x^2)+b*x+c" && f == 1) vars = "*x+";
0468             
0469             if (func->currentText() == "y=a*(x^3)+b*(x^2)+c*x+d" && f == 0) vars = "*(x^3)+";
0470             if (func->currentText() == "y=a*(x^3)+b*(x^2)+c*x+d" && f == 1) vars = "*(x^2)+";
0471             if (func->currentText() == "y=a*(x^3)+b*(x^2)+c*x+d" && f == 2) vars = "*x+";
0472             
0473             if (func->currentText() == "y=a*(x^4)+b*(x^3)+c*(x^2)+d*x+e" && f == 0) vars = "*(x^4)+";
0474             if (func->currentText() == "y=a*(x^4)+b*(x^3)+c*(x^2)+d*x+e" && f == 1) vars = "*(x^3)+";
0475             if (func->currentText() == "y=a*(x^4)+b*(x^3)+c*(x^2)+d*x+e" && f == 2) vars = "*(x^2)+";
0476             if (func->currentText() == "y=a*(x^4)+b*(x^3)+c*(x^2)+d*x+e" && f == 3) vars = "*x+";
0477             
0478             if (func->currentText() == "y=a*(e^x)+c" && f == 0) vars = "*exp(x)+";
0479             
0480             if (func->currentText() == "y=a*ln(x)+c" && f == 0) vars = "*ln(x)+";
0481             
0482             if (func->currentText() == "y=(a/x)+b" && f == 0) vars = "/x+";
0483             
0484             myresult = myresult + vars;
0485         }
0486         
0487         //here I can save the entire network for reuse
0488         if (NNsavename != "") {
0489             QByteArray banfc = NNsavename.toLatin1();
0490             char *tmc = banfc.data();
0491             myNet->saveNetwork(tmc);
0492             //qDebug() << "Saved neural network in" << NNsavename;
0493         }
0494     } //here ends the "else"
0495 
0496     return myresult;
0497 }
0498 
0499 QString Calculations::solvex(QString yvalue, QString dnum) {
0500     //yvalue contains the equation of Y-axis variable
0501     //Remember that the function to elevate to power is Math.pow(b,e)
0502     //dnum is the value of x
0503     //the E must be changed to *10^: for example, the function
0504     //y=4.6374269005847954E-8*(x^3)+-1.8212280701754386E-5*(x^2)+0.002477485380117*x+0
0505     //should be
0506     //y=4.6374269005847954*10^-8*(x^3)+-1.8212280701754386*10^-5*(x^2)+0.002477485380117*x+0
0507     
0508     QString mreport;
0509     QString tempy;
0510     QString tempyold;
0511     QString tempyolda = "";
0512     QString tempyn = "";
0513     int olda =0;
0514     mreport ="";
0515     QString tempyval;
0516     tempy = "";
0517     if (check(yvalue)==false) return "";
0518     for (int i=0; i<yvalue.length()+1;i++) {
0519         if (yvalue[i]=='q' or yvalue[i]=='w' or yvalue[i]=='e' or yvalue[i]=='r' or yvalue[i]=='t' or yvalue[i]=='y' or yvalue[i]=='u' or yvalue[i]=='i' or yvalue[i]=='o' or yvalue[i]=='p' or yvalue[i]=='a' or yvalue[i]=='s' or yvalue[i]=='d' or yvalue[i]=='f' or yvalue[i]=='g' or yvalue[i]=='h' or yvalue[i]=='j' or yvalue[i]=='k' or yvalue[i]=='l' or yvalue[i]=='z' or yvalue[i]=='x' or yvalue[i]=='c' or yvalue[i]=='v' or yvalue[i]=='b' or yvalue[i]=='n' or yvalue[i]=='m' or yvalue[i]=='Q' or yvalue[i]=='W' or yvalue[i]=='E' or yvalue[i]=='R' or yvalue[i]=='T' or yvalue[i]=='Y' or yvalue[i]=='U' or yvalue[i]=='I' or yvalue[i]=='O' or yvalue[i]=='P' or yvalue[i]=='A' or yvalue[i]=='S' or yvalue[i]=='D' or yvalue[i]=='F' or yvalue[i]=='G' or yvalue[i]=='H' or yvalue[i]=='J' or yvalue[i]=='K' or yvalue[i]=='L' or yvalue[i]=='Z' or yvalue[i]=='X' or yvalue[i]=='C' or yvalue[i]=='V' or yvalue[i]=='B' or yvalue[i]=='N' or yvalue[i]=='M') tempyn = tempyn + yvalue[i];
0520         // every letter will be added in the variable tempyn so we can study it
0521         tempy = "";
0522         if  (yvalue[i]=='=' or yvalue[i]=='+' or yvalue[i]=='-' or yvalue[i]=='*' or yvalue[i]=='/' or yvalue[i]=='(' or yvalue[i]==')' or yvalue[i]=='1' or yvalue[i]=='2' or yvalue[i]=='3' or yvalue[i]=='4' or yvalue[i]=='5' or yvalue[i]=='6' or yvalue[i]=='7' or yvalue[i]=='8' or yvalue[i]=='9' or yvalue[i]=='0' or yvalue[i]=='.' or yvalue[i]==',' ) tempyn = "";
0523         if (tempyn=="x") tempy=dnum; //replace every x with the correct numerical value
0524         //use the correct functions
0525         if (tempyn=="cos") tempy = "Math.cos";
0526         if (tempyn=="sin") tempy = "Math.sin";
0527         if (tempyn=="tan") tempy = "Math.tan";
0528         if (tempyn=="cot") tempy = "Math.cot";
0529         if (tempyn=="exp") tempy = "Math.exp";
0530         if (tempyn=="abs") tempy = "Math.abs";
0531         if (tempyn=="acos") tempy = "Math.acos";
0532         if (tempyn=="atan") tempy = "Math.atan";
0533         if (tempyn=="atan2") tempy = "Math.atan2";
0534         if (tempyn=="asin") tempy = "Math.asin";
0535         if (tempyn=="ceil") tempy = "Math.ceil";
0536         if (tempyn=="floor") tempy = "Math.floor";
0537         if (tempyn=="log") tempy = "Math.log"; //here's the usual problem: some people call log the logarithm in e, others call it ln
0538         if (tempyn=="ln") tempy = "Math.log"; //here's the usual problem: some people call log the logarithm in e, others call it ln
0539         if (tempyn=="max") tempy = "Math.max";
0540         if (tempyn=="min") tempy = "Math.min";
0541         if (tempyn=="random") tempy = "Math.random";
0542         if (tempyn=="round") tempy = "Math.round";
0543         if (tempyn=="sqrt") tempy = "Math.sqrt";
0544         if (tempyn=="E") {
0545             tempy = "*Math.pow(10,";
0546             do{
0547                 i++;
0548                 tempy = tempy + yvalue[i];
0549             }while ((QString(yvalue[i+1])!=QString("*")));//until i+1=="*"
0550             tempy = tempy + ')';
0551         }
0552         //the simbol ^ should be replaced by Math.pow(base, exp)
0553         if (olda==1) {
0554             //we need to know when we get a simbol to know the power exponent is ended
0555             tempyold = tempyold + yvalue[i];
0556             if  (yvalue[i]=='(' or yvalue[i]==')' ) {
0557                 tempyval = tempyval + QString("Math.pow(") + tempyolda + QString(",") + tempyold + QString(")");
0558                 tempyolda = "";
0559                 tempyold  = "";
0560                 olda = 0;
0561             }
0562         } else {
0563             //if the character is a number or a mathematic simbol we simply copy it
0564             if  ((yvalue[i]=='=' or yvalue[i]=='+' or yvalue[i]=='-' or yvalue[i]=='*' or yvalue[i]=='/' or yvalue[i]=='(' or yvalue[i]==')' or yvalue[i]=='1' or yvalue[i]=='2' or yvalue[i]=='3' or yvalue[i]=='4' or yvalue[i]=='5' or yvalue[i]=='6' or yvalue[i]=='7' or yvalue[i]=='8' or yvalue[i]=='9' or yvalue[i]=='0' or yvalue[i]=='.' or yvalue[i]==',' ) and (olda!=1) ) tempyval = tempyval + yvalue[i];
0565             if (yvalue[i]=='^') {
0566                 olda =1;
0567             }
0568             if ((yvalue[i+1]!='^') and (yvalue[i]!='^') and !(tempy.isEmpty())) {
0569                 tempyval = tempyval + tempy;
0570                 tempy ="";
0571             }
0572             if (yvalue[i+1]=='^') {
0573                 tempyolda = tempy;
0574                 tempy ="";
0575             }
0576             if (tempyval!="") mreport = tempyval;
0577         }
0578     }
0579     return mreport;
0580 }
0581 
0582 QString Calculations::replacevar(QString yvalue, QString dnum, QString var) {
0583     //yvalue contains the equation of Y-axis variable
0584     //Remember that the function to elevate to power is Math.pow(b,e)
0585     //dnum is the value of x
0586     QString mreport;
0587     QString tempy;
0588     QString tempyn = "";
0589     int olda =0;
0590     mreport ="";
0591     QString tempyval;
0592     tempy = "";
0593     if (check(yvalue)==false) return "";
0594     for (int i=0; i<yvalue.length()+1;i++) {
0595         if (yvalue[i]=='q' or yvalue[i]=='w' or yvalue[i]=='e' or yvalue[i]=='r' or yvalue[i]=='t' or yvalue[i]=='y' or yvalue[i]=='u' or yvalue[i]=='i' or yvalue[i]=='o' or yvalue[i]=='p' or yvalue[i]=='a' or yvalue[i]=='s' or yvalue[i]=='d' or yvalue[i]=='f' or yvalue[i]=='g' or yvalue[i]=='h' or yvalue[i]=='j' or yvalue[i]=='k' or yvalue[i]=='l' or yvalue[i]=='z' or yvalue[i]=='x' or yvalue[i]=='c' or yvalue[i]=='v' or yvalue[i]=='b' or yvalue[i]=='n' or yvalue[i]=='m' or yvalue[i]=='Q' or yvalue[i]=='W' or yvalue[i]=='E' or yvalue[i]=='R' or yvalue[i]=='T' or yvalue[i]=='Y' or yvalue[i]=='U' or yvalue[i]=='I' or yvalue[i]=='O' or yvalue[i]=='P' or yvalue[i]=='A' or yvalue[i]=='S' or yvalue[i]=='D' or yvalue[i]=='F' or yvalue[i]=='G' or yvalue[i]=='H' or yvalue[i]=='J' or yvalue[i]=='K' or yvalue[i]=='L' or yvalue[i]=='Z' or yvalue[i]=='X' or yvalue[i]=='C' or yvalue[i]=='V' or yvalue[i]=='B' or yvalue[i]=='N' or yvalue[i]=='M') tempyn = tempyn + yvalue[i];
0596         // every letter will be added in the variable tempyn so we can study it
0597         tempy = "";
0598         if  (yvalue[i]=='+' or yvalue[i]=='-' or yvalue[i]=='*' or yvalue[i]=='/' or yvalue[i]=='(' or yvalue[i]==')' or yvalue[i]=='1' or yvalue[i]=='2' or yvalue[i]=='3' or yvalue[i]=='4' or yvalue[i]=='5' or yvalue[i]=='6' or yvalue[i]=='7' or yvalue[i]=='8' or yvalue[i]=='9' or yvalue[i]=='0' or yvalue[i]=='.' or yvalue[i]==',' ) tempyn = "";
0599         if  ((yvalue[i+1]=='+' or yvalue[i+1]=='=' or yvalue[i+1]=='-' or yvalue[i+1]=='*' or yvalue[i+1]=='^' or yvalue[i+1]=='/' or yvalue[i+1]=='(' or yvalue[i+1]==')' or yvalue[i+1]=='1' or yvalue[i+1]=='2' or yvalue[i+1]=='3' or yvalue[i+1]=='4' or yvalue[i+1]=='5' or yvalue[i+1]=='6' or yvalue[i+1]=='7' or yvalue[i+1]=='8' or yvalue[i+1]=='9' or yvalue[i+1]=='0' or yvalue[i+1]=='.' or yvalue[i+1]==' ' or yvalue[i+1]==',' or yvalue[i+1]=='=' or (i+1)==(yvalue.length())) ) {
0600             if (tempyn==var) tempyval = tempyval + dnum; //replace every x with the correct value
0601             if (tempyn!=var) tempyval = tempyval + tempyn;
0602             tempyn = "";
0603         }
0604         //use the correct functions
0605         //if the carachter is a number or a mathematic simbol we simply copy it
0606         if  ((yvalue[i]=='=' or yvalue[i]=='+' or yvalue[i]=='-' or yvalue[i]=='*' or yvalue[i]=='^' or yvalue[i]=='/' or yvalue[i]=='(' or yvalue[i]==')' or yvalue[i]=='1' or yvalue[i]=='2' or yvalue[i]=='3' or yvalue[i]=='4' or yvalue[i]=='5' or yvalue[i]=='6' or yvalue[i]=='7' or yvalue[i]=='8' or yvalue[i]=='9' or yvalue[i]=='0' or yvalue[i]=='.' or yvalue[i]==',' ) and (olda!=1) ) tempyval = tempyval + yvalue[i];
0607         
0608         if (tempyval!="") mreport = tempyval;
0609     }
0610     return mreport;
0611 }
0612 
0613 bool Calculations::check(QString func) { //returns true if it does not contain dangerous chars, false if there is one
0614     
0615     bool result = true;
0616     if (func.isEmpty()) result = false;
0617     
0618     for (int i=0; i<func.length();i++) {
0619         if (!(func.at(i).isLetter() or func.at(i).isNumber() or func.at(i)=='+' or func.at(i)=='-' or func.at(i)=='^' or func.at(i)=='*' or func.at(i)=='/' or func.at(i)=='(' or func.at(i)==')' or func.at(i)=='.' or func.at(i)==','or func.at(i)=='=')) result = false;
0620     }
0621     if (func.indexOf("**")!=-1) result = false;
0622     if (func.indexOf("==")!=-1) result = false;
0623     if (func.indexOf("/*")!=-1) result = false;
0624     if (func.indexOf("//")!=-1) result = false;
0625     if (func.indexOf("\\")!=-1) result = false;
0626     if (func.indexOf("..")!=-1) result = false;
0627     if (func.indexOf(",,")!=-1) result = false;
0628     
0629     return result;
0630 }
0631