Skip to content

Commit 4f7e69f

Browse files
author
zjroth
committedJul 30, 2012
Added license and matlab files; modified readme and .gitignore
1 parent 2871b08 commit 4f7e69f

File tree

6 files changed

+274
-4
lines changed

6 files changed

+274
-4
lines changed
 

‎+Cliquer/Compile.m

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
function Compile()
2+
% Compiles Cliquer and the MEX files using it.
3+
% Invokes the system 'make' command and the MATLAB command 'mex'.
4+
5+
% The directory in which the Cliquer source code resides.
6+
strDir = fileparts(which('Cliquer.Compile')); %[fileparts(tmp) '/cliquer/'];
7+
8+
% clean old stuff
9+
system(['make -C ' strDir '/cliquer/ clean']);
10+
11+
% Build cliquer.
12+
system(['make -C ' strDir '/cliquer/']);
13+
14+
% A function name.
15+
strFcn = 'FindAll';
16+
17+
% Complile the MEX function.
18+
mex(['-I' strDir], ...
19+
['-I' strDir '/cliquer'], ...
20+
[strDir '/' strFcn '.c'], ...
21+
[strDir '/cliquer/cliquer.o'], ...
22+
[strDir '/cliquer/graph.o'], ...
23+
[strDir '/cliquer/reorder.o']);
24+
25+
% The resultant MEX file will be automatically placed in the current
26+
% working directory. Move this file to the Cliquer package directory.
27+
system(['mv ' strFcn '.mex* ' strDir '/']);
28+
29+
% Tell the user that we're done compiling.
30+
disp('Finished compiling Cliquer!');
31+
end

‎+Cliquer/FindAll.c

