00001
00042
00043
00044 #include <SharkDefs.h>
00045 #include <ReClaM/FFNet.h>
00046 #include <sstream>
00047
00048
00049 using namespace std;
00050
00051
00067 FFNet::~FFNet()
00068 {
00069 if (z) delete [] z;
00070 }
00071
00072
00111 double FFNet::g(double a)
00112 {
00113 return 1 / (1 + exp(-a));
00114 }
00115
00116
00117
00144 double FFNet::dg(double ga)
00145 {
00146 return ga *(1 - ga);
00147 }
00148
00149
00150
00190 double FFNet::gOutput(double a)
00191 {
00192 return 1 / (1 + exp(-a));
00193 }
00194
00195
00223 double FFNet::dgOutput(double ga)
00224 {
00225 return ga *(1 - ga);
00226 }
00227
00228
00254 void FFNet::initWeights(long seed, double l, double h)
00255 {
00256 Rng::seed(seed);
00257 for (unsigned i = inputDimension; i < numberOfNeurons; i++)
00258 {
00259 for (unsigned j = 0; j < i; j++)
00260 if (connection(i, j)) weight(i, j) = Rng::uni(l, h);
00261 if (connectionMatrix(i, bias)) weight(i, bias) = Rng::uni(l, h);
00262 }
00263 writeParameters();
00264 }
00265
00266
00291 inline
00292 void FFNet::initWeights(double l, double h)
00293 {
00294 for (unsigned i = inputDimension; i < numberOfNeurons; i++)
00295 {
00296 for (unsigned j = 0; j < i; j++)
00297 if (connection(i, j)) weight(i, j) = Rng::uni(l, h);
00298 if (connectionMatrix(i, bias)) weight(i, bias) = Rng::uni(l, h);
00299 }
00300 writeParameters();
00301 }
00302
00303
00329 inline
00330 void FFNet::model(const Array<double> &input, Array<double> &output)
00331 {
00332 readParameters();
00333 if (input.ndim() == 1)
00334 {
00335 output.resize(outputDimension, false);
00336 activate(input);
00337 for (unsigned i = firstOutputNeuron, c = 0 ; i < numberOfNeurons; i++, c++)
00338 output(c) = z[i];
00339 }
00340 else
00341 {
00342 output.resize(input.dim(0), outputDimension, false);
00343 for (unsigned pattern = 0; pattern < input.dim(0); pattern++)
00344 {
00345 activate(input[pattern]);
00346 for (unsigned i = firstOutputNeuron, c = 0 ; i < numberOfNeurons; i++, c++)
00347 output(pattern, c) = z[i];
00348 }
00349 }
00350 }
00351
00352
00374 inline
00375 void FFNet::backprop(Array<double>& derivative)
00376 {
00377 unsigned i, j;
00378 unsigned c;
00379 unsigned pos;
00380 double sum;
00381
00382
00383
00384
00385
00386 for (j = firstOutputNeuron; j < numberOfNeurons; j++)
00387 for (c = 0; c < outputDimension; c++)
00388 if (c + firstOutputNeuron == j) d(c, j) = dgOutput(z[j]);
00389 else d(c, j) = 0;
00390
00391
00392 for (j = firstOutputNeuron - 1; j >= inputDimension; j--)
00393 {
00394 for (c = 0; c < outputDimension; c++)
00395 {
00396 sum = 0;
00397 for (i = j + 1; i < numberOfNeurons; i++)
00398 {
00399 if (connection(i, j)) sum += weight(i, j) * d(c, i);
00400 }
00401 d(c, j) = dg(z[j]) * sum;
00402 }
00403 }
00404
00405
00406
00407 pos = 0;
00408 for (i = inputDimension; i < numberOfNeurons; i++)
00409 {
00410 for (j = 0; j < i; j++)
00411 {
00412 if (connection(i, j))
00413 {
00414 for (c = 0; c < outputDimension; c++)
00415 {
00416 derivative(c, pos) += d(c, i) * z[j];
00417 }
00418 pos++;
00419 }
00420 }
00421 if (connection(i, bias))
00422 {
00423 for (c = 0; c < outputDimension; c++)
00424 {
00425 derivative(c, pos) += d(c, i);
00426 }
00427 pos++;
00428 }
00429 }
00430 }
00431
00432
00457 void FFNet::modelDerivative(const Array<double> &input, Array<double> &output, Array<double>& derivative)
00458 {
00459 unsigned i;
00460 unsigned c;
00461
00462 derivative.resize(getOutputDimension(), getParameterDimension(), false);
00463 derivative = 0.;
00464
00465 readParameters();
00466
00467 if (input.ndim() == 1)
00468 {
00469 output.resize(getOutputDimension(), false);
00470
00471
00472 activate(input);
00473
00474 for (i = firstOutputNeuron, c = 0 ; i < numberOfNeurons; i++, c++) {
00475 output(c) = z[i];
00476 }
00477
00478
00479 backprop(derivative);
00480 }
00481 else
00482 {
00483 output.resize(input.dim(0), getOutputDimension(), false);
00484 for (unsigned pattern = 0; pattern < input.dim(0); pattern++)
00485 {
00486 activate(input[pattern]);
00487 for (i = firstOutputNeuron, c = 0 ; i < numberOfNeurons; i++, c++) {
00488 output(pattern, c) = z[i];
00489 }
00490 backprop(derivative);
00491 }
00492 }
00493 };
00494
00495 void FFNet::generalDerivative(const Array<double>& input, const Array<double>& coeffs, Array<double>& derivative)
00496 {
00497 unsigned i, j;
00498 unsigned c;
00499 unsigned pos;
00500 double sum;
00501
00502 for (i = firstOutputNeuron, c = 0 ; i < numberOfNeurons; i++, c++)
00503 {
00504 delta(i) = coeffs(c) * dgOutput(z[i]);
00505 }
00506
00507
00508 for (j = firstOutputNeuron - 1; j >= inputDimension; j--)
00509 {
00510 sum = 0;
00511 for (i = j + 1; i < numberOfNeurons; i++)
00512 {
00513 if (connection(i, j)) sum += weight(i, j) * delta(i);
00514 }
00515 delta(j) = dg(z[j]) * sum;
00516 }
00517
00518
00519 pos = 0;
00520 for (i = inputDimension; i < numberOfNeurons; i++)
00521 {
00522 for (j = 0; j < i; j++)
00523 {
00524 if (connection(i, j))
00525 {
00526 derivative(pos) -= delta(i) * z[j];
00527 pos++;
00528 }
00529 }
00530 if (connection(i, bias))
00531 {
00532 derivative(pos) -= delta(i);
00533 pos++;
00534 }
00535 }
00536 };
00537
00538
00566 void FFNet::modelDerivative(const Array<double>& input, Array<double>& derivative)
00567 {
00568 readParameters();
00569
00570 derivative.resize(getOutputDimension(), getParameterDimension(), false);
00571 derivative = 0.;
00572
00573 if (input.ndim() == 1)
00574 {
00575 activate(input);
00576
00577 backprop(derivative);
00578 }
00579 else
00580 {
00581 stringstream s;
00582 s << "the derivative of the model with respect to more than one input is not defined" << endl;
00583 throw SHARKEXCEPTION(s.str().c_str());
00584 }
00585 };
00586
00587
00588
00612 void FFNet::resize()
00613 {
00614 numberOfNeurons = connectionMatrix.dim(0);
00615 bias = numberOfNeurons;
00616 firstOutputNeuron = numberOfNeurons - outputDimension;
00617
00618 unsigned numberOfWeights = 0;
00619 for (unsigned i = 0; i < connectionMatrix.dim(0); i++)
00620 {
00621 for (unsigned j = 0; j < i; j++)
00622 if (connectionMatrix(i, j)) numberOfWeights++;
00623 if (connectionMatrix(i, bias)) numberOfWeights++;
00624 }
00625
00626 parameter.resize(numberOfWeights, false);
00627 d.resize(outputDimension, numberOfNeurons, false);
00628 delta.resize(numberOfNeurons, false);
00629
00630 if (z) delete [] z;
00631 if (numberOfNeurons) z = new double[numberOfNeurons];
00632 else z = NULL;
00633 }
00634
00635
00636
00660 FFNet::FFNet(const unsigned in, const unsigned out)
00661 {
00662 inputDimension = in;
00663 outputDimension = out;
00664
00665 numberOfNeurons = 0;
00666 bias = 0;
00667 firstOutputNeuron = 0;
00668
00669 z = NULL;
00670 }
00671
00672
00673
00702 FFNet::FFNet(const unsigned in, unsigned out,
00703 const Array<int>& cmat)
00704 {
00705 if (cmat.ndim() != 2)
00706 {
00707 stringstream s;
00708 s << "connection matrix has not dimension two" << endl;
00709 throw SHARKEXCEPTION(s.str().c_str());
00710 }
00711 if (cmat.dim(0) != (cmat.dim(1) - 1))
00712 {
00713 stringstream s;
00714 s << "connection matrix has to be (N + 1) x N" << endl;
00715 throw SHARKEXCEPTION(s.str().c_str());
00716 }
00717
00718 inputDimension = in;
00719 outputDimension = out;
00720 connectionMatrix = cmat;
00721
00722 weightMatrix.resize(connectionMatrix, false);
00723 weightMatrix = 0;
00724
00725 z = NULL;
00726
00727 resize();
00728 writeParameters();
00729 }
00730
00731
00732
00760 FFNet::FFNet(const unsigned in, unsigned out,
00761 const Array<int>& cmat, const Array<double>& wmat)
00762 {
00763 if (cmat.ndim() != 2)
00764 {
00765 stringstream s;
00766 s << "connection matrix has not dimension two" << endl;
00767 throw SHARKEXCEPTION(s.str().c_str());
00768 }
00769 if (cmat.dim(0) != (cmat.dim(1) - 1))
00770 {
00771 stringstream s;
00772 s << "connection matrix has to be (N + 1) x N" << endl;
00773 throw SHARKEXCEPTION(s.str().c_str());
00774 }
00775 if (wmat.ndim() != 2)
00776 {
00777 stringstream s;
00778 s << "weight matrix has not dimension two" << endl;
00779 throw SHARKEXCEPTION(s.str().c_str());
00780 }
00781 if (wmat.dim(0) != (wmat.dim(1) - 1))
00782 {
00783 stringstream s;
00784 s << "weight matrix has to be (N + 1) x N" << endl;
00785 throw SHARKEXCEPTION(s.str().c_str());
00786 }
00787
00788 inputDimension = in;
00789 outputDimension = out;
00790 connectionMatrix = cmat;
00791 weightMatrix = wmat;
00792
00793 z = NULL;
00794 resize();
00795 writeParameters();
00796 }
00797
00798
00799
00851 FFNet::FFNet(const string &filename)
00852 {
00853 ifstream input(filename.c_str());
00854 if (!input)
00855 {
00856 stringstream s;
00857 s << "cannot open net file " << filename << endl;
00858 throw SHARKEXCEPTION(s.str().c_str());
00859 }
00860 z = NULL;
00861 input >> *this;
00862 input.close();
00863 }
00864
00865
00866
00893 void FFNet::setStructure(const Array<int>& cmat, const Array<double>& wmat)
00894 {
00895 if ((cmat.ndim() != 2) ||
00896 (wmat.ndim() != 2))
00897 {
00898 stringstream s;
00899 s << "connection or weight matrix has not dimension two" << endl;
00900 throw SHARKEXCEPTION(s.str().c_str());
00901 }
00902
00903 if ((cmat.dim(0) != (cmat.dim(1) - 1)) ||
00904 (cmat.dim(0) != wmat.dim(0)) ||
00905 (cmat.dim(1) != wmat.dim(1)))
00906 {
00907 stringstream s;
00908 s << "connection and weight matrices have to be (N + 1) x N" << endl;
00909 throw SHARKEXCEPTION(s.str().c_str());
00910 }
00911
00912 connectionMatrix = cmat;
00913 weightMatrix = wmat;
00914
00915 resize();
00916 writeParameters();
00917 }
00918
00919
00920
00921
00957 void FFNet::setStructure(Array<unsigned> &layers,
00958 bool ff_layer,
00959 bool ff_in_out,
00960 bool ff_all,
00961 bool bias)
00962 {
00963 unsigned N = 0;
00964 unsigned row,
00965 column,
00966 k,
00967 z_pos,
00968 s_pos;
00969
00970
00971
00972
00973
00974
00975 for (k = 0; k < layers.dim(0); k++) N += layers(k);
00976 connectionMatrix.resize(N, N + 1);
00977 connectionMatrix = 0;
00978
00979
00980
00981
00982
00983 if (ff_layer)
00984 {
00985 z_pos = layers(0);
00986 s_pos = 0;
00987 for (k = 0; k < layers.dim(0) - 1; k++)
00988 {
00989 for (row = z_pos; row < z_pos + layers(k + 1); row++)
00990 for (column = s_pos; column < s_pos + layers(k); column++)
00991 connectionMatrix(row, column) = 1;
00992 s_pos += layers(k);
00993 z_pos += layers(k + 1);
00994 }
00995 }
00996
00997
00998
00999
01000 if (ff_in_out)
01001 {
01002 for (row = N - layers(layers.dim(0) - 1); row < N; row++)
01003 for (column = 0; column < layers(0); column++)
01004 connectionMatrix(row, column) = 1;
01005 }
01006
01007
01008
01009
01010
01011 if (ff_all)
01012 {
01013 z_pos = layers(0);
01014 s_pos = 0;
01015 for (k = 0; k < layers.dim(0) - 1; k++)
01016 {
01017 for (row = z_pos; row < z_pos + layers(k + 1); row++)
01018 for (column = 0; column < s_pos + layers(k); column++)
01019 connectionMatrix(row, column) = 1;
01020 s_pos += layers(k);
01021 z_pos += layers(k + 1);
01022 }
01023 }
01024
01025
01026
01027
01028
01029 if (bias)
01030 for (k = layers(0); k < N; k++) connectionMatrix(k, N) = 1;
01031
01032 weightMatrix.resize(connectionMatrix.dim(0), connectionMatrix.dim(1), false);
01033 weightMatrix = 0.;
01034
01035
01036 inputDimension = layers(0);
01037 outputDimension = layers(layers.dim(0) - 1);
01038
01039 resize();
01040 parameter = 0;
01041
01042 writeParameters();
01043 }
01044
01045
01046
01086 void FFNet::setStructure(unsigned in, unsigned hidden, unsigned out,
01087 bool ff_layer,
01088 bool ff_in_out,
01089 bool ff_all,
01090 bool bias)
01091 {
01092 Array<unsigned> layer(3);
01093 layer(0) = in;
01094 layer(1) = hidden;
01095 layer(2) = out;
01096 setStructure(layer, ff_layer, ff_in_out, ff_all, bias);
01097 }
01098
01099
01100
01141 void FFNet::setStructure(unsigned in, unsigned hidden1, unsigned hidden2, unsigned out,
01142 bool ff_layer,
01143 bool ff_in_out,
01144 bool ff_all,
01145 bool bias)
01146 {
01147 Array<unsigned> layer(4);
01148 layer(0) = in;
01149 layer(1) = hidden1;
01150 layer(2) = hidden2;
01151 layer(3) = out;
01152 setStructure(layer, ff_layer, ff_in_out, ff_all, bias);
01153 }
01154
01155
01180 void FFNet::setStructure(const Array<int>& cmat)
01181 {
01182 if (cmat.ndim() != 2)
01183 {
01184 stringstream s;
01185 s << "connection matrix has not dimension two" << endl;
01186 throw SHARKEXCEPTION(s.str().c_str());
01187 }
01188 if (cmat.dim(0) != (cmat.dim(1) - 1))
01189 {
01190 stringstream s;
01191 s << "connection matrix has to be (N + 1) x N" << endl;
01192 throw SHARKEXCEPTION(s.str().c_str());
01193 }
01194
01195 connectionMatrix = cmat;
01196 weightMatrix.resize(cmat.dim(0), cmat.dim(1), false);
01197
01198 resize();
01199 parameter = 0;
01200
01201 writeParameters();
01202 }
01203
01204
01205
01239 void FFNet::setStructure(const Array<double>& wmat, bool preserve)
01240 {
01241 if (wmat.ndim() != 2)
01242 {
01243 stringstream s;
01244 s << "weight matrix has not dimension two" << endl;
01245 throw SHARKEXCEPTION(s.str().c_str());
01246 }
01247 if (wmat.dim(0) != (wmat.dim(1) - 1))
01248 {
01249 stringstream s;
01250 s << "weight matrix has to be (N + 1) x N" << endl;
01251 throw SHARKEXCEPTION(s.str().c_str());
01252 }
01253
01254 weightMatrix = wmat;
01255 connectionMatrix.resize(wmat.dim(0), wmat.dim(1), false);
01256
01257 numberOfNeurons = connectionMatrix.dim(0);
01258 bias = numberOfNeurons;
01259 firstOutputNeuron = numberOfNeurons - outputDimension;
01260
01261 unsigned numberOfWeights = 0;
01262 for (unsigned i = 0; i < connectionMatrix.dim(0); i++)
01263 {
01264 for (unsigned j = 0; j < i; j++)
01265 {
01266 if (preserve)
01267 {
01268 if (weightMatrix(i, j) != 0.)
01269 {
01270 if (connectionMatrix(i, j) == 0)
01271 {
01272 stringstream s;
01273 s << "weight specified for non-existing connection" << endl;
01274 throw SHARKEXCEPTION(s.str().c_str());
01275 }
01276 numberOfWeights++;
01277 }
01278 else if (connectionMatrix(i, j) != 0) numberOfWeights++;
01279 if (weightMatrix(i, bias) != 0.)
01280 {
01281 if (connectionMatrix(i, bias) == 0)
01282 {
01283 stringstream s;
01284 s << "weight specified for non-existing bias" << endl;
01285 throw SHARKEXCEPTION(s.str().c_str());
01286 }
01287 numberOfWeights++;
01288 }
01289 else if (connectionMatrix(i, bias) != 0) numberOfWeights++;
01290 }
01291 else
01292 {
01293 if (weightMatrix(i, j) != 0.)
01294 {
01295 connectionMatrix(i, j) = 1;
01296 numberOfWeights++;
01297 }
01298 else
01299 {
01300 connectionMatrix(i, j) = 0;
01301 }
01302 if (weightMatrix(i, bias) != 0.)
01303 {
01304 connectionMatrix(i, bias) = 1;
01305 numberOfWeights++;
01306 }
01307 else
01308 {
01309 connectionMatrix(i, bias) = 0;
01310 }
01311 }
01312 }
01313 }
01314
01315 resize();
01316 writeParameters();
01317 }
01318
01319
01346 void FFNet::writeParameters()
01347 {
01348 for (unsigned k = 0, i = 0; i < connectionMatrix.dim(0); i++)
01349 {
01350 for (unsigned j = 0; j < i; j++)
01351 {
01352 if (connectionMatrix(i, j))
01353 {
01354 parameter(k) = weight(i, j);
01355 k++;
01356 }
01357 }
01358 if (i >= inputDimension)
01359 {
01360 if (connectionMatrix(i, bias))
01361 {
01362 parameter(k) = weight(i, bias);
01363 k++;
01364 }
01365 }
01366 }
01367 }
01368
01369
01395 void FFNet::readParameters()
01396 {
01397 for (unsigned k = 0, i = 0; i < connectionMatrix.dim(0); i++)
01398 {
01399 for (unsigned j = 0; j < i; j++)
01400 {
01401 if (connectionMatrix(i, j))
01402 {
01403 weight(i, j) = parameter(k);
01404 k++;
01405 }
01406 }
01407 if (i >= inputDimension)
01408 {
01409 if (connectionMatrix(i, bias))
01410 {
01411 weight(i, bias) = parameter(k);
01412 k++;
01413 }
01414 }
01415 }
01416 }
01417
01418
01419
01439 const Array< double > &FFNet::getWeights()
01440 {
01441 readParameters();
01442 return weightMatrix;
01443 }
01444
01445
01461 const Array< int > &FFNet::getConnections()
01462 {
01463 return connectionMatrix;
01464 }
01465
01466
01490 void FFNet::write(ostream& os) const
01491 {
01492 os << inputDimension << " " << outputDimension << "\n";
01493 writeArray(connectionMatrix, os, "", "\n", ' ');
01494 writeArray(weightMatrix, os, "", "\n", ' ');
01495 }
01496
01497
01498
01525 void FFNet::read(istream& is)
01526 {
01527 unsigned i, j, n, pos;
01528 double v, dn;
01529 vector<double> l;
01530
01531 is >> inputDimension;
01532 is >> outputDimension;
01533
01534 is >> v;
01535 while (is)
01536 {
01537 l.push_back(v);
01538 is >> v;
01539 }
01540
01541 if (!l.size())
01542 {
01543 stringstream s;
01544 s << "no matrices given in net file";
01545 throw SHARKEXCEPTION(s.str().c_str());
01546 }
01547
01548 dn = (sqrt(1. + l.size() * 2.) - 1.) / 2.;
01549 n = unsigned(dn);
01550 if (double(n) == dn)
01551 {
01552 connectionMatrix.resize(n, n + 1, false);
01553 weightMatrix.resize(n, n + 1, false);
01554
01555 pos = 0;
01556 for (i = 0; i < n; i++)
01557 {
01558 for (j = 0; j < n + 1; j++)
01559 {
01560 connectionMatrix(i, j) = unsigned(l[pos]);
01561 pos++;
01562 }
01563 }
01564
01565 for (i = 0; i < n; i++)
01566 {
01567 for (j = 0; j < n + 1; j++)
01568 {
01569 weightMatrix(i, j) = l[pos];
01570 pos++;
01571 }
01572 }
01573 }
01574 else
01575 {
01576 dn = (sqrt(1. + l.size() * 8.) - 1.) / 4.;
01577 n = unsigned(dn);
01578 if (double(n) == dn)
01579 {
01580 connectionMatrix.resize(n, n + 1, false);
01581 weightMatrix.resize(n, n + 1, false);
01582
01583 pos = 0;
01584 for (i = 0; i < n; i++)
01585 {
01586 for (j = 0; j < n; j++)
01587 {
01588 connectionMatrix(i, j) = unsigned(l[pos]);
01589 pos++;
01590 }
01591
01592 if (i >= inputDimension) connectionMatrix(i, n) = 1;
01593 else connectionMatrix(i, n) = 0;
01594 }
01595 for (i = 0; i < n; i++)
01596 {
01597 for (j = 0; j < n + 1; j++)
01598 {
01599 weightMatrix(i, j) = l[pos];
01600 pos++;
01601 }
01602 }
01603 }
01604 else
01605 {
01606 stringstream s;
01607 s << "cannot parse network configuration file" << endl;
01608 throw SHARKEXCEPTION(s.str().c_str());
01609 }
01610 }
01611
01612 resize();
01613 writeParameters();
01614 }
01615
01616
01617 void FFNet::replaceInString(const std::string &str, std::string &newString, const std::string &token, const std::string &newToken1, int newToken2, const std::string &newToken3)
01618 {
01619 std::ostringstream buffer;
01620
01621 buffer << newToken2;
01622 std::string newToken = newToken1 + buffer.str() + newToken3;
01623
01624 std::string::size_type pos;
01625 newString = str;
01626
01627 pos = newString.find(token, 0);
01628 while (pos != std::string::npos)
01629 {
01630 newString.replace(pos, token.length(), newToken);
01631 pos = newString.find(token, 0);
01632 }
01633 }
01634
01635 void FFNet::writeSource(std::ostream &os, const char *g, const char *gOut, unsigned p)
01636 {
01637 unsigned i, j;
01638 bool first;
01639 std::string str;
01640
01641 os.precision(p);
01642
01643 os << "void model(double *in, double *out) {\n";
01644 for (j = 0; j < inputDimension; j++)
01645 os << " double z" << j << " = in[" << j << "];\n";
01646
01647 for (i = inputDimension; i < firstOutputNeuron; i++)
01648 {
01649 first = true;
01650 for (j = 0; j < i; j++)
01651 if (connectionMatrix(i, j))
01652 {
01653 if (first)
01654 {
01655 os << " double z" << i << " = z" << j << " * " << weightMatrix(i, j);
01656 first = false;
01657 }
01658 else
01659 {
01660 os << " + z" << j << " * " << weightMatrix(i, j);
01661 }
01662 }
01663
01664 if( connectionMatrix(i, bias) ) {
01665 if (first)
01666 {
01667 os << "double z" << i << " = " << weightMatrix(i, bias);
01668 first = false;
01669 }
01670 else
01671 {
01672 os << " + " << weightMatrix(i, bias);
01673 }
01674 }
01675
01676 if (!first)
01677 {
01678 os << ";\n";
01679 replaceInString(g, str, "#", "z", i, "");
01680 os << " z" << i << " = " << str << ";\n";
01681 }
01682 }
01683 for (i = firstOutputNeuron; i < numberOfNeurons; i++)
01684 {
01685 first = true;
01686
01687 for (j = 0; j < i; j++)
01688 if (connectionMatrix(i, j))
01689 {
01690 if (first)
01691 {
01692 os << " out[" << i - firstOutputNeuron << "] = " << "z" << j
01693 << " * " << weightMatrix(i, j);
01694 first = false;
01695 }
01696 else
01697 {
01698 os << " + z" << j << " * " << weightMatrix(i, j);
01699 }
01700 }
01701 if( connectionMatrix(i, bias) ) {
01702 if (first)
01703 {
01704 os << " out[" << i - firstOutputNeuron << "] = "
01705 << weightMatrix(i, bias);
01706 first = false;
01707 }
01708 else
01709 {
01710 os << " + " << weightMatrix(i, bias);
01711 }
01712 }
01713
01714 if (!first)
01715 {
01716 os << ";\n";
01717 if((strlen(gOut) != 1) || (*gOut != '#')) {
01718 replaceInString(gOut, str, "#", "out[", i - firstOutputNeuron, "]");
01719 os << " out[" << i - firstOutputNeuron << "] = " << str << ";\n";
01720 }
01721 }
01722 }
01723 os << "};" << std::endl;
01724 }
01725
01726