00001 #include "mex.h"
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <math.h>
00005 #include "mexhead.h"
00006 #include "Doc/assignment_docstring.h"
00007 #include "graphtypes.h"
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define NARGIN_MIN 1
00036 #define NARGIN_MAX 1
00037 #define NARGOUT_MIN 1
00038 #define NARGOUT_MAX 3
00039
00040 #define ARG_rho 0
00041 #define ARG_pi1 0
00042 #define ARG_pi2 1
00043 #define ARG_s 2
00044
00045 #define PROGNAME assignment
00046 static const char *progname = "assignment";
00047 static const char *in_specs[NARGIN_MAX] = {
00048 "IM"};
00049 static const char *in_names[NARGIN_MAX] = {
00050 "rho"};
00051 static const char *out_names[NARGOUT_MAX] = {
00052 "pi1",
00053 "pi2",
00054 "score" };
00055
00056
00057 static
00058 Graph
00059 translateMatrix2Graph(int *size, const mxArray *matrix, int *total_weight);
00060
00061
00067 #ifdef StaticP
00068 StaticP
00069 #endif
00070 void
00071 mexFunction(int nlhs,
00072 mxArray *plhs[],
00073 int nrhs,
00074 const mxArray *prhs[])
00075 {
00076 char errstr[256];
00077 int i, j;
00078 int M, N;
00079 int score;
00080 int size;
00081 int weight;
00082 int *Mate;
00083 Graph graph;
00084 double *pi1;
00085 double *pi2;
00086 Edge p = NULL;
00087
00088
00089 if (nrhs < 0) {
00090 plhs[0] = mxt_PackSignature((mxt_Signature) (-nrhs),
00091 NARGIN_MIN, NARGIN_MAX,
00092 NARGOUT_MIN, NARGOUT_MAX,
00093 in_names, in_specs, out_names, docstring);
00094 return;
00095 }
00096
00097 if ((nrhs < NARGIN_MIN) || (nrhs > NARGIN_MAX))
00098 mexErrMsgTxt((snprintf(errstr, sizeof(errstr),
00099 "%s: Expect %d <= input args <= %d",
00100 progname, NARGIN_MIN, NARGIN_MAX), errstr));
00101 if ((nlhs < NARGOUT_MIN) || (nlhs > NARGOUT_MAX))
00102 mexErrMsgTxt((snprintf(errstr, sizeof(errstr),
00103 "%s: Expect %d <= output args <= %d",
00104 progname, NARGOUT_MIN, NARGOUT_MAX), errstr));
00105 mexargparse(nrhs, prhs, in_names, in_specs, NULL, progname);
00106
00107
00108
00109 graph = translateMatrix2Graph(&size, prhs[ARG_rho], &weight);
00110 Mate = Weighted_Match(graph, 1, 1);
00111
00112
00113 M = mxGetM(prhs[ARG_rho]);
00114 N = mxGetN(prhs[ARG_rho]);
00115 plhs[ARG_pi1] = mxCreateDoubleMatrix(1, M, mxREAL);
00116 plhs[ARG_pi2] = mxCreateDoubleMatrix(1, N, mxREAL);
00117 plhs[ARG_s] = mxCreateDoubleMatrix(1, 1, mxREAL);
00118 pi1 = mxGetPr(plhs[ARG_pi1]);
00119 pi2 = mxGetPr(plhs[ARG_pi2]);
00120
00121
00122 size = Degree(graph, 0);
00123
00124
00125 for (i = 1; i <= N; i++) {
00126 pi2[i-1] = Mate[i] ? Mate[i] - N : 0;
00127 #ifdef MEX_DEBUG
00128 printf("%d -> \t%d\n", i, (int) pi2[i-1]);
00129 #endif
00130 }
00131
00132 for (i = N+1; i <= N+M; i++) {
00133 pi1[i-(N+1)] = Mate[i] ? Mate[i] : 0;
00134 #ifdef MEX_DEBUG
00135 printf("%d -> \t%d\n", i, (int) pi1[i-(N+1)]);
00136 #endif
00137 }
00138
00139 score = 0;
00140 for (i = 1; i <= size; i++) {
00141 p = FirstEdge(graph, i);
00142 for (j = 1; j <= Degree(graph, i); j++) {
00143 if (EndPoint(p) == Mate[i]) {
00144 score += ELabel(p);
00145 #ifdef MEX_DEBUG
00146 printf("%d -> \t%d\t%d\n", i, Mate[i], ELabel(p));
00147 #endif
00148 }
00149 p = NextEdge(p);
00150 }
00151 }
00152
00153 *mxGetPr(plhs[ARG_s]) = (double) score * 0.5;
00154 }
00155
00156
00163 static
00164 Graph
00165 translateMatrix2Graph(int *size, const mxArray *matrix, int *total_weight)
00166 {
00167 int edges = 0;
00168 int degree = 0;
00169 int vlabel = 0;
00170 int elabel = 0;
00171 int adj_node = 0;
00172 int i = 0;
00173 int j = 0;
00174 int classes1 = 0;
00175 int classes2 = 0;
00176 int weight = 0;
00177 char c = 0;
00178 double *ptr = (double *) NULL;
00179 Graph graph = (Graph) NULL;
00180
00181
00182 #ifdef MEX_DEBUG
00183 mexPrintf("Debug: Entering translateMatrix2Graph().\n");
00184 #endif
00185
00186 classes1 = mxGetN(matrix);
00187 classes2 = mxGetM(matrix);
00188 ptr = mxGetPr(matrix);
00189
00190 *size = classes1 + classes2;
00191 edges = classes1 * classes2;
00192
00193 graph = NewGraph( *size );
00194
00195 for (i = 1; i <= *size; ++i) {
00196
00197
00198
00199
00200
00201
00202 Xcoord(graph, i) = 0;
00203 Ycoord(graph, i) = 0;
00204 }
00205
00206 *total_weight = 0;
00207
00208 #ifdef MEX_DEBUG
00209 mexPrintf("Debug: Will call AddEdge() %d times.\n", edges);
00210 #endif
00211
00212 for (i = 1; i <= classes1; ++i) {
00213 for (j = 1; j <= classes2; ++j) {
00214 weight = (int) *ptr++;
00215 *total_weight += weight;
00216 AddEdge(graph, i, j + classes1, weight);
00217 }
00218 }
00219
00220 #ifdef MEX_DEBUG
00221 mexPrintf("Debug: Done calling AddEdge() %d times.\n", edges);
00222 mexPrintf("Debug: Leaving translateMatrix2Graph().\n");
00223 #endif
00224
00225 return graph;
00226 }
00227
00228