+187
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#include <math.h>
2+
#include "mex.h"
3+
#include <stdio.h>
4+
#include "cliquer.h"
5+
6+
/* Output Arguments */
7+
#define OUTPUT plhs[0]
8+
9+
#if !defined(MAX)
10+
#define MAX(A, B) ((A) > (B) ? (A) : (B))
11+
#endif
12+
13+
#if !defined(MIN)
14+
#define MIN(A, B) ((A) < (B) ? (A) : (B))
15+
#endif
16+
17+
graph_t* MatrixToGraph(double *adjac_mtx_ptr, int iGraphOrder)
18+
{
19+
int i, j, idx;
20+
graph_t *ptrGraph;
21+
22+
/* Initialize the graph that we want to return. */
23+
ptrGraph = graph_new(iGraphOrder);
24+
25+
/* Loop through the adjacency matrix to create the graph. We assume
26+
* that the adjacency matrix is symmetric and only consider the super-
27+
* diagonals of the matrix. */
28+
/* The indexing here seems flipped, but it's due to the translation
29+
* between MATLAB and C element ordering. */
30+
for (j = 0; j < iGraphOrder; j++)
31+
for (i = j + 1; i < iGraphOrder; i++)
32+
{
33+
/* The matrix adj_mtx is stored as a 1-dimensional array, so
34+
* we must convert the coordinate (i, j) to the corresponding
35+
* 1-dimensional index. */
36+
idx = j + i * iGraphOrder;
37+
38+
/* If the entry of the adjacency matrix is a 1, we want to add
39+
* an edge to our graph. */
40+
if(adjac_mtx_ptr[idx] == 1)
41+
GRAPH_ADD_EDGE(ptrGraph, i, j);
42+
}
43+
44+
/* Just to be cautios, ensure that we've produced a valid graph. */
45+
ASSERT(graph_test(ptrGraph, NULL));
46+
47+
return ptrGraph;
48+
}
49+
50+
int FindCliques(graph_t *ptrGraph, int iMinWeight, int iMaxWeight,
51+
int bOnlyMaximal, int iMaxNumCliques, set_t *ptrCliqueList,
52+
int iCliqueListLength)
53+
{
54+
int iNumCliques;
55+
clique_options localopts;
56+
57+
/* Set the clique_options. These fields should all be null except
58+
* 'clique_list' and 'clique_list_length', which store the list of
59+
* cliques and the maximum length of the list of cliques, respectively. */
60+
localopts.time_function = NULL;
61+
localopts.reorder_function = NULL;
62+
localopts.reorder_map = NULL;
63+
localopts.clique_list = ptrCliqueList;
64+
localopts.clique_list_length = iCliqueListLength;
65+
localopts.user_function = NULL;
66+
localopts.user_data = NULL;
67+
68+
/* Find all of the maximal (argument 4) cliques in this graph of
69+
* minimum size 1 (argument 2) and no maximum size (argument 3). */
70+
iNumCliques = clique_find_all(ptrGraph, iMinWeight, iMaxWeight, bOnlyMaximal,
71+
&localopts);
72+
73+
return iNumCliques;
74+
}
75+
76+
/**
77+
* Find all of the maximal cliques in the provided matlab matrix, which
78+
* should represent an adjacency matrix. Most of this function just
79+
* translates from MATLAB input for processing with Cliquer and then
80+
* translates the output of Cliquer back into MATLAB data.
81+
*
82+
* The MATLAB arguments are as follows:
83+
* prhs[0] mtxAdj The input adjacency matrix. Only the upper-
84+
* triangular part of this is used.
85+
* prhs[1] iMinWeight The minimum weight of cliques to find.
86+
* prhs[2] iMaxWeight The maximum weight of cliques to find.
87+
* prhs[3] bOnlyMaximal If `false` (i.e., zero), return all cliques;
88+
* otherwise, return only maximal cliques.
89+
* prhs[4] iMaxNumCliques The maximum number of cliques to be returned
90+
* (due to a [perceived] limitation of Cliquer).
91+
*/
92+
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
93+
{
94+
/* Ensure that an appropriate number of arguments were provided and that an
95+
* an appropriate number of return variables were requested. */
96+
if (nrhs != 5)
97+
mexErrMsgTxt("Exactly five input arguments are required.");
98+
else if (nlhs > 2)
99+
mexErrMsgTxt("Too many output arguments were requested.");
100+
101+
/* Retrieve and store the size of the input adjacency matrix for size
102+
* checking and later use. */
103+
mwSize iRows = mxGetM(prhs[0]);
104+
mwSize iCols = mxGetN(prhs[0]);
105+
106+
/* Perform size- and type-checking on the input values. */
107+
if ((iRows != iCols) || !mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]))
108+
mexErrMsgTxt("The first argument must be an integer-valued square matrix.");
109+
else if (mxGetM(prhs[1]) != 1 || mxGetN(prhs[1]) != 1 || !mxIsNumeric(prhs[1]))
110+
mexErrMsgTxt("The second argument must be an integer.");
111+
else if (mxGetM(prhs[2]) != 1 || mxGetN(prhs[2]) != 1 || !mxIsNumeric(prhs[2]))
112+
mexErrMsgTxt("The third argument must be an integer.");
113+
else if (mxGetM(prhs[3]) != 1 || mxGetN(prhs[3]) != 1 || !mxIsLogical(prhs[3]))
114+
mexErrMsgTxt("The fourth argument must be a logical scalar.");
115+
else if (mxGetM(prhs[4]) != 1 || mxGetN(prhs[4]) != 1 || !mxIsNumeric(prhs[4]))
116+
mexErrMsgTxt("The fifth argument must be an integer.");
117+
118+
/* Declare variables to hold the input arguments (except the first). Each
119+
* of these can be retrieved by indexing `prhs`. */
120+
int iMinWeight = MAX(0, (int) mxGetScalar(prhs[1]));
121+
int iMaxWeight = MIN(iCols, (int) mxGetScalar(prhs[2]));
122+
int bOnlyMaximal = (mxGetScalar(prhs[3]) == 0) ? FALSE : TRUE;
123+
int iMaxNumCliques = (int) mxGetScalar(prhs[4]);
124+
125+
/* These variables are for storing the graph corresponding to the input
126+
* adjacency matrix, the list of cliques found in that graph, and the return
127+
* value for this MATLAB function. */
128+
graph_t *ptrGraph;
129+
set_t arrCliqueList[iMaxNumCliques];
130+
double *ptrOutputMatrix;
131+
132+
/* Miscellaneous variable declarations. */
133+
int i, j, idx, iNumCliques, iNumCliquesReturned;
134+
135+
/* Create a graph from the adjacency matrix `prhs[0]`. */
136+
ptrGraph = MatrixToGraph(mxGetPr(prhs[0]), iCols);
137+
138+
/* Find the cliques in the associated graph. */
139+
iNumCliques = FindCliques(ptrGraph, iMinWeight, iMaxWeight, bOnlyMaximal,
140+
iMaxNumCliques, arrCliqueList, iMaxNumCliques);
141+
142+
/* We are done with the graph. Free the memory used to store it. */
143+
graph_free(ptrGraph);
144+
145+
/* Retrieve the number of cliques returned by the function, which is bounded
146+
* above by `iMaxNumCliques`. */
147+
iNumCliquesReturned = MIN(iNumCliques, iMaxNumCliques);
148+
149+
/* Output the total number of cliques found. */
150+
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
151+
mxGetPr(plhs[0])[0] = iNumCliques;
152+
153+
/* Create the output matrix, which will have one row for each clique and
154+
* one column for each node of the graph. */
155+
plhs[1] = mxCreateDoubleMatrix(iNumCliquesReturned, iCols, mxREAL);
156+
ptrOutputMatrix = mxGetPr(plhs[1]);
157+
158+
/* Fill in the rows of the output matrix by looping through the cliques
159+
* that were found. */
160+
for (i = 0; i < iNumCliquesReturned; i++)
161+
{
162+
/* Fill in the entries of this row by looping through the corresponding
163+
* clique to find the vertices contained in the clique. */
164+
for (j = 0; j < SET_MAX_SIZE(arrCliqueList[i]); j++)
165+
{
166+
/* The entries of the output matrix are initialized to zeros. If
167+
* the vertex 'j' is in clique 'i', place a 1 in the (i, j) entry
168+
* of the output matrix. */
169+
if (SET_CONTAINS(arrCliqueList[i], j))
170+
{
171+
/* Matrices in Matlab are stored column-wise (i.e., the columns
172+
* of the matrix are stacked and stored as a column vector); so,
173+
* we must access the output as a 1-dimensional array. The index
174+
* of the entry corresponding to the (i, j) position in this
175+
* matrix is calculated in 'idx' below. */
176+
idx = j * iNumCliques + i;
177+
ptrOutputMatrix[idx] = 1;
178+
}
179+
}
180+
181+
/* Now that we've stored this clique as a row in a matrix, we can free
182+
* the memory used to store the clique. */
183+
set_free(arrCliqueList[i]);
184+
}
185+
186+
return;
187+
}

