Network.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. /* Network.cpp
  2. *
  3. * Copyright (C) 2009,2011-2017 Paul Boersma
  4. *
  5. * This code is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This code is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. * See the GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*
  19. * pb 2009/02/27 created
  20. * pb 2009/03/05 setClamping
  21. * pb 2009/05/14 zeroActivities, normalizeActivities
  22. * pb 2009/06/11 connection plasticities
  23. * pb 2011/03/29 C++
  24. * pb 2012/03/18 more weight update rules: instar, outstar, inoutstar
  25. * pb 2012/04/19 more activation clipping rules: linear
  26. * pb 2012/06/02 activation spreading rules: sudden, gradual
  27. */
  28. #include "Network.h"
  29. #include "oo_DESTROY.h"
  30. #include "Network_def.h"
  31. #include "oo_COPY.h"
  32. #include "Network_def.h"
  33. #include "oo_EQUAL.h"
  34. #include "Network_def.h"
  35. #include "oo_CAN_WRITE_AS_ENCODING.h"
  36. #include "Network_def.h"
  37. #include "oo_WRITE_TEXT.h"
  38. #include "Network_def.h"
  39. #include "oo_READ_TEXT.h"
  40. #include "Network_def.h"
  41. #include "oo_WRITE_BINARY.h"
  42. #include "Network_def.h"
  43. #include "oo_READ_BINARY.h"
  44. #include "Network_def.h"
  45. #include "oo_DESCRIPTION.h"
  46. #include "Network_def.h"
  47. #include "enums_getText.h"
  48. #include "Network_enums.h"
  49. #include "enums_getValue.h"
  50. #include "Network_enums.h"
  51. void structNetwork :: v_info ()
  52. {
  53. structDaata :: v_info ();
  54. MelderInfo_writeLine (U"Spreading rate: ", our spreadingRate);
  55. MelderInfo_writeLine (U"Activity clipping rule: ", kNetwork_activityClippingRule_getText (our activityClippingRule));
  56. MelderInfo_writeLine (U"Minimum activity: ", our minimumActivity);
  57. MelderInfo_writeLine (U"Maximum activity: ", our maximumActivity);
  58. MelderInfo_writeLine (U"Activity leak: ", our activityLeak);
  59. MelderInfo_writeLine (U"Learning rate: ", our learningRate);
  60. MelderInfo_writeLine (U"Minimum weight: ", our minimumWeight);
  61. MelderInfo_writeLine (U"Maximum weight: ", our maximumWeight);
  62. MelderInfo_writeLine (U"Weight leak: ", our weightLeak);
  63. MelderInfo_writeLine (U"Number of nodes: ", our numberOfNodes);
  64. MelderInfo_writeLine (U"Number of connections: ", our numberOfConnections);
  65. }
  66. Thing_implement (Network, Daata, 6);
  67. void Network_init (Network me, double spreadingRate, kNetwork_activityClippingRule activityClippingRule,
  68. double minimumActivity, double maximumActivity, double activityLeak,
  69. double learningRate, double minimumWeight, double maximumWeight, double weightLeak,
  70. double xmin, double xmax, double ymin, double ymax, integer numberOfNodes, integer numberOfConnections)
  71. {
  72. my spreadingRate = spreadingRate;
  73. my activityClippingRule = activityClippingRule;
  74. my minimumActivity = minimumActivity;
  75. my maximumActivity = maximumActivity;
  76. my activityLeak = activityLeak;
  77. my learningRate = learningRate;
  78. my minimumWeight = minimumWeight;
  79. my maximumWeight = maximumWeight;
  80. my weightLeak = weightLeak;
  81. my instar = 0.0;
  82. my outstar = 0.0;
  83. my xmin = xmin;
  84. my xmax = xmax;
  85. my ymin = ymin;
  86. my ymax = ymax;
  87. my numberOfNodes = numberOfNodes;
  88. my nodes = NUMvector <structNetworkNode> (1, numberOfNodes);
  89. my numberOfConnections = numberOfConnections;
  90. my connections = NUMvector <structNetworkConnection> (1, numberOfConnections);
  91. }
  92. autoNetwork Network_create (double spreadingRate, kNetwork_activityClippingRule activityClippingRule,
  93. double minimumActivity, double maximumActivity, double activityLeak,
  94. double learningRate, double minimumWeight, double maximumWeight, double weightLeak,
  95. double xmin, double xmax, double ymin, double ymax, integer numberOfNodes, integer numberOfConnections)
  96. {
  97. try {
  98. autoNetwork me = Thing_new (Network);
  99. Network_init (me.get(), spreadingRate, activityClippingRule, minimumActivity, maximumActivity, activityLeak,
  100. learningRate, minimumWeight, maximumWeight, weightLeak,
  101. xmin, xmax, ymin, ymax, numberOfNodes, numberOfConnections);
  102. return me;
  103. } catch (MelderError) {
  104. Melder_throw (U"Network not created.");
  105. }
  106. }
  107. double Network_getActivity (Network me, integer nodeNumber) {
  108. try {
  109. if (nodeNumber <= 0 || nodeNumber > my numberOfNodes)
  110. Melder_throw (me, U": node number (", nodeNumber, U") out of the range 1..", my numberOfNodes, U".");
  111. return my nodes [nodeNumber]. activity;
  112. } catch (MelderError) {
  113. Melder_throw (me, U": activity not gotten.");
  114. }
  115. }
  116. void Network_setActivity (Network me, integer nodeNumber, double activity) {
  117. try {
  118. if (nodeNumber <= 0 || nodeNumber > my numberOfNodes)
  119. Melder_throw (me, U": node number (", nodeNumber, U") out of the range 1..", my numberOfNodes, U".");
  120. my nodes [nodeNumber]. activity = my nodes [nodeNumber]. excitation = activity;
  121. } catch (MelderError) {
  122. Melder_throw (me, U": activity not set.");
  123. }
  124. }
  125. double Network_getWeight (Network me, integer connectionNumber) {
  126. try {
  127. if (connectionNumber <= 0 || connectionNumber > my numberOfConnections)
  128. Melder_throw (me, U": connection number (", connectionNumber, U") out of the range 1..", my numberOfConnections, U".");
  129. return my connections [connectionNumber]. weight;
  130. } catch (MelderError) {
  131. Melder_throw (me, U": weight not gotten.");
  132. }
  133. }
  134. void Network_setWeight (Network me, integer connectionNumber, double weight) {
  135. try {
  136. if (connectionNumber <= 0 || connectionNumber > my numberOfConnections)
  137. Melder_throw (me, U": connection number (", connectionNumber, U") out of the range 1..", my numberOfConnections, U".");
  138. my connections [connectionNumber]. weight = weight;
  139. } catch (MelderError) {
  140. Melder_throw (me, U": weight not set.");
  141. }
  142. }
  143. void Network_setClamping (Network me, integer nodeNumber, bool clamped) {
  144. try {
  145. if (nodeNumber <= 0 || nodeNumber > my numberOfNodes)
  146. Melder_throw (me, U": node number (", nodeNumber, U") out of the range 1..", my numberOfNodes, U".");
  147. my nodes [nodeNumber]. clamped = clamped;
  148. } catch (MelderError) {
  149. Melder_throw (me, U": clamping not set.");
  150. }
  151. }
  152. void Network_spreadActivities (Network me, integer numberOfSteps) {
  153. for (integer istep = 1; istep <= numberOfSteps; istep ++) {
  154. for (integer inode = 1; inode <= my numberOfNodes; inode ++) {
  155. NetworkNode node = & my nodes [inode];
  156. if (! node -> clamped)
  157. node -> excitation -= my spreadingRate * my activityLeak * node -> excitation;
  158. }
  159. for (integer iconn = 1; iconn <= my numberOfConnections; iconn ++) {
  160. NetworkConnection connection = & my connections [iconn];
  161. NetworkNode nodeFrom = & my nodes [connection -> nodeFrom];
  162. NetworkNode nodeTo = & my nodes [connection -> nodeTo];
  163. double shunting = my connections [iconn]. weight >= 0.0 ? my shunting : 0.0; // only for excitatory connections
  164. if (! nodeFrom -> clamped)
  165. nodeFrom -> excitation += my spreadingRate * nodeTo -> activity * (my connections [iconn]. weight - shunting * nodeFrom -> excitation);
  166. if (! nodeTo -> clamped)
  167. nodeTo -> excitation += my spreadingRate * nodeFrom -> activity * (my connections [iconn]. weight - shunting * nodeTo -> excitation);
  168. }
  169. for (integer inode = 1; inode <= my numberOfNodes; inode ++) {
  170. NetworkNode node = & my nodes [inode];
  171. if (! node -> clamped) {
  172. switch (my activityClippingRule) {
  173. case kNetwork_activityClippingRule::SIGMOID:
  174. node -> activity = my minimumActivity +
  175. (my maximumActivity - my minimumActivity) * NUMsigmoid (node -> excitation - 0.5 * (my minimumActivity + my maximumActivity));
  176. break;
  177. case kNetwork_activityClippingRule::LINEAR:
  178. if (node -> excitation < my minimumActivity) {
  179. node -> activity = my minimumActivity;
  180. } else if (node -> excitation > my maximumActivity) {
  181. node -> activity = my maximumActivity;
  182. } else {
  183. node -> activity = node -> excitation;
  184. }
  185. break;
  186. case kNetwork_activityClippingRule::TOP_SIGMOID:
  187. if (node -> excitation <= my minimumActivity) {
  188. node -> activity = my minimumActivity;
  189. } else {
  190. node -> activity = my minimumActivity +
  191. (my maximumActivity - my minimumActivity) * (2.0 * NUMsigmoid (2.0 * (node -> excitation - my minimumActivity) / (my maximumActivity - my minimumActivity)) - 1.0);
  192. trace (U"excitation ", node -> excitation, U", activity ", node -> activity);
  193. }
  194. break;
  195. }
  196. }
  197. }
  198. }
  199. }
  200. void Network_zeroActivities (Network me, integer nodeMin, integer nodeMax) {
  201. if (my numberOfNodes < 1) return;
  202. if (nodeMax == 0) { nodeMin = 1; nodeMax = my numberOfNodes; }
  203. if (nodeMin < 1) nodeMin = 1;
  204. if (nodeMax > my numberOfNodes) nodeMax = my numberOfNodes;
  205. for (integer inode = nodeMin; inode <= nodeMax; inode ++) {
  206. my nodes [inode]. activity = my nodes [inode]. excitation = 0.0;
  207. }
  208. }
  209. void Network_normalizeActivities (Network me, integer nodeMin, integer nodeMax) {
  210. if (my numberOfNodes < 1) return;
  211. if (nodeMax == 0) { nodeMin = 1; nodeMax = my numberOfNodes; }
  212. if (nodeMin < 1) nodeMin = 1;
  213. if (nodeMax > my numberOfNodes) nodeMax = my numberOfNodes;
  214. if (nodeMax < nodeMin) return;
  215. longdouble sum = 0.0;
  216. for (integer inode = nodeMin; inode <= nodeMax; inode ++) {
  217. sum += my nodes [inode]. activity;
  218. }
  219. double average = (double) sum / (nodeMax - nodeMin + 1);
  220. for (integer inode = nodeMin; inode <= nodeMax; inode ++) {
  221. my nodes [inode]. activity -= average;
  222. }
  223. }
  224. void Network_updateWeights (Network me) {
  225. for (integer iconn = 1; iconn <= my numberOfConnections; iconn ++) {
  226. NetworkConnection connection = & my connections [iconn];
  227. NetworkNode nodeFrom = & my nodes [connection -> nodeFrom];
  228. NetworkNode nodeTo = & my nodes [connection -> nodeTo];
  229. connection -> weight += connection -> plasticity * my learningRate *
  230. (nodeFrom -> activity * nodeTo -> activity - (my instar * nodeTo -> activity + my outstar * nodeFrom -> activity + my weightLeak) * connection -> weight);
  231. if (connection -> weight < my minimumWeight) connection -> weight = my minimumWeight;
  232. else if (connection -> weight > my maximumWeight) connection -> weight = my maximumWeight;
  233. }
  234. }
  235. void Network_normalizeWeights (Network me, integer nodeMin, integer nodeMax, integer nodeFromMin, integer nodeFromMax, double newSum) {
  236. if (my numberOfNodes < 1) return;
  237. if (nodeMax == 0) { nodeMin = 1; nodeMax = my numberOfNodes; }
  238. if (nodeMin < 1) nodeMin = 1;
  239. if (nodeMax > my numberOfNodes) nodeMax = my numberOfNodes;
  240. if (nodeMax < nodeMin) return;
  241. for (integer inode = nodeMin; inode <= nodeMax; inode ++) {
  242. longdouble sum = 0.0;
  243. for (integer iconn = 1; iconn <= my numberOfConnections; iconn ++) {
  244. NetworkConnection connection = & my connections [iconn];
  245. if (connection -> nodeTo == inode && connection -> nodeFrom >= nodeFromMin && connection -> nodeFrom <= nodeFromMax) {
  246. sum += connection -> weight;
  247. }
  248. }
  249. if (sum != 0.0) {
  250. double factor = newSum / (double) sum;
  251. for (integer iconn = 1; iconn <= my numberOfConnections; iconn ++) {
  252. NetworkConnection connection = & my connections [iconn];
  253. if (connection -> nodeTo == inode && connection -> nodeFrom >= nodeFromMin && connection -> nodeFrom <= nodeFromMax) {
  254. connection -> weight *= factor;
  255. }
  256. }
  257. }
  258. }
  259. }
  260. autoNetwork Network_create_rectangle (double spreadingRate, enum kNetwork_activityClippingRule activityClippingRule,
  261. double minimumActivity, double maximumActivity, double activityLeak,
  262. double learningRate, double minimumWeight, double maximumWeight, double weightLeak,
  263. integer numberOfRows, integer numberOfColumns, bool bottomRowClamped,
  264. double initialMinimumWeight, double initialMaximumWeight)
  265. {
  266. try {
  267. autoNetwork me = Network_create (spreadingRate, activityClippingRule, minimumActivity, maximumActivity, activityLeak,
  268. learningRate, minimumWeight, maximumWeight, weightLeak,
  269. 0.0, numberOfColumns, 0.0, numberOfRows, numberOfRows * numberOfColumns,
  270. numberOfRows * (numberOfColumns - 1) + numberOfColumns * (numberOfRows - 1));
  271. /*
  272. * Define nodes.
  273. */
  274. for (integer inode = 1; inode <= my numberOfNodes; inode ++) {
  275. NetworkNode node = & my nodes [inode];
  276. node -> x = (inode - 1) % numberOfColumns + 0.5;
  277. node -> y = (inode - 1) / numberOfColumns + 0.5;
  278. node -> clamped = bottomRowClamped && inode <= numberOfColumns;
  279. node -> activity = NUMrandomUniform (my minimumActivity, my maximumActivity);
  280. }
  281. /*
  282. * Define connections.
  283. */
  284. integer iconn = 0;
  285. for (integer irow = 1; irow <= numberOfRows; irow ++) {
  286. for (integer icol = 1; icol <= numberOfColumns - 1; icol ++) {
  287. NetworkConnection conn = & my connections [++ iconn];
  288. conn -> nodeFrom = (irow - 1) * numberOfColumns + icol;
  289. conn -> nodeTo = conn -> nodeFrom + 1;
  290. conn -> weight = NUMrandomUniform (initialMinimumWeight, initialMaximumWeight);
  291. conn -> plasticity = 1.0;
  292. }
  293. }
  294. for (integer irow = 1; irow <= numberOfRows - 1; irow ++) {
  295. for (integer icol = 1; icol <= numberOfColumns; icol ++) {
  296. NetworkConnection conn = & my connections [++ iconn];
  297. conn -> nodeFrom = (irow - 1) * numberOfColumns + icol;
  298. conn -> nodeTo = conn -> nodeFrom + numberOfColumns;
  299. conn -> weight = NUMrandomUniform (initialMinimumWeight, initialMaximumWeight);
  300. conn -> plasticity = 1.0;
  301. }
  302. }
  303. Melder_assert (iconn == my numberOfConnections);
  304. return me;
  305. } catch (MelderError) {
  306. Melder_throw (U"Rectangular network not created.");
  307. }
  308. }
  309. autoNetwork Network_create_rectangle_vertical (double spreadingRate, enum kNetwork_activityClippingRule activityClippingRule,
  310. double minimumActivity, double maximumActivity, double activityLeak,
  311. double learningRate, double minimumWeight, double maximumWeight, double weightLeak,
  312. integer numberOfRows, integer numberOfColumns, bool bottomRowClamped,
  313. double initialMinimumWeight, double initialMaximumWeight)
  314. {
  315. try {
  316. autoNetwork me = Network_create (spreadingRate, activityClippingRule, minimumActivity, maximumActivity, activityLeak,
  317. learningRate, minimumWeight, maximumWeight, weightLeak,
  318. 0.0, numberOfColumns, 0.0, numberOfRows, numberOfRows * numberOfColumns,
  319. numberOfColumns * numberOfColumns * (numberOfRows - 1));
  320. /*
  321. * Define nodes.
  322. */
  323. for (integer inode = 1; inode <= my numberOfNodes; inode ++) {
  324. NetworkNode node = & my nodes [inode];
  325. node -> x = (inode - 1) % numberOfColumns + 0.5;
  326. node -> y = (inode - 1) / numberOfColumns + 0.5;
  327. node -> clamped = bottomRowClamped && inode <= numberOfColumns;
  328. node -> activity = NUMrandomUniform (my minimumActivity, my maximumActivity);
  329. }
  330. /*
  331. * Define connections.
  332. */
  333. integer iconn = 0;
  334. for (integer icol = 1; icol <= numberOfColumns; icol ++) {
  335. for (integer jcol = 1; jcol <= numberOfColumns; jcol ++) {
  336. for (integer irow = 1; irow <= numberOfRows - 1; irow ++) {
  337. NetworkConnection conn = & my connections [++ iconn];
  338. conn -> nodeFrom = (irow - 1) * numberOfColumns + icol;
  339. conn -> nodeTo = irow * numberOfColumns + jcol;
  340. conn -> weight = NUMrandomUniform (initialMinimumWeight, initialMaximumWeight);
  341. conn -> plasticity = 1.0;
  342. }
  343. }
  344. }
  345. Melder_assert (iconn == my numberOfConnections);
  346. return me;
  347. } catch (MelderError) {
  348. Melder_throw (U"Vertical rectangular network not created.");
  349. }
  350. }
  351. void Network_draw (Network me, Graphics graphics, bool useColour) {
  352. double saveLineWidth = Graphics_inqLineWidth (graphics);
  353. Graphics_setInner (graphics);
  354. Graphics_setWindow (graphics, my xmin, my xmax, my ymin, my ymax);
  355. if (useColour) {
  356. Graphics_setColour (graphics, Graphics_SILVER);
  357. Graphics_fillRectangle (graphics, my xmin, my xmax, my ymin, my ymax);
  358. }
  359. /*
  360. * Draw connections.
  361. */
  362. for (integer iconn = 1; iconn <= my numberOfConnections; iconn ++) {
  363. NetworkConnection conn = & my connections [iconn];
  364. if (fabs (conn -> weight) >= 0.01) {
  365. NetworkNode nodeFrom = & my nodes [conn -> nodeFrom];
  366. NetworkNode nodeTo = & my nodes [conn -> nodeTo];
  367. Graphics_setLineWidth (graphics, fabs (conn -> weight) * 6.0);
  368. Graphics_setColour (graphics, conn -> weight < 0.0 ? ( useColour ? Graphics_WHITE : Graphics_SILVER ) : Graphics_BLACK);
  369. Graphics_line (graphics, nodeFrom -> x, nodeFrom -> y, nodeTo -> x, nodeTo -> y);
  370. }
  371. }
  372. Graphics_setLineWidth (graphics, 1.0);
  373. /*
  374. * Draw the backgrounds of the nodes.
  375. */
  376. for (integer inode = 1; inode <= my numberOfNodes; inode ++) {
  377. NetworkNode node = & my nodes [inode];
  378. Graphics_setColour (graphics, useColour ? Graphics_SILVER : Graphics_WHITE);
  379. Graphics_fillCircle_mm (graphics, node -> x, node -> y, 5.0);
  380. }
  381. /*
  382. * Draw the edges of the nodes.
  383. */
  384. Graphics_setColour (graphics, Graphics_BLACK);
  385. Graphics_setLineWidth (graphics, 2.0);
  386. for (integer inode = 1; inode <= my numberOfNodes; inode ++) {
  387. NetworkNode node = & my nodes [inode];
  388. Graphics_setLineType (graphics, node -> clamped ? Graphics_DRAWN : Graphics_DOTTED);
  389. Graphics_circle_mm (graphics, node -> x, node -> y, 5.2);
  390. }
  391. /*
  392. * Draw the activities of the nodes.
  393. */
  394. for (integer inode = 1; inode <= my numberOfNodes; inode ++) {
  395. NetworkNode node = & my nodes [inode];
  396. double activity = fabs (node -> activity);
  397. if (activity >= 1.0) activity = sqrt (activity);
  398. double diameter = activity * 5.0;
  399. if (diameter != 0.0) {
  400. Graphics_setColour (graphics,
  401. useColour ? ( node -> activity < 0.0 ? Graphics_BLUE : Graphics_RED )
  402. : ( node -> activity < 0.0 ? Graphics_SILVER : Graphics_BLACK));
  403. Graphics_fillCircle_mm (graphics, node -> x, node -> y, diameter);
  404. }
  405. }
  406. Graphics_setColour (graphics, Graphics_BLACK);
  407. Graphics_setLineWidth (graphics, saveLineWidth);
  408. Graphics_setLineType (graphics, Graphics_DRAWN);
  409. Graphics_unsetInner (graphics);
  410. }
  411. void Network_addNode (Network me, double x, double y, double activity, bool clamped) {
  412. try {
  413. integer numberOfNodes = my numberOfNodes;
  414. NUMvector_append (& my nodes, 1, & numberOfNodes);
  415. my numberOfNodes = numberOfNodes;
  416. my nodes [my numberOfNodes]. x = x;
  417. my nodes [my numberOfNodes]. y = y;
  418. my nodes [my numberOfNodes]. activity = my nodes [my numberOfNodes]. excitation = activity;
  419. my nodes [my numberOfNodes]. clamped = clamped;
  420. } catch (MelderError) {
  421. Melder_throw (me, U": node not added.");
  422. }
  423. }
  424. void Network_addConnection (Network me, integer nodeFrom, integer nodeTo, double weight, double plasticity) {
  425. try {
  426. integer numberOfConnections = my numberOfConnections;
  427. NUMvector_append (& my connections, 1, & numberOfConnections);
  428. my numberOfConnections = numberOfConnections;
  429. my connections [my numberOfConnections]. nodeFrom = nodeFrom;
  430. my connections [my numberOfConnections]. nodeTo = nodeTo;
  431. my connections [my numberOfConnections]. weight = weight;
  432. my connections [my numberOfConnections]. plasticity = plasticity;
  433. } catch (MelderError) {
  434. Melder_throw (me, U": connection not added.");
  435. }
  436. }
  437. void Network_setInstar (Network me, double instar) {
  438. my instar = instar;
  439. }
  440. void Network_setOutstar (Network me, double outstar) {
  441. my outstar = outstar;
  442. }
  443. void Network_setWeightLeak (Network me, double weightLeak) {
  444. my weightLeak = weightLeak;
  445. }
  446. void Network_setActivityLeak (Network me, double activityLeak) {
  447. my activityLeak = activityLeak;
  448. Network_zeroActivities (me, 0, 0);
  449. }
  450. void Network_setShunting (Network me, double shunting) {
  451. my shunting = shunting;
  452. Network_zeroActivities (me, 0, 0);
  453. }
  454. void Network_setActivityClippingRule (Network me, enum kNetwork_activityClippingRule activityClippingRule) {
  455. my activityClippingRule = activityClippingRule;
  456. Network_zeroActivities (me, 0, 0);
  457. }
  458. autoTable Network_nodes_downto_Table (Network me, integer fromNodeNumber, integer toNodeNumber,
  459. bool includeNodeNumbers,
  460. bool includeX, bool includeY, int positionDecimals,
  461. bool includeClamped,
  462. bool includeActivity, bool includeExcitation, int activityDecimals)
  463. {
  464. try {
  465. if (fromNodeNumber < 1) fromNodeNumber = 1;
  466. if (toNodeNumber > my numberOfNodes) toNodeNumber = my numberOfNodes;
  467. if (fromNodeNumber > toNodeNumber)
  468. fromNodeNumber = 1, toNodeNumber = my numberOfNodes;
  469. integer numberOfNodes = toNodeNumber - fromNodeNumber + 1;
  470. Melder_assert (numberOfNodes >= 1);
  471. autoTable thee = Table_createWithoutColumnNames (numberOfNodes,
  472. includeNodeNumbers + includeX + includeY + includeClamped + includeActivity + includeExcitation);
  473. integer icol = 0;
  474. if (includeNodeNumbers) Table_setColumnLabel (thee.get(), ++ icol, U"node");
  475. if (includeX) Table_setColumnLabel (thee.get(), ++ icol, U"x");
  476. if (includeY) Table_setColumnLabel (thee.get(), ++ icol, U"y");
  477. if (includeClamped) Table_setColumnLabel (thee.get(), ++ icol, U"clamped");
  478. if (includeActivity) Table_setColumnLabel (thee.get(), ++ icol, U"activity");
  479. if (includeExcitation) Table_setColumnLabel (thee.get(), ++ icol, U"excitation");
  480. for (integer inode = fromNodeNumber; inode <= toNodeNumber; inode ++) {
  481. NetworkNode node = & my nodes [inode];
  482. icol = 0;
  483. if (includeNodeNumbers) Table_setNumericValue (thee.get(), inode, ++ icol, inode);
  484. if (includeX) Table_setStringValue (thee.get(), inode, ++ icol, Melder_fixed (node -> x, positionDecimals));
  485. if (includeY) Table_setStringValue (thee.get(), inode, ++ icol, Melder_fixed (node -> y, positionDecimals));
  486. if (includeClamped) Table_setNumericValue (thee.get(), inode, ++ icol, node -> clamped);
  487. if (includeActivity) Table_setStringValue (thee.get(), inode, ++ icol, Melder_fixed (node -> activity, activityDecimals));
  488. if (includeExcitation) Table_setStringValue (thee.get(), inode, ++ icol, Melder_fixed (node -> excitation, activityDecimals));
  489. }
  490. return thee;
  491. } catch (MelderError) {
  492. Melder_throw (me, U": not converted to Table.");
  493. }
  494. }
  495. void Network_listNodes (Network me, integer fromNodeNumber, integer toNodeNumber,
  496. bool includeNodeNumbers,
  497. bool includeX, bool includeY, int positionDecimals,
  498. bool includeClamped,
  499. bool includeActivity, bool includeExcitation, int activityDecimals)
  500. {
  501. try {
  502. autoTable table = Network_nodes_downto_Table (me, fromNodeNumber, toNodeNumber, includeNodeNumbers,
  503. includeX, includeY, positionDecimals, includeClamped, includeActivity, includeExcitation, activityDecimals);
  504. Table_list (table.get(), false);
  505. } catch (MelderError) {
  506. Melder_throw (me, U": not listed.");
  507. }
  508. }
  509. /* End of file Network.cpp */