// separator is a string containing the symbol/character separating entries // and replace contains a separator-separated list of characters to replace // by the separator beforehand QList<double> DynamicsPlotterUtil::getDoublesFromString(const QString &list, const QString &separator, const QString &replace) { QString tmp(list); if(!replace.isEmpty()) { QStringList replist = replace.split(separator, QString::SkipEmptyParts); for(int i = 0; i < replist.size(); ++i) { tmp.replace(replist.at(i), separator); } } QStringList doublelist = tmp.split(separator, QString::SkipEmptyParts); QList<double> output; bool ok; for(int i = 0; i < doublelist.size(); ++i) { double d = doublelist.at(i).toDouble(&ok); if(!ok) { reportProblem("DynamicsPlotterUtil::getDoublesFromString : " "Unable to convert ["+doublelist.at(i)+"] to double"); return QList<double>(); } output.append(d); } return output; }
static int loadCoreLibrary (JNIEnv *env) { if (coreHandle) return 1; if ((coreHandle = dlopen("libbrltty_core.so", RTLD_NOW | RTLD_GLOBAL))) { int allFound = 1; const SymbolEntry *symbol = symbolTable; while (symbol->name) { const void **pointer = symbol->pointer; if ((*pointer = dlsym(coreHandle, symbol->name))) { LOG("core symbol: %s -> %p", symbol->name, *pointer); } else { LOG("core symbol not found: %s", symbol->name); allFound = 0; } symbol += 1; } if (allFound) return 1; } reportProblem(env, "java/lang/UnsatisfiedLinkError", "%s", dlerror()); return 0; }
/** * * The neuronsWithActivationChange parameter can be used to collect all DoubelValues that correspond * to activation values of neurons. These neurons have to be collected in each DymnamcisPlotter in * variable DynamcisPlotter::mNeuronsWithActivationsToTransfer to be handled correctly, if the * activation of a neuron should be varied during an analyzer run. Otherwise the varied activations * are immediately overwritten by the newly calculated activations at the first network update. * * If this method is used to collect elements that will NOT be changed during analyzer runs, * then the last parameter MUST be empty. Othewise activations of neurons collected in this way * will be treated differently compared to the other neurons in the network. This may lead to * unexpected and erroneous behavior. * * @param specifier the specification of the desired DoubleValue object. * @param networkElements the list of objects that are considered to find the specified DoubleValue object. * @param neuronsWithActivationChange (optional) list to collect all activation values that are going to be changed during a run. */ DoubleValue* DynamicsPlotterUtil::getElementValue(QString const &specifier, QList<NeuralNetworkElement*> const &networkElements, QList<Neuron*> *neuronsWithActivationChange) { if(specifier.isEmpty()) { reportProblem("DynamicsPlotterUtil::getElementValue(2) : " "Empty specifier!"); return 0; } QStringList specifierParts = specifier.split(":"); if(specifierParts.size() < 2 || specifierParts.size() > 3) { reportProblem("DynamicsPlotterUtil::getElementValue(2) : " "Invalid specifier ["+specifier+"]!"); return 0; } bool idValid; QString idString = specifierParts.first(); QString parameter = specifier; parameter = parameter.remove(0, idString.size()+1); qulonglong id = idString.toULongLong(&idValid); if(!idValid) { reportProblem("DynamicsPlotterUtil::getElementValue(2) : " "Invalid ID ["+idString+"]!"); return 0; } NeuralNetworkElement* networkElement; networkElement = NeuralNetwork::selectNetworkElementById(id, networkElements); if(networkElement == 0) { reportProblem("DynamicsPlotterUtil::getElementValue(2) : " "No element with ID ["+idString+"] " "found in given list!"); return 0; } DoubleValue* elementValue; elementValue = getElementValue(parameter, networkElement, neuronsWithActivationChange); if(elementValue == 0) { reportProblem("DynamicsPlotterUtil::getElementValue(2) : " "Could not find specified parameter value at element!"); return 0; } return elementValue; }
double DynamicsPlotterUtil::getDistance(const QList<double> &state1, const QList<double> &state2) { if(state1.size() != state2.size()) { reportProblem("DynamicsPlotterUtil::getDistance : State dimensions do not match."); return 0; } double sum = 0; for(int i = 0; i < state1.size(); ++i) { sum += pow(state1.at(i)-state2.at(i),2); } return sqrt(sum); }
QList<double> DynamicsPlotterUtil::getNeuronActivations(NeuralNetwork* network) { if(network == 0) { reportProblem("DynamicsPlotterUtil::getNeuronActivations : No network"); return QList<double>(); } QList<double> activations; QList<Neuron*> neurons = network->getNeurons(); for(int n = 0; n < neurons.size(); ++n) { activations.append(neurons.at(n)->getLastActivation()); } return activations; }
double DynamicsPlotterUtil::getMeanValue(const QList<DoubleValue*> &valuesList) { if(valuesList.isEmpty()) { reportProblem("DynamicsPlotterUtil::getMeanValue : Empty list. Nothing to do."); return 0; } int nrValues = valuesList.size(); double meanValue = 0; for(int currVal = 0; currVal < nrValues; ++currVal) { DoubleValue* dVal = valuesList.at(currVal); if(dVal == 0) { reportProblem("DynamicsPlotterUtil::getMeanValue : Encountered NULL element."); return 0; } meanValue += dVal->get(); } return meanValue / nrValues; }
QList<double> DynamicsPlotterUtil::getMeanValues(const QList< QList<DoubleValue*> > &valuesListList) { QList<double> meanValues, emptyList; emptyList = QList<double>(); if(valuesListList.isEmpty()) { reportProblem("DynamicsPlotterUtil::getMeanValues : Empty list. Nothing to do."); return emptyList; } for(int currList = 0; currList < valuesListList.size(); ++currList) { meanValues.append(getMeanValue(valuesListList.at(currList))); } return meanValues; }
bool DynamicsPlotterUtil::compareNetworkStates(const QList<double> &state1, const QList<double> &state2, double accuracy) { if(state1.size() != state2.size()) { reportProblem("DynamicsPlotterUtil: Cannot compare network states, they " "appear to be from different networks"); return false; } for(int i = 0; i < state1.size(); ++i) { if(!Math::compareDoubles(state1.at(i), state2.at(i), accuracy) ) { return false; } } return true; }
static int loadCoreLibrary (JNIEnv *env) { if (coreHandle) return 1; if ((coreHandle = dlopen("libbrltty_core.so", RTLD_NOW | RTLD_GLOBAL))) { const SymbolEntry *symbol = symbolTable; while (symbol->name) { const void **pointer = symbol->pointer; if (!(*pointer = dlsym(coreHandle, symbol->name))) goto error; symbol += 1; } return 1; } error: reportProblem(env, "java/lang/UnsatisfiedLinkError", "%s", dlerror()); return 0; }
void BasinPlotter::calculateData() { // get program core Core *core = Core::getInstance(); // get network ModularNeuralNetwork *network = getCurrentNetwork(); if(network == 0) { Core::log("BasinPlotter: Could not find a neural network to work with! Aborting.", true); return; } QList<NeuralNetworkElement*> networkElements; network->getNetworkElements(networkElements); QList<DoubleValue*> networkValues = DynamicsPlotterUtil::getNetworkValues(networkElements); // Get parameters for varied elements QString variedX = mVariedX->get(); QString variedY = mVariedY->get(); if(variedX.isEmpty() || variedY.isEmpty()) { reportProblem("BasinPlotter: No elements to vary."); return; } DoubleValue *variedValX = DynamicsPlotterUtil::getElementValue( variedX, networkElements, &mNeuronsWithActivationsToTransfer); DoubleValue *variedValY = DynamicsPlotterUtil::getElementValue( variedY, networkElements, &mNeuronsWithActivationsToTransfer); if(variedValX == 0 || variedValY == 0) { reportProblem("BasinPlotter: NULL pointer for varied element. Aborting."); return; } QList<double> variedRangeX = DynamicsPlotterUtil::getDoublesFromString(mVariedRangeX->get()); QList<double> variedRangeY = DynamicsPlotterUtil::getDoublesFromString(mVariedRangeY->get()); if(variedRangeX.size() != 2 || variedRangeY.size() != 2) { reportProblem("BasinPlotter: Not a valid range given."); return; } int resolutionX = mResolutionX->get(); int resolutionY = mResolutionY->get(); //avoid division by zero! if(resolutionX < 2 || resolutionY < 2) { reportProblem("BasinPlotter: Invalid resolution given."); return; } // projected elements int nrProjections = 0; QString projectionsX = mProjectionsX->get(); QString projectionsY = mProjectionsY->get(); QList< QList<DoubleValue*> > projectionValuesX; QList< QList<DoubleValue*> > projectionValuesY; QList<double> projectionRangesX; QList<double> projectionRangesY; if(projectionsX != "0" && projectionsY != "0") { QList<QStringList> projectionListX = DynamicsPlotterUtil::parseElementString(projectionsX); QList<QStringList> projectionListY = DynamicsPlotterUtil::parseElementString(projectionsY); projectionValuesX = DynamicsPlotterUtil::getElementValues(projectionListX, networkElements); projectionValuesY = DynamicsPlotterUtil::getElementValues(projectionListY, networkElements); if(projectionValuesX.isEmpty() || projectionValuesY.isEmpty()) { reportProblem("BasinPlotter: Could not find specified elements to project onto."); return; } if(projectionValuesX.size() != projectionValuesY.size()) { reportProblem("BasinPlotter: Mismatching number of projected elements for the two axes."); return; } projectionRangesX = DynamicsPlotterUtil::getDoublesFromString(mProjectionRangesX->get()); projectionRangesY = DynamicsPlotterUtil::getDoublesFromString(mProjectionRangesY->get()); if(projectionRangesX.size() != 2*projectionValuesX.size() || projectionRangesY.size() != 2*projectionValuesY.size()) { reportProblem("BasinPlotter: Given ranges for projection don't match number of elements."); return; } nrProjections = projectionValuesX.size(); } // save original values for clean-up QList<double> variedValuesOrig; variedValuesOrig.append(QList<double>() << variedValX->get() << variedValY->get()); bool resetNetworkActivation = mResetNetworkActivation->get(); storeCurrentNetworkActivities(); /* store network configuration (bias terms, synapse weights, observable parameters of TFs, AFs, SFs. */ bool restoreNetConfiguration = mRestoreNetworkConfiguration->get(); storeNetworkConfiguration(); //This is important when the physical simulator is activated! bool resetSimulation = mResetSimulator->get(); triggerReset(); // PREPARE data matrix double xStart = variedRangeX.first(); double xEnd = variedRangeX.last(); double xStepSize = (xEnd - xStart) / (double) (resolutionX - 1); int roundDigits = mRoundDigits->get(); double xVal; QList<double> xValues; double yStart = variedRangeY.first(); double yEnd = variedRangeY.last(); double yStepSize = (yEnd - yStart) / (double) (resolutionY - 1); double yVal; QList<double> yValues; { //Thread safety of matrix. QMutexLocker guard(mDynamicsPlotManager->getMatrixLocker()); mData->clear(); mData->resize(resolutionX + 1, resolutionY + 1, 3 + nrProjections); mData->fill(0); // calculate values and draw axes for(int x = 1; x <= resolutionX; ++x) { xVal = xStart + (x - 1) * xStepSize; mData->set(Math::round(xVal, 5), x, 0, 0); mData->set(Math::round(xVal, 5), x, 0, 1); mData->set(Math::round(xVal, 5), x, 0, 2); if(roundDigits >= 0) { xVal = Math::round(xVal, roundDigits); } xValues.append(xVal); } for(int y = 1; y <= resolutionY; ++y) { yVal = yStart + (y - 1) * yStepSize; mData->set(Math::round(yVal, 5), 0, y, 0); mData->set(Math::round(yVal, 5), 0, y, 1); mData->set(Math::round(yVal, 5), 0, y, 2); if(roundDigits >= 0) { yVal = Math::round(yVal, roundDigits); } yValues.append(yVal); } // same for additional projections for(int currProj = 0; currProj < nrProjections; ++currProj) { double pStartX = projectionRangesX.at(currProj * 2); double pEndX = projectionRangesX.at(currProj * 2 + 1); double pStepX = (pEndX - pStartX) / (double) (resolutionX - 1); for(int x = 1; x <= resolutionX; ++x) { mData->set(Math::round((pStartX + (x - 1) * pStepX), 5), x, 0, 3 + currProj); } double pStartY = projectionRangesY.at(currProj * 2); double pEndY = projectionRangesY.at(currProj * 2 + 1); double pStepY = (pEndY - pStartY) / (double) (resolutionY - 1); for(int y = 1; y <= resolutionY; ++y) { mData->set(Math::round((pStartY + (y - 1) * pStepY), 5), 0, y, 3 + currProj); } } } // MAIN LOOP over x parameter points int stepsRun = mStepsToRun->get(); int stepsCheck = mStepsToCheck->get(); double accuracy = mAccuracy->get(); QList< QList<double> > attractors; for(int x = 1; x <= resolutionX && mActiveValue->get(); ++x) { mProgressPercentage->set((double)(100 * x / resolutionX)); // INNER LOOP over y parameter points for(int y = 1; y <= resolutionY && mActiveValue->get(); ++y) { if(resetSimulation) { triggerReset(); } if(restoreNetConfiguration) { restoreNetworkConfiguration(); } if(resetNetworkActivation) { restoreCurrentNetworkActivites(); } // set x parameter variedValX->set(xValues.at(x - 1)); // set y parameter variedValY->set(yValues.at(y - 1)); if(!notifyNetworkParametersChanged(network)) { return; } for(int runStep = 0; runStep < stepsRun && mActiveValue->get(); ++runStep) { // let the network run for 1 timestep triggerNetworkStep(); } QList< QList<double> > networkStates; QList<double> networkState; QList< QPair<double,double> > variedPositions; QList< QPair< QList<double>, QList<double> > > projectionPositions; bool foundMatch = false; int attrPeriod = 0; for(int checkStep = 0; checkStep <= stepsCheck && !foundMatch && mActiveValue->get(); ++checkStep) { triggerNetworkStep(); // get current network state networkState = DynamicsPlotterUtil::getNetworkState(networkValues); // abort on empty state if(networkState.isEmpty()) { reportProblem("BasinPlotter: Encountered empty network state."); return; } // compare states to find attractors for(int period = 1; period <= checkStep && !foundMatch; ++period) { foundMatch = DynamicsPlotterUtil::compareNetworkStates( networkStates.at(checkStep-period), networkState, accuracy); attrPeriod = period; } // save current state as last one networkStates.append(networkState); variedPositions.append(QPair<double,double>(variedValX->get(), variedValY->get())); if(nrProjections > 0) { QPair< QList<double>, QList<double> > currentPositions; currentPositions.first = DynamicsPlotterUtil::getMeanValues(projectionValuesX); currentPositions.second = DynamicsPlotterUtil::getMeanValues(projectionValuesY); projectionPositions.append(currentPositions); } } // at this point, either an attractor has been found if(foundMatch && mActiveValue->get()) { // check for past attractors bool attrMatch = false; int attrNo = 1; while(attrNo <= attractors.size() && !attrMatch) { for(int state = 1; state <= attrPeriod && !attrMatch; ++state) { attrMatch = DynamicsPlotterUtil::compareNetworkStates( attractors.at(attrNo-1), networkStates.at(networkStates.size()-state), // was: size()-1-state accuracy); } attrNo++; } //Thread safety of matrix. QMutexLocker guard(mDynamicsPlotManager->getMatrixLocker()); // write matrix mData->set(attrNo, x, y, 0); mData->set(attrPeriod, x, y, 1); // calculate and plot attractor position int nrPositions = variedPositions.size(); for(int periodPos = 1; periodPos <= attrPeriod; ++periodPos) { int currPosition = nrPositions - periodPos; double currValX = variedPositions.at(currPosition).first; double currValY = variedPositions.at(currPosition).second; int attrPosX = ceil((currValX - xStart) / xStepSize + 1); int attrPosY = ceil((currValY - yStart) / yStepSize + 1); mData->set(attrNo, attrPosX, attrPosY, 2); for(int currProj = 0; currProj < nrProjections; ++currProj) { double xVal = projectionPositions.at(currPosition).first.at(currProj); double yVal = projectionPositions.at(currPosition).second.at(currProj); double pStartX = projectionRangesX.at(currProj * 2); double pEndX = projectionRangesX.at(currProj * 2 + 1); double pStepX = (pEndX - pStartX) / (double) (resolutionX - 1); double pStartY = projectionRangesY.at(currProj * 2); double pEndY = projectionRangesY.at(currProj * 2 + 1); double pStepY = (pEndY - pStartY) / (double) (resolutionY - 1); int xPos = floor((xVal - pStartX) / pStepX + 1); int yPos = floor((yVal - pStartY) / pStepY + 1); mData->set(attrNo, xPos, yPos, 3 + currProj); } } if(!attrMatch) { attractors.append(networkStates.last()); } } // or not, but then there's nothing to do :D // runtime maintencance if(core->isShuttingDown()) { return; } core->executePendingTasks(); } } // CLEAN UP variedValX->set(variedValuesOrig.at(0)); variedValY->set(variedValuesOrig.at(1)); notifyNetworkParametersChanged(network); triggerReset(); restoreNetworkConfiguration(); restoreCurrentNetworkActivites(); }
static void reportOutOfMemory (JNIEnv *env, const char *description) { reportProblem(env, "java/lang/OutOfMemoryError", "cannot allocate %s", description); }
void LyapunovExponent::calculateData() { // get program core Core *core = Core::getInstance(); // get network ModularNeuralNetwork *network = getCurrentNetwork(); QList<NeuralNetworkElement*> networkElements; network->getNetworkElements(networkElements); QList<DoubleValue*> networkValues = DynamicsPlotterUtil::getNetworkValues(networkElements); // Get parameters for varied element QString variedElement = mVariedElement->get(); if(variedElement.isEmpty()) { reportProblem("LyapunovExponent: No element to vary."); return; } DoubleValue *variedValue = DynamicsPlotterUtil::getElementValue(variedElement, networkElements); if(variedValue == 0) { reportProblem("LyapunovExponent: Invalid value or specifier."); return; } QList<double> variedRange = DynamicsPlotterUtil::getDoublesFromString(mVariedRange->get()); if(variedRange.size() != 2) { reportProblem("LyapunovExponent: Invalid parameter range."); return; } int resolutionX = mResolutionX->get(); int resolutionY = mResolutionY->get(); //avoid division by zero! if(resolutionX < 2 || resolutionY < 2) { reportProblem("LyapunovExponent: Invalid resolution given."); return; } // Let costraint resolver run properly (order matters!) storeNetworkConfiguration(); storeCurrentNetworkActivities(); triggerReset(); restoreCurrentNetworkActivites(); restoreNetworkConfiguration(); notifyNetworkParametersChanged(network); // save original value double originalValue = variedValue->get(); double valStep = (variedRange.at(1) - variedRange.at(0)) / (double) (resolutionX - 1); QList<double> variedValues; // prepare data matrix { //Thread safety of matrix. QMutexLocker guard(mDynamicsPlotManager->getMatrixLocker()); mData->clear(); mData->resize(resolutionX + 1, resolutionY + 1, 1); mData->fill(0); for(int x = 1; x <= resolutionX; ++x) { double val = variedRange.at(0) + (x-1) * valStep; variedValues.append(val); mData->set(val, x, 0, 0); } } int stepsPrePlot = mStepsPrePlot->get(); int stepsToPlot = mStepsToPlot->get(); bool drawNL = mDrawNL->get(); QList<double> ynum; double eps = pow(10,-9); for(int x = 0; x < variedValues.size(); ++x) { // set initial conditions of this run/trajectory variedValue->set(variedValues.at(x)); notifyNetworkParametersChanged(network); // calculate activation after X PrePlot-Steps for(int s = 0; s < stepsPrePlot && mActiveValue->get(); ++s) { triggerNetworkStep(); } // list for states QList< QList<double> > networkStates; for(int s = 0; s < stepsToPlot && mActiveValue->get(); ++s) { triggerNetworkStep(); // get current state of the network QList<double> networkState = DynamicsPlotterUtil::getNetworkState(networkValues); // save to list networkStates.append(networkState); } double ljanum = 0; int c = 0; for(int i = 0; i < networkStates.size() - 1; ++i) { double dy = 10000000, df = 100000000; bool found = false; for(int j = 0; j < networkStates.size() - 1; ++j) { double d = DynamicsPlotterUtil::getDistance( networkStates.at(i), networkStates.at(j)); if(d < dy && d > eps) { dy = d; df = DynamicsPlotterUtil::getDistance( networkStates.at(i + 1), networkStates.at(j + 1)); found = true; } } if(found && dy != 0 && df != 0) { ljanum += log(df / dy); c++; } } // save current hightest exponent ynum.append(ljanum / c); // find smallest and biggest exponent double ymin = ynum.first(); double ymax = ynum.first(); for(int i = 1; i < ynum.size(); ++i) { double y = ynum.at(i); if(y < ymin) { ymin = y; } if(y > ymax) { ymax = y; } } double ystep = (ymax - ymin) / (double)(resolutionY - 1); if(ystep == 0) { reportProblem("LyapunovExponent: No suitable data found."); ymin = 1; ymax = 1; } { //Thread safety of matrix. QMutexLocker guard(mDynamicsPlotManager->getMatrixLocker()); // clear data matrix mData->fill(0); // rescale for(int y = 1; y <= resolutionY; ++y) { double v = ymin + (y-1) * ystep; mData->set(Math::round(v, 5), 0, y, 0); } // fill rescaled matrix again for(int x = 1; x <= ynum.size(); ++x) { double v = min(max(ymin, ynum.at(x - 1)), ymax); int y = ceil(((v - ymin) / ystep) + 1); mData->set(1, x, y, 0); } // find null position (if any) int ny = ceil(((-ymin)/ystep)+1); // and draw red line indicating y=0 if(drawNL && ny < resolutionY && ny > 0) { for(int x = 0; x < resolutionX; ++x) { if(mData->get(x, ny, 0) == 0) { mData->set(2, x, ny, 0); } } } } // runtime maintencance if(core->isShuttingDown()) { return; } core->executePendingTasks(); } // re-set original parameter value variedValue->set(originalValue); // CLEAN UP notifyNetworkParametersChanged(network); triggerReset(); restoreNetworkConfiguration(); restoreCurrentNetworkActivites(); }
DoubleValue* DynamicsPlotterUtil::getElementValue(QString const &specifier, NeuralNetworkElement* networkElement, QList<Neuron*> *neuronsWithActivationChange) { QString parameter, variable; QStringList nParams, sParams; nParams << "o" << "a" << "b" << "tf" << "af"; sParams << "w" << "sf"; if(specifier.isEmpty()) { reportProblem("DynamicsPlotterUtil::getElementValue(1) : Empty parameter specification"); return 0; } if(specifier.contains(":")) { QStringList paramParts = specifier.split(":"); if(paramParts.size() > 2) { reportProblem("DynamicsPlotterUtil::getElementValue(1) : Invalid parameter specification"); return 0; } parameter = paramParts.first(); variable = paramParts.last(); } else { parameter = specifier; } // requested parameter is neuron-specific if(nParams.contains(parameter)) { Neuron *neuron = dynamic_cast<Neuron*>(networkElement); if(neuron != 0) { if(parameter == specifier) { // no variable requested if(parameter == nParams.at(0)) { // output "o" return &(neuron->getOutputActivationValue()); } if(parameter == nParams.at(1)) { // activation "a" if(neuronsWithActivationChange != 0) { neuronsWithActivationChange->append(neuron); } return &(neuron->getActivationValue()); } if(parameter == nParams.at(2)) { // bias "b" return &(neuron->getBiasValue()); } } else { // variable requested if(parameter == nParams.at(3)) { // TransferFunction "tf" TransferFunction *tf = neuron->getTransferFunction(); if(tf != 0) { DoubleValue *tfo = dynamic_cast<DoubleValue*>(tf->getObservableOutput(variable)); if(tfo != 0) { return tfo; } DoubleValue *tfp = dynamic_cast<DoubleValue*>(tf->getParameter(variable)); if(tfp != 0) { return tfp; } } } if(parameter == nParams.at(4)) { // ActivationFunction "af" ActivationFunction *af = neuron->getActivationFunction(); if(af != 0) { DoubleValue *afo = dynamic_cast<DoubleValue*>(af->getObservableOutput(variable)); if(afo != 0) { return afo; } DoubleValue *afp = dynamic_cast<DoubleValue*>(af->getParameter(variable)); if(afp != 0) { return afp; } } } } // requested parameter has not been found, report reportProblem("DynamicsPlotterUtil::getElementValue(1) : " "Found neuron ["+QString::number(neuron->getId())+"] " "but not the specified observable or function parameter " "["+specifier+"]"); } } // requested parameter is synapse-specific if(sParams.contains(parameter)) { Synapse *synapse = dynamic_cast<Synapse*>(networkElement); if(synapse != 0) { if(parameter == specifier) { // no variable requested if(parameter == sParams.at(0)) { // weight w return &(synapse->getStrengthValue()); } } else { // variable requested if(parameter == sParams.at(1)) { SynapseFunction *sf = synapse->getSynapseFunction(); if(sf != 0) { DoubleValue *sfo = dynamic_cast<DoubleValue*>(sf->getObservableOutput(variable)); if(sfo != 0) { return sfo; } DoubleValue *sfp = dynamic_cast<DoubleValue*>(sf->getParameter(variable)); if(sfp != 0) { return sfp; } } } } // requested parameter has not been found, report reportProblem("DynamicsPlotterUtil::getElementValue(1) : " "Found synapse ["+QString::number(synapse->getId())+"] " "but not the specified observable or function parameter " "["+specifier+"]"); } } // neuron/synapse or specified parameter not found // do not report here, since getElementValues // correctly calls this function with non-matching // specifier-element pairs return 0; }
// returns a list of references to relevant network element values QList<DoubleValue*> DynamicsPlotterUtil::getNetworkValues(const QList<NeuralNetworkElement*> networkElements) { QList<DoubleValue*> list; for(int i = 0; i < networkElements.size(); ++i) { NeuralNetworkElement *e = networkElements.at(i); if(e == 0) { reportProblem("DynamicsPlotterUtil::getNetworkState : " "NeuralNetworkElement is NULL!"); return QList<DoubleValue*>(); } Neuron *n = dynamic_cast<Neuron*>(e); if(n != 0) { DoubleValue *d = &(n->getActivationValue()); list.append(d); DoubleValue *b = &(n->getBiasValue()); list.append(b); ObservableNetworkElement *tf = dynamic_cast<ObservableNetworkElement*>(n->getTransferFunction()); if(tf != 0) { QList<Value*> tfVals = tf->getObservableOutputs(); for(int j = 0; j < tfVals.size(); ++j) { DoubleValue *v = dynamic_cast<DoubleValue*>(tfVals.at(j)); if(v != 0) { list.append(v); } } } ObservableNetworkElement *af = dynamic_cast<ObservableNetworkElement*>(n->getActivationFunction()); if(af != 0) { QList<Value*> afVals = af->getObservableOutputs(); for(int j = 0; j < afVals.size(); ++j) { DoubleValue *v = dynamic_cast<DoubleValue*>(afVals.at(j)); if(v != 0) { list.append(v); } } } } Synapse *s = dynamic_cast<Synapse*>(e); if(s != 0) { DoubleValue *d = &(s->getStrengthValue()); list.append(d); ObservableNetworkElement *sf = dynamic_cast<ObservableNetworkElement*>(s->getSynapseFunction()); if(sf != 0) { QList<Value*> sfVals = sf->getObservableOutputs(); for(int j = 0; j < sfVals.size(); ++j) { DoubleValue *v = dynamic_cast<DoubleValue*>(sfVals.at(j)); if(v != 0) { list.append(v); } } } } } return list; }
/** * * The neuronsWithActivationChange parameter can be used to collect all DoubelValues that correspond * to activation values of neurons. These neurons have to be collected in each DymnamcisPlotter in * variable DynamcisPlotter::mNeuronsWithActivationsToTransfer to be handled correctly, if the * activation of a neuron should be varied during an analyzer run. Otherwise the varied activations * are immediately overwritten by the newly calculated activations at the first network update. * * If this method is used to collect elements that will NOT be changed during analyzer runs, * then the last parameter MUST be empty. Othewise activations of neurons collected in this way * will be treated differently compared to the other neurons in the network. This may lead to * unexpected and erroneous behavior. * * @param specifierLists a list of stringlists, containing the single specifications of DoubleValues. * @param networkElements the list of objects that are considered to find the specified DoubleValue object. * @param neuronsWithActivationChange (optional) list to collect all activation values that are going to be changed during a run. */ QList< QList<DoubleValue*> > DynamicsPlotterUtil::getElementValues(QList<QStringList> const &specifierLists, QList<NeuralNetworkElement*> const &networkElements, QList<Neuron*> *neuronsWithActivationChange) { QList< QList<DoubleValue*> > plotElements, emptyList; emptyList = QList< QList<DoubleValue*> >(); for(int listNr = 0; listNr < specifierLists.size(); ++listNr) { QList<DoubleValue*> elementValues; QStringList specifierList = specifierLists.at(listNr); for(int specifierNr = 0; specifierNr < specifierList.size(); ++specifierNr) { QString specifier = specifierList.at(specifierNr); if(specifier.isEmpty()) { reportProblem("DynamicsPlotterUtil::getElementValues : Empty specifier!"); return emptyList; } QStringList parameters = specifier.split(":"); if(parameters.size() < 2 || parameters.size() > 3) { reportProblem("DynamicsPlotterUtil::getElementValues : Invalid specifier ["+specifier+"]!"); return emptyList; } if(parameters.first() == "all") { QList<DoubleValue*> netValues; DoubleValue* elementValue; QString parameter = specifier.remove("all:"); for(int elemNr = 0; elemNr < networkElements.size(); ++elemNr) { NeuralNetworkElement* networkElement = networkElements.at(elemNr); elementValue = getElementValue(parameter, networkElement, neuronsWithActivationChange); if(elementValue != 0) { netValues.append(elementValue); } } elementValues.append(netValues); } else { DoubleValue* elementValue; elementValue = getElementValue(specifier, networkElements, neuronsWithActivationChange); if(elementValue == 0) { reportProblem("DynamicsPlotterUtil::getElementValues : Could not find a value " "for element specifier ["+specifier+"]!"); return emptyList; } elementValues.append(elementValue); } } plotElements.append(elementValues); } return plotElements; }