Skip to content
This repository was archived by the owner on May 13, 2024. It is now read-only.

Commit fa922e1

Browse files
authored
Merge pull request #5 from idodoron11/division-alg
Division alg
2 parents 6262600 + 67eb3a3 commit fa922e1

10 files changed

+407
-81
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ set(CMAKE_C_STANDARD 90)
55
set(GCC_COVERAGE_COMPILE_FLAGS "-ansi -Wall -Wextra -Werror -pedantic-errors")
66
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
77

8-
add_executable(cluster cluster.c spmat.c matrix.h matrix.c graph.h graph.c VerticesGroup.h VerticesGroup.c)
8+
add_executable(cluster cluster.c spmat.c matrix.h matrix.c graph.h graph.c LinkedList.h LinkedList.c VerticesGroup.h VerticesGroup.c division.h division.c)

LinkedList.c

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#include <stdlib.h>
2+
#include "LinkedList.h"
3+
4+
/**
5+
* Creates a new empty linked list.
6+
* @return a pointer to the new list.
7+
*/
8+
LinkedList *createLinkedList(){
9+
LinkedList *list = malloc(sizeof(LinkedList));
10+
list->length = 0;
11+
return list;
12+
}
13+
14+
/**
15+
* Destroys a given list and frees up its allocated memory.
16+
* @param list a linked list.
17+
*/
18+
void freeLinkedList(LinkedList *list){
19+
LinkedListNode *temp;
20+
LinkedListNode *node = list->first;
21+
if (node != NULL) {
22+
do {
23+
temp = node->next;
24+
free(node);
25+
node = temp;
26+
} while (node != list->first);
27+
}
28+
free(list);
29+
}
30+
31+
/**
32+
* Inserts a new item to a given list.
33+
* In case this list functions as a list of VerticesGroups, 'value' should be a pointer to a 'VerticesGroup'.
34+
* @param list the list where the item should be inserted.
35+
* @param pointer a pointer to some variable of any type. (casting). Can be NULL.
36+
* @param index an integer.
37+
* @return a pointer to the new LinkedListNode.
38+
*/
39+
void *insertItem(LinkedList *list, void *pointer, int index){
40+
LinkedListNode *node = malloc(sizeof(LinkedListNode));
41+
node->pointer = pointer;
42+
node->index = index;
43+
if (list->length != 0) {
44+
node->next = list->first;
45+
node->prev = list->first->prev;
46+
list->first->prev->next = node;
47+
list->first->prev = node;
48+
} else {
49+
list->first = node;
50+
node->prev = node;
51+
node->next = node;
52+
}
53+
list->length++;
54+
return node;
55+
}
56+
57+
/**
58+
* Removes a specific item from a list.
59+
* @param list a linked list
60+
* @param item a LinkedListNode pointer to some item in 'list'.
61+
*/
62+
void removeItem(LinkedList *list, LinkedListNode *item){
63+
LinkedListNode *oldPrev = item->prev;
64+
LinkedListNode *oldNext = item->next;
65+
if(list->length > 1){
66+
oldPrev->next = oldNext;
67+
oldNext->prev = oldPrev;
68+
free(item);
69+
list->length--;
70+
}
71+
else if(list->length == 1){
72+
free(item);
73+
list->first = NULL;
74+
list->length = 0;
75+
}
76+
}

LinkedList.h

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef CLUSTER_LINKEDLIST_H
2+
#define CLUSTER_LINKEDLIST_H
3+
4+
#include "VerticesGroup.h"
5+
6+
typedef struct _LinkedListNode {
7+
void *pointer;
8+
int index;
9+
struct _LinkedListNode *next;
10+
struct _LinkedListNode *prev;
11+
} LinkedListNode;
12+
typedef struct _LinkedList {
13+
LinkedListNode *first;
14+
int length;
15+
} LinkedList;
16+
17+
LinkedList *createLinkedList();
18+
19+
void freeLinkedList(LinkedList *list);
20+
21+
void *insertItem(LinkedList *list, void *pointer, int index);
22+
23+
void removeItem(LinkedList *list, LinkedListNode *item);
24+
25+
#endif

VerticesGroup.c

+51-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
VerticesGroup *createVerticesGroup() {
88
VerticesGroup *group = malloc(sizeof(VerticesGroup));
99
group->size = 0;
10+
group->edgesMinusBHatSubMatrix = NULL;
11+
group->edgeSubMatrix = NULL;
12+
group->bSubMatrix = NULL;
13+
group->bHatSubMatrix = NULL;
1014
return group;
1115
}
1216

