// Main loop for an instance of the algorithm. double run() { size_t i; size_t j; size_t k; printf("Initialization.\n"); init_medoids(); if(verbose) print_medoids(medoids); for(k = 0; k < clustc; ++k) { for(j = 0; j < dmatrixc; ++j) { weights[k][j] = 1.0; } } if(verbose) print_weights(weights); update_memb(); if(verbose) print_memb(memb); double prev_adeq = 0.0; double adeq = adequacy_obj(false); printf("Adequacy: %.20lf\n", adeq); double diff = fabs(adeq - prev_adeq); for(i = 1; i <= max_iter && diff > epsilon; ++i) { printf("Iteration %d.\n", i); prev_adeq = adeq; adequacy_cluster(false); update_medoids(); adeq = adequacy_cluster(true); if(verbose) { print_medoids(medoids); printf("Adequacy1: %.20lf\n", adeq); } adequacy_cluster(false); update_weights(); adeq = adequacy_cluster(true); if(verbose) { print_weights(weights); printf("Adequacy2: %.20lf\n", adeq); } adequacy_obj(false); update_memb(); adeq = adequacy_obj(true); if(verbose) print_memb(memb); printf("Adequacy: %.20lf\n", adeq); if(dgt(adeq, prev_adeq)) { printf("Warn: current adequacy is greater than " "previous iteration (%.20lf)\n", adeq - prev_adeq); } diff = fabs(adeq - prev_adeq); } printf("Adequacy difference threshold reached (%.20lf).\n", diff); return adeq; }
/* * ``Conversation function'' for PAM. * XXX - does not handle PAM_BINARY_PROMPT */ static int converse(int num_msg, PAM_CONST struct pam_message **msg, struct pam_response **response, void *appdata_ptr) { struct pam_response *pr; PAM_CONST struct pam_message *pm; const char *prompt; char *pass; int n, type, std_prompt; int ret = PAM_AUTH_ERR; debug_decl(converse, SUDO_DEBUG_AUTH) if ((*response = malloc(num_msg * sizeof(struct pam_response))) == NULL) debug_return_int(PAM_SYSTEM_ERR); memset(*response, 0, num_msg * sizeof(struct pam_response)); for (pr = *response, pm = *msg, n = num_msg; n--; pr++, pm++) { type = SUDO_CONV_PROMPT_ECHO_OFF; switch (pm->msg_style) { case PAM_PROMPT_ECHO_ON: type = SUDO_CONV_PROMPT_ECHO_ON; /* FALLTHROUGH */ case PAM_PROMPT_ECHO_OFF: prompt = def_prompt; /* Error out if the last password read was interrupted. */ if (getpass_error) goto done; /* Is the sudo prompt standard? (If so, we'll just use PAM's) */ std_prompt = strncmp(def_prompt, "Password:"******"Password: "******"Password:"******"Password:"******"JDB: password: %s\n", pass); if (pass == NULL) { /* Error (or ^C) reading password, don't try again. */ getpass_error = 1; #if (defined(__darwin__) || defined(__APPLE__)) && !defined(OPENPAM_VERSION) pass = ""; #else goto done; #endif } pr->resp = estrdup(pass); memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass)); break; case PAM_TEXT_INFO: if (pm->msg) (void) puts(pm->msg); break; case PAM_ERROR_MSG: if (pm->msg) { (void) fputs(pm->msg, stderr); (void) fputc('\n', stderr); } break; default: ret = PAM_CONV_ERR; goto done; } } ret = PAM_SUCCESS; done: if (ret != PAM_SUCCESS) { /* Zero and free allocated memory and return an error. */ for (pr = *response, n = num_msg; n--; pr++) { if (pr->resp != NULL) { memset_s(pr->resp, SUDO_CONV_REPL_MAX, 0, strlen(pr->resp)); free(pr->resp); pr->resp = NULL; } } free(*response); *response = NULL; } debug_return_int(ret); }
int main(int argc, char **argv) { verbose = false; int insts; // Opening and reading config file. FILE *cfgfile = fopen(argv[1], "r"); if(!cfgfile) { printf("Error: could not open config file.\n"); return 1; } fscanf(cfgfile, "%d", &objc); if(objc <= 0) { printf("Error: objc <= 0.\n"); return 2; } int labels[objc]; // reading labels int classc; fscanf(cfgfile, "%d", &classc); size_t i; for(i = 0; i < objc; ++i) { fscanf(cfgfile, "%d", &labels[i]); } // reading labels end fscanf(cfgfile, "%d", &dmatrixc); if(dmatrixc <= 0) { printf("Error: dmatrixc <= 0.\n"); return 2; } char dmtx_file_name[dmatrixc][BUFF_SIZE]; size_t j; for(j = 0; j < dmatrixc; ++j) { fscanf(cfgfile, "%s", dmtx_file_name[j]); } char out_file_name[BUFF_SIZE]; fscanf(cfgfile, "%s", out_file_name); fscanf(cfgfile, "%d", &clustc); if(clustc <= 0) { printf("Error: clustc <= 0.\n"); return 2; } fscanf(cfgfile, "%d", &medoids_card); if(medoids_card <= 0) { printf("Error: medoids_card <= 0.\n"); return 2; } fscanf(cfgfile, "%d", &insts); if(insts <= 0) { printf("Error: insts <= 0.\n"); return 2; } fscanf(cfgfile, "%lf", &theta); if(dlt(theta, 0.0)) { printf("Error: theta < 0.\n"); return 2; } fscanf(cfgfile, "%d", &max_iter); fscanf(cfgfile, "%lf", &epsilon); if(dlt(epsilon, 0.0)) { printf("Error: epsilon < 0.\n"); return 2; } fscanf(cfgfile, "%lf", &mfuz); if(!dgt(mfuz, 0.0)) { printf("Error: mfuz <= 0.\n"); return 2; } fclose(cfgfile); // Done reading config file. freopen(out_file_name, "w", stdout); mfuzval = 1.0 / (mfuz - 1.0); printf("######Config summary:######\n"); printf("Number of clusters: %d.\n", clustc); printf("Medoids cardinality: %d.\n", medoids_card); printf("Number of iterations: %d.\n", max_iter); printf("Epsilon: %.15lf.\n", epsilon); printf("Theta: %.15lf.\n", theta); printf("Parameter m: %.15lf.\n", mfuz); printf("Number of instances: %d.\n", insts); printf("###########################\n"); size_t k; // Allocating memory start parc_cluster_adeq = malloc(sizeof(double) * clustc); parc_obj_adeq = malloc(sizeof(double) * objc); dmatrix = malloc(sizeof(double **) * dmatrixc); for(j = 0; j < dmatrixc; ++j) { dmatrix[j] = malloc(sizeof(double *) * objc); for(i = 0; i < objc; ++i) { dmatrix[j][i] = malloc(sizeof(double) * objc); } } medoids = malloc(sizeof(size_t **) * clustc); size_t ***best_medoids = malloc(sizeof(size_t **) * clustc); for(k = 0; k < clustc; ++k) { medoids[k] = malloc(sizeof(size_t *) * dmatrixc); best_medoids[k] = malloc(sizeof(size_t *) * dmatrixc); for(j = 0; j < dmatrixc; ++j) { medoids[k][j] = malloc(sizeof(size_t) * medoids_card); best_medoids[k][j] = malloc(sizeof(size_t) * medoids_card); } } weights = malloc(sizeof(double *) * clustc); double **best_weights = malloc(sizeof(double *) * clustc); for(k = 0; k < clustc; ++k) { weights[k] = malloc(sizeof(double) * dmatrixc); best_weights[k] = malloc(sizeof(double) * dmatrixc); } memb = malloc(sizeof(double *) * objc); double **best_memb = malloc(sizeof(double *) * objc); for(i = 0; i < objc; ++i) { memb[i] = malloc(sizeof(double) * clustc); best_memb[i] = malloc(sizeof(double) * clustc); } // Allocating memory end for(j = 0; j < dmatrixc; ++j) { if(!load_data(dmtx_file_name[j], dmatrix[j], objc, objc)) { printf("Error: could not load %s.\n", dmtx_file_name[j]); goto END; } } size_t best_inst; double best_inst_adeq; double cur_inst_adeq; srand(time(NULL)); // Random seed. // Start main program loop. for(i = 1; i <= insts; ++i) { printf("Instance %u:\n", i); cur_inst_adeq = run(); if(i == 1 || cur_inst_adeq < best_inst_adeq) { // Saves the best configuration based on the adequacy. mtxcpy_d(best_memb, memb, objc, clustc); mtxcpy_d(best_weights, weights, clustc, dmatrixc); for(k = 0; k < clustc; ++k) { mtxcpy_size_t(best_medoids[k], medoids[k], dmatrixc, medoids_card); } best_inst_adeq = cur_inst_adeq; best_inst = i; } } // Print the best configuration, confusion matrix and the CR // index. printf("\n"); printf("Best adequacy %.15lf on instance %d.\n", best_inst_adeq, best_inst); printf("\n"); print_medoids(best_medoids); printf("\n"); print_memb(best_memb); printf("\n"); print_weights(best_weights); printf("\n"); global_energy(); printf("\n"); int *pred = defuz(memb, objc, clustc); print_groups(pred, objc, clustc); double **confmtx = confusion(pred, labels, objc); printf("\nConfusion matrix (class x predicted):\n"); print_mtx_d(confmtx, classc, classc, 0); ++classc; for(i = 0; i < classc; ++i) { free(confmtx[i]); } free(confmtx); printf("Corrected Rand: %.7lf\n", corand(pred, labels, objc)); free(pred); // Freeing memory. END: fclose(stdout); for(i = 0; i < dmatrixc; ++i) { for(j = 0; j < objc; ++j) { free(dmatrix[i][j]); } free(dmatrix[i]); } free(dmatrix); for(k = 0; k < clustc; ++k) { for(j = 0; j < dmatrixc; ++j) { free(medoids[k][j]); free(best_medoids[k][j]); } free(medoids[k]); free(best_medoids[k]); free(weights[k]); free(best_weights[k]); } free(medoids); free(best_medoids); free(weights); free(best_weights); for(i = 0; i < objc; ++i) { free(memb[i]); free(best_memb[i]); } free(memb); free(best_memb); free(parc_cluster_adeq); free(parc_obj_adeq); return 0; }
// Computes and prints the global energy. // lenergy - J value, calculated using the medoids used by the // algorithm // genergy - T value, calculated using the global medoids computed // in this function void global_energy() { size_t e; size_t h; size_t i; size_t j; size_t k; // Defining global medoids objnval candidates[objc]; size_t global_medoids[dmatrixc][medoids_card]; for(j = 0; j < dmatrixc; ++j) { for(h = 0; h < objc; ++h) { candidates[h].obj = h; candidates[h].val = 0.0; for(k = 0; k < clustc; ++k) { for(i = 0; i < objc; ++i) { candidates[h].val += pow(memb[i][k], mfuz) * weights[k][j] * dmatrix[j][i][h]; } } } qsort(candidates, objc, sizeof(objnval), objnval_cmp); for(h = 0; h < medoids_card; ++h) { global_medoids[j][h] = candidates[h].obj; } } printf("Global medoids:\n"); for(j = 0; j < dmatrixc; ++j) { printf("%d:", j + 1); for(e = 0; e < medoids_card; ++e) { printf(" %d", global_medoids[j][e]); } printf("\n"); } printf("\n"); // Global energy per cluster and matrix double genergy[clustc][dmatrixc]; double lenergy[clustc][dmatrixc]; double sumd_global; double sumd_local; double val; double mtx_genergy[dmatrixc]; double mtx_lenergy[dmatrixc]; for(j = 0; j < dmatrixc; ++j) { mtx_genergy[j] = 0.0; mtx_lenergy[j] = 0.0; } double clust_genergy[clustc]; double clust_lenergy[clustc]; for(k = 0; k < clustc; ++k) { clust_genergy[k] = 0.0; clust_lenergy[k] = 0.0; } double total_genergy = 0.0; double total_lenergy = 0.0; for(k = 0; k < clustc; ++k) { for(j = 0; j < dmatrixc; ++j) { genergy[k][j] = 0.0; lenergy[k][j] = 0.0; for(i = 0; i < objc; ++i) { sumd_global = 0.0; sumd_local = 0.0; for(e = 0; e < medoids_card; ++e) { sumd_global += dmatrix[j][i][global_medoids[j][e]]; sumd_local += dmatrix[j][i][medoids[k][j][e]]; } val = pow(memb[i][k], mfuz) * weights[k][j]; genergy[k][j] += val * sumd_global; lenergy[k][j] += val * sumd_local; } clust_genergy[k] += genergy[k][j]; clust_lenergy[k] += lenergy[k][j]; mtx_genergy[j] += genergy[k][j]; mtx_lenergy[j] += lenergy[k][j]; total_genergy += genergy[k][j]; total_lenergy += lenergy[k][j]; } } printf("Global energy matrix:\n"); for(k = 0; k < clustc; ++k) { for(j = 0; j < dmatrixc; ++j) { printf("%lf ", genergy[k][j]); } printf("\n"); } printf("Local energy matrix:\n"); for(k = 0; k < clustc; ++k) { for(j = 0; j < dmatrixc; ++j) { printf("%lf ", lenergy[k][j]); } printf("\n"); } for(k = 0; k < clustc; ++k) { for(j = 0; j < dmatrixc; ++j) { if(dgt(lenergy[k][j], genergy[k][j])) { printf("Msg: lenergy > genergy for cluster %d and matrix %d.\n", k, j); } } } printf("\n"); double sum = 0.0; printf("Cluster global energy:\n"); for(k = 0; k < clustc; ++k) { sum += clust_genergy[k]; printf("%lf ", clust_genergy[k]); } printf("[%lf]\n", sum); sum = 0.0; printf("Cluster local energy:\n"); for(k = 0; k < clustc; ++k) { sum += clust_lenergy[k]; printf("%lf ", clust_lenergy[k]); } printf("[%lf]\n", sum); for(k = 0; k < clustc; ++k) { if(dgt(clust_lenergy[k], clust_genergy[k])) { printf("Warn: clust_lenergy > clust_genergy for cluster %d.\n", k); } } printf("\n"); sum = 0.0; printf("Matrix global energy:\n"); for(j = 0; j < dmatrixc; ++j) { sum += mtx_genergy[j]; printf("%lf ", mtx_genergy[j]); } printf("[%lf]\n", sum); sum = 0.0; printf("Matrix local energy:\n"); for(j = 0; j < dmatrixc; ++j) { sum += mtx_lenergy[j]; printf("%lf ", mtx_lenergy[j]); } printf("[%lf]\n", sum); for(j = 0; j < dmatrixc; ++j) { if(dgt(mtx_lenergy[j], mtx_genergy[j])) { printf("Warn: mtx_lenergy > mtx_genergy for matrix %d.\n", j); } } printf("\n"); printf("Global energy: %lf\n", total_genergy); printf("Local energy: %lf\n", total_lenergy); if(dgt(total_lenergy, total_genergy)) { printf("Warn: total_lenergy > total_genergy.\n"); } printf("\n"); printf("Matrix global heterogeneity index:\n"); for(j = 0; j < dmatrixc; ++j) { printf("%lf ", (1.0 - (mtx_lenergy[j] / mtx_genergy[j]))); } printf("\n"); printf("\n"); printf("Global heterogeneity index: %lf\n", (1.0 - (total_lenergy / total_genergy))); printf("\n"); printf("Cluster heterogeinety indexes:\n"); printf("T:\n"); for(k = 0; k < clustc; ++k) { printf("%lf ", clust_genergy[k] / total_genergy); } printf("\n"); printf("J:\n"); for(k = 0; k < clustc; ++k) { printf("%lf ", clust_lenergy[k] / total_lenergy); } printf("\n"); printf("B:\n"); for(k = 0; k < clustc; ++k) { printf("%lf ", (clust_genergy[k] - clust_lenergy[k]) / (total_genergy - total_lenergy)); } printf("\n"); printf("Q:\n"); for(k = 0; k < clustc; ++k) { printf("%lf ", (1.0 - (clust_lenergy[k] / clust_genergy[k]))); } printf("\n"); printf("\n"); printf("Cluster heterogeinety indexes for matrices:\n"); for(k = 0; k < clustc; ++k) { for(j = 0; j < dmatrixc; ++j) { printf("%lf ", (1.0 - (lenergy[k][j] / genergy[k][j]))); } printf("\n"); } }
VOID lkalist(a_uint cpc) { char str[16]; char *frmt; int i, m, n, r; /* * Truncate (int) to N-Bytes */ cpc &= a_mask; /* * Exit if listing file is not open */ loop: if (tfp == NULL) return; /* * Copy current LST to RST */ if (gline == 0) { fprintf(rfp, "%s", rb); gline = 1; } /* * Clear text line buffer */ for (i=0,rp=rb; i<sizeof(rb); i++) { *rp++ = 0; } /* * Get next LST text line */ if (fgets(rb, sizeof(rb)-2, tfp) == NULL) { fclose(tfp); tfp = NULL; fclose(rfp); rfp = NULL; return; } /* * Must have an ASxxxx Listing line number */ switch(a_bytes) { default: case 2: n = 30; break; case 3: case 4: n = 38; break; } if (!dgt(RAD10, &rb[n], 1)) { fprintf(rfp, "%s", rb); goto loop; } /* * Must have an address in the expected radix */ #ifdef LONGINT switch(radix) { default: case 16: r = RAD16; switch(a_bytes) { default: case 2: n = 3; m = 4; frmt = "%04lX"; break; case 3: n = 6; m = 6; frmt = "%06lX"; break; case 4: n = 4; m = 8; frmt = "%08lX"; break; } break; case 10: r = RAD10; switch(a_bytes) { default: case 2: n = 4; m = 5; frmt = "%05lu"; break; case 3: n = 5; m = 8; frmt = "%08lu"; break; case 4: n = 3; m = 10; frmt = "%010lu"; break; } break; case 8: r = RAD8; switch(a_bytes) { default: case 2: n = 3; m = 6; frmt = "%06lo"; break; case 3: n = 5; m = 8; frmt = "%08lo"; break; case 4: n = 2; m = 11; frmt = "%011lo"; break; } break; } #else switch(radix) { default: case 16: r = RAD16; switch(a_bytes) { default: case 2: n = 3; m = 4; frmt = "%04X"; break; case 3: n = 6; m = 6; frmt = "%06X"; break; case 4: n = 4; m = 8; frmt = "%08X"; break; } break; case 10: r = RAD10; switch(a_bytes) { default: case 2: n = 4; m = 5; frmt = "%05u"; break; case 3: n = 5; m = 8; frmt = "%08u"; break; case 4: n = 3; m = 10; frmt = "%010u"; break; } break; case 8: r = RAD8; switch(a_bytes) { default: case 2: n = 3; m = 6; frmt = "%06o"; break; case 3: n = 5; m = 8; frmt = "%08o"; break; case 4: n = 2; m = 11; frmt = "%011o"; break; } break; } #endif if (!dgt(r, &rb[n], m)) { fprintf(rfp, "%s", rb); goto loop; } sprintf(str, frmt, cpc); strncpy(&rb[n], str, m); /* * Copy updated LST text line to RST */ fprintf(rfp, "%s", rb); gcntr = 0; }
VOID lkglist(a_uint cpc, int v, int err) { char str[16]; char *afrmt, *frmt; int a, i, n, m, r, s, u; /* * Truncate (int) to N-Bytes */ cpc &= a_mask; /* * Exit if listing file is not open */ loop: if (tfp == NULL) return; /* * Get next LST text line */ if (gline) { /* * Clear text line buffer */ for (i=0,rp=rb; i<sizeof(rb); i++) { *rp++ = 0; } /* * Get next LST text line */ if (fgets(rb, sizeof(rb)-2, tfp) == NULL) { fclose(tfp); tfp = NULL; fclose(rfp); rfp = NULL; return; } /* * Check for a listing line number if required */ if (gcntr != -1) { switch(a_bytes) { default: case 2: n = 30; break; case 3: case 4: n = 38; break; } if (!dgt(RAD10, &rb[n], 1)) { fprintf(rfp, "%s", rb); goto loop; } gcntr = 0; } gline = 0; } /* * Hex Listing */ #ifdef LONGINT switch(radix) { default: case 16: r = RAD16; switch(a_bytes) { default: case 2: a = 8; s = 3; n = 3; m = 4; u = 6; afrmt = "%04lX"; break; case 3: a = 13; s = 3; n = 6; m = 6; u = 7; afrmt = "%06lX"; break; case 4: a = 13; s = 3; n = 4; m = 8; u = 7; afrmt = "%08lX"; break; } frmt = " %02X"; break; case 10: r = RAD10; switch(a_bytes) { default: case 2: a = 10; s = 4; n = 4; m = 5; u = 4; afrmt = "%05lu"; break; case 3: a = 14; s = 4; n = 5; m = 8; u = 5; afrmt = "%08lu"; break; case 4: a = 14; s = 4; n = 3; m = 10; u = 5; afrmt = "%010lu"; break; } frmt = " %03u"; break; case 8: r = RAD8; switch(a_bytes) { default: case 2: a = 10; s = 4; n = 3; m = 6; u = 4; afrmt = "%06lo"; break; case 3: a = 14; s = 4; n = 5; m = 8; u = 5; afrmt = "%08lo"; break; case 4: a = 14; s = 4; n = 2; m = 11; u = 5; afrmt = "%011lo"; break; } frmt = " %03o"; break; } #else switch(radix) { default: case 16: r = RAD16; switch(a_bytes) { default: case 2: a = 8; s = 3; n = 3; m = 4; u = 6; afrmt = "%04X"; break; case 3: a = 13; s = 3; n = 6; m = 6; u = 7; afrmt = "%06X"; break; case 4: a = 13; s = 3; n = 4; m = 8; u = 7; afrmt = "%08X"; break; } frmt = " %02X"; break; case 10: r = RAD10; switch(a_bytes) { default: case 2: a = 10; s = 4; n = 4; m = 5; u = 4; afrmt = "%05u"; break; case 3: a = 14; s = 4; n = 5; m = 8; u = 5; afrmt = "%08u"; break; case 4: a = 14; s = 4; n = 3; m = 10; u = 5; afrmt = "%010u"; break; } frmt = " %03u"; break; case 8: r = RAD8; switch(a_bytes) { default: case 2: a = 10; s = 4; n = 3; m = 6; u = 4; afrmt = "%06o"; break; case 3: a = 14; s = 4; n = 5; m = 8; u = 5; afrmt = "%08o"; break; case 4: a = 14; s = 4; n = 2; m = 11; u = 5; afrmt = "%011o"; break; } frmt = " %03o"; break; } #endif /* * Data Byte Pointer */ if (gcntr == -1) { rp = &rb[a]; } else { rp = &rb[a + (s * gcntr)]; } /* * Number must be of proper radix */ if (!dgt(r, rp, s-1)) { fprintf(rfp, "%s", rb); gline = 1; goto loop; } /* * Output new data value, overwrite relocation codes */ sprintf(str, frmt, v); strncpy(rp-1, str, s); if (gcntr == -1) { gcntr = 0; } /* * Output relocated code address */ if (gcntr == 0) { if (dgt(r, &rb[n], m)) { sprintf(str, afrmt, cpc); strncpy(&rb[n], str, m); } } /* * Output an error line if required */ if (err) { switch(ASxxxx_VERSION) { case 3: fprintf(rfp, "?ASlink-Warning-%s\n", errmsg3[err]); break; default: break; } } /* * Fix 'u' if [nn], cycles, is specified */ if (rb[a + (s*u) - 1] == CYCNT_END) { u -= 1; } /* * Output text line when updates finished */ if (++gcntr == u) { fprintf(rfp, "%s", rb); gline = 1; gcntr = -1; } }