2015-07-11 18:56:02 +08:00
/*
2019-01-20 23:15:10 +08:00
Copyright ( c ) 2008 - 2019 Jan W . Krieger ( < jan @ jkrieger . de > )
2015-07-11 18:56:02 +08:00
2015-07-12 22:34:27 +08:00
2015-07-11 18:56:02 +08:00
This software is free software : you can redistribute it and / or modify
it under the terms of the GNU Lesser General Public License ( LGPL ) as published by
the Free Software Foundation , either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU Lesser General Public License ( LGPL ) for more details .
You should have received a copy of the GNU Lesser General Public License ( LGPL )
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2018-12-19 00:13:18 +08:00
# include "jkqtplotter/jkqtpgraphsparsedfunction.h"
# include "jkqtplotter/jkqtpgraphs.h"
2018-11-26 03:25:44 +08:00
# include "jkqtplotter/jkqtpbaseplotter.h"
# include "jkqtplottertools/jkqtptools.h"
2015-07-11 18:56:02 +08:00
# include <stdlib.h>
# include <QDebug>
# include <QElapsedTimer>
2018-12-24 03:27:24 +08:00
# include <utility>
2015-07-11 18:56:02 +08:00
2019-01-20 17:49:29 +08:00
JKQTPXParsedFunctionLineGraph : : JKQTPXParsedFunctionLineGraph ( JKQTBasePlotter * parent ) :
JKQTPXFunctionLineGraph ( parent )
2018-12-24 22:07:14 +08:00
{
fdata . parser = new JKQTPMathParser ( ) ;
fdata . node = nullptr ;
fdata . varcount = 0 ;
function = " " ;
parameterColumn = - 1 ;
set_params ( & fdata ) ;
2019-01-26 03:16:04 +08:00
setPlotFunction ( & JKQTPXParsedFunctionLineGraph : : JKQTPXParsedFunctionLineGraphFunction ) ;
2018-12-24 22:07:14 +08:00
efdata . parser = new JKQTPMathParser ( ) ;
efdata . node = nullptr ;
efdata . varcount = 0 ;
errorFunction = " " ;
errorParameterColumn = - 1 ;
set_errorParams ( & efdata ) ;
2019-01-20 17:49:29 +08:00
set_errorPlotFunction ( & JKQTPXParsedFunctionLineGraph : : JKQTPXParsedFunctionLineGraphFunction ) ;
2018-12-24 22:07:14 +08:00
}
2019-01-20 23:15:10 +08:00
JKQTPXParsedFunctionLineGraph : : JKQTPXParsedFunctionLineGraph ( JKQTPlotter * parent ) :
2019-01-20 17:49:29 +08:00
JKQTPXFunctionLineGraph ( parent )
2018-12-24 22:07:14 +08:00
{
fdata . parser = new JKQTPMathParser ( ) ;
fdata . node = nullptr ;
fdata . varcount = 0 ;
function = " " ;
parameterColumn = - 1 ;
set_params ( & fdata ) ;
2019-01-26 03:16:04 +08:00
setPlotFunction ( & JKQTPXParsedFunctionLineGraph : : JKQTPXParsedFunctionLineGraphFunction ) ;
2018-12-24 22:07:14 +08:00
efdata . parser = new JKQTPMathParser ( ) ;
efdata . node = nullptr ;
efdata . varcount = 0 ;
errorFunction = " " ;
errorParameterColumn = - 1 ;
set_errorParams ( & efdata ) ;
2019-01-20 17:49:29 +08:00
set_errorPlotFunction ( & JKQTPXParsedFunctionLineGraph : : JKQTPXParsedFunctionLineGraphFunction ) ;
2018-12-24 22:07:14 +08:00
}
2019-01-20 17:49:29 +08:00
JKQTPXParsedFunctionLineGraph : : ~ JKQTPXParsedFunctionLineGraph ( )
2018-12-24 22:07:14 +08:00
{
if ( fdata . node ) delete fdata . node ;
delete fdata . parser ;
if ( efdata . node ) delete efdata . node ;
delete efdata . parser ;
}
2019-01-20 17:49:29 +08:00
void JKQTPXParsedFunctionLineGraph : : createPlotData ( bool /*collectParams*/ )
2018-12-24 22:07:14 +08:00
{
collectParameters ( ) ;
//QElapsedTimer timer;
//timer.start();
for ( int i = 0 ; i < fdata . varcount ; i + + ) {
fdata . parser - > deleteVariable ( std : : string ( " p " ) + jkqtp_inttostr ( i + 1 ) ) ;
}
fdata . varcount = 0 ;
try {
QVector < double > * parameters = static_cast < QVector < double > * > ( params ) ;
if ( parameters ) {
for ( int i = 0 ; i < parameters - > size ( ) ; i + + ) {
fdata . parser - > addVariableDouble ( std : : string ( " p " ) + jkqtp_inttostr ( fdata . varcount + 1 ) , parameters - > at ( i ) ) ;
fdata . varcount = fdata . varcount + 1 ;
}
}
fdata . parser - > addVariableDouble ( std : : string ( " x " ) , 0.0 ) ;
if ( fdata . node ) delete fdata . node ;
//qint64 t=timer.elapsed();
//qDebug()<<"createPlotData(): adding variables: "<<t<<"ms";
fdata . node = fdata . parser - > parse ( function . toStdString ( ) ) ;
//qDebug()<<"createPlotData(): parsing: "<<timer.elapsed()-t<<"ms";
} catch ( std : : exception & /*E*/ ) {
//qDebug()<<QString("parser error: %1").arg(E.what());
}
//qint64 t0=timer.elapsed();
for ( int i = 0 ; i < efdata . varcount ; i + + ) {
efdata . parser - > deleteVariable ( std : : string ( " p " ) + jkqtp_inttostr ( i + 1 ) ) ;
}
efdata . varcount = 0 ;
try {
QVector < double > * errorParameters = static_cast < QVector < double > * > ( errorParams ) ;
if ( errorParameters ) {
for ( int i = 0 ; i < errorParameters - > size ( ) ; i + + ) {
efdata . parser - > addVariableDouble ( std : : string ( " p " ) + jkqtp_inttostr ( efdata . varcount + 1 ) , errorParameters - > at ( i ) ) ;
efdata . varcount = efdata . varcount + 1 ;
}
}
efdata . parser - > addVariableDouble ( std : : string ( " x " ) , 0.0 ) ;
if ( efdata . node ) delete efdata . node ;
//qint64 t=timer.elapsed();
//qDebug()<<"createPlotData(): adding variables: "<<t-t0<<"ms";
efdata . node = efdata . parser - > parse ( errorFunction . toStdString ( ) ) ;
//qDebug()<<"createPlotData(): parsing: "<<timer.elapsed()-t<<"ms";
} catch ( std : : exception & /*E*/ ) {
//qDebug()<<QString("parser error: %1").arg(E.what());
}
set_params ( & fdata ) ;
2019-01-26 03:16:04 +08:00
setPlotFunction ( JKQTPXParsedFunctionLineGraphFunction ) ;
2018-12-24 22:07:14 +08:00
set_errorParams ( & efdata ) ;
2019-01-20 17:49:29 +08:00
set_errorPlotFunction ( JKQTPXParsedFunctionLineGraphFunction ) ;
2018-12-24 22:07:14 +08:00
//qint64 t=timer.elapsed();
2019-01-20 17:49:29 +08:00
JKQTPXFunctionLineGraph : : createPlotData ( false ) ;
//qDebug()<<"createPlotData(): JKQTPXFunctionLineGraph::createPlotData(): "<<timer.elapsed()-t<<"ms";
2018-12-24 22:07:14 +08:00
/*int count=0;
doublePair * d = data ;
while ( d ! = nullptr ) {
count + + ;
d = d - > next ;
}
qDebug ( ) < < " refined to " < < count < < " daatapoints " ; */
}
2019-01-20 17:49:29 +08:00
double JKQTPXParsedFunctionLineGraph : : JKQTPXParsedFunctionLineGraphFunction ( double x , void * data ) {
JKQTPXParsedFunctionLineGraph : : JKQTPXParsedFunctionLineGraphFunctionData * d = ( JKQTPXParsedFunctionLineGraph : : JKQTPXParsedFunctionLineGraphFunctionData * ) data ;
2015-07-11 18:56:02 +08:00
if ( d & & d - > parser & & d - > node ) {
try {
d - > parser - > addVariableDouble ( " x " , x ) ;
JKQTPMathParser : : jkmpResult r = d - > node - > evaluate ( ) ;
if ( r . isValid ) {
if ( r . type = = JKQTPMathParser : : jkmpBool ) {
return r . boolean ? 1.0 : 0.0 ;
} else if ( r . type = = JKQTPMathParser : : jkmpDouble ) {
return r . num ;
}
}
2018-12-06 02:23:11 +08:00
} catch ( std : : exception & /*E*/ ) {
2015-07-11 18:56:02 +08:00
//qDebug()<<QString("parser error: %1").arg(E.what());
/*ok= QMessageBox::critical(this, tr("QuickFit-table"),
tr ( " An error occured while parsing the expression '%1' in cell (row, column)=(%3, %4): \n %2 \n \n \" OK \" will still go on evaluating \n \" Cancel \" will cancel evaluation for the rest of the cells. " ) . arg ( dlgMathExpression - > getExpression ( ) ) . arg ( E . what ( ) ) . arg ( row ) . arg ( column ) ,
QMessageBox : : Ok | QMessageBox : : Cancel , QMessageBox : : Ok ) = = QMessageBox : : Ok ; */
}
}
return NAN ;
}
2018-12-24 22:07:14 +08:00
2019-01-20 17:49:29 +08:00
JKQTPYParsedFunctionLineGraph : : JKQTPYParsedFunctionLineGraph ( JKQTBasePlotter * parent ) :
JKQTPYFunctionLineGraph ( parent )
2015-07-11 18:56:02 +08:00
{
fdata . parser = new JKQTPMathParser ( ) ;
2018-11-18 18:59:30 +08:00
fdata . node = nullptr ;
2015-07-11 18:56:02 +08:00
fdata . varcount = 0 ;
function = " " ;
parameterColumn = - 1 ;
set_params ( & fdata ) ;
2019-01-26 03:16:04 +08:00
setPlotFunction ( & JKQTPYParsedFunctionLineGraph : : JKQTPYParsedFunctionLineGraphFunction ) ;
2015-07-11 18:56:02 +08:00
efdata . parser = new JKQTPMathParser ( ) ;
2018-11-18 18:59:30 +08:00
efdata . node = nullptr ;
2015-07-11 18:56:02 +08:00
efdata . varcount = 0 ;
errorFunction = " " ;
errorParameterColumn = - 1 ;
set_errorParams ( & efdata ) ;
2019-01-20 17:49:29 +08:00
set_errorPlotFunction ( & JKQTPYParsedFunctionLineGraph : : JKQTPYParsedFunctionLineGraphFunction ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
JKQTPYParsedFunctionLineGraph : : JKQTPYParsedFunctionLineGraph ( JKQTPlotter * parent ) :
2019-01-20 17:49:29 +08:00
JKQTPYFunctionLineGraph ( parent )
2015-08-02 19:36:54 +08:00
{
fdata . parser = new JKQTPMathParser ( ) ;
2018-11-18 18:59:30 +08:00
fdata . node = nullptr ;
2015-08-02 19:36:54 +08:00
fdata . varcount = 0 ;
function = " " ;
parameterColumn = - 1 ;
set_params ( & fdata ) ;
2019-01-26 03:16:04 +08:00
setPlotFunction ( & JKQTPYParsedFunctionLineGraph : : JKQTPYParsedFunctionLineGraphFunction ) ;
2015-08-02 19:36:54 +08:00
efdata . parser = new JKQTPMathParser ( ) ;
2018-11-18 18:59:30 +08:00
efdata . node = nullptr ;
2015-08-02 19:36:54 +08:00
efdata . varcount = 0 ;
errorFunction = " " ;
errorParameterColumn = - 1 ;
set_errorParams ( & efdata ) ;
2019-01-20 17:49:29 +08:00
set_errorPlotFunction ( & JKQTPYParsedFunctionLineGraph : : JKQTPYParsedFunctionLineGraphFunction ) ;
2015-08-02 19:36:54 +08:00
}
2018-12-24 22:07:14 +08:00
2019-01-20 17:49:29 +08:00
JKQTPYParsedFunctionLineGraph : : ~ JKQTPYParsedFunctionLineGraph ( )
2015-07-11 18:56:02 +08:00
{
if ( fdata . node ) delete fdata . node ;
delete fdata . parser ;
if ( efdata . node ) delete efdata . node ;
delete efdata . parser ;
}
2019-01-20 17:49:29 +08:00
void JKQTPYParsedFunctionLineGraph : : createPlotData ( bool /*collectParams*/ )
2015-07-11 18:56:02 +08:00
{
collectParameters ( ) ;
2015-08-02 19:36:54 +08:00
//QElapsedTimer timer;
//timer.start();
2015-07-11 18:56:02 +08:00
for ( int i = 0 ; i < fdata . varcount ; i + + ) {
fdata . parser - > deleteVariable ( std : : string ( " p " ) + jkqtp_inttostr ( i + 1 ) ) ;
}
fdata . varcount = 0 ;
try {
2018-12-24 22:07:14 +08:00
QVector < double > * parameters = static_cast < QVector < double > * > ( params ) ;
if ( parameters ) {
for ( int i = 0 ; i < parameters - > size ( ) ; i + + ) {
fdata . parser - > addVariableDouble ( std : : string ( " p " ) + jkqtp_inttostr ( fdata . varcount + 1 ) , parameters - > at ( i ) ) ;
2015-07-11 18:56:02 +08:00
fdata . varcount = fdata . varcount + 1 ;
}
}
fdata . parser - > addVariableDouble ( std : : string ( " x " ) , 0.0 ) ;
2018-12-24 22:07:14 +08:00
fdata . parser - > addVariableDouble ( std : : string ( " y " ) , 0.0 ) ;
2015-07-11 18:56:02 +08:00
if ( fdata . node ) delete fdata . node ;
2015-08-02 19:36:54 +08:00
//qint64 t=timer.elapsed();
2015-07-11 18:56:02 +08:00
//qDebug()<<"createPlotData(): adding variables: "<<t<<"ms";
fdata . node = fdata . parser - > parse ( function . toStdString ( ) ) ;
//qDebug()<<"createPlotData(): parsing: "<<timer.elapsed()-t<<"ms";
2018-12-06 02:23:11 +08:00
} catch ( std : : exception & /*E*/ ) {
2015-07-11 18:56:02 +08:00
//qDebug()<<QString("parser error: %1").arg(E.what());
}
2015-08-02 19:36:54 +08:00
//qint64 t0=timer.elapsed();
2015-07-11 18:56:02 +08:00
for ( int i = 0 ; i < efdata . varcount ; i + + ) {
efdata . parser - > deleteVariable ( std : : string ( " p " ) + jkqtp_inttostr ( i + 1 ) ) ;
}
efdata . varcount = 0 ;
try {
2018-12-24 22:07:14 +08:00
QVector < double > * errorParameters = static_cast < QVector < double > * > ( errorParams ) ;
if ( errorParameters ) {
for ( int i = 0 ; i < errorParameters - > size ( ) ; i + + ) {
efdata . parser - > addVariableDouble ( std : : string ( " p " ) + jkqtp_inttostr ( efdata . varcount + 1 ) , errorParameters - > at ( i ) ) ;
2015-07-11 18:56:02 +08:00
efdata . varcount = efdata . varcount + 1 ;
}
}
efdata . parser - > addVariableDouble ( std : : string ( " x " ) , 0.0 ) ;
2018-12-24 22:07:14 +08:00
efdata . parser - > addVariableDouble ( std : : string ( " y " ) , 0.0 ) ;
2015-07-11 18:56:02 +08:00
if ( efdata . node ) delete efdata . node ;
2015-08-02 19:36:54 +08:00
//qint64 t=timer.elapsed();
2015-07-11 18:56:02 +08:00
//qDebug()<<"createPlotData(): adding variables: "<<t-t0<<"ms";
efdata . node = efdata . parser - > parse ( errorFunction . toStdString ( ) ) ;
//qDebug()<<"createPlotData(): parsing: "<<timer.elapsed()-t<<"ms";
2018-12-06 02:23:11 +08:00
} catch ( std : : exception & /*E*/ ) {
2015-07-11 18:56:02 +08:00
//qDebug()<<QString("parser error: %1").arg(E.what());
}
set_params ( & fdata ) ;
2019-01-26 03:16:04 +08:00
setPlotFunction ( JKQTPYParsedFunctionLineGraphFunction ) ;
2015-07-11 18:56:02 +08:00
set_errorParams ( & efdata ) ;
2019-01-20 17:49:29 +08:00
set_errorPlotFunction ( JKQTPYParsedFunctionLineGraphFunction ) ;
2015-07-11 18:56:02 +08:00
2015-08-02 19:36:54 +08:00
//qint64 t=timer.elapsed();
2019-01-20 17:49:29 +08:00
JKQTPYFunctionLineGraph : : createPlotData ( false ) ;
//qDebug()<<"createPlotData(): JKQTPYFunctionLineGraph::createPlotData(): "<<timer.elapsed()-t<<"ms";
2015-07-11 18:56:02 +08:00
/*int count=0;
doublePair * d = data ;
2018-11-18 18:59:30 +08:00
while ( d ! = nullptr ) {
2015-07-11 18:56:02 +08:00
count + + ;
d = d - > next ;
}
qDebug ( ) < < " refined to " < < count < < " daatapoints " ; */
}
2018-12-24 22:07:14 +08:00
2019-01-20 17:49:29 +08:00
double JKQTPYParsedFunctionLineGraph : : JKQTPYParsedFunctionLineGraphFunction ( double x , void * data ) {
JKQTPYParsedFunctionLineGraph : : JKQTPYParsedFunctionLineGraphFunctionData * d = ( JKQTPYParsedFunctionLineGraph : : JKQTPYParsedFunctionLineGraphFunctionData * ) data ;
2018-12-24 22:07:14 +08:00
if ( d & & d - > parser & & d - > node ) {
try {
d - > parser - > addVariableDouble ( " x " , x ) ;
d - > parser - > addVariableDouble ( " y " , x ) ;
JKQTPMathParser : : jkmpResult r = d - > node - > evaluate ( ) ;
if ( r . isValid ) {
if ( r . type = = JKQTPMathParser : : jkmpBool ) {
return r . boolean ? 1.0 : 0.0 ;
} else if ( r . type = = JKQTPMathParser : : jkmpDouble ) {
return r . num ;
}
}
} catch ( std : : exception & /*E*/ ) {
//qDebug()<<QString("parser error: %1").arg(E.what());
/*ok= QMessageBox::critical(this, tr("QuickFit-table"),
tr ( " An error occured while parsing the expression '%1' in cell (row, column)=(%3, %4): \n %2 \n \n \" OK \" will still go on evaluating \n \" Cancel \" will cancel evaluation for the rest of the cells. " ) . arg ( dlgMathExpression - > getExpression ( ) ) . arg ( E . what ( ) ) . arg ( row ) . arg ( column ) ,
QMessageBox : : Ok | QMessageBox : : Cancel , QMessageBox : : Ok ) = = QMessageBox : : Ok ; */
}
}
return NAN ;
}