‎+Cliquer/FindAll.m

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
%--------------------------------------------------------------------------
2+
% Usage:
3+
% [iNumCliques, mtxCliques] = Cliquer.FindAll(mtxAdj, iMinSize,
4+
% iMaxSize, bOnlyMaximal, iMaxNumCliques)
5+
% Description:
6+
% Find all of the cliques of a given size in the graph represented by
7+
% (the upper-triangular portion of) the input matrix.
8+
% Arguments:
9+
% mtxAdj
10+
% An adjacency matrix for a graph.
11+
% iMinSize
12+
% The minimum size of the cliques to be found. Must be positive.
13+
% iMaxSize
14+
% The maximum size of the cliques to be found. Must be
15+
% nonnegative. Set to zero to have no upper bound on clique
16+
% size.
17+
% bOnlyMaximal
18+
% A logical input that is `true` if only maximal cliques should be
19+
% counted and `false` if all cliques should be counted.
20+
% iMaxNumCliques
21+
% The maximum number of cliques to be returned by this function. I
22+
% believe that this is necessary due to a limitation of Cliquer. Note
23+
% that the correct total number "iNumCliques" is returned even if
24+
% "iMaxNumCliques" is smaller.
25+
% Return values:
26+
% iNumCliques
27+
% The total number of cliques within the range of sizes.
28+
% mtxCliques
29+
% The matrix of actual cliques found (up to `iMaxNumCliques` only).
30+
%--------------------------------------------------------------------------
31+
32+
% THIS IS JUST A DUMMY FILE SO THAT WE CAN HAVE APPROPRIATE
33+
% DOCUMENTATION OF THE C-CODE BY THE SAME NAME!

‎.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
*~
22
*.o
3-
*.mex*
3+
*.mex*
4+
+Cliquer/cliquer/cl

‎LICENSE.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
The matlab-cliquer project is licensed unter the GNU General Public Licence Version 2:
2+
3+
> Copyright (C) 2012 Carina Curto, Zachary Roth
4+
>
5+
> This program 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 program 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. See the GNU
13+
> General Public License for more details.
14+
>
15+
> You should have received a copy of the GNU General Public License
16+
> along with this program; if not, write to the Free Software
17+
> Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18+
> USA

‎README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
Short description
1+
Description
22
--------------------
33
This project contains a MATLAB package containing a MEX interface to the C program [Cliquer](http://users.tkk.fi/pat/cliquer.html/), which contains a collection of optimized routines for finding cliques in graphs. A (very slightly) modified version of the Cliquer project is included here for convenience (and because a slight modification was required to make the MEX compiler happy on my machine).
44

5-
This project currently only utilizes a small subset of Cliquer's functionality (specifically a portion dealing with unweighted graphs).
5+
Additional README and LICENSE files for Cliquer can be found in the directory `+Cliquer/cliquer/`. This project currently utilizes only a small subset of Cliquer's functionality (specifically a portion dealing with unweighted graphs).
66

77
Usage
88
--------------------
@@ -12,4 +12,4 @@ Usage
1212

1313
2. Execute the MATLAB command `Cliquer.Compile()` to compile both the C program Cliquer and the MEX interface. This compile function is provided for convenience but basically just compiles Cliquer, compiles the MEX function, and then moves the MEX function into the package directory.
1414

15-
3. Cliquer's functionality can now be accessed with the command `Cliquer.FindAll`, and documentation can be accessed with `help Cliquer.FindAll`.
15+
3. Cliquer's functionality can now be accessed with the command `Cliquer.FindAll`, and documentation can be accessed with `help Cliquer.FindAll`.

0 commit comments

Comments
 (0)