@@ -20,13 +24,21 @@ void freeVerticesGroup(VerticesGroup *group) {
2024
node = temp;
2125
} while (node != group->first);
2226
}
23-
freeMatrix(group->bHatSubMatrix);
24-
group->edgeSubMatrix->free(group->edgeSubMatrix);
27+
if (group->bHatSubMatrix != NULL) {
28+
freeMatrix(group->bHatSubMatrix);
29+
}
30+
if (group->edgesMinusBHatSubMatrix != NULL) {
31+
freeMatrix(group->edgesMinusBHatSubMatrix);
32+
}
33+
if (group->edgeSubMatrix != NULL) {
34+
group->edgeSubMatrix->free(group->edgeSubMatrix);
35+
}
2536
}
2637

2738
VertexNode *addVertexToGroup(VerticesGroup *group, int index) {
2839
VertexNode *node = malloc(sizeof(VertexNode));
2940
node->index = index;
41+
node->hasMoved = 0;
3042
if (group->size != 0) {
3143
node->next = group->first;
3244
node->prev = group->first->prev;
@@ -41,15 +53,29 @@ VertexNode *addVertexToGroup(VerticesGroup *group, int index) {
4153
return node;
4254
}
4355

56+
void removeVertexFromGroup(VerticesGroup *group, VertexNode *node) {
57+
if (group->first == node) {
58+
if (group->size == 1) {
59+
group->first = NULL;
60+
} else {
61+
group->first = node->next;
62+
}
63+
}
64+
node->prev->next = node->next;
65+
node->next->prev = node->prev;
66+
group->size--;
67+
free(node);
68+
}
69+
4470
/**
4571
* Adds a sequence of indices to the group.
4672
* @param group the group to which nodes are added.
4773
* @param sequence a sequence of integers, representing nodes in a graph.
4874
* @param length the length of the input sequence.
4975
*/
50-
void addSequence(VerticesGroup *group, int *sequence, int length){
76+
void addSequence(VerticesGroup *group, int *sequence, int length) {
5177
int i;
52-
for(i = 0; i < length; ++i)
78+
for (i = 0; i < length; ++i)
5379
addVertexToGroup(group, sequence[i]);
5480
}
5581

@@ -66,6 +92,7 @@ void calculateSubMatrix(Matrix *A, int M, VerticesGroup *group) {
6692
int i = 0, j;
6793
if (group->size != 0) {
6894
group->edgeSubMatrix = spmat_allocate_list(group->size);
95+
group->edgesMinusBHatSubMatrix = createMatrix(group->size);
6996
group->bSubMatrix = createMatrix(group->size);
7097
group->bHatSubMatrix = createMatrix(group->size);
7198
group->verticesArr = malloc(sizeof(int) * group->size);
@@ -81,6 +108,7 @@ void calculateSubMatrix(Matrix *A, int M, VerticesGroup *group) {
81108
row[j] = readVal(A, group->verticesArr[i], group->verticesArr[j]);
82109
/* For each vertex v: A[v][0] + ... + A[v][n-1] = deg(v) */
83110
expectedEdges = A->rowSums[group->verticesArr[i]] * A->rowSums[group->verticesArr[j]] / M;
111+
setVal(group->edgesMinusBHatSubMatrix, i, j, -expectedEdges);
84112
setVal(group->bSubMatrix, i, j, row[j] - expectedEdges);
85113
/* the case where delta(i,j)=0 */
86114
if (i != j) {
@@ -89,10 +117,29 @@ void calculateSubMatrix(Matrix *A, int M, VerticesGroup *group) {
89117
}
90118
/* the case where i=j and so delta(i,j)=1. we subtract deg(i) from B[g][i][j]. */
91119
setVal(group->bHatSubMatrix, i, i, readVal(group->bSubMatrix, i, i) - group->bSubMatrix->rowSums[i]);
120+
setVal(group->edgesMinusBHatSubMatrix, i, i,
121+
readVal(group->edgesMinusBHatSubMatrix, i, i) - group->bSubMatrix->rowSums[i]);
92122
group->edgeSubMatrix->add_row(group->edgeSubMatrix, row, i);
93123
}
94124

95125
free(row);
96126
}
97127
}
98128

129+
/**
130+
* Calculate modularity delta of group's division given by an eigenvector
131+
* @param group
132+
* @param s eigenvector
133+
* @return
134+
*/
135+
double calculateModularity(VerticesGroup *group, double *s) {
136+
double *res, numRes;
137+
res = malloc(group->size * sizeof(double));
138+
group->edgeSubMatrix->mult(group->edgeSubMatrix, s, res);
139+
numRes = vectorMult(s, res, group->size);
140+
matrixVectorMult(group->edgesMinusBHatSubMatrix, s, res);
141+
numRes -= vectorMult(s, res, group->size);
142+
numRes *= 0.5;
143+
free(res);
144+
return numRes;
145+
}

VerticesGroup.h

+9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
typedef struct vertexNode {
88
int index;
9+
/*Has the node's group changed during modularity maximization*/
10+
int hasMoved;
911
struct vertexNode *next;
1012
struct vertexNode *prev;
1113
} VertexNode;
@@ -15,8 +17,11 @@ typedef struct verticesGroup {
1517
int size;
1618
int *verticesArr;
1719
spmat *edgeSubMatrix;
20+
/*a matrix that equals bHat-A*/
21+
Matrix *edgesMinusBHatSubMatrix;
1822
Matrix *bSubMatrix;
1923
Matrix *bHatSubMatrix;
24+
2025
} VerticesGroup;
2126

2227
VerticesGroup *createVerticesGroup();
@@ -25,8 +30,12 @@ void freeVerticesGroup(VerticesGroup *group);
2530

2631
VertexNode *addVertexToGroup(VerticesGroup *group, int index);
2732

33+
void removeVertexFromGroup(VerticesGroup *group, VertexNode *node);
34+
2835
void addSequence(VerticesGroup *group, int *sequence, int length);
2936

3037
void calculateSubMatrix(Matrix *A, int M, VerticesGroup *group);
3138

39+
double calculateModularity(VerticesGroup *group, double *s);
40+
3241
#endif

cluster.c

+24-63
Original file line numberDiff line numberDiff line change
@@ -5,73 +5,34 @@
55
#include "spmat.h"
66
#include "graph.h"
77
#include "VerticesGroup.h"
8-
9-
void randVector(double *vector, int n);
10-
11-
void printVector(double *vector, int length);
8+
#include "LinkedList.h"
9+
#include "division.h"
1210

1311
int main() {
14-
spmat *A;
15-
Matrix *AMatrix;
16-
int M, n, gSize = 20;
17-
double *vector, *s, lambda;
18-
graph *G = constructGraphFromInput("graph.in");
19-
int gVertices[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
12+
int i = 1, j;
13+
LinkedList *groupsLst;
14+
LinkedListNode *node;
2015
VerticesGroup *group;
21-
n = G->n;
16+
VertexNode *vNode;
17+
graph *G = constructGraphFromInput("graph.in");
2218
srand(time(0));
23-
vector = malloc(gSize * sizeof(double));
24-
s = malloc(gSize * sizeof(double));
25-
AMatrix = createMatrix(n);
26-
/* A = generateRandomSymSpmat(n, 20, AMatrix); */
27-
A = G->spAdjMat;
28-
AMatrix = G->adjMat;
29-
M = G->M;
30-
group = createVerticesGroup();
31-
addSequence(group, gVertices, gSize);
32-
calculateSubMatrix(AMatrix, M, group);
33-
randVector(vector, gSize);
34-
printf("Edges matrix:\n");
35-
printSpmat(A);
36-
printf("\nEdges sub matrix:\n");
37-
printSpmat(group->edgeSubMatrix);
38-
printf("\nB sub matrix:\n");
39-
printMatrix(group->bSubMatrix);
40-
printf("\nB-hat sub matrix:\n");
41-
printMatrix(group->bHatSubMatrix);
42-
printf("\nShifted B-hat sub matrix:\n");
43-
setMatrixShift(group->bHatSubMatrix, 1);
44-
printMatrix(group->bHatSubMatrix);
45-
setMatrixShift(group->bHatSubMatrix, 0);
46-
printf("\ns vector:\n");
47-
lambda = powerIteration(group->bHatSubMatrix, vector, s);
48-
printVector(s, gSize);
49-
printf("\nlambda: %f\n", lambda);
50-
return 0;
51-
}
52-
53-
/**
54-
* Generate a random vector
55-
* @param vector an allocated array of size n for the vector
56-
* @param n the size of the vector
57-
*/
58-
void randVector(double *vector, int n) {
59-
int i;
60-
for (i = 0; i < n; i++) {
61-
*(vector + i) = rand();
19+
groupsLst = divisionAlgorithm(G);
20+
node = groupsLst->first;
21+
if (node != NULL) {
22+
do {
23+
printf("Group %d:\n", i);
24+
group = (VerticesGroup *) node->pointer;
25+
vNode = group->first;
26+
for (j = 0; j < group->size; j++) {
27+
printf("%d ", vNode->index);
28+
vNode = vNode->next;
29+
}
30+
printf("\n\n");
31+
i++;
32+
node = node->next;
33+
} while (node != groupsLst->first);
6234
}
63-
}
6435

65-
/**
66-
* Print vector
67-
* @param vector
68-
* @param length
69-
*/
70-
void printVector(double *vector, int length) {
71-
int i;
72-
printf("( ");
73-
for (i = 0; i < length; i++) {
74-
printf("%.1f ", vector[i]);
75-
}
76-
printf(" )\n");
36+
return 0;
7737
}
38+

0 commit comments

Comments
 (0)