@@ -1146,127 +1146,6 @@ C_CHANGESTAT_FN(c_ctriple) {
11461146 }
11471147}
11481148
1149- /*****************
1150- changestat: d_cycle
1151- *****************/
1152- void edgewise_path_recurse (Network * nwp , Vertex dest , Vertex curnode ,
1153- int * visited , Vertex curlen , int * countv , Vertex maxlen , Rboolean semi );
1154- void edgewise_cycle_census (Network * nwp , Vertex tail , Vertex head ,
1155- int * countv , Vertex maxlen , Rboolean semi );
1156-
1157- I_CHANGESTAT_FN (i_cycle ) {
1158- ALLOC_STORAGE (IINPUT_PARAM [1 ]* 2 , int , dummy );
1159- (void )(dummy ); // Suppress unused warning.
1160- }
1161-
1162- C_CHANGESTAT_FN (c_cycle ) {
1163- GET_STORAGE (int , countv );
1164- int emult ;
1165-
1166- /*Perform initial setup*/
1167- Rboolean semi = (Rboolean ) (IINPUT_PARAM [0 ]); /*Are we using semicycles?*/
1168- Vertex maxlen = (Vertex ) (IINPUT_PARAM [1 ]); /*Get max cycle length*/
1169-
1170- /* *** don't forget tail -> head */
1171- /*Clear out the count vector*/
1172- memset (countv , 0 , sizeof (* countv )* (maxlen - 1 ));
1173- /*In semi-cycle case, this toggle can't matter if there is a*/
1174- /*head->tail edge in the graph; not counting saves much time.*/
1175- if (!(semi && (IS_OUTEDGE (head ,tail )))){
1176- /*Count the cycles associated with this edge*/
1177- edgewise_cycle_census (nwp ,tail ,head ,countv ,maxlen ,semi );
1178-
1179- /*Make the change, as needed*/
1180- if ((!DIRECTED )&& (tail > head ))
1181- emult = IS_OUTEDGE (head , tail ) ? -1 : 1 ;
1182- else
1183- emult = edgestate ? -1 : 1 ;
1184- for (unsigned int j = 0 , k = 0 ; j < maxlen - 1 ;j ++ )
1185- if (IINPUT_PARAM [2 + j ]> 0 )
1186- CHANGE_STAT [k ++ ]+= emult * countv [j ];
1187- }
1188- }
1189-
1190- /*****************
1191- edgewise_path_recurse: Called by d_cycle
1192- *****************/
1193- void edgewise_path_recurse (Network * nwp , Vertex dest , Vertex curnode ,
1194- int * visited , Vertex curlen , int * countv , Vertex maxlen , Rboolean semi ) {
1195- Vertex v ;
1196- Edge e ;
1197-
1198- /*If we've found a path to the destination, increment the census vector*/
1199- if (DIRECTED ){ /*Use outedges, or both if counting semi-paths*/
1200- if (!semi )
1201- countv [curlen ] += IS_OUTEDGE (curnode , dest );
1202- else
1203- countv [curlen ] += (IS_OUTEDGE (curnode , dest ) || IS_INEDGE (curnode , dest ));
1204- }else { /*For undirected graphs, edges go from low to high*/
1205- if (curnode < dest )
1206- countv [curlen ] += IS_OUTEDGE (curnode , dest );
1207- else
1208- countv [curlen ] += IS_INEDGE (curnode , dest );
1209- }
1210-
1211- /*If possible, keep searching for novel paths*/
1212- if (curlen < maxlen - 2 ){
1213- visited [curlen + 1 ]= curnode ; /*Add current node to visited list*/
1214-
1215- /*Recurse on all unvisited neighbors of curnode*/
1216- STEP_THROUGH_OUTEDGES (curnode ,e ,v ){
1217- Rboolean rflag = TRUE;
1218- for (Vertex i = 0 ;(i <=curlen )&& (rflag );i ++ ) /*Check earlier nodes in path*/
1219- rflag = (v != visited [i ]);
1220- if (rflag )
1221- edgewise_path_recurse (nwp ,dest ,v ,visited ,curlen + 1 ,countv ,maxlen , semi );
1222- }
1223- if (semi || (!DIRECTED )){ /*If semi or !directed, need in-neighbors too*/
1224- STEP_THROUGH_INEDGES (curnode ,e ,v ){
1225- Rboolean rflag = ((!DIRECTED )|| (!(IS_OUTEDGE (curnode ,v ))));
1226- for (Vertex i = 0 ;(i <=curlen )&& (rflag );i ++ ) /*Check earlier nodes in path*/
1227- rflag = (v != visited [i ]);
1228- if (rflag )
1229- edgewise_path_recurse (nwp ,dest ,v ,visited ,curlen + 1 ,countv ,maxlen , semi );
1230- }
1231- }
1232- }
1233- }
1234-
1235- /*****************
1236- edgewise_cycle_census: Called by d_cycle
1237- *****************/
1238- void edgewise_cycle_census (Network * nwp , Vertex tail , Vertex head ,
1239- int * countv , Vertex maxlen , Rboolean semi ) {
1240- /* *** don't forget tail -> head */
1241- int * visited ;
1242- Vertex v ;
1243- Edge e ;
1244-
1245- /*First, check for a 2-cycle (but only if directed and !semi)*/
1246- if (DIRECTED && (!semi ) && IS_OUTEDGE (head ,tail ))
1247- countv [0 ]++ ;
1248- if (N_NODES == 2 )
1249- return ; /*Failsafe for graphs of order 2*/
1250-
1251- /*Perform the recursive path count*/
1252- visited = countv + maxlen ; /*Locate the list of visited nodes*/
1253- memset (visited , 0 , sizeof (* visited )* maxlen );
1254- visited [0 ]= tail ;
1255- visited [1 ]= head ;
1256-
1257- /*Recurse on each neighbor of head*/
1258- STEP_THROUGH_OUTEDGES (head ,e ,v ){
1259- if (v != tail )
1260- edgewise_path_recurse (nwp ,tail ,v ,visited ,1 ,countv ,maxlen ,semi );
1261- }
1262- if (semi || (!DIRECTED )){ /*If semi or !directed, need in-neighbors too*/
1263- STEP_THROUGH_INEDGES (head ,e ,v ){
1264- if ((v != tail )&& ((!DIRECTED )|| (!(IS_OUTEDGE (head ,v )))))
1265- edgewise_path_recurse (nwp ,tail ,v ,visited ,1 ,countv ,maxlen , semi );
1266- }
1267- }
1268- }
1269-
12701149/******************** changestats: D ***********/
12711150/*****************
12721151 changestat: d_degcor
0 commit comments