00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "liboutputfunctions.h"
00021 #include "cluster.h"
00022 #include <QStringList>
00023 #include <QRegExp>
00024 #include <cmath>
00025
00026 namespace farsa {
00027
00028 IdentityFunction::IdentityFunction()
00029 : OutputFunction() {
00030 }
00031
00032 void IdentityFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00033 outputs.copyValues( inputs );
00034 }
00035
00036 bool IdentityFunction::derivate( const DoubleVector&, const DoubleVector&, DoubleVector& derivates ) const {
00037 derivates.setAll( 1.0 );
00038 return true;
00039 }
00040
00041 void IdentityFunction::configure(ConfigurationParameters& params, QString prefix)
00042 {
00043 ((void)params);
00044 ((void)prefix);
00045
00046 }
00047
00048 void IdentityFunction::save(ConfigurationParameters& params, QString prefix)
00049 {
00050
00051 params.startObjectParameters(prefix, "IdentityFunction", this);
00052 }
00053
00054 ScaleFunction::ScaleFunction( double rate )
00055 : OutputFunction() {
00056 this->rate = rate;
00057 }
00058
00059 void ScaleFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00060 mul( outputs, rate, inputs );
00061 }
00062
00063 bool ScaleFunction::derivate( const DoubleVector&, const DoubleVector&, DoubleVector& derivates ) const {
00064 derivates.setAll( rate );
00065 return true;
00066 }
00067
00068 void ScaleFunction::configure(ConfigurationParameters& params, QString prefix)
00069 {
00070 rate = 1.0;
00071 QString str = params.getValue(prefix + "rate");
00072 if (!str.isEmpty()) {
00073 bool ok;
00074 rate = str.toDouble(&ok);
00075 if (!ok) {
00076 rate = 1.0;
00077 }
00078 }
00079 }
00080
00081 void ScaleFunction::save(ConfigurationParameters& params, QString prefix)
00082 {
00083 params.startObjectParameters(prefix, "ScaleFunction", this);
00084 params.createParameter(prefix, "rate", QString::number(rate));
00085 }
00086
00087 GainFunction::GainFunction( double gain )
00088 : OutputFunction() {
00089 gainv = gain;
00090 }
00091
00092 void GainFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00093 outputs.copyValues( inputs );
00094 outputs += gainv;
00095 }
00096
00097 bool GainFunction::derivate( const DoubleVector&, const DoubleVector&, DoubleVector& derivates ) const {
00098 derivates.setAll( 1.0 );
00099 return true;
00100 }
00101
00102 void GainFunction::configure(ConfigurationParameters& params, QString prefix)
00103 {
00104 gainv = 1.0;
00105 QString str = params.getValue(prefix + "gain");
00106 if (!str.isEmpty()) {
00107 bool ok;
00108 gainv = str.toDouble(&ok);
00109 if (!ok) {
00110 gainv = 1.0;
00111 }
00112 }
00113 }
00114
00115 void GainFunction::save(ConfigurationParameters& params, QString prefix)
00116 {
00117 params.startObjectParameters(prefix, "GainFunction", this);
00118 params.createParameter(prefix, "gain", QString::number(gainv));
00119 }
00120
00121 SigmoidFunction::SigmoidFunction( double l ) : OutputFunction() {
00122 lambda = l;
00123 }
00124
00125 void SigmoidFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00126
00127
00128 inv( exp( mul( outputs, -lambda, inputs ) ) += 1.0 );
00129 }
00130
00131 bool SigmoidFunction::derivate( const DoubleVector&, const DoubleVector& outputs, DoubleVector& derivates ) const {
00132
00133 subtract( derivates, 1.0, outputs );
00134 derivates *= outputs;
00135 derivates *= lambda;
00136 return true;
00137 }
00138
00139 void SigmoidFunction::configure(ConfigurationParameters& params, QString prefix)
00140 {
00141 lambda = 1.0;
00142 QString str = params.getValue(prefix + "lambda");
00143 if (!str.isEmpty()) {
00144 bool ok;
00145 lambda = str.toDouble(&ok);
00146 if (!ok) {
00147 lambda = 1.0;
00148 }
00149 }
00150 }
00151
00152 void SigmoidFunction::save(ConfigurationParameters& params, QString prefix)
00153 {
00154 params.startObjectParameters(prefix, "SigmoidFunction", this);
00155 params.createParameter(prefix, "lambda", QString::number(lambda));
00156 }
00157
00158 FakeSigmoidFunction::FakeSigmoidFunction( double l )
00159 : OutputFunction() {
00160 lambda = l;
00161 }
00162
00163 void FakeSigmoidFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00164 unsigned int size = inputs.size();
00165 double x;
00166 double x0 = 6. + 2./3.;
00167 double zero = 0.5;
00168 for ( unsigned int i = 0; i<size; i++ ) {
00169 x = inputs[i];
00170 x *= lambda;
00171 x -= (.5 - zero) / (.075 + zero);
00172 if ( x <= -x0 ) {
00173 outputs[i] = 0.0;
00174 } else {
00175 if ( x < x0 ) {
00176 outputs[i] = .5 + .575 * x / ( 1.0 + fabs(x) );
00177 } else {
00178 outputs[i] = 1.0;
00179 }
00180 }
00181 }
00182 }
00183
00184 bool FakeSigmoidFunction::derivate( const DoubleVector&, const DoubleVector& outputs, DoubleVector& derivates ) const {
00185
00186 subtract( derivates, 1.0, outputs );
00187 derivates *= outputs;
00188 derivates *= lambda;
00189 return true;
00190 }
00191
00192 void FakeSigmoidFunction::configure(ConfigurationParameters& params, QString prefix)
00193 {
00194 lambda = 1.0;
00195 QString str = params.getValue(prefix + "lambda");
00196 if (!str.isEmpty()) {
00197 bool ok;
00198 lambda = str.toDouble(&ok);
00199 if (!ok) {
00200 lambda = 1.0;
00201 }
00202 }
00203 }
00204
00205 void FakeSigmoidFunction::save(ConfigurationParameters& params, QString prefix)
00206 {
00207 params.startObjectParameters(prefix, "FakeSigmoidFunction", this);
00208 params.createParameter(prefix, "lambda", QString::number(lambda));
00209 }
00210
00211 ScaledSigmoidFunction::ScaledSigmoidFunction( double l, double min, double max )
00212 : OutputFunction() {
00213 lambda = l;
00214 this->min = min;
00215 this->max = max;
00216 }
00217
00218 void ScaledSigmoidFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00219
00220
00221
00222 inv( exp( mul( outputs, -lambda, inputs ) ) += 1.0 );
00223
00224 outputs *= max-min;
00225 outputs += min;
00226 }
00227
00228 bool ScaledSigmoidFunction::derivate( const DoubleVector&, const DoubleVector& outputs, DoubleVector& derivates ) const {
00229
00230 subtract( derivates, 1.0, outputs );
00231 derivates *= outputs;
00232 derivates *= lambda;
00233 return true;
00234 }
00235
00236 void ScaledSigmoidFunction::configure(ConfigurationParameters& params, QString prefix)
00237 {
00238 lambda = 1.0;
00239 QString str = params.getValue(prefix + "lambda");
00240 if (!str.isEmpty()) {
00241 bool ok;
00242 lambda = str.toDouble(&ok);
00243 if (!ok) {
00244 lambda = 1.0;
00245 }
00246 }
00247
00248 min = -1.0;
00249 str = params.getValue(prefix + "min");
00250 if (!str.isEmpty()) {
00251 bool ok;
00252 min = str.toDouble(&ok);
00253 if (!ok) {
00254 min = -1.0;
00255 }
00256 }
00257
00258 max = 1.0;
00259 str = params.getValue(prefix + "max");
00260 if (!str.isEmpty()) {
00261 bool ok;
00262 max = str.toDouble(&ok);
00263 if (!ok) {
00264 max = 1.0;
00265 }
00266 }
00267 }
00268
00269 void ScaledSigmoidFunction::save(ConfigurationParameters& params, QString prefix)
00270 {
00271 params.startObjectParameters(prefix, "ScaledSigmoidFunction", this);
00272 params.createParameter(prefix, "lambda", QString::number(lambda));
00273 params.createParameter(prefix, "min", QString::number(min));
00274 params.createParameter(prefix, "max", QString::number(max));
00275 }
00276
00277 RampFunction::RampFunction()
00278 : OutputFunction() {
00279 min_x = 0.0;
00280 max_x = 0.0;
00281 min_y = 0.0;
00282 max_y = 0.0;
00283 }
00284
00285 RampFunction::RampFunction( double minX, double maxX, double minY, double maxY )
00286 : OutputFunction() {
00287 min_x = minX;
00288 max_x = maxX;
00289 min_y = minY;
00290 max_y = maxY;
00291 }
00292
00293 void RampFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00294 unsigned int size = inputs.size();
00295 double m = ( max_y-min_y )/( max_x-min_x );
00296 double q = min_y - m*min_x;
00297 for ( unsigned int i = 0; i<size; i++ ) {
00298 double ret = m*(inputs[i]) + q;
00299 if (ret < min_y) {
00300 outputs[i] = min_y;
00301 } else if (ret > max_y) {
00302 outputs[i] = max_y;
00303 } else {
00304 outputs[i] = ret;
00305 }
00306 }
00307 }
00308
00309 bool RampFunction::derivate( const DoubleVector& inputs, const DoubleVector&, DoubleVector& derivates ) const {
00310 for( unsigned int i=0; i<inputs.size(); i++ ) {
00311 if ( inputs[i] >= min_x && inputs[i] <= max_x ) {
00312 derivates[i] = ( max_y-min_y )/( max_x-min_x );
00313 } else {
00314 double y;
00315 y = 1.0/( 1.0 + std::exp( -inputs[i] ) );
00316 derivates[i] = y * ( 1.0 - y );
00317 }
00318 }
00319 return true;
00320 }
00321
00322 void RampFunction::configure(ConfigurationParameters& params, QString prefix)
00323 {
00324 min_x = 0.0;
00325 QString str = params.getValue(prefix + "minX");
00326 if (!str.isEmpty()) {
00327 bool ok;
00328 min_x = str.toDouble(&ok);
00329 if (!ok) {
00330 min_x = 0.0;
00331 }
00332 }
00333
00334 max_x = 0.0;
00335 str = params.getValue(prefix + "maxX");
00336 if (!str.isEmpty()) {
00337 bool ok;
00338 max_x = str.toDouble(&ok);
00339 if (!ok) {
00340 max_x = 0.0;
00341 }
00342 }
00343
00344 min_y = 0.0;
00345 str = params.getValue(prefix + "minY");
00346 if (!str.isEmpty()) {
00347 bool ok;
00348 min_y = str.toDouble(&ok);
00349 if (!ok) {
00350 min_y = 0.0;
00351 }
00352 }
00353
00354 max_y = 0.0;
00355 str = params.getValue(prefix + "maxY");
00356 if (!str.isEmpty()) {
00357 bool ok;
00358 max_y = str.toDouble(&ok);
00359 if (!ok) {
00360 max_y = 0.0;
00361 }
00362 }
00363 }
00364
00365 void RampFunction::save(ConfigurationParameters& params, QString prefix)
00366 {
00367 params.startObjectParameters(prefix, "RampFunction", this);
00368 params.createParameter(prefix, "minX", QString::number(min_x));
00369 params.createParameter(prefix, "maxX", QString::number(max_x));
00370 params.createParameter(prefix, "minY", QString::number(min_y));
00371 params.createParameter(prefix, "maxY", QString::number(max_y));
00372 }
00373
00374 LinearFunction::LinearFunction()
00375 : OutputFunction() {
00376 m = 0.0;
00377 b = 0.0;
00378 }
00379
00380 LinearFunction::LinearFunction( double m, double b )
00381 : OutputFunction() {
00382 this->m = m;
00383 this->b = b;
00384 }
00385
00386 void LinearFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00387 mul( outputs, m, inputs ) += b;
00388 }
00389
00390 bool LinearFunction::derivate( const DoubleVector& , const DoubleVector&, DoubleVector& derivates ) const {
00391 derivates.setAll( m );
00392 return true;
00393 }
00394
00395 void LinearFunction::configure(ConfigurationParameters& params, QString prefix)
00396 {
00397 m = 0.0;
00398 QString str = params.getValue(prefix + "m");
00399 if (!str.isEmpty()) {
00400 bool ok;
00401 m = str.toDouble(&ok);
00402 if (!ok) {
00403 m = 0.0;
00404 }
00405 }
00406
00407 b = 0.0;
00408 str = params.getValue(prefix + "b");
00409 if (!str.isEmpty()) {
00410 bool ok;
00411 b = str.toDouble(&ok);
00412 if (!ok) {
00413 b = 0.0;
00414 }
00415 }
00416 }
00417
00418 void LinearFunction::save(ConfigurationParameters& params, QString prefix)
00419 {
00420 params.startObjectParameters(prefix, "LinearFunction", this);
00421 params.createParameter(prefix, "m", QString::number(m));
00422 params.createParameter(prefix, "b", QString::number(b));
00423 }
00424
00425 StepFunction::StepFunction( double min, double max, double threshold )
00426 : OutputFunction() {
00427 this->min = min;
00428 this->max = max;
00429 this->threshold = threshold;
00430 }
00431
00432 void StepFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00433 unsigned int size = inputs.size();
00434 for ( unsigned int i = 0; i<size; i++ ) {
00435 ( inputs[i] > threshold ) ? outputs[i] = max : outputs[i] = min;
00436 }
00437 }
00438
00439 bool StepFunction::derivate( const DoubleVector& inputs, const DoubleVector&, DoubleVector& derivates ) const {
00440
00441 for( unsigned int i=0; i<inputs.size(); i++ ) {
00442 double y;
00443 y = 1.0/( 1.0 + std::exp( -inputs[i] ) );
00444 derivates[i] = y * ( 1.0 - y );
00445 }
00446 return true;
00447 }
00448
00449 void StepFunction::configure(ConfigurationParameters& params, QString prefix)
00450 {
00451 min = 0.0;
00452 QString str = params.getValue(prefix + "min");
00453 if (!str.isEmpty()) {
00454 bool ok;
00455 min = str.toDouble(&ok);
00456 if (!ok) {
00457 min = 0.0;
00458 }
00459 }
00460
00461 max = 1.0;
00462 str = params.getValue(prefix + "max");
00463 if (!str.isEmpty()) {
00464 bool ok;
00465 max = str.toDouble(&ok);
00466 if (!ok) {
00467 max = 1.0;
00468 }
00469 }
00470
00471 threshold = 0.0;
00472 str = params.getValue(prefix + "threshold");
00473 if (!str.isEmpty()) {
00474 bool ok;
00475 threshold = str.toDouble(&ok);
00476 if (!ok) {
00477 threshold = 0.0;
00478 }
00479 }
00480 }
00481
00482 void StepFunction::save(ConfigurationParameters& params, QString prefix)
00483 {
00484 params.startObjectParameters(prefix, "StepFunction", this);
00485 params.createParameter(prefix, "min", QString::number(min));
00486 params.createParameter(prefix, "max", QString::number(max));
00487 params.createParameter(prefix, "threshold", QString::number(threshold));
00488 }
00489
00490 LeakyIntegratorFunction::LeakyIntegratorFunction()
00491 : OutputFunction(), delta(), outprev()
00492 {
00493 }
00494
00495 LeakyIntegratorFunction::LeakyIntegratorFunction( const DoubleVector& d )
00496 : OutputFunction(), delta(d.size()), outprev(d.size()) {
00497 delta.copyValues( d );
00498 outprev.zeroing();
00499 }
00500
00501 void LeakyIntegratorFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00502
00503
00504
00505 outputs = subtract( outputs, outprev, inputs );
00506 outputs *= delta;
00507 outputs += inputs;
00508 outprev.copyValues( outputs );
00509 }
00510
00511 void LeakyIntegratorFunction::zeroingStatus() {
00512 outprev.zeroing();
00513 }
00514
00515 void LeakyIntegratorFunction::clusterSetted() {
00516 if ( clusterv->numNeurons() != delta.size() ) {
00517 delta.resize( clusterv->numNeurons() );
00518 outprev.resize( clusterv->numNeurons() );
00519 }
00520 }
00521
00522 void LeakyIntegratorFunction::configure(ConfigurationParameters& params, QString prefix)
00523 {
00524
00525 QString str = params.getValue(prefix + "delta");
00526 if (!str.isEmpty()) {
00527 QStringList list = str.split(QRegExp("\\s+"), QString::SkipEmptyParts);
00528 delta.resize(list.size());
00529 for( int i = 0; i < list.size(); i++) {
00530 bool ok;
00531 delta[i] = list[i].toDouble(&ok);
00532 if (!ok) {
00533 delta[i] = 0.0;
00534 }
00535 }
00536 }
00537
00538
00539 str = params.getValue(prefix + "outprev");
00540 if (!str.isEmpty()) {
00541 QStringList list = str.split(QRegExp("\\s+"), QString::SkipEmptyParts);
00542 outprev.resize(list.size());
00543 for( int i = 0; i < list.size(); i++) {
00544 bool ok;
00545 outprev[i] = list[i].toDouble(&ok);
00546 if (!ok) {
00547 outprev[i] = 0.0;
00548 }
00549 }
00550 }
00551 outprev.resize(delta.size());
00552 }
00553
00554 void LeakyIntegratorFunction::save(ConfigurationParameters& params, QString prefix)
00555 {
00556 params.startObjectParameters(prefix, "LeakyIntegratorFunction", this);
00557
00558
00559 QStringList list;
00560 for (unsigned int i = 0; i < delta.size(); i++) {
00561 list.push_back(QString::number(delta[i]));
00562 }
00563 params.createParameter(prefix, "delta", list.join(" "));
00564
00565
00566 list.clear();
00567 for (unsigned int i = 0; i < delta.size(); i++) {
00568 list.push_back(QString::number(outprev[i]));
00569 }
00570 params.createParameter(prefix, "outprev", list.join(" "));
00571 }
00572
00573 LogLikeFunction::LogLikeFunction( double A, double B )
00574 : OutputFunction() {
00575 this->A = A;
00576 this->B = B;
00577 }
00578
00579 void LogLikeFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00580
00581 outputs = inv( mul( outputs, A, inputs ) += (1.0+B) );
00582 outputs *= inputs;
00583 }
00584
00585 void LogLikeFunction::configure(ConfigurationParameters& params, QString prefix)
00586 {
00587 A = 1.0;
00588 QString str = params.getValue(prefix + "A");
00589 if (!str.isEmpty()) {
00590 bool ok;
00591 A = str.toDouble(&ok);
00592 if (!ok) {
00593 A = 1.0;
00594 }
00595 }
00596
00597 B = 5.0;
00598 str = params.getValue(prefix + "B");
00599 if (!str.isEmpty()) {
00600 bool ok;
00601 B = str.toDouble(&ok);
00602 if (!ok) {
00603 B = 5.0;
00604 }
00605 }
00606 }
00607
00608 void LogLikeFunction::save(ConfigurationParameters& params, QString prefix)
00609 {
00610 params.startObjectParameters(prefix, "LogLikeFunction", this);
00611 params.createParameter(prefix, "A", QString::number(A));
00612 params.createParameter(prefix, "B", QString::number(B));
00613 }
00614
00615 CompositeFunction::CompositeFunction()
00616 : OutputFunction(), first(), second(), mid() {
00617 }
00618
00619 CompositeFunction::CompositeFunction( OutputFunction *f, OutputFunction *g )
00620 : OutputFunction(), first(f), second(g), mid() {
00621 }
00622
00623 CompositeFunction::~CompositeFunction() {
00624
00625 }
00626
00627 void CompositeFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00628 first->apply( inputs, mid );
00629 second->apply( mid, outputs );
00630 }
00631
00632 bool CompositeFunction::setFirstFunction( OutputFunction *f ) {
00633 first.reset(f);
00634 first->setCluster( clusterv );
00635 return true;
00636 }
00637
00638 OutputFunction* CompositeFunction::getFirstFunction() {
00639 return first.get();
00640 }
00641
00642 bool CompositeFunction::setSecondFunction( OutputFunction *g ) {
00643 second.reset(g);
00644 second->setCluster( clusterv );
00645 return true;
00646 }
00647
00648 OutputFunction* CompositeFunction::getSecondFunction() {
00649 return second.get();
00650 }
00651
00652 void CompositeFunction::clusterSetted() {
00653 mid.resize( clusterv->numNeurons() );
00654 first->setCluster( clusterv );
00655 second->setCluster( clusterv );
00656 }
00657
00658 void CompositeFunction::configure(ConfigurationParameters& params, QString prefix)
00659 {
00660
00661
00662 first.reset(params.getObjectFromParameter<OutputFunction>(prefix + "first", false, false));
00663 second.reset(params.getObjectFromParameter<OutputFunction>(prefix + "second", false, false));
00664
00665
00666
00667 }
00668
00669 void CompositeFunction::save(ConfigurationParameters& params, QString prefix)
00670 {
00671 params.startObjectParameters(prefix, "CompositeFunction", this);
00672 params.createParameter(prefix, "first", first.get());
00673 params.createParameter(prefix, "second", second.get());
00674
00675
00676
00677 }
00678
00679 LinearComboFunction::LinearComboFunction()
00680 : OutputFunction(), first(), second(), mid()
00681 {
00682 this->w1 = 0.0;
00683 this->w2 = 0.0;
00684 }
00685
00686 LinearComboFunction::LinearComboFunction( double w1, OutputFunction *f, double w2, OutputFunction *g )
00687 : OutputFunction(), first(f), second(g), mid() {
00688 this->w1 = w1;
00689 this->w2 = w2;
00690 }
00691
00692 LinearComboFunction::~LinearComboFunction() {
00693
00694 }
00695
00696 void LinearComboFunction::apply( DoubleVector& inputs, DoubleVector& outputs ) {
00697 first->apply( inputs, mid );
00698 mid *= w1;
00699 second->apply( inputs, outputs );
00700 outputs *= w2;
00701 outputs += mid;
00702 }
00703
00704 bool LinearComboFunction::setFirstFunction( OutputFunction *f ) {
00705 first.reset(f);
00706 first->setCluster( clusterv );
00707 return true;
00708 }
00709
00710 OutputFunction* LinearComboFunction::getFirstFunction() {
00711 return first.get();
00712 }
00713
00714 bool LinearComboFunction::setFirstWeight( double v ) {
00715 w1 = v;
00716 return true;
00717 }
00718
00719 double LinearComboFunction::getFirstWeight() {
00720 return w1;
00721 }
00722
00723 bool LinearComboFunction::setSecondFunction( OutputFunction *g ) {
00724 second.reset(g);
00725 second->setCluster( clusterv );
00726 return true;
00727 }
00728
00729 OutputFunction* LinearComboFunction::getSecondFunction() {
00730 return second.get();
00731 }
00732
00733 bool LinearComboFunction::setSecondWeight( double v ) {
00734 w2 = v;
00735 return true;
00736 }
00737
00738 double LinearComboFunction::getSecondWeight() {
00739 return w2;
00740 }
00741
00742 void LinearComboFunction::clusterSetted() {
00743 mid.resize( clusterv->numNeurons() );
00744 first->setCluster( clusterv );
00745 second->setCluster( clusterv );
00746 }
00747
00748 void LinearComboFunction::configure(ConfigurationParameters& params, QString prefix)
00749 {
00750
00751
00752 first.reset(params.getObjectFromParameter<OutputFunction>(prefix + "first", false, false));
00753
00754 w1 = 0.0;
00755 QString str = params.getValue(prefix + "w1");
00756 if (!str.isEmpty()) {
00757 bool ok;
00758 w1 = str.toDouble(&ok);
00759 if (!ok) {
00760 w1 = 0.0;
00761 }
00762 }
00763
00764 second.reset(params.getObjectFromParameter<OutputFunction>(prefix + "second", false, false));
00765
00766 w2 = 0.0;
00767 str = params.getValue(prefix + "w2");
00768 if (!str.isEmpty()) {
00769 bool ok;
00770 w2 = str.toDouble(&ok);
00771 if (!ok) {
00772 w2 = 0.0;
00773 }
00774 }
00775
00776
00777
00778 }
00779
00780 void LinearComboFunction::save(ConfigurationParameters& params, QString prefix)
00781 {
00782 params.startObjectParameters(prefix, "LinearComboFunction", this);
00783 params.createParameter(prefix, "first", first.get());
00784 params.createParameter(prefix, "w1", QString::number(w1));
00785 params.createParameter(prefix, "second", second.get());
00786 params.createParameter(prefix, "w2", QString::number(w2));
00787
00788
00789
00790 }
00791
00792 }