#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include <math.h>
#include <assert.h>
#if defined(HAVE_CALLGRIND)
#include <valgrind/callgrind.h>
#else
#define CALLGRIND_START_INSTRUMENTATION() do { } while (0)
#define CALLGRIND_STOP_INSTRUMENTATION() do { } while (0)
#define CALLGRIND_DUMP_STATS() do { } while (0)
#define CALLGRIND_ZERO_STATS() do { } while (0)
#define CALLGRIND_TOGGLE_COLLECT() do { } while (0)
#endif
#include "smut.h"
#include "timer.h"
#include "auction.h"
#if !defined(HAVE_RESTRICT)
#define restrict
#endif
int
main (int argc, char **argv)
{
FILE *f, *fout = NULL;
int err;
struct spcsr_t A;
double mu_min;
int relgap = 0;
double shiftamount;
double *R, *C;
double *expint;
int *match, *invmatch;
double *price, *profit = NULL;
int errflg, i, j;
double p, d, td;
volatile double auction_primal = 0.0, mc64_primal = 0.0;
/* gcc-3.4 compiler bug? ap becomes zero after calling mc64
with optimization */
struct Timer timer;
assert(sizeof(int) == 4);
if (argc <= 1) {
printf("No files\n");
return -1;
}
f = fopen(argv[1], "rb");
if (!f) {
perror("Error opening file: ");
return -1;
}
err = spcsr_load_binfile (f, &A);
if (err) {
printf ("Error reading: %d\n", err);
return -1;
}
fclose(f);
mu_min = 1.0 / A.nr;
if (argc > 3)
mu_min = strtod(argv[3], NULL);
if (argc > 4)
relgap = 1;
if (A.nr != A.nc) return 0;
R = malloc (A.nr * sizeof(double));
C = malloc (A.nc * sizeof(double));
expint = malloc (A.nent * sizeof(double));
match = malloc (A.nc * sizeof(int));
invmatch = malloc (A.nr * sizeof(int));
memset (match, -1, A.nc * sizeof(int));
memset (invmatch, -1, A.nr * sizeof(int));
price = calloc (A.nc, sizeof(double));
printf ("nr = %d nc = %d nent = %d\n", A.nr, A.nc, A.nent);
#if 0
spcsr_lascaling (&A, R, C);
spcsr_apply_scaling (&A, R, C);
#elif 1
spcsr_lascale (&A, R, C);
#endif
#if 1
auction_toexpint (&A, expint);
#else
auction_toexp (&A, expint);
#endif
shiftamount = auction_shift (&A, expint);
{
int k;
double mx = -HUGE_VAL, mn = HUGE_VAL;
for (k = 0; k < A.nent; ++k) {
double e = expint[k];
if (e < mn) mn = e;
if (e > mx) mx = e;
}
printf ("expint max: %g , min %g\n", mx, mn);
}
memset (match, -1, A.nc * sizeof(int));
memset (price, 0, A.nc * sizeof(double));
CALLGRIND_START_INSTRUMENTATION();
initialize_timer (&timer);
start_timer (&timer);
errflg = auction_scaling (A, expint, match, price, mu_min, relgap);
stop_timer (&timer);
if (errflg)
fprintf (stderr, "Errflg: %d\n", errflg);
CALLGRIND_STOP_INSTRUMENTATION();
auction_eval_primal_mdual (A, expint, match, price, &auction_primal, &d);
td = timer_duration(timer);
printf ("Primal: %20g\nDual: %20g\nTime: %20g\nmu_min: %20g\n",
auction_primal, d, td, mu_min);
{
int i, j;
for (j = 0; j < A.nc; ++j) {
if (match[j] < 0) printf("column %d is unmatched\n", j);
if (match[j] >= A.nr) printf("column %d's match out of range (%d/%d)\n",
j, match[j], A.nr);
}
for (i = 0; i < A.nr; ++i) {
int k;
int found_match = 0;
for (k = A.rowoff[i]; k < A.rowoff[i+1]; ++k) {
const int j = A.colind[k];
if (i == match[j]) ++found_match;
}
if (!found_match) printf ("row %d is unmatched\n", i);
if (found_match > 1) printf ("row %d is multiply matched\n", i);
}
}
if (argc > 2) {
fout = fopen (argv[2], "wb");
}
if (fout) {
int bo_tag = 1;
int i, j, k;
fwrite (&bo_tag, sizeof(int), 1, fout);
fwrite (&mu_min, sizeof(double), 1, fout);
fwrite (&relgap, sizeof(int), 1, fout);
fwrite (&auction_primal, sizeof(double), 1, fout);
fwrite (&d, sizeof(double), 1, fout);
fwrite (&td, sizeof(double), 1, fout);
fwrite (match, sizeof(int), A.nc, fout);
profit = malloc (A.nr * sizeof(double));
for (i = 0; i < A.nr; ++i) {
profit[i] = 0.0;
for (k = A.rowoff[i]; k < A.rowoff[i+1]; ++k) {
const int j = A.colind[k];
const double e = expint[k];
#if 0
if (e > 0 && isinf(e))
printf ("inf expint[%d] (%d, %d)\n", k, i, j);
#endif
if (isinf(price[j]))
price[j] = e;
if (!isinf(e))
profit[i] = fmax(profit[i], price[j] - e);
assert(!isinf(profit[i]));
}
if (profit[i] == -HUGE_VAL) profit[i] = 0.0;
}
#if 0
printf ("shiftamount %g\n", shiftamount);
#endif
for (j = 0; j < A.nc; ++j) {
double tmp;
tmp = C[j] * scalbn(1.0, (int)price[j] + shiftamount);
#if 0
printf ("price[%d] = %g ===> %g (%g)\n", j, price[j], tmp, C[j]);
#endif
price[j] = tmp;
}
for (i = 0; i < A.nc; ++i) {
double tmp;
tmp = R[i] * scalbn(1.0, (int)profit[i]);
#if 0
printf ("profit[%d] = %g ===> %g (%g)\n", i, profit[i], tmp, R[i]);
#endif
profit[i] = tmp;
}
fwrite(price, sizeof(double), A.nc, fout);
fwrite(profit, sizeof(double), A.nc, fout);
}
if (profit) free(profit);
free (price);
free (invmatch);
free (match);
free (expint);
free (R);
free (C);
spcsr_free (&A);
return 0;
}