bool Statistics::algorithm() { KstVectorPtr data = inputVector(DATA); KstScalarPtr mean = outputScalar(MEAN); KstScalarPtr minimum = outputScalar(MINIMUM); KstScalarPtr maximum = outputScalar(MAXIMUM); KstScalarPtr variance = outputScalar(VARIANCE); KstScalarPtr standard_deviation = outputScalar(STANDARD_DEVIATION); KstScalarPtr median = outputScalar(MEDIAN); KstScalarPtr absolute_deviation = outputScalar(ABSOLUTE_DEVIATION); KstScalarPtr skewness = outputScalar(SKEWNESS); KstScalarPtr kurtosis = outputScalar(KURTOSIS); double* pCopy; double dMean = 0.0; double dMedian = 0.0; double dStandardDeviation = 0.0; double dTotal = 0.0; double dSquaredTotal = 0.0; double dMinimum = 0.0; double dMaximum = 0.0; double dVariance = 0.0; double dAbsoluteDeviation = 0.0; double dSkewness = 0.0; double dKurtosis = 0.0; int iLength; int iRetVal = false; if (data->length() > 0) { iLength = data->length(); for (int i=0; i<iLength; i++) { if (i == 0 || data->value()[i] < dMinimum) { dMinimum = data->value()[i]; } if (i == 0 || data->value()[i] > dMaximum) { dMaximum = data->value()[i]; } dTotal += data->value()[i]; dSquaredTotal += data->value()[i] * data->value()[i]; } dMean = dTotal / (double)iLength; if (iLength > 1) { dVariance = 1.0 / ( (double)iLength - 1.0 ); dVariance *= dSquaredTotal - ( dTotal * dTotal / (double)iLength ); if (dVariance > 0.0) { dStandardDeviation = sqrt( dVariance ); } else { dVariance = 0.0; dStandardDeviation = 0.0; } } for (int i=0; i<iLength; i++) { dAbsoluteDeviation += fabs( data->value()[i] - dMean ); dSkewness += pow( data->value()[i] - dMean, 3.0 ); dKurtosis += pow( data->value()[i] - dMean, 4.0 ); } dAbsoluteDeviation /= (double)iLength; dSkewness /= (double)iLength * pow( dStandardDeviation, 3.0 ); dKurtosis /= (double)iLength * pow( dStandardDeviation, 4.0 ); dKurtosis -= 3.0; /* sort by phase... */ pCopy = (double*)calloc( iLength, sizeof( double ) ); if (pCopy != NULL) { memcpy( pCopy, data->value(), iLength * sizeof( double ) ); quicksort( pCopy, 0, iLength-1 ); dMedian = pCopy[ iLength / 2 ]; free( pCopy ); } mean->setValue(dMean); minimum->setValue(dMinimum); maximum->setValue(dMaximum); variance->setValue(dVariance); standard_deviation->setValue(dStandardDeviation); median->setValue(dMedian); absolute_deviation->setValue(dAbsoluteDeviation); skewness->setValue(dSkewness); kurtosis->setValue(dKurtosis); iRetVal = true; } return iRetVal; }
KstObject::UpdateType KstCPlugin::update(int update_counter) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (!isValid()) { return setLastUpdateResult(NO_CHANGE); } if (recursed()) { return setLastUpdateResult(NO_CHANGE); } bool force = dirty(); setDirty(false); if (KstObject::checkUpdateCounter(update_counter) && !force) { return lastUpdateResult(); } #define CLEANUP() do {\ for (unsigned i = 0; i < _outStringCnt; ++i) { \ if (_outStrings[i]) { \ free(_outStrings[i]); \ _outStrings[i] = 0L; \ } \ } \ for (unsigned i = 0; i < _inStringCnt; ++i) { \ if (_inStrings[i]) { \ free(_inStrings[i]); \ _inStrings[i] = 0L; \ } \ } \ } while(0) writeLockInputsAndOutputs(); const QValueList<Plugin::Data::IOValue>& itable = _plugin->data()._inputs; const QValueList<Plugin::Data::IOValue>& otable = _plugin->data()._outputs; int itcnt = 0, vitcnt = 0, sitcnt = 0; bool doUpdate = force; // Populate the input scalars and vectors for (QValueList<Plugin::Data::IOValue>::ConstIterator it = itable.begin(); it != itable.end(); ++it) { if ((*it)._type == Plugin::Data::IOValue::TableType) { if (!_inputVectors.contains((*it)._name)) { KstDebug::self()->log(i18n("Input vector [%1] for plugin %2 not found. Unable to continue.").arg((*it)._name).arg(tagName()), KstDebug::Error); CLEANUP(); return setLastUpdateResult(NO_CHANGE); } KstVectorPtr iv = _inputVectors[(*it)._name]; if (!iv) { kstdFatal() << "Input vector \"" << (*it)._name << "\" for plugin " << tag().displayString() << " is invalid." << endl; } doUpdate = (UPDATE == iv->update(update_counter)) || doUpdate; _inVectors[vitcnt] = iv->value(); _inArrayLens[vitcnt++] = iv->length(); } else if ((*it)._type == Plugin::Data::IOValue::FloatType) { KstScalarPtr is = _inputScalars[(*it)._name]; if (!is) { kstdFatal() << "Input scalar \"" << (*it)._name << "\" for plugin " << tag().displayString() << " is invalid." << endl; } doUpdate = (UPDATE == is->update(update_counter)) || doUpdate; _inScalars[itcnt++] = is->value(); } else if ((*it)._type == Plugin::Data::IOValue::StringType) { KstStringPtr is = _inputStrings[(*it)._name]; if (!is) { kstdFatal() << "Input string \"" << (*it)._name << "\" for plugin " << tag().displayString() << " is invalid." << endl; } doUpdate = (UPDATE == is->update(update_counter)) || doUpdate; // Maybe we should use UTF-8 instead? _inStrings[sitcnt++] = strdup(is->value().latin1()); } else if ((*it)._type == Plugin::Data::IOValue::PidType) { _inScalars[itcnt++] = getpid(); } } if (!doUpdate) { CLEANUP(); unlockInputsAndOutputs(); return setLastUpdateResult(NO_CHANGE); } vitcnt = 0; // Populate the output vectors for (QValueList<Plugin::Data::IOValue>::ConstIterator it = otable.begin(); it != otable.end(); ++it) { if ((*it)._type == Plugin::Data::IOValue::TableType) { if (!_outputVectors.contains((*it)._name)) { KstDebug::self()->log(i18n("Output vector [%1] for plugin %2 not found. Unable to continue.").arg((*it)._name).arg(tagName()), KstDebug::Error); CLEANUP(); unlockInputsAndOutputs(); return setLastUpdateResult(NO_CHANGE); } _outVectors[vitcnt] = _outputVectors[(*it)._name]->value(); _outArrayLens[vitcnt++] = _outputVectors[(*it)._name]->length(); } } if (_outStringCnt > 0) { memset(_outStrings, 0, _outStringCnt*sizeof(char *)); } int rc; if (_inStringCnt > 0 || _outStringCnt > 0) { if (_plugin->data()._localdata) { rc = _plugin->call(_inVectors, _inArrayLens, _inScalars, _outVectors, _outArrayLens, _outScalars, const_cast<const char**>(_inStrings), _outStrings, &_localData); } else { rc = _plugin->call(_inVectors, _inArrayLens, _inScalars, _outVectors, _outArrayLens, _outScalars, const_cast<const char**>(_inStrings), _outStrings); } } else { if (_plugin->data()._localdata) { rc = _plugin->call(_inVectors, _inArrayLens, _inScalars, _outVectors, _outArrayLens, _outScalars, &_localData); } else { rc = _plugin->call(_inVectors, _inArrayLens, _inScalars, _outVectors, _outArrayLens, _outScalars); } } if (rc == 0) { itcnt = 0; vitcnt = 0; sitcnt = 0; setLastUpdateResult(UPDATE); // make sure that provider callbacks work // Read back the output vectors and scalars for (QValueList<Plugin::Data::IOValue>::ConstIterator it = otable.begin(); it != otable.end(); ++it) { if ((*it)._type == Plugin::Data::IOValue::TableType) { KstVectorPtr vp = _outputVectors[(*it)._name]; vectorRealloced(vp, _outVectors[vitcnt], _outArrayLens[vitcnt]); vp->setDirty(); // Inefficient, but do we have any other choice? We don't really know // from the plugin how much of this vector is "new" or "shifted" vp->setNewAndShift(vp->length(), vp->numShift()); vp->update(update_counter); vitcnt++; } else if ((*it)._type == Plugin::Data::IOValue::FloatType) { KstScalarPtr sp = _outputScalars[(*it)._name]; sp->setValue(_outScalars[itcnt++]); sp->update(update_counter); } else if ((*it)._type == Plugin::Data::IOValue::StringType) { KstStringPtr sp = _outputStrings[(*it)._name]; sp->setValue(_outStrings[sitcnt++]); sp->update(update_counter); } } // if we have a fit plugin then create the necessary scalars from the parameter vector createFitScalars(); _lastError = QString::null; } else if (rc > 0) { if (_lastError.isEmpty()) { const char *err = _plugin->errorCode(rc); if (err && *err) { _lastError = err; KstDebug::self()->log(i18n("Plugin %1 produced error: %2.").arg(tagName()).arg(_lastError), KstDebug::Error); } else { _lastError = QString::null; } } } else { bool doSend = _lastError.isEmpty() ? true : false; switch (rc) { case -1: _lastError = i18n("Generic Error"); break; case -2: _lastError = i18n("Input Error"); break; case -3: _lastError = i18n("Memory Error"); break; default: _lastError = i18n("Unknown Error"); break; } if (doSend) { KstDebug::self()->log(i18n("Plugin %2 produced error: %1.").arg(_lastError).arg(tagName()), KstDebug::Error); } } unlockInputsAndOutputs(); CLEANUP(); #undef CLEANUP return setLastUpdateResult(UPDATE); }
void doTests() { KstScalarPtr sp = new KstScalar; doTest(!sp->tagName().isEmpty()); doTest(sp->value() == 0.0); *sp = 3.1415; doTest(sp->displayable()); doTest(sp->value() == 3.1415); sp->setValue(2.1415); doTest(sp->value() == 2.1415); sp->setValue(NOPOINT); doTest(sp->value() != sp->value()); sp->setValue(INF); doTest(sp->value() == INF); doTest((*sp = 2.0).value() == 2.0); SListener *listener = new SListener; sp->connect(sp, SIGNAL(trigger()), listener, SLOT(trigger())); *sp = 3.1415; doTest(listener->_trigger == 1); sp->setValue(3.1415); doTest(listener->_trigger == 2); *sp = 1.1415; doTest(listener->_trigger == 3); KstScalarPtr sp2 = new KstScalar(sp->tagName()); doTest(sp2->tagName() == sp->tagName() + "'"); doTest(sp->isGlobal()); doTest(sp2->isGlobal()); doTest(sp->displayable()); doTest(sp2->displayable()); QDomNode n; QDomElement e; n = makeDOM1("load1", "2.14159265").firstChild(); e = n.toElement(); KstScalarPtr sp3 = new KstScalar(e); doTest(sp3->orphan() == false); doTest(sp3->value() == 2.14159265); doTest(sp3->tagName() == "load1"); doTest(sp3->isGlobal()); doTest(sp3->displayable()); n = makeDOM1("55.4232", "55.4232", true).firstChild(); e = n.toElement(); KstScalarPtr sp4 = new KstScalar(e); doTest(sp4->orphan()); doTest(sp4->value() == 55.4232); doTest(sp4->tagName() == "55.4232"); doTest(sp4->isGlobal()); doTest(!sp4->displayable()); n = makeDOM1("load2", "NAN").firstChild(); e = n.toElement(); sp4 = new KstScalar(e); doTest(sp4->value() != sp4->value()); n = makeDOM1("load3", "INF").firstChild(); e = n.toElement(); sp4 = new KstScalar(e); doTest(sp4->value() == INF); n = makeDOM1("load4", "-INF").firstChild(); e = n.toElement(); sp4 = new KstScalar(e); doTest(sp4->value() == -INF); delete listener; }