|
kusano |
7d535a |
/* mc64ad.f -- translated by f2c (version 20100827).
|
|
kusano |
7d535a |
You must link the resulting object file with libf2c:
|
|
kusano |
7d535a |
on Microsoft Windows system, link with libf2c.lib;
|
|
kusano |
7d535a |
on Linux or Unix systems, link with .../path/to/libf2c.a -lm
|
|
kusano |
7d535a |
or, if you install libf2c.a in a standard place, with -lf2c -lm
|
|
kusano |
7d535a |
-- in that order, at the end of the command line, as in
|
|
kusano |
7d535a |
cc *.o -lf2c -lm
|
|
kusano |
7d535a |
Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
http://www.netlib.org/f2c/libf2c.zip
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
#include "slu_ddefs.h"
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
#define abs(a) ((a) >= 0) ? (a) : -(a)
|
|
kusano |
7d535a |
#define min(a,b) ((a) < (b)) ? (a) : (b)
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Table of constant values */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
static int_t c__1 = 1;
|
|
kusano |
7d535a |
static int_t c__2 = 2;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* CCCC COPYRIGHT (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* CCCC Research Councils. All rights reserved. */
|
|
kusano |
7d535a |
/* CCCC PACKAGE MC64A/AD */
|
|
kusano |
7d535a |
/* CCCC AUTHORS Iain Duff (i.duff@rl.ac.uk) and Jacko Koster (jak@ii.uib.no) */
|
|
kusano |
7d535a |
/* CCCC LAST UPDATE 20/09/99 */
|
|
kusano |
7d535a |
/* CCCC */
|
|
kusano |
7d535a |
/* *** Conditions on external use *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* The user shall acknowledge the contribution of this */
|
|
kusano |
7d535a |
/* package in any publication of material dependent upon the use of */
|
|
kusano |
7d535a |
/* the package. The user shall use reasonable endeavours to notify */
|
|
kusano |
7d535a |
/* the authors of the package of this publication. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* The user can modify this code but, at no time */
|
|
kusano |
7d535a |
/* shall the right or title to all or any part of this package pass */
|
|
kusano |
7d535a |
/* to the user. The user shall make available free of charge */
|
|
kusano |
7d535a |
/* to the authors for any purpose all information relating to any */
|
|
kusano |
7d535a |
/* alteration or addition made to this package for the purposes of */
|
|
kusano |
7d535a |
/* extending the capabilities or enhancing the performance of this */
|
|
kusano |
7d535a |
/* package. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* The user shall not pass this code directly to a third party without the */
|
|
kusano |
7d535a |
/* express prior consent of the authors. Users wanting to licence their */
|
|
kusano |
7d535a |
/* own copy of these routines should send email to hsl@aeat.co.uk */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* None of the comments from the Copyright notice up to and including this */
|
|
kusano |
7d535a |
/* one shall be removed or altered in any way. */
|
|
kusano |
7d535a |
/* ********************************************************************** */
|
|
kusano |
7d535a |
/* Subroutine */ int_t mc64id_(int_t *icntl)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
int_t i__;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *** Copyright (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* Research Councils *** */
|
|
kusano |
7d535a |
/* *** Although every effort has been made to ensure robustness and *** */
|
|
kusano |
7d535a |
/* *** reliability of the subroutines in this MC64 suite, we *** */
|
|
kusano |
7d535a |
/* *** disclaim any liability arising through the use or misuse of *** */
|
|
kusano |
7d535a |
/* *** any of the subroutines. *** */
|
|
kusano |
7d535a |
/* *** Any problems? Contact ... */
|
|
kusano |
7d535a |
/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Purpose */
|
|
kusano |
7d535a |
/* ======= */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* The components of the array ICNTL control the action of MC64A/AD. */
|
|
kusano |
7d535a |
/* Default values for these are set in this subroutine. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Parameters */
|
|
kusano |
7d535a |
/* ========== */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ICNTL(1) has default value 6. */
|
|
kusano |
7d535a |
/* It is the output stream for error messages. If it */
|
|
kusano |
7d535a |
/* is negative, these messages will be suppressed. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ICNTL(2) has default value 6. */
|
|
kusano |
7d535a |
/* It is the output stream for warning messages. */
|
|
kusano |
7d535a |
/* If it is negative, these messages are suppressed. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ICNTL(3) has default value -1. */
|
|
kusano |
7d535a |
/* It is the output stream for monitoring printing. */
|
|
kusano |
7d535a |
/* If it is negative, these messages are suppressed. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ICNTL(4) has default value 0. */
|
|
kusano |
7d535a |
/* If left at the defaut value, the incoming data is checked for */
|
|
kusano |
7d535a |
/* out-of-range indices and duplicates. Setting ICNTL(4) to any */
|
|
kusano |
7d535a |
/* other will avoid the checks but is likely to cause problems */
|
|
kusano |
7d535a |
/* later if out-of-range indices or duplicates are present. */
|
|
kusano |
7d535a |
/* The user should only set ICNTL(4) non-zero, if the data is */
|
|
kusano |
7d535a |
/* known to avoid these problems. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ICNTL(5) to ICNTL(10) are not used by MC64A/AD but are set to */
|
|
kusano |
7d535a |
/* zero in this routine. */
|
|
kusano |
7d535a |
/* Initialization of the ICNTL array. */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--icntl;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
icntl[1] = 6;
|
|
kusano |
7d535a |
icntl[2] = 6;
|
|
kusano |
7d535a |
icntl[3] = -1;
|
|
kusano |
7d535a |
for (i__ = 4; i__ <= 10; ++i__) {
|
|
kusano |
7d535a |
icntl[i__] = 0;
|
|
kusano |
7d535a |
/* L10: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} /* mc64id_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ********************************************************************** */
|
|
kusano |
7d535a |
/* Subroutine */ int_t mc64ad_(int_t *job, int_t *n, int_t *ne, int_t *
|
|
kusano |
7d535a |
ip, int_t *irn, double *a, int_t *num, int_t *cperm,
|
|
kusano |
7d535a |
int_t *liw, int_t *iw, int_t *ldw, double *dw, int_t *
|
|
kusano |
7d535a |
icntl, int_t *info)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int_t i__1, i__2;
|
|
kusano |
7d535a |
double d__1, d__2;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Builtin functions */
|
|
kusano |
7d535a |
double log(double);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
int_t i__, j, k;
|
|
kusano |
7d535a |
double fact, rinf;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
extern /* Subroutine */ int_t mc21ad_(int_t *, int_t *, int_t *,
|
|
kusano |
7d535a |
int_t *, int_t *, int_t *, int_t *, int_t *), mc64bd_(
|
|
kusano |
7d535a |
int_t *, int_t *, int_t *, int_t *, double *, int_t
|
|
kusano |
7d535a |
*, int_t *, int_t *, int_t *, int_t *, int_t *,
|
|
kusano |
7d535a |
double *), mc64rd_(int_t *, int_t *, int_t *, int_t *,
|
|
kusano |
7d535a |
double *), mc64sd_(int_t *, int_t *, int_t *, int_t *
|
|
kusano |
7d535a |
, double *, int_t *, int_t *, int_t *, int_t *,
|
|
kusano |
7d535a |
int_t *, int_t *, int_t *, int_t *, int_t *), mc64wd_(
|
|
kusano |
7d535a |
int_t *, int_t *, int_t *, int_t *, double *, int_t
|
|
kusano |
7d535a |
*, int_t *, int_t *, int_t *, int_t *, int_t *, int_t
|
|
kusano |
7d535a |
*, double *, double *);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *** Copyright (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* Research Councils *** */
|
|
kusano |
7d535a |
/* *** Although every effort has been made to ensure robustness and *** */
|
|
kusano |
7d535a |
/* *** reliability of the subroutines in this MC64 suite, we *** */
|
|
kusano |
7d535a |
/* *** disclaim any liability arising through the use or misuse of *** */
|
|
kusano |
7d535a |
/* *** any of the subroutines. *** */
|
|
kusano |
7d535a |
/* *** Any problems? Contact ... */
|
|
kusano |
7d535a |
/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Purpose */
|
|
kusano |
7d535a |
/* ======= */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* This subroutine attempts to find a column permutation for an NxN */
|
|
kusano |
7d535a |
/* sparse matrix A = {a_ij} that makes the permuted matrix have N */
|
|
kusano |
7d535a |
/* entries on its diagonal. */
|
|
kusano |
7d535a |
/* If the matrix is structurally nonsingular, the subroutine optionally */
|
|
kusano |
7d535a |
/* returns a column permutation that maximizes the smallest element */
|
|
kusano |
7d535a |
/* on the diagonal, maximizes the sum of the diagonal entries, or */
|
|
kusano |
7d535a |
/* maximizes the product of the diagonal entries of the permuted matrix. */
|
|
kusano |
7d535a |
/* For the latter option, the subroutine also finds scaling factors */
|
|
kusano |
7d535a |
/* that may be used to scale the matrix so that the nonzero diagonal */
|
|
kusano |
7d535a |
/* entries of the permuted matrix are one in absolute value and all the */
|
|
kusano |
7d535a |
/* off-diagonal entries are less than or equal to one in absolute value. */
|
|
kusano |
7d535a |
/* The natural logarithms of the scaling factors u(i), i=1..N, for the */
|
|
kusano |
7d535a |
/* rows and v(j), j=1..N, for the columns are returned so that the */
|
|
kusano |
7d535a |
/* scaled matrix B = {b_ij} has entries b_ij = a_ij * EXP(u_i + v_j). */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Parameters */
|
|
kusano |
7d535a |
/* ========== */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* JOB is an INT_T variable which must be set by the user to */
|
|
kusano |
7d535a |
/* control the action. It is not altered by the subroutine. */
|
|
kusano |
7d535a |
/* Possible values for JOB are: */
|
|
kusano |
7d535a |
/* 1 Compute a column permutation of the matrix so that the */
|
|
kusano |
7d535a |
/* permuted matrix has as many entries on its diagonal as possible. */
|
|
kusano |
7d535a |
/* The values on the diagonal are of arbitrary size. HSL subroutine */
|
|
kusano |
7d535a |
/* MC21A/AD is used for this. See [1]. */
|
|
kusano |
7d535a |
/* 2 Compute a column permutation of the matrix so that the smallest */
|
|
kusano |
7d535a |
/* value on the diagonal of the permuted matrix is maximized. */
|
|
kusano |
7d535a |
/* See [3]. */
|
|
kusano |
7d535a |
/* 3 Compute a column permutation of the matrix so that the smallest */
|
|
kusano |
7d535a |
/* value on the diagonal of the permuted matrix is maximized. */
|
|
kusano |
7d535a |
/* The algorithm differs from the one used for JOB = 2 and may */
|
|
kusano |
7d535a |
/* have quite a different performance. See [2]. */
|
|
kusano |
7d535a |
/* 4 Compute a column permutation of the matrix so that the sum */
|
|
kusano |
7d535a |
/* of the diagonal entries of the permuted matrix is maximized. */
|
|
kusano |
7d535a |
/* See [3]. */
|
|
kusano |
7d535a |
/* 5 Compute a column permutation of the matrix so that the product */
|
|
kusano |
7d535a |
/* of the diagonal entries of the permuted matrix is maximized */
|
|
kusano |
7d535a |
/* and vectors to scale the matrix so that the nonzero diagonal */
|
|
kusano |
7d535a |
/* entries of the permuted matrix are one in absolute value and */
|
|
kusano |
7d535a |
/* all the off-diagonal entries are less than or equal to one in */
|
|
kusano |
7d535a |
/* absolute value. See [3]. */
|
|
kusano |
7d535a |
/* Restriction: 1 <= JOB <= 5. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* N is an INT_T variable which must be set by the user to the */
|
|
kusano |
7d535a |
/* order of the matrix A. It is not altered by the subroutine. */
|
|
kusano |
7d535a |
/* Restriction: N >= 1. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* NE is an INT_T variable which must be set by the user to the */
|
|
kusano |
7d535a |
/* number of entries in the matrix. It is not altered by the */
|
|
kusano |
7d535a |
/* subroutine. */
|
|
kusano |
7d535a |
/* Restriction: NE >= 1. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* IP is an INT_T array of length N+1. */
|
|
kusano |
7d535a |
/* IP(J), J=1..N, must be set by the user to the position in array IRN */
|
|
kusano |
7d535a |
/* of the first row index of an entry in column J. IP(N+1) must be set */
|
|
kusano |
7d535a |
/* to NE+1. It is not altered by the subroutine. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* IRN is an INT_T array of length NE. */
|
|
kusano |
7d535a |
/* IRN(K), K=1..NE, must be set by the user to hold the row indices of */
|
|
kusano |
7d535a |
/* the entries of the matrix. Those belonging to column J must be */
|
|
kusano |
7d535a |
/* stored contiguously in the positions IP(J)..IP(J+1)-1. The ordering */
|
|
kusano |
7d535a |
/* of the row indices within each column is unimportant. Repeated */
|
|
kusano |
7d535a |
/* entries are not allowed. The array IRN is not altered by the */
|
|
kusano |
7d535a |
/* subroutine. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* A is a REAL (DOUBLE PRECISION in the D-version) array of length NE. */
|
|
kusano |
7d535a |
/* The user must set A(K), K=1..NE, to the numerical value of the */
|
|
kusano |
7d535a |
/* entry that corresponds to IRN(K). */
|
|
kusano |
7d535a |
/* It is not used by the subroutine when JOB = 1. */
|
|
kusano |
7d535a |
/* It is not altered by the subroutine. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* NUM is an INT_T variable that need not be set by the user. */
|
|
kusano |
7d535a |
/* On successful exit, NUM will be the number of entries on the */
|
|
kusano |
7d535a |
/* diagonal of the permuted matrix. */
|
|
kusano |
7d535a |
/* If NUM < N, the matrix is structurally singular. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* CPERM is an INT_T array of length N that need not be set by the */
|
|
kusano |
7d535a |
/* user. On successful exit, CPERM contains the column permutation. */
|
|
kusano |
7d535a |
/* Column CPERM(J) of the original matrix is column J in the permuted */
|
|
kusano |
7d535a |
/* matrix, J=1..N. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* LIW is an INT_T variable that must be set by the user to */
|
|
kusano |
7d535a |
/* the dimension of array IW. It is not altered by the subroutine. */
|
|
kusano |
7d535a |
/* Restriction: */
|
|
kusano |
7d535a |
/* JOB = 1 : LIW >= 5N */
|
|
kusano |
7d535a |
/* JOB = 2 : LIW >= 4N */
|
|
kusano |
7d535a |
/* JOB = 3 : LIW >= 10N + NE */
|
|
kusano |
7d535a |
/* JOB = 4 : LIW >= 5N */
|
|
kusano |
7d535a |
/* JOB = 5 : LIW >= 5N */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* IW is an INT_T array of length LIW that is used for workspace. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* LDW is an INT_T variable that must be set by the user to the */
|
|
kusano |
7d535a |
/* dimension of array DW. It is not altered by the subroutine. */
|
|
kusano |
7d535a |
/* Restriction: */
|
|
kusano |
7d535a |
/* JOB = 1 : LDW is not used */
|
|
kusano |
7d535a |
/* JOB = 2 : LDW >= N */
|
|
kusano |
7d535a |
/* JOB = 3 : LDW >= NE */
|
|
kusano |
7d535a |
/* JOB = 4 : LDW >= 2N + NE */
|
|
kusano |
7d535a |
/* JOB = 5 : LDW >= 3N + NE */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* DW is a REAL (DOUBLE PRECISION in the D-version) array of length LDW */
|
|
kusano |
7d535a |
/* that is used for workspace. If JOB = 5, on return, */
|
|
kusano |
7d535a |
/* DW(i) contains u_i, i=1..N, and DW(N+j) contains v_j, j=1..N. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ICNTL is an INT_T array of length 10. Its components control the */
|
|
kusano |
7d535a |
/* output of MC64A/AD and must be set by the user before calling */
|
|
kusano |
7d535a |
/* MC64A/AD. They are not altered by the subroutine. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ICNTL(1) must be set to specify the output stream for */
|
|
kusano |
7d535a |
/* error messages. If ICNTL(1) < 0, messages are suppressed. */
|
|
kusano |
7d535a |
/* The default value set by MC46I/ID is 6. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ICNTL(2) must be set by the user to specify the output stream for */
|
|
kusano |
7d535a |
/* warning messages. If ICNTL(2) < 0, messages are suppressed. */
|
|
kusano |
7d535a |
/* The default value set by MC46I/ID is 6. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ICNTL(3) must be set by the user to specify the output stream for */
|
|
kusano |
7d535a |
/* diagnostic messages. If ICNTL(3) < 0, messages are suppressed. */
|
|
kusano |
7d535a |
/* The default value set by MC46I/ID is -1. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ICNTL(4) must be set by the user to a value other than 0 to avoid */
|
|
kusano |
7d535a |
/* checking of the input data. */
|
|
kusano |
7d535a |
/* The default value set by MC46I/ID is 0. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* INFO is an INT_T array of length 10 which need not be set by the */
|
|
kusano |
7d535a |
/* user. INFO(1) is set non-negative to indicate success. A negative */
|
|
kusano |
7d535a |
/* value is returned if an error occurred, a positive value if a */
|
|
kusano |
7d535a |
/* warning occurred. INFO(2) holds further information on the error. */
|
|
kusano |
7d535a |
/* On exit from the subroutine, INFO(1) will take one of the */
|
|
kusano |
7d535a |
/* following values: */
|
|
kusano |
7d535a |
/* 0 : successful entry (for structurally nonsingular matrix). */
|
|
kusano |
7d535a |
/* +1 : successful entry (for structurally singular matrix). */
|
|
kusano |
7d535a |
/* +2 : the returned scaling factors are large and may cause */
|
|
kusano |
7d535a |
/* overflow when used to scale the matrix. */
|
|
kusano |
7d535a |
/* (For JOB = 5 entry only.) */
|
|
kusano |
7d535a |
/* -1 : JOB < 1 or JOB > 5. Value of JOB held in INFO(2). */
|
|
kusano |
7d535a |
/* -2 : N < 1. Value of N held in INFO(2). */
|
|
kusano |
7d535a |
/* -3 : NE < 1. Value of NE held in INFO(2). */
|
|
kusano |
7d535a |
/* -4 : the defined length LIW violates the restriction on LIW. */
|
|
kusano |
7d535a |
/* Value of LIW required given by INFO(2). */
|
|
kusano |
7d535a |
/* -5 : the defined length LDW violates the restriction on LDW. */
|
|
kusano |
7d535a |
/* Value of LDW required given by INFO(2). */
|
|
kusano |
7d535a |
/* -6 : entries are found whose row indices are out of range. INFO(2) */
|
|
kusano |
7d535a |
/* contains the index of a column in which such an entry is found. */
|
|
kusano |
7d535a |
/* -7 : repeated entries are found. INFO(2) contains the index of a */
|
|
kusano |
7d535a |
/* column in which such entries are found. */
|
|
kusano |
7d535a |
/* INFO(3) to INFO(10) are not currently used and are set to zero by */
|
|
kusano |
7d535a |
/* the routine. */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* References: */
|
|
kusano |
7d535a |
/* [1] I. S. Duff, (1981), */
|
|
kusano |
7d535a |
/* "Algorithm 575. Permutations for a zero-free diagonal", */
|
|
kusano |
7d535a |
/* ACM Trans. Math. Software 7(3), 387-390. */
|
|
kusano |
7d535a |
/* [2] I. S. Duff and J. Koster, (1998), */
|
|
kusano |
7d535a |
/* "The design and use of algorithms for permuting large */
|
|
kusano |
7d535a |
/* entries to the diagonal of sparse matrices", */
|
|
kusano |
7d535a |
/* SIAM J. Matrix Anal. Appl., vol. 20, no. 4, pp. 889-901. */
|
|
kusano |
7d535a |
/* [3] I. S. Duff and J. Koster, (1999), */
|
|
kusano |
7d535a |
/* "On algorithms for permuting large entries to the diagonal */
|
|
kusano |
7d535a |
/* of sparse matrices", */
|
|
kusano |
7d535a |
/* Technical Report RAL-TR-1999-030, RAL, Oxfordshire, England. */
|
|
kusano |
7d535a |
/* Local variables and parameters */
|
|
kusano |
7d535a |
/* External routines and functions */
|
|
kusano |
7d535a |
/* EXTERNAL FD05AD */
|
|
kusano |
7d535a |
/* DOUBLE PRECISION FD05AD */
|
|
kusano |
7d535a |
/* Intrinsic functions */
|
|
kusano |
7d535a |
/* Set RINF to largest positive real number (infinity) */
|
|
kusano |
7d535a |
/* XSL RINF = FD05AD(5) */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--cperm;
|
|
kusano |
7d535a |
--ip;
|
|
kusano |
7d535a |
--a;
|
|
kusano |
7d535a |
--irn;
|
|
kusano |
7d535a |
--iw;
|
|
kusano |
7d535a |
--dw;
|
|
kusano |
7d535a |
--icntl;
|
|
kusano |
7d535a |
--info;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
rinf = dlamch_("Overflow");
|
|
kusano |
7d535a |
/* Check value of JOB */
|
|
kusano |
7d535a |
if (*job < 1 || *job > 5) {
|
|
kusano |
7d535a |
info[1] = -1;
|
|
kusano |
7d535a |
info[2] = *job;
|
|
kusano |
7d535a |
if (icntl[1] >= 0) {
|
|
kusano |
7d535a |
printf(" ****** Error in MC64A/AD. INFO(1) = %2d", info[1],
|
|
kusano |
7d535a |
" because JOB = %d\n", *job);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L99;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Check value of N */
|
|
kusano |
7d535a |
if (*n < 1) {
|
|
kusano |
7d535a |
info[1] = -2;
|
|
kusano |
7d535a |
info[2] = *n;
|
|
kusano |
7d535a |
if (icntl[1] >= 0) {
|
|
kusano |
7d535a |
printf(" ****** Error in MC64A/AD. INFO(1) = %2d", info[1],
|
|
kusano |
7d535a |
" because N = %d\n", *job);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L99;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Check value of NE */
|
|
kusano |
7d535a |
if (*ne < 1) {
|
|
kusano |
7d535a |
info[1] = -3;
|
|
kusano |
7d535a |
info[2] = *ne;
|
|
kusano |
7d535a |
if (icntl[1] >= 0) {
|
|
kusano |
7d535a |
printf(" ****** Error in MC64A/AD. INFO(1) = %2d", info[1],
|
|
kusano |
7d535a |
" because NE = %d\n", *job);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L99;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Check LIW */
|
|
kusano |
7d535a |
if (*job == 1) {
|
|
kusano |
7d535a |
k = *n * 5;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*job == 2) {
|
|
kusano |
7d535a |
k = *n << 2;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*job == 3) {
|
|
kusano |
7d535a |
k = *n * 10 + *ne;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*job == 4) {
|
|
kusano |
7d535a |
k = *n * 5;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*job == 5) {
|
|
kusano |
7d535a |
k = *n * 5;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*liw < k) {
|
|
kusano |
7d535a |
info[1] = -4;
|
|
kusano |
7d535a |
info[2] = k;
|
|
kusano |
7d535a |
if (icntl[1] >= 0) {
|
|
kusano |
7d535a |
printf(" ****** Error in MC64A/AD. INFO(1) = %2d", info[1],
|
|
kusano |
7d535a |
" LIW too small, must be at least %8d\n", k);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L99;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Check LDW */
|
|
kusano |
7d535a |
/* If JOB = 1, do not check */
|
|
kusano |
7d535a |
if (*job > 1) {
|
|
kusano |
7d535a |
if (*job == 2) {
|
|
kusano |
7d535a |
k = *n;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*job == 3) {
|
|
kusano |
7d535a |
k = *ne;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*job == 4) {
|
|
kusano |
7d535a |
k = (*n << 1) + *ne;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*job == 5) {
|
|
kusano |
7d535a |
k = *n * 3 + *ne;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*ldw < k) {
|
|
kusano |
7d535a |
info[1] = -5;
|
|
kusano |
7d535a |
info[2] = k;
|
|
kusano |
7d535a |
if (icntl[1] >= 0) {
|
|
kusano |
7d535a |
printf(" ****** Error in MC64A/AD. INFO(1) = %2d", info[1],
|
|
kusano |
7d535a |
" LDW too small, must be at least %8d\n", k);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L99;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (icntl[4] == 0) {
|
|
kusano |
7d535a |
/* Check row indices. Use IW(1:N) as workspace */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__1; ++i__) {
|
|
kusano |
7d535a |
iw[i__] = 0;
|
|
kusano |
7d535a |
/* L3: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
/* Check for row indices that are out of range */
|
|
kusano |
7d535a |
if (i__ < 1 || i__ > *n) {
|
|
kusano |
7d535a |
info[1] = -6;
|
|
kusano |
7d535a |
info[2] = j;
|
|
kusano |
7d535a |
if (icntl[1] >= 0) {
|
|
kusano |
7d535a |
printf(" ****** Error in MC64A/AD. INFO(1) = %2d",
|
|
kusano |
7d535a |
info[1], " Column %8d", j,
|
|
kusano |
7d535a |
" contains an entry with invalid row index %8d\n", i__);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L99;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Check for repeated row indices within a column */
|
|
kusano |
7d535a |
if (iw[i__] == j) {
|
|
kusano |
7d535a |
info[1] = -7;
|
|
kusano |
7d535a |
info[2] = j;
|
|
kusano |
7d535a |
if (icntl[1] >= 0) {
|
|
kusano |
7d535a |
printf(" ****** Error in MC64A/AD. INFO(1) = %2d", info[1],
|
|
kusano |
7d535a |
" Column %8d", j,
|
|
kusano |
7d535a |
" contains two or more entries with row index %8d\n", i__);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L99;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
iw[i__] = j;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L4: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L6: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Print diagnostics on input */
|
|
kusano |
7d535a |
if (icntl[3] >= 0) {
|
|
kusano |
7d535a |
printf(" ****** Input parameters for MC64A/AD: JOB = %8d,"
|
|
kusano |
7d535a |
" N = %d, NE = %8d\n", *job, *n, *ne);
|
|
kusano |
7d535a |
printf(" IP(1:N+1) = ");
|
|
kusano |
7d535a |
for (j=1; j<=(*n+1); ++j) {
|
|
kusano |
7d535a |
printf("%8d", ip[j]);
|
|
kusano |
7d535a |
if (j%8 == 0) printf("\n");
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
printf("\n IRN(1:NE) = ");
|
|
kusano |
7d535a |
for (j=1; j<=(*ne); ++j) {
|
|
kusano |
7d535a |
printf("%8d", irn[j]);
|
|
kusano |
7d535a |
if (j%8 == 0) printf("\n");
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
printf("\n");
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (*job > 1) {
|
|
kusano |
7d535a |
printf(" A(1:NE) = ");
|
|
kusano |
7d535a |
for (j=1; j<=(*ne); ++j) {
|
|
kusano |
7d535a |
printf("%f14.4", a[j]);
|
|
kusano |
7d535a |
if (j%4 == 0) printf("\n");
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
printf("\n");
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Set components of INFO to zero */
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= 10; ++i__) {
|
|
kusano |
7d535a |
info[i__] = 0;
|
|
kusano |
7d535a |
/* L8: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Compute maximum matching with MC21A/AD */
|
|
kusano |
7d535a |
if (*job == 1) {
|
|
kusano |
7d535a |
/* Put length of column J in IW(J) */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
iw[j] = ip[j + 1] - ip[j];
|
|
kusano |
7d535a |
/* L10: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* IW(N+1:5N) is workspace */
|
|
kusano |
7d535a |
#if 0
|
|
kusano |
7d535a |
mc21ad_(n, &irn[1], ne, &ip[1], &iw[1], &cperm[1], num, &iw[*n+1]);
|
|
kusano |
7d535a |
#else
|
|
kusano |
7d535a |
printf(" ****** Warning from MC64A/AD. Need to link mc21ad.\n");
|
|
kusano |
7d535a |
#endif
|
|
kusano |
7d535a |
goto L90;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Compute bottleneck matching */
|
|
kusano |
7d535a |
if (*job == 2) {
|
|
kusano |
7d535a |
/* IW(1:5N), DW(1:N) are workspaces */
|
|
kusano |
7d535a |
mc64bd_(n, ne, &ip[1], &irn[1], &a[1], &cperm[1], num, &iw[1], &iw[*n
|
|
kusano |
7d535a |
+ 1], &iw[(*n << 1) + 1], &iw[*n * 3 + 1], &dw[1]);
|
|
kusano |
7d535a |
goto L90;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Compute bottleneck matching */
|
|
kusano |
7d535a |
if (*job == 3) {
|
|
kusano |
7d535a |
/* Copy IRN(K) into IW(K), ABS(A(K)) into DW(K), K=1..NE */
|
|
kusano |
7d535a |
i__1 = *ne;
|
|
kusano |
7d535a |
for (k = 1; k <= i__1; ++k) {
|
|
kusano |
7d535a |
iw[k] = irn[k];
|
|
kusano |
7d535a |
dw[k] = (d__1 = a[k], abs(d__1));
|
|
kusano |
7d535a |
/* L20: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Sort entries in each column by decreasing value. */
|
|
kusano |
7d535a |
mc64rd_(n, ne, &ip[1], &iw[1], &dw[1]);
|
|
kusano |
7d535a |
/* IW(NE+1:NE+10N) is workspace */
|
|
kusano |
7d535a |
mc64sd_(n, ne, &ip[1], &iw[1], &dw[1], &cperm[1], num, &iw[*ne + 1], &
|
|
kusano |
7d535a |
iw[*ne + *n + 1], &iw[*ne + (*n << 1) + 1], &iw[*ne + *n * 3
|
|
kusano |
7d535a |
+ 1], &iw[*ne + (*n << 2) + 1], &iw[*ne + *n * 5 + 1], &iw[*
|
|
kusano |
7d535a |
ne + *n * 6 + 1]);
|
|
kusano |
7d535a |
goto L90;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*job == 4) {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
fact = 0.;
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
if ((d__1 = a[k], abs(d__1)) > fact) {
|
|
kusano |
7d535a |
fact = (d__2 = a[k], abs(d__2));
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L30: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
dw[(*n << 1) + k] = fact - (d__1 = a[k], abs(d__1));
|
|
kusano |
7d535a |
/* L40: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L50: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* B = DW(2N+1:2N+NE); IW(1:5N) and DW(1:2N) are workspaces */
|
|
kusano |
7d535a |
mc64wd_(n, ne, &ip[1], &irn[1], &dw[(*n << 1) + 1], &cperm[1], num, &
|
|
kusano |
7d535a |
iw[1], &iw[*n + 1], &iw[(*n << 1) + 1], &iw[*n * 3 + 1], &iw[(
|
|
kusano |
7d535a |
*n << 2) + 1], &dw[1], &dw[*n + 1]);
|
|
kusano |
7d535a |
goto L90;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*job == 5) {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
fact = 0.;
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
dw[*n * 3 + k] = (d__1 = a[k], abs(d__1));
|
|
kusano |
7d535a |
if (dw[*n * 3 + k] > fact) {
|
|
kusano |
7d535a |
fact = dw[*n * 3 + k];
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L60: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
dw[(*n << 1) + j] = fact;
|
|
kusano |
7d535a |
if (fact != 0.) {
|
|
kusano |
7d535a |
fact = log(fact);
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
fact = rinf / *n;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
if (dw[*n * 3 + k] != 0.) {
|
|
kusano |
7d535a |
dw[*n * 3 + k] = fact - log(dw[*n * 3 + k]);
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
dw[*n * 3 + k] = rinf / *n;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L70: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L75: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* B = DW(3N+1:3N+NE); IW(1:5N) and DW(1:2N) are workspaces */
|
|
kusano |
7d535a |
mc64wd_(n, ne, &ip[1], &irn[1], &dw[*n * 3 + 1], &cperm[1], num, &iw[
|
|
kusano |
7d535a |
1], &iw[*n + 1], &iw[(*n << 1) + 1], &iw[*n * 3 + 1], &iw[(*n
|
|
kusano |
7d535a |
<< 2) + 1], &dw[1], &dw[*n + 1]);
|
|
kusano |
7d535a |
if (*num == *n) {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
if (dw[(*n << 1) + j] != 0.) {
|
|
kusano |
7d535a |
dw[*n + j] -= log(dw[(*n << 1) + j]);
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
dw[*n + j] = 0.;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L80: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Check size of scaling factors */
|
|
kusano |
7d535a |
fact = log(rinf) * .5f;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
if (dw[j] < fact && dw[*n + j] < fact) {
|
|
kusano |
7d535a |
goto L86;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
info[1] = 2;
|
|
kusano |
7d535a |
goto L90;
|
|
kusano |
7d535a |
L86:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* GO TO 90 */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L90:
|
|
kusano |
7d535a |
if (info[1] == 0 && *num < *n) {
|
|
kusano |
7d535a |
/* Matrix is structurally singular, return with warning */
|
|
kusano |
7d535a |
info[1] = 1;
|
|
kusano |
7d535a |
if (icntl[2] >= 0) {
|
|
kusano |
7d535a |
printf(" ****** Warning from MC64A/AD. INFO(1) = %2d", info[1],
|
|
kusano |
7d535a |
" The matrix is structurally singular.\n");
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (info[1] == 2) {
|
|
kusano |
7d535a |
/* Scaling factors are large, return with warning */
|
|
kusano |
7d535a |
if (icntl[2] >= 0) {
|
|
kusano |
7d535a |
printf(" ****** Warning from MC64A/AD. INFO(1) = %2d\n", info[1],
|
|
kusano |
7d535a |
" Some scaling factors may be too large.\n");
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Print diagnostics on output */
|
|
kusano |
7d535a |
if (icntl[3] >= 0) {
|
|
kusano |
7d535a |
printf(" ****** Output parameters for MC64A/AD: INFO(1:2) = %8d%8d\n",
|
|
kusano |
7d535a |
info[1], info[2]);
|
|
kusano |
7d535a |
printf(" NUM = ", *num);
|
|
kusano |
7d535a |
printf(" CPERM(1:N) = ");
|
|
kusano |
7d535a |
for (j=1; j<=*n; ++j) {
|
|
kusano |
7d535a |
printf("%8d", cperm[j]);
|
|
kusano |
7d535a |
if (j%8 == 0) printf("\n");
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*job == 5) {
|
|
kusano |
7d535a |
printf("\n DW(1:N) = ");
|
|
kusano |
7d535a |
for (j=1; j<=*n; ++j) {
|
|
kusano |
7d535a |
printf("%11.3f", dw[j]);
|
|
kusano |
7d535a |
if (j%5 == 0) printf("\n");
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
printf("\n DW(N+1:2N) = ");
|
|
kusano |
7d535a |
for (j=1; j<=*n; ++j) {
|
|
kusano |
7d535a |
printf("%11.3f", dw[*n+j]);
|
|
kusano |
7d535a |
if (j%5 == 0) printf("\n");
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
printf("\n");
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Return from subroutine. */
|
|
kusano |
7d535a |
L99:
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} /* mc64ad_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ********************************************************************** */
|
|
kusano |
7d535a |
/* Subroutine */ int_t mc64bd_(int_t *n, int_t *ne, int_t *ip, int_t *
|
|
kusano |
7d535a |
irn, double *a, int_t *iperm, int_t *num, int_t *jperm,
|
|
kusano |
7d535a |
int_t *pr, int_t *q, int_t *l, double *d__)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int_t i__1, i__2, i__3;
|
|
kusano |
7d535a |
double d__1, d__2, d__3;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
int_t i__, j, k;
|
|
kusano |
7d535a |
double a0;
|
|
kusano |
7d535a |
int_t i0, q0;
|
|
kusano |
7d535a |
double ai, di;
|
|
kusano |
7d535a |
int_t ii, jj, kk;
|
|
kusano |
7d535a |
double bv;
|
|
kusano |
7d535a |
int_t up;
|
|
kusano |
7d535a |
double dq0;
|
|
kusano |
7d535a |
int_t kk1, kk2;
|
|
kusano |
7d535a |
double csp;
|
|
kusano |
7d535a |
int_t isp, jsp, low;
|
|
kusano |
7d535a |
double dnew;
|
|
kusano |
7d535a |
int_t jord, qlen, idum, jdum;
|
|
kusano |
7d535a |
double rinf;
|
|
kusano |
7d535a |
extern /* Subroutine */ int_t mc64dd_(int_t *, int_t *, int_t *,
|
|
kusano |
7d535a |
double *, int_t *, int_t *), mc64ed_(int_t *, int_t *,
|
|
kusano |
7d535a |
int_t *, double *, int_t *, int_t *), mc64fd_(int_t *
|
|
kusano |
7d535a |
, int_t *, int_t *, int_t *, double *, int_t *, int_t *);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *** Copyright (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* Research Councils *** */
|
|
kusano |
7d535a |
/* *** Although every effort has been made to ensure robustness and *** */
|
|
kusano |
7d535a |
/* *** reliability of the subroutines in this MC64 suite, we *** */
|
|
kusano |
7d535a |
/* *** disclaim any liability arising through the use or misuse of *** */
|
|
kusano |
7d535a |
/* *** any of the subroutines. *** */
|
|
kusano |
7d535a |
/* *** Any problems? Contact ... */
|
|
kusano |
7d535a |
/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* N, NE, IP, IRN are described in MC64A/AD. */
|
|
kusano |
7d535a |
/* A is a REAL (DOUBLE PRECISION in the D-version) array of length */
|
|
kusano |
7d535a |
/* NE. A(K), K=1..NE, must be set to the value of the entry */
|
|
kusano |
7d535a |
/* that corresponds to IRN(K). It is not altered. */
|
|
kusano |
7d535a |
/* IPERM is an INT_T array of length N. On exit, it contains the */
|
|
kusano |
7d535a |
/* matching: IPERM(I) = 0 or row I is matched to column IPERM(I). */
|
|
kusano |
7d535a |
/* NUM is INT_T variable. On exit, it contains the cardinality of the */
|
|
kusano |
7d535a |
/* matching stored in IPERM. */
|
|
kusano |
7d535a |
/* IW is an INT_T work array of length 4N. */
|
|
kusano |
7d535a |
/* DW is a REAL (DOUBLE PRECISION in D-version) work array of length N. */
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
/* Local parameters */
|
|
kusano |
7d535a |
/* Intrinsic functions */
|
|
kusano |
7d535a |
/* External subroutines and/or functions */
|
|
kusano |
7d535a |
/* EXTERNAL FD05AD,MC64DD,MC64ED,MC64FD, DLAMCH */
|
|
kusano |
7d535a |
/* DOUBLE PRECISION FD05AD, DLAMCH */
|
|
kusano |
7d535a |
/* Set RINF to largest positive real number */
|
|
kusano |
7d535a |
/* XSL RINF = FD05AD(5) */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--d__;
|
|
kusano |
7d535a |
--l;
|
|
kusano |
7d535a |
--q;
|
|
kusano |
7d535a |
--pr;
|
|
kusano |
7d535a |
--jperm;
|
|
kusano |
7d535a |
--iperm;
|
|
kusano |
7d535a |
--ip;
|
|
kusano |
7d535a |
--a;
|
|
kusano |
7d535a |
--irn;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
rinf = dlamch_("Overflow");
|
|
kusano |
7d535a |
/* Initialization */
|
|
kusano |
7d535a |
*num = 0;
|
|
kusano |
7d535a |
bv = rinf;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (k = 1; k <= i__1; ++k) {
|
|
kusano |
7d535a |
iperm[k] = 0;
|
|
kusano |
7d535a |
jperm[k] = 0;
|
|
kusano |
7d535a |
pr[k] = ip[k];
|
|
kusano |
7d535a |
d__[k] = 0.;
|
|
kusano |
7d535a |
/* L10: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Scan columns of matrix; */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
a0 = -1.;
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
ai = (d__1 = a[k], abs(d__1));
|
|
kusano |
7d535a |
if (ai > d__[i__]) {
|
|
kusano |
7d535a |
d__[i__] = ai;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (jperm[j] != 0) {
|
|
kusano |
7d535a |
goto L30;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (ai >= bv) {
|
|
kusano |
7d535a |
a0 = bv;
|
|
kusano |
7d535a |
if (iperm[i__] != 0) {
|
|
kusano |
7d535a |
goto L30;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
jperm[j] = i__;
|
|
kusano |
7d535a |
iperm[i__] = j;
|
|
kusano |
7d535a |
++(*num);
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
if (ai <= a0) {
|
|
kusano |
7d535a |
goto L30;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
a0 = ai;
|
|
kusano |
7d535a |
i0 = i__;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L30:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (a0 != -1. && a0 < bv) {
|
|
kusano |
7d535a |
bv = a0;
|
|
kusano |
7d535a |
if (iperm[i0] != 0) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
iperm[i0] = j;
|
|
kusano |
7d535a |
jperm[j] = i0;
|
|
kusano |
7d535a |
++(*num);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L20:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Update BV with smallest of all the largest maximum absolute values */
|
|
kusano |
7d535a |
/* of the rows. */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__1; ++i__) {
|
|
kusano |
7d535a |
/* Computing MIN */
|
|
kusano |
7d535a |
d__1 = bv, d__2 = d__[i__];
|
|
kusano |
7d535a |
bv = min(d__1,d__2);
|
|
kusano |
7d535a |
/* L25: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*num == *n) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Rescan unassigned columns; improve initial assignment */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
if (jperm[j] != 0) {
|
|
kusano |
7d535a |
goto L95;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
ai = (d__1 = a[k], abs(d__1));
|
|
kusano |
7d535a |
if (ai < bv) {
|
|
kusano |
7d535a |
goto L50;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (iperm[i__] == 0) {
|
|
kusano |
7d535a |
goto L90;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
jj = iperm[i__];
|
|
kusano |
7d535a |
kk1 = pr[jj];
|
|
kusano |
7d535a |
kk2 = ip[jj + 1] - 1;
|
|
kusano |
7d535a |
if (kk1 > kk2) {
|
|
kusano |
7d535a |
goto L50;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__3 = kk2;
|
|
kusano |
7d535a |
for (kk = kk1; kk <= i__3; ++kk) {
|
|
kusano |
7d535a |
ii = irn[kk];
|
|
kusano |
7d535a |
if (iperm[ii] != 0) {
|
|
kusano |
7d535a |
goto L70;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if ((d__1 = a[kk], abs(d__1)) >= bv) {
|
|
kusano |
7d535a |
goto L80;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L70:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
pr[jj] = kk2 + 1;
|
|
kusano |
7d535a |
L50:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L95;
|
|
kusano |
7d535a |
L80:
|
|
kusano |
7d535a |
jperm[jj] = ii;
|
|
kusano |
7d535a |
iperm[ii] = jj;
|
|
kusano |
7d535a |
pr[jj] = kk + 1;
|
|
kusano |
7d535a |
L90:
|
|
kusano |
7d535a |
++(*num);
|
|
kusano |
7d535a |
jperm[j] = i__;
|
|
kusano |
7d535a |
iperm[i__] = j;
|
|
kusano |
7d535a |
pr[j] = k + 1;
|
|
kusano |
7d535a |
L95:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*num == *n) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Prepare for main loop */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__1; ++i__) {
|
|
kusano |
7d535a |
d__[i__] = -1.;
|
|
kusano |
7d535a |
l[i__] = 0;
|
|
kusano |
7d535a |
/* L99: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Main loop ... each pass round this loop is similar to Dijkstra's */
|
|
kusano |
7d535a |
/* algorithm for solving the single source shortest path problem */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (jord = 1; jord <= i__1; ++jord) {
|
|
kusano |
7d535a |
if (jperm[jord] != 0) {
|
|
kusano |
7d535a |
goto L100;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
qlen = 0;
|
|
kusano |
7d535a |
low = *n + 1;
|
|
kusano |
7d535a |
up = *n + 1;
|
|
kusano |
7d535a |
/* CSP is cost of shortest path to any unassigned row */
|
|
kusano |
7d535a |
/* ISP is matrix position of unassigned row element in shortest path */
|
|
kusano |
7d535a |
/* JSP is column index of unassigned row element in shortest path */
|
|
kusano |
7d535a |
csp = -1.;
|
|
kusano |
7d535a |
/* Build shortest path tree starting from unassigned column JORD */
|
|
kusano |
7d535a |
j = jord;
|
|
kusano |
7d535a |
pr[j] = -1;
|
|
kusano |
7d535a |
/* Scan column J */
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
dnew = (d__1 = a[k], abs(d__1));
|
|
kusano |
7d535a |
if (csp >= dnew) {
|
|
kusano |
7d535a |
goto L115;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (iperm[i__] == 0) {
|
|
kusano |
7d535a |
/* Row I is unassigned; update shortest path info */
|
|
kusano |
7d535a |
csp = dnew;
|
|
kusano |
7d535a |
isp = i__;
|
|
kusano |
7d535a |
jsp = j;
|
|
kusano |
7d535a |
if (csp >= bv) {
|
|
kusano |
7d535a |
goto L160;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
d__[i__] = dnew;
|
|
kusano |
7d535a |
if (dnew >= bv) {
|
|
kusano |
7d535a |
/* Add row I to Q2 */
|
|
kusano |
7d535a |
--low;
|
|
kusano |
7d535a |
q[low] = i__;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
/* Add row I to Q, and push it */
|
|
kusano |
7d535a |
++qlen;
|
|
kusano |
7d535a |
l[i__] = qlen;
|
|
kusano |
7d535a |
mc64dd_(&i__, n, &q[1], &d__[1], &l[1], &c__1);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
jj = iperm[i__];
|
|
kusano |
7d535a |
pr[jj] = j;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L115:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__2 = *num;
|
|
kusano |
7d535a |
for (jdum = 1; jdum <= i__2; ++jdum) {
|
|
kusano |
7d535a |
/* If Q2 is empty, extract new rows from Q */
|
|
kusano |
7d535a |
if (low == up) {
|
|
kusano |
7d535a |
if (qlen == 0) {
|
|
kusano |
7d535a |
goto L160;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__ = q[1];
|
|
kusano |
7d535a |
if (csp >= d__[i__]) {
|
|
kusano |
7d535a |
goto L160;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
bv = d__[i__];
|
|
kusano |
7d535a |
i__3 = *n;
|
|
kusano |
7d535a |
for (idum = 1; idum <= i__3; ++idum) {
|
|
kusano |
7d535a |
mc64ed_(&qlen, n, &q[1], &d__[1], &l[1], &c__1);
|
|
kusano |
7d535a |
l[i__] = 0;
|
|
kusano |
7d535a |
--low;
|
|
kusano |
7d535a |
q[low] = i__;
|
|
kusano |
7d535a |
if (qlen == 0) {
|
|
kusano |
7d535a |
goto L153;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__ = q[1];
|
|
kusano |
7d535a |
if (d__[i__] != bv) {
|
|
kusano |
7d535a |
goto L153;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L152: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Move row Q0 */
|
|
kusano |
7d535a |
L153:
|
|
kusano |
7d535a |
--up;
|
|
kusano |
7d535a |
q0 = q[up];
|
|
kusano |
7d535a |
dq0 = d__[q0];
|
|
kusano |
7d535a |
l[q0] = up;
|
|
kusano |
7d535a |
/* Scan column that matches with row Q0 */
|
|
kusano |
7d535a |
j = iperm[q0];
|
|
kusano |
7d535a |
i__3 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__3; ++k) {
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
/* Update D(I) */
|
|
kusano |
7d535a |
if (l[i__] >= up) {
|
|
kusano |
7d535a |
goto L155;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Computing MIN */
|
|
kusano |
7d535a |
d__2 = dq0, d__3 = (d__1 = a[k], abs(d__1));
|
|
kusano |
7d535a |
dnew = min(d__2,d__3);
|
|
kusano |
7d535a |
if (csp >= dnew) {
|
|
kusano |
7d535a |
goto L155;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (iperm[i__] == 0) {
|
|
kusano |
7d535a |
/* Row I is unassigned; update shortest path info */
|
|
kusano |
7d535a |
csp = dnew;
|
|
kusano |
7d535a |
isp = i__;
|
|
kusano |
7d535a |
jsp = j;
|
|
kusano |
7d535a |
if (csp >= bv) {
|
|
kusano |
7d535a |
goto L160;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
di = d__[i__];
|
|
kusano |
7d535a |
if (di >= bv || di >= dnew) {
|
|
kusano |
7d535a |
goto L155;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
d__[i__] = dnew;
|
|
kusano |
7d535a |
if (dnew >= bv) {
|
|
kusano |
7d535a |
/* Delete row I from Q (if necessary); add row I to Q2 */
|
|
kusano |
7d535a |
if (di != -1.) {
|
|
kusano |
7d535a |
mc64fd_(&l[i__], &qlen, n, &q[1], &d__[1], &l[1],
|
|
kusano |
7d535a |
&c__1);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
l[i__] = 0;
|
|
kusano |
7d535a |
--low;
|
|
kusano |
7d535a |
q[low] = i__;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
/* Add row I to Q (if necessary); push row I up Q */
|
|
kusano |
7d535a |
if (di == -1.) {
|
|
kusano |
7d535a |
++qlen;
|
|
kusano |
7d535a |
l[i__] = qlen;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
mc64dd_(&i__, n, &q[1], &d__[1], &l[1], &c__1);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Update tree */
|
|
kusano |
7d535a |
jj = iperm[i__];
|
|
kusano |
7d535a |
pr[jj] = j;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L155:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L150: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* If CSP = MINONE, no augmenting path is found */
|
|
kusano |
7d535a |
L160:
|
|
kusano |
7d535a |
if (csp == -1.) {
|
|
kusano |
7d535a |
goto L190;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Update bottleneck value */
|
|
kusano |
7d535a |
bv = min(bv,csp);
|
|
kusano |
7d535a |
/* Find augmenting path by tracing backward in PR; update IPERM,JPERM */
|
|
kusano |
7d535a |
++(*num);
|
|
kusano |
7d535a |
i__ = isp;
|
|
kusano |
7d535a |
j = jsp;
|
|
kusano |
7d535a |
i__2 = *num + 1;
|
|
kusano |
7d535a |
for (jdum = 1; jdum <= i__2; ++jdum) {
|
|
kusano |
7d535a |
i0 = jperm[j];
|
|
kusano |
7d535a |
jperm[j] = i__;
|
|
kusano |
7d535a |
iperm[i__] = j;
|
|
kusano |
7d535a |
j = pr[j];
|
|
kusano |
7d535a |
if (j == -1) {
|
|
kusano |
7d535a |
goto L190;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__ = i0;
|
|
kusano |
7d535a |
/* L170: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
L190:
|
|
kusano |
7d535a |
i__2 = *n;
|
|
kusano |
7d535a |
for (kk = up; kk <= i__2; ++kk) {
|
|
kusano |
7d535a |
i__ = q[kk];
|
|
kusano |
7d535a |
d__[i__] = -1.;
|
|
kusano |
7d535a |
l[i__] = 0;
|
|
kusano |
7d535a |
/* L191: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__2 = up - 1;
|
|
kusano |
7d535a |
for (kk = low; kk <= i__2; ++kk) {
|
|
kusano |
7d535a |
i__ = q[kk];
|
|
kusano |
7d535a |
d__[i__] = -1.;
|
|
kusano |
7d535a |
/* L192: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__2 = qlen;
|
|
kusano |
7d535a |
for (kk = 1; kk <= i__2; ++kk) {
|
|
kusano |
7d535a |
i__ = q[kk];
|
|
kusano |
7d535a |
d__[i__] = -1.;
|
|
kusano |
7d535a |
l[i__] = 0;
|
|
kusano |
7d535a |
/* L193: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L100:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of main loop */
|
|
kusano |
7d535a |
/* BV is bottleneck value of final matching */
|
|
kusano |
7d535a |
if (*num == *n) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Matrix is structurally singular, complete IPERM. */
|
|
kusano |
7d535a |
/* JPERM, PR are work arrays */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
jperm[j] = 0;
|
|
kusano |
7d535a |
/* L300: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
k = 0;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__1; ++i__) {
|
|
kusano |
7d535a |
if (iperm[i__] == 0) {
|
|
kusano |
7d535a |
++k;
|
|
kusano |
7d535a |
pr[k] = i__;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
j = iperm[i__];
|
|
kusano |
7d535a |
jperm[j] = i__;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L310: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
k = 0;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__1; ++i__) {
|
|
kusano |
7d535a |
if (jperm[i__] != 0) {
|
|
kusano |
7d535a |
goto L320;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
++k;
|
|
kusano |
7d535a |
jdum = pr[k];
|
|
kusano |
7d535a |
iperm[jdum] = i__;
|
|
kusano |
7d535a |
L320:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L1000:
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} /* mc64bd_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ********************************************************************** */
|
|
kusano |
7d535a |
/* Subroutine */ int_t mc64dd_(int_t *i__, int_t *n, int_t *q, double
|
|
kusano |
7d535a |
*d__, int_t *l, int_t *iway)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int_t i__1;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
double di;
|
|
kusano |
7d535a |
int_t qk, pos, idum, posk;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *** Copyright (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* Research Councils *** */
|
|
kusano |
7d535a |
/* *** Although every effort has been made to ensure robustness and *** */
|
|
kusano |
7d535a |
/* *** reliability of the subroutines in this MC64 suite, we *** */
|
|
kusano |
7d535a |
/* *** disclaim any liability arising through the use or misuse of *** */
|
|
kusano |
7d535a |
/* *** any of the subroutines. *** */
|
|
kusano |
7d535a |
/* *** Any problems? Contact ... */
|
|
kusano |
7d535a |
/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Variables N,Q,D,L are described in MC64B/BD */
|
|
kusano |
7d535a |
/* IF IWAY is equal to 1, then */
|
|
kusano |
7d535a |
/* node I is pushed from its current position upwards */
|
|
kusano |
7d535a |
/* IF IWAY is not equal to 1, then */
|
|
kusano |
7d535a |
/* node I is pushed from its current position downwards */
|
|
kusano |
7d535a |
/* Local variables and parameters */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--l;
|
|
kusano |
7d535a |
--d__;
|
|
kusano |
7d535a |
--q;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
di = d__[*i__];
|
|
kusano |
7d535a |
pos = l[*i__];
|
|
kusano |
7d535a |
/* POS is index of current position of I in the tree */
|
|
kusano |
7d535a |
if (*iway == 1) {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (idum = 1; idum <= i__1; ++idum) {
|
|
kusano |
7d535a |
if (pos <= 1) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
posk = pos / 2;
|
|
kusano |
7d535a |
qk = q[posk];
|
|
kusano |
7d535a |
if (di <= d__[qk]) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
q[pos] = qk;
|
|
kusano |
7d535a |
l[qk] = pos;
|
|
kusano |
7d535a |
pos = posk;
|
|
kusano |
7d535a |
/* L10: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (idum = 1; idum <= i__1; ++idum) {
|
|
kusano |
7d535a |
if (pos <= 1) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
posk = pos / 2;
|
|
kusano |
7d535a |
qk = q[posk];
|
|
kusano |
7d535a |
if (di >= d__[qk]) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
q[pos] = qk;
|
|
kusano |
7d535a |
l[qk] = pos;
|
|
kusano |
7d535a |
pos = posk;
|
|
kusano |
7d535a |
/* L15: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy if; this point is never reached */
|
|
kusano |
7d535a |
L20:
|
|
kusano |
7d535a |
q[pos] = *i__;
|
|
kusano |
7d535a |
l[*i__] = pos;
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} /* mc64dd_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ********************************************************************** */
|
|
kusano |
7d535a |
/* Subroutine */ int_t mc64ed_(int_t *qlen, int_t *n, int_t *q,
|
|
kusano |
7d535a |
double *d__, int_t *l, int_t *iway)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int_t i__1;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
int_t i__;
|
|
kusano |
7d535a |
double di, dk, dr;
|
|
kusano |
7d535a |
int_t pos, idum, posk;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *** Copyright (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* Research Councils *** */
|
|
kusano |
7d535a |
/* *** Although every effort has been made to ensure robustness and *** */
|
|
kusano |
7d535a |
/* *** reliability of the subroutines in this MC64 suite, we *** */
|
|
kusano |
7d535a |
/* *** disclaim any liability arising through the use or misuse of *** */
|
|
kusano |
7d535a |
/* *** any of the subroutines. *** */
|
|
kusano |
7d535a |
/* *** Any problems? Contact ... */
|
|
kusano |
7d535a |
/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Variables QLEN,N,Q,D,L are described in MC64B/BD (IWAY = 1) or */
|
|
kusano |
7d535a |
/* MC64W/WD (IWAY = 2) */
|
|
kusano |
7d535a |
/* The root node is deleted from the binary heap. */
|
|
kusano |
7d535a |
/* Local variables and parameters */
|
|
kusano |
7d535a |
/* Move last element to begin of Q */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--l;
|
|
kusano |
7d535a |
--d__;
|
|
kusano |
7d535a |
--q;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
i__ = q[*qlen];
|
|
kusano |
7d535a |
di = d__[i__];
|
|
kusano |
7d535a |
--(*qlen);
|
|
kusano |
7d535a |
pos = 1;
|
|
kusano |
7d535a |
if (*iway == 1) {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (idum = 1; idum <= i__1; ++idum) {
|
|
kusano |
7d535a |
posk = pos << 1;
|
|
kusano |
7d535a |
if (posk > *qlen) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
dk = d__[q[posk]];
|
|
kusano |
7d535a |
if (posk < *qlen) {
|
|
kusano |
7d535a |
dr = d__[q[posk + 1]];
|
|
kusano |
7d535a |
if (dk < dr) {
|
|
kusano |
7d535a |
++posk;
|
|
kusano |
7d535a |
dk = dr;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (di >= dk) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Exchange old last element with larger priority child */
|
|
kusano |
7d535a |
q[pos] = q[posk];
|
|
kusano |
7d535a |
l[q[pos]] = pos;
|
|
kusano |
7d535a |
pos = posk;
|
|
kusano |
7d535a |
/* L10: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (idum = 1; idum <= i__1; ++idum) {
|
|
kusano |
7d535a |
posk = pos << 1;
|
|
kusano |
7d535a |
if (posk > *qlen) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
dk = d__[q[posk]];
|
|
kusano |
7d535a |
if (posk < *qlen) {
|
|
kusano |
7d535a |
dr = d__[q[posk + 1]];
|
|
kusano |
7d535a |
if (dk > dr) {
|
|
kusano |
7d535a |
++posk;
|
|
kusano |
7d535a |
dk = dr;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (di <= dk) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Exchange old last element with smaller child */
|
|
kusano |
7d535a |
q[pos] = q[posk];
|
|
kusano |
7d535a |
l[q[pos]] = pos;
|
|
kusano |
7d535a |
pos = posk;
|
|
kusano |
7d535a |
/* L15: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy if; this point is never reached */
|
|
kusano |
7d535a |
L20:
|
|
kusano |
7d535a |
q[pos] = i__;
|
|
kusano |
7d535a |
l[i__] = pos;
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} /* mc64ed_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ********************************************************************** */
|
|
kusano |
7d535a |
/* Subroutine */ int_t mc64fd_(int_t *pos0, int_t *qlen, int_t *n,
|
|
kusano |
7d535a |
int_t *q, double *d__, int_t *l, int_t *iway)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int_t i__1;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
int_t i__;
|
|
kusano |
7d535a |
double di, dk, dr;
|
|
kusano |
7d535a |
int_t qk, pos, idum, posk;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *** Copyright (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* Research Councils *** */
|
|
kusano |
7d535a |
/* *** Although every effort has been made to ensure robustness and *** */
|
|
kusano |
7d535a |
/* *** reliability of the subroutines in this MC64 suite, we *** */
|
|
kusano |
7d535a |
/* *** disclaim any liability arising through the use or misuse of *** */
|
|
kusano |
7d535a |
/* *** any of the subroutines. *** */
|
|
kusano |
7d535a |
/* *** Any problems? Contact ... */
|
|
kusano |
7d535a |
/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Variables QLEN,N,Q,D,L are described in MC64B/BD (IWAY = 1) or */
|
|
kusano |
7d535a |
/* MC64WD (IWAY = 2). */
|
|
kusano |
7d535a |
/* Move last element in the heap */
|
|
kusano |
7d535a |
/* Quick return, if possible */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--l;
|
|
kusano |
7d535a |
--d__;
|
|
kusano |
7d535a |
--q;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
if (*qlen == *pos0) {
|
|
kusano |
7d535a |
--(*qlen);
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Move last element from queue Q to position POS0 */
|
|
kusano |
7d535a |
/* POS is current position of node I in the tree */
|
|
kusano |
7d535a |
i__ = q[*qlen];
|
|
kusano |
7d535a |
di = d__[i__];
|
|
kusano |
7d535a |
--(*qlen);
|
|
kusano |
7d535a |
pos = *pos0;
|
|
kusano |
7d535a |
if (*iway == 1) {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (idum = 1; idum <= i__1; ++idum) {
|
|
kusano |
7d535a |
if (pos <= 1) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
posk = pos / 2;
|
|
kusano |
7d535a |
qk = q[posk];
|
|
kusano |
7d535a |
if (di <= d__[qk]) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
q[pos] = qk;
|
|
kusano |
7d535a |
l[qk] = pos;
|
|
kusano |
7d535a |
pos = posk;
|
|
kusano |
7d535a |
/* L10: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
L20:
|
|
kusano |
7d535a |
q[pos] = i__;
|
|
kusano |
7d535a |
l[i__] = pos;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (idum = 1; idum <= i__1; ++idum) {
|
|
kusano |
7d535a |
posk = pos << 1;
|
|
kusano |
7d535a |
if (posk > *qlen) {
|
|
kusano |
7d535a |
goto L40;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
dk = d__[q[posk]];
|
|
kusano |
7d535a |
if (posk < *qlen) {
|
|
kusano |
7d535a |
dr = d__[q[posk + 1]];
|
|
kusano |
7d535a |
if (dk < dr) {
|
|
kusano |
7d535a |
++posk;
|
|
kusano |
7d535a |
dk = dr;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (di >= dk) {
|
|
kusano |
7d535a |
goto L40;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
qk = q[posk];
|
|
kusano |
7d535a |
q[pos] = qk;
|
|
kusano |
7d535a |
l[qk] = pos;
|
|
kusano |
7d535a |
pos = posk;
|
|
kusano |
7d535a |
/* L30: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (idum = 1; idum <= i__1; ++idum) {
|
|
kusano |
7d535a |
if (pos <= 1) {
|
|
kusano |
7d535a |
goto L34;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
posk = pos / 2;
|
|
kusano |
7d535a |
qk = q[posk];
|
|
kusano |
7d535a |
if (di >= d__[qk]) {
|
|
kusano |
7d535a |
goto L34;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
q[pos] = qk;
|
|
kusano |
7d535a |
l[qk] = pos;
|
|
kusano |
7d535a |
pos = posk;
|
|
kusano |
7d535a |
/* L32: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
L34:
|
|
kusano |
7d535a |
q[pos] = i__;
|
|
kusano |
7d535a |
l[i__] = pos;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (idum = 1; idum <= i__1; ++idum) {
|
|
kusano |
7d535a |
posk = pos << 1;
|
|
kusano |
7d535a |
if (posk > *qlen) {
|
|
kusano |
7d535a |
goto L40;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
dk = d__[q[posk]];
|
|
kusano |
7d535a |
if (posk < *qlen) {
|
|
kusano |
7d535a |
dr = d__[q[posk + 1]];
|
|
kusano |
7d535a |
if (dk > dr) {
|
|
kusano |
7d535a |
++posk;
|
|
kusano |
7d535a |
dk = dr;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (di <= dk) {
|
|
kusano |
7d535a |
goto L40;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
qk = q[posk];
|
|
kusano |
7d535a |
q[pos] = qk;
|
|
kusano |
7d535a |
l[qk] = pos;
|
|
kusano |
7d535a |
pos = posk;
|
|
kusano |
7d535a |
/* L36: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy if; this point is never reached */
|
|
kusano |
7d535a |
L40:
|
|
kusano |
7d535a |
q[pos] = i__;
|
|
kusano |
7d535a |
l[i__] = pos;
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} /* mc64fd_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ********************************************************************** */
|
|
kusano |
7d535a |
/* Subroutine */ int_t mc64rd_(int_t *n, int_t *ne, int_t *ip, int_t *
|
|
kusano |
7d535a |
irn, double *a)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int_t i__1, i__2, i__3;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
int_t j, k, r__, s;
|
|
kusano |
7d535a |
double ha;
|
|
kusano |
7d535a |
int_t hi, td, mid, len, ipj;
|
|
kusano |
7d535a |
double key;
|
|
kusano |
7d535a |
int_t last, todo[50], first;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *** Copyright (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* Research Councils *** */
|
|
kusano |
7d535a |
/* *** Although every effort has been made to ensure robustness and *** */
|
|
kusano |
7d535a |
/* *** reliability of the subroutines in this MC64 suite, we *** */
|
|
kusano |
7d535a |
/* *** disclaim any liability arising through the use or misuse of *** */
|
|
kusano |
7d535a |
/* *** any of the subroutines. *** */
|
|
kusano |
7d535a |
/* *** Any problems? Contact ... */
|
|
kusano |
7d535a |
/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* This subroutine sorts the entries in each column of the */
|
|
kusano |
7d535a |
/* sparse matrix (defined by N,NE,IP,IRN,A) by decreasing */
|
|
kusano |
7d535a |
/* numerical value. */
|
|
kusano |
7d535a |
/* Local constants */
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
/* Local arrays */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--ip;
|
|
kusano |
7d535a |
--a;
|
|
kusano |
7d535a |
--irn;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
len = ip[j + 1] - ip[j];
|
|
kusano |
7d535a |
if (len <= 1) {
|
|
kusano |
7d535a |
goto L100;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
ipj = ip[j];
|
|
kusano |
7d535a |
/* Sort array roughly with partial quicksort */
|
|
kusano |
7d535a |
if (len < 15) {
|
|
kusano |
7d535a |
goto L400;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
todo[0] = ipj;
|
|
kusano |
7d535a |
todo[1] = ipj + len;
|
|
kusano |
7d535a |
td = 2;
|
|
kusano |
7d535a |
L500:
|
|
kusano |
7d535a |
first = todo[td - 2];
|
|
kusano |
7d535a |
last = todo[td - 1];
|
|
kusano |
7d535a |
/* KEY is the smallest of two values present in interval [FIRST,LAST) */
|
|
kusano |
7d535a |
key = a[(first + last) / 2];
|
|
kusano |
7d535a |
i__2 = last - 1;
|
|
kusano |
7d535a |
for (k = first; k <= i__2; ++k) {
|
|
kusano |
7d535a |
ha = a[k];
|
|
kusano |
7d535a |
if (ha == key) {
|
|
kusano |
7d535a |
goto L475;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (ha > key) {
|
|
kusano |
7d535a |
goto L470;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
key = ha;
|
|
kusano |
7d535a |
goto L470;
|
|
kusano |
7d535a |
L475:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Only one value found in interval, so it is already sorted */
|
|
kusano |
7d535a |
td += -2;
|
|
kusano |
7d535a |
goto L425;
|
|
kusano |
7d535a |
/* Reorder interval [FIRST,LAST) such that entries before MID are gt KEY */
|
|
kusano |
7d535a |
L470:
|
|
kusano |
7d535a |
mid = first;
|
|
kusano |
7d535a |
i__2 = last - 1;
|
|
kusano |
7d535a |
for (k = first; k <= i__2; ++k) {
|
|
kusano |
7d535a |
if (a[k] <= key) {
|
|
kusano |
7d535a |
goto L450;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
ha = a[mid];
|
|
kusano |
7d535a |
a[mid] = a[k];
|
|
kusano |
7d535a |
a[k] = ha;
|
|
kusano |
7d535a |
hi = irn[mid];
|
|
kusano |
7d535a |
irn[mid] = irn[k];
|
|
kusano |
7d535a |
irn[k] = hi;
|
|
kusano |
7d535a |
++mid;
|
|
kusano |
7d535a |
L450:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Both subintervals [FIRST,MID), [MID,LAST) are nonempty */
|
|
kusano |
7d535a |
/* Stack the longest of the two subintervals first */
|
|
kusano |
7d535a |
if (mid - first >= last - mid) {
|
|
kusano |
7d535a |
todo[td + 1] = last;
|
|
kusano |
7d535a |
todo[td] = mid;
|
|
kusano |
7d535a |
todo[td - 1] = mid;
|
|
kusano |
7d535a |
/* TODO(TD-1) = FIRST */
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
todo[td + 1] = mid;
|
|
kusano |
7d535a |
todo[td] = first;
|
|
kusano |
7d535a |
todo[td - 1] = last;
|
|
kusano |
7d535a |
todo[td - 2] = mid;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
td += 2;
|
|
kusano |
7d535a |
L425:
|
|
kusano |
7d535a |
if (td == 0) {
|
|
kusano |
7d535a |
goto L400;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* There is still work to be done */
|
|
kusano |
7d535a |
if (todo[td - 1] - todo[td - 2] >= 15) {
|
|
kusano |
7d535a |
goto L500;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Next interval is already short enough for straightforward insertion */
|
|
kusano |
7d535a |
td += -2;
|
|
kusano |
7d535a |
goto L425;
|
|
kusano |
7d535a |
/* Complete sorting with straightforward insertion */
|
|
kusano |
7d535a |
L400:
|
|
kusano |
7d535a |
i__2 = ipj + len - 1;
|
|
kusano |
7d535a |
for (r__ = ipj + 1; r__ <= i__2; ++r__) {
|
|
kusano |
7d535a |
if (a[r__ - 1] < a[r__]) {
|
|
kusano |
7d535a |
ha = a[r__];
|
|
kusano |
7d535a |
hi = irn[r__];
|
|
kusano |
7d535a |
a[r__] = a[r__ - 1];
|
|
kusano |
7d535a |
irn[r__] = irn[r__ - 1];
|
|
kusano |
7d535a |
i__3 = ipj + 1;
|
|
kusano |
7d535a |
for (s = r__ - 1; s >= i__3; --s) {
|
|
kusano |
7d535a |
if (a[s - 1] < ha) {
|
|
kusano |
7d535a |
a[s] = a[s - 1];
|
|
kusano |
7d535a |
irn[s] = irn[s - 1];
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
a[s] = ha;
|
|
kusano |
7d535a |
irn[s] = hi;
|
|
kusano |
7d535a |
goto L200;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L300: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
a[ipj] = ha;
|
|
kusano |
7d535a |
irn[ipj] = hi;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L200:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L100:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} /* mc64rd_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ********************************************************************** */
|
|
kusano |
7d535a |
/* Subroutine */ int_t mc64sd_(int_t *n, int_t *ne, int_t *ip, int_t *
|
|
kusano |
7d535a |
irn, double *a, int_t *iperm, int_t *numx, int_t *w,
|
|
kusano |
7d535a |
int_t *len, int_t *lenl, int_t *lenh, int_t *fc, int_t *iw,
|
|
kusano |
7d535a |
int_t *iw4)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int_t i__1, i__2, i__3, i__4;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
int_t i__, j, k, l, ii, mod, cnt, num;
|
|
kusano |
7d535a |
double bval, bmin, bmax, rinf;
|
|
kusano |
7d535a |
int_t nval, wlen, idum1, idum2, idum3;
|
|
kusano |
7d535a |
extern /* Subroutine */ int_t mc64qd_(int_t *, int_t *, int_t *,
|
|
kusano |
7d535a |
int_t *, int_t *, double *, int_t *, double *),
|
|
kusano |
7d535a |
mc64ud_(int_t *, int_t *, int_t *, int_t *, int_t *,
|
|
kusano |
7d535a |
int_t *, int_t *, int_t *, int_t *, int_t *, int_t *,
|
|
kusano |
7d535a |
int_t *, int_t *, int_t *, int_t *);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *** Copyright (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* Research Councils *** */
|
|
kusano |
7d535a |
/* *** Although every effort has been made to ensure robustness and *** */
|
|
kusano |
7d535a |
/* *** reliability of the subroutines in this MC64 suite, we *** */
|
|
kusano |
7d535a |
/* *** disclaim any liability arising through the use or misuse of *** */
|
|
kusano |
7d535a |
/* *** any of the subroutines. *** */
|
|
kusano |
7d535a |
/* *** Any problems? Contact ... */
|
|
kusano |
7d535a |
/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* N, NE, IP, IRN, are described in MC64A/AD. */
|
|
kusano |
7d535a |
/* A is a REAL (DOUBLE PRECISION in the D-version) array of length NE. */
|
|
kusano |
7d535a |
/* A(K), K=1..NE, must be set to the value of the entry that */
|
|
kusano |
7d535a |
/* corresponds to IRN(k). The entries in each column must be */
|
|
kusano |
7d535a |
/* non-negative and ordered by decreasing value. */
|
|
kusano |
7d535a |
/* IPERM is an INT_T array of length N. On exit, it contains the */
|
|
kusano |
7d535a |
/* bottleneck matching: IPERM(I) - 0 or row I is matched to column */
|
|
kusano |
7d535a |
/* IPERM(I). */
|
|
kusano |
7d535a |
/* NUMX is an INT_T variable. On exit, it contains the cardinality */
|
|
kusano |
7d535a |
/* of the matching stored in IPERM. */
|
|
kusano |
7d535a |
/* IW is an INT_T work array of length 10N. */
|
|
kusano |
7d535a |
/* FC is an int_t array of length N that contains the list of */
|
|
kusano |
7d535a |
/* unmatched columns. */
|
|
kusano |
7d535a |
/* LEN(J), LENL(J), LENH(J) are int_t arrays of length N that point */
|
|
kusano |
7d535a |
/* to entries in matrix column J. */
|
|
kusano |
7d535a |
/* In the matrix defined by the column parts IP(J)+LENL(J) we know */
|
|
kusano |
7d535a |
/* a matching does not exist; in the matrix defined by the column */
|
|
kusano |
7d535a |
/* parts IP(J)+LENH(J) we know one exists. */
|
|
kusano |
7d535a |
/* LEN(J) lies between LENL(J) and LENH(J) and determines the matrix */
|
|
kusano |
7d535a |
/* that is tested for a maximum matching. */
|
|
kusano |
7d535a |
/* W is an int_t array of length N and contains the indices of the */
|
|
kusano |
7d535a |
/* columns for which LENL ne LENH. */
|
|
kusano |
7d535a |
/* WLEN is number of indices stored in array W. */
|
|
kusano |
7d535a |
/* IW is int_t work array of length N. */
|
|
kusano |
7d535a |
/* IW4 is int_t work array of length 4N used by MC64U/UD. */
|
|
kusano |
7d535a |
/* EXTERNAL FD05AD,MC64QD,MC64UD */
|
|
kusano |
7d535a |
/* DOUBLE PRECISION FD05AD */
|
|
kusano |
7d535a |
/* BMIN and BMAX are such that a maximum matching exists for the input */
|
|
kusano |
7d535a |
/* matrix in which all entries smaller than BMIN are dropped. */
|
|
kusano |
7d535a |
/* For BMAX, a maximum matching does not exist. */
|
|
kusano |
7d535a |
/* BVAL is a value between BMIN and BMAX. */
|
|
kusano |
7d535a |
/* CNT is the number of calls made to MC64U/UD so far. */
|
|
kusano |
7d535a |
/* NUM is the cardinality of last matching found. */
|
|
kusano |
7d535a |
/* Set RINF to largest positive real number */
|
|
kusano |
7d535a |
/* XSL RINF = FD05AD(5) */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--iw4;
|
|
kusano |
7d535a |
--iw;
|
|
kusano |
7d535a |
--fc;
|
|
kusano |
7d535a |
--lenh;
|
|
kusano |
7d535a |
--lenl;
|
|
kusano |
7d535a |
--len;
|
|
kusano |
7d535a |
--w;
|
|
kusano |
7d535a |
--iperm;
|
|
kusano |
7d535a |
--ip;
|
|
kusano |
7d535a |
--a;
|
|
kusano |
7d535a |
--irn;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
rinf = dlamch_("Overflow");
|
|
kusano |
7d535a |
/* Compute a first maximum matching from scratch on whole matrix. */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
fc[j] = j;
|
|
kusano |
7d535a |
iw[j] = 0;
|
|
kusano |
7d535a |
len[j] = ip[j + 1] - ip[j];
|
|
kusano |
7d535a |
/* L20: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* The first call to MC64U/UD */
|
|
kusano |
7d535a |
cnt = 1;
|
|
kusano |
7d535a |
mod = 1;
|
|
kusano |
7d535a |
*numx = 0;
|
|
kusano |
7d535a |
mc64ud_(&cnt, &mod, n, &irn[1], ne, &ip[1], &len[1], &fc[1], &iw[1], numx,
|
|
kusano |
7d535a |
n, &iw4[1], &iw4[*n + 1], &iw4[(*n << 1) + 1], &iw4[*n * 3 + 1]);
|
|
kusano |
7d535a |
/* IW contains a maximum matching of length NUMX. */
|
|
kusano |
7d535a |
num = *numx;
|
|
kusano |
7d535a |
if (num != *n) {
|
|
kusano |
7d535a |
/* Matrix is structurally singular */
|
|
kusano |
7d535a |
bmax = rinf;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
/* Matrix is structurally nonsingular, NUM=NUMX=N; */
|
|
kusano |
7d535a |
/* Set BMAX just above the smallest of all the maximum absolute */
|
|
kusano |
7d535a |
/* values of the columns */
|
|
kusano |
7d535a |
bmax = rinf;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
bval = 0.f;
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
if (a[k] > bval) {
|
|
kusano |
7d535a |
bval = a[k];
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L25: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (bval < bmax) {
|
|
kusano |
7d535a |
bmax = bval;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L30: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
bmax *= 1.001f;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Initialize BVAL,BMIN */
|
|
kusano |
7d535a |
bval = 0.f;
|
|
kusano |
7d535a |
bmin = 0.f;
|
|
kusano |
7d535a |
/* Initialize LENL,LEN,LENH,W,WLEN according to BMAX. */
|
|
kusano |
7d535a |
/* Set LEN(J), LENH(J) just after last entry in column J. */
|
|
kusano |
7d535a |
/* Set LENL(J) just after last entry in column J with value ge BMAX. */
|
|
kusano |
7d535a |
wlen = 0;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
l = ip[j + 1] - ip[j];
|
|
kusano |
7d535a |
lenh[j] = l;
|
|
kusano |
7d535a |
len[j] = l;
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
if (a[k] < bmax) {
|
|
kusano |
7d535a |
goto L46;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L45: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Column J is empty or all entries are ge BMAX */
|
|
kusano |
7d535a |
k = ip[j + 1];
|
|
kusano |
7d535a |
L46:
|
|
kusano |
7d535a |
lenl[j] = k - ip[j];
|
|
kusano |
7d535a |
/* Add J to W if LENL(J) ne LENH(J) */
|
|
kusano |
7d535a |
if (lenl[j] == l) {
|
|
kusano |
7d535a |
goto L48;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
++wlen;
|
|
kusano |
7d535a |
w[wlen] = j;
|
|
kusano |
7d535a |
L48:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Main loop */
|
|
kusano |
7d535a |
i__1 = *ne;
|
|
kusano |
7d535a |
for (idum1 = 1; idum1 <= i__1; ++idum1) {
|
|
kusano |
7d535a |
if (num == *numx) {
|
|
kusano |
7d535a |
/* We have a maximum matching in IW; store IW in IPERM */
|
|
kusano |
7d535a |
i__2 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__2; ++i__) {
|
|
kusano |
7d535a |
iperm[i__] = iw[i__];
|
|
kusano |
7d535a |
/* L50: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Keep going round this loop until matching IW is no longer maximum. */
|
|
kusano |
7d535a |
i__2 = *ne;
|
|
kusano |
7d535a |
for (idum2 = 1; idum2 <= i__2; ++idum2) {
|
|
kusano |
7d535a |
bmin = bval;
|
|
kusano |
7d535a |
if (bmax == bmin) {
|
|
kusano |
7d535a |
goto L99;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Find splitting value BVAL */
|
|
kusano |
7d535a |
mc64qd_(&ip[1], &lenl[1], &len[1], &w[1], &wlen, &a[1], &nval,
|
|
kusano |
7d535a |
&bval);
|
|
kusano |
7d535a |
if (nval <= 1) {
|
|
kusano |
7d535a |
goto L99;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Set LEN such that all matrix entries with value lt BVAL are */
|
|
kusano |
7d535a |
/* discarded. Store old LEN in LENH. Do this for all columns W(K). */
|
|
kusano |
7d535a |
/* Each step, either K is incremented or WLEN is decremented. */
|
|
kusano |
7d535a |
k = 1;
|
|
kusano |
7d535a |
i__3 = *n;
|
|
kusano |
7d535a |
for (idum3 = 1; idum3 <= i__3; ++idum3) {
|
|
kusano |
7d535a |
if (k > wlen) {
|
|
kusano |
7d535a |
goto L71;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
j = w[k];
|
|
kusano |
7d535a |
i__4 = ip[j] + lenl[j];
|
|
kusano |
7d535a |
for (ii = ip[j] + len[j] - 1; ii >= i__4; --ii) {
|
|
kusano |
7d535a |
if (a[ii] >= bval) {
|
|
kusano |
7d535a |
goto L60;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__ = irn[ii];
|
|
kusano |
7d535a |
if (iw[i__] != j) {
|
|
kusano |
7d535a |
goto L55;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Remove entry from matching */
|
|
kusano |
7d535a |
iw[i__] = 0;
|
|
kusano |
7d535a |
--num;
|
|
kusano |
7d535a |
fc[*n - num] = j;
|
|
kusano |
7d535a |
L55:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L60:
|
|
kusano |
7d535a |
lenh[j] = len[j];
|
|
kusano |
7d535a |
/* IP(J)+LEN(J)-1 is last entry in column ge BVAL */
|
|
kusano |
7d535a |
len[j] = ii - ip[j] + 1;
|
|
kusano |
7d535a |
/* If LENH(J) = LENL(J), remove J from W */
|
|
kusano |
7d535a |
if (lenl[j] == lenh[j]) {
|
|
kusano |
7d535a |
w[k] = w[wlen];
|
|
kusano |
7d535a |
--wlen;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
++k;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L70: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L71:
|
|
kusano |
7d535a |
if (num < *numx) {
|
|
kusano |
7d535a |
goto L81;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L80: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
/* Set mode for next call to MC64U/UD */
|
|
kusano |
7d535a |
L81:
|
|
kusano |
7d535a |
mod = 1;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
/* We do not have a maximum matching in IW. */
|
|
kusano |
7d535a |
bmax = bval;
|
|
kusano |
7d535a |
/* BMIN is the bottleneck value of a maximum matching; */
|
|
kusano |
7d535a |
/* for BMAX the matching is not maximum, so BMAX>BMIN */
|
|
kusano |
7d535a |
/* IF (BMAX .EQ. BMIN) GO TO 99 */
|
|
kusano |
7d535a |
/* Find splitting value BVAL */
|
|
kusano |
7d535a |
mc64qd_(&ip[1], &len[1], &lenh[1], &w[1], &wlen, &a[1], &nval, &
|
|
kusano |
7d535a |
bval);
|
|
kusano |
7d535a |
if (nval == 0 || bval == bmin) {
|
|
kusano |
7d535a |
goto L99;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Set LEN such that all matrix entries with value ge BVAL are */
|
|
kusano |
7d535a |
/* inside matrix. Store old LEN in LENL. Do this for all columns W(K). */
|
|
kusano |
7d535a |
/* Each step, either K is incremented or WLEN is decremented. */
|
|
kusano |
7d535a |
k = 1;
|
|
kusano |
7d535a |
i__2 = *n;
|
|
kusano |
7d535a |
for (idum3 = 1; idum3 <= i__2; ++idum3) {
|
|
kusano |
7d535a |
if (k > wlen) {
|
|
kusano |
7d535a |
goto L88;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
j = w[k];
|
|
kusano |
7d535a |
i__3 = ip[j] + lenh[j] - 1;
|
|
kusano |
7d535a |
for (ii = ip[j] + len[j]; ii <= i__3; ++ii) {
|
|
kusano |
7d535a |
if (a[ii] < bval) {
|
|
kusano |
7d535a |
goto L86;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L85: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L86:
|
|
kusano |
7d535a |
lenl[j] = len[j];
|
|
kusano |
7d535a |
len[j] = ii - ip[j];
|
|
kusano |
7d535a |
if (lenl[j] == lenh[j]) {
|
|
kusano |
7d535a |
w[k] = w[wlen];
|
|
kusano |
7d535a |
--wlen;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
++k;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L87: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
/* Set mode for next call to MC64U/UD */
|
|
kusano |
7d535a |
L88:
|
|
kusano |
7d535a |
mod = 0;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
++cnt;
|
|
kusano |
7d535a |
mc64ud_(&cnt, &mod, n, &irn[1], ne, &ip[1], &len[1], &fc[1], &iw[1], &
|
|
kusano |
7d535a |
num, numx, &iw4[1], &iw4[*n + 1], &iw4[(*n << 1) + 1], &iw4[*
|
|
kusano |
7d535a |
n * 3 + 1]);
|
|
kusano |
7d535a |
/* IW contains maximum matching of length NUM */
|
|
kusano |
7d535a |
/* L90: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
/* BMIN is bottleneck value of final matching */
|
|
kusano |
7d535a |
L99:
|
|
kusano |
7d535a |
if (*numx == *n) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* The matrix is structurally singular, complete IPERM */
|
|
kusano |
7d535a |
/* W, IW are work arrays */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
w[j] = 0;
|
|
kusano |
7d535a |
/* L300: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
k = 0;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__1; ++i__) {
|
|
kusano |
7d535a |
if (iperm[i__] == 0) {
|
|
kusano |
7d535a |
++k;
|
|
kusano |
7d535a |
iw[k] = i__;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
j = iperm[i__];
|
|
kusano |
7d535a |
w[j] = i__;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L310: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
k = 0;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
if (w[j] != 0) {
|
|
kusano |
7d535a |
goto L320;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
++k;
|
|
kusano |
7d535a |
idum1 = iw[k];
|
|
kusano |
7d535a |
iperm[idum1] = j;
|
|
kusano |
7d535a |
L320:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L1000:
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} /* mc64sd_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ********************************************************************** */
|
|
kusano |
7d535a |
/* Subroutine */ int_t mc64qd_(int_t *ip, int_t *lenl, int_t *lenh,
|
|
kusano |
7d535a |
int_t *w, int_t *wlen, double *a, int_t *nval, double *
|
|
kusano |
7d535a |
val)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int_t i__1, i__2, i__3;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
int_t j, k, s;
|
|
kusano |
7d535a |
double ha;
|
|
kusano |
7d535a |
int_t ii, pos;
|
|
kusano |
7d535a |
double split[10];
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *** Copyright (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* Research Councils *** */
|
|
kusano |
7d535a |
/* *** Although every effort has been made to ensure robustness and *** */
|
|
kusano |
7d535a |
/* *** reliability of the subroutines in this MC64 suite, we *** */
|
|
kusano |
7d535a |
/* *** disclaim any liability arising through the use or misuse of *** */
|
|
kusano |
7d535a |
/* *** any of the subroutines. *** */
|
|
kusano |
7d535a |
/* *** Any problems? Contact ... */
|
|
kusano |
7d535a |
/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* This routine searches for at most XX different numerical values */
|
|
kusano |
7d535a |
/* in the columns W(1:WLEN). XX>=2. */
|
|
kusano |
7d535a |
/* Each column J is scanned between IP(J)+LENL(J) and IP(J)+LENH(J)-1 */
|
|
kusano |
7d535a |
/* until XX values are found or all columns have been considered. */
|
|
kusano |
7d535a |
/* On output, NVAL is the number of different values that is found */
|
|
kusano |
7d535a |
/* and SPLIT(1:NVAL) contains the values in decreasing order. */
|
|
kusano |
7d535a |
/* If NVAL > 0, the routine returns VAL = SPLIT((NVAL+1)/2). */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Scan columns in W(1:WLEN). For each encountered value, if value not */
|
|
kusano |
7d535a |
/* already present in SPLIT(1:NVAL), insert value such that SPLIT */
|
|
kusano |
7d535a |
/* remains sorted by decreasing value. */
|
|
kusano |
7d535a |
/* The sorting is done by straightforward insertion; therefore the use */
|
|
kusano |
7d535a |
/* of this routine should be avoided for large XX (XX < 20). */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--a;
|
|
kusano |
7d535a |
--w;
|
|
kusano |
7d535a |
--lenh;
|
|
kusano |
7d535a |
--lenl;
|
|
kusano |
7d535a |
--ip;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
*nval = 0;
|
|
kusano |
7d535a |
i__1 = *wlen;
|
|
kusano |
7d535a |
for (k = 1; k <= i__1; ++k) {
|
|
kusano |
7d535a |
j = w[k];
|
|
kusano |
7d535a |
i__2 = ip[j] + lenh[j] - 1;
|
|
kusano |
7d535a |
for (ii = ip[j] + lenl[j]; ii <= i__2; ++ii) {
|
|
kusano |
7d535a |
ha = a[ii];
|
|
kusano |
7d535a |
if (*nval == 0) {
|
|
kusano |
7d535a |
split[0] = ha;
|
|
kusano |
7d535a |
*nval = 1;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
/* Check presence of HA in SPLIT */
|
|
kusano |
7d535a |
for (s = *nval; s >= 1; --s) {
|
|
kusano |
7d535a |
if (split[s - 1] == ha) {
|
|
kusano |
7d535a |
goto L15;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (split[s - 1] > ha) {
|
|
kusano |
7d535a |
pos = s + 1;
|
|
kusano |
7d535a |
goto L21;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L20: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
pos = 1;
|
|
kusano |
7d535a |
/* The insertion */
|
|
kusano |
7d535a |
L21:
|
|
kusano |
7d535a |
i__3 = pos;
|
|
kusano |
7d535a |
for (s = *nval; s >= i__3; --s) {
|
|
kusano |
7d535a |
split[s] = split[s - 1];
|
|
kusano |
7d535a |
/* L22: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
split[pos - 1] = ha;
|
|
kusano |
7d535a |
++(*nval);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Exit loop if XX values are found */
|
|
kusano |
7d535a |
if (*nval == 10) {
|
|
kusano |
7d535a |
goto L11;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L15:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L10: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Determine VAL */
|
|
kusano |
7d535a |
L11:
|
|
kusano |
7d535a |
if (*nval > 0) {
|
|
kusano |
7d535a |
*val = split[(*nval + 1) / 2 - 1];
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} /* mc64qd_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ********************************************************************** */
|
|
kusano |
7d535a |
/* Subroutine */ int_t mc64ud_(int_t *id, int_t *mod, int_t *n, int_t *
|
|
kusano |
7d535a |
irn, int_t *lirn, int_t *ip, int_t *lenc, int_t *fc, int_t *
|
|
kusano |
7d535a |
iperm, int_t *num, int_t *numx, int_t *pr, int_t *arp,
|
|
kusano |
7d535a |
int_t *cv, int_t *out)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int_t i__1, i__2, i__3, i__4;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
int_t i__, j, k, j1, ii, kk, id0, id1, in1, in2, nfc, num0, num1, num2,
|
|
kusano |
7d535a |
jord, last;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *** Copyright (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* Research Councils *** */
|
|
kusano |
7d535a |
/* *** Although every effort has been made to ensure robustness and *** */
|
|
kusano |
7d535a |
/* *** reliability of the subroutines in this MC64 suite, we *** */
|
|
kusano |
7d535a |
/* *** disclaim any liability arising through the use or misuse of *** */
|
|
kusano |
7d535a |
/* *** any of the subroutines. *** */
|
|
kusano |
7d535a |
/* *** Any problems? Contact ... */
|
|
kusano |
7d535a |
/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* PR(J) is the previous column to J in the depth first search. */
|
|
kusano |
7d535a |
/* Array PR is used as workspace in the sorting algorithm. */
|
|
kusano |
7d535a |
/* Elements (I,IPERM(I)) I=1,..,N are entries at the end of the */
|
|
kusano |
7d535a |
/* algorithm unless N assignments have not been made in which case */
|
|
kusano |
7d535a |
/* N-NUM pairs (I,IPERM(I)) will not be entries in the matrix. */
|
|
kusano |
7d535a |
/* CV(I) is the most recent loop number (ID+JORD) at which row I */
|
|
kusano |
7d535a |
/* was visited. */
|
|
kusano |
7d535a |
/* ARP(J) is the number of entries in column J which have been scanned */
|
|
kusano |
7d535a |
/* when looking for a cheap assignment. */
|
|
kusano |
7d535a |
/* OUT(J) is one less than the number of entries in column J which have */
|
|
kusano |
7d535a |
/* not been scanned during one pass through the main loop. */
|
|
kusano |
7d535a |
/* NUMX is maximum possible size of matching. */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--out;
|
|
kusano |
7d535a |
--cv;
|
|
kusano |
7d535a |
--arp;
|
|
kusano |
7d535a |
--pr;
|
|
kusano |
7d535a |
--iperm;
|
|
kusano |
7d535a |
--fc;
|
|
kusano |
7d535a |
--lenc;
|
|
kusano |
7d535a |
--ip;
|
|
kusano |
7d535a |
--irn;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
if (*id == 1) {
|
|
kusano |
7d535a |
/* The first call to MC64U/UD. */
|
|
kusano |
7d535a |
/* Initialize CV and ARP; parameters MOD, NUMX are not accessed */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__1; ++i__) {
|
|
kusano |
7d535a |
cv[i__] = 0;
|
|
kusano |
7d535a |
arp[i__] = 0;
|
|
kusano |
7d535a |
/* L5: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
num1 = *n;
|
|
kusano |
7d535a |
num2 = *n;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
/* Not the first call to MC64U/UD. */
|
|
kusano |
7d535a |
/* Re-initialize ARP if entries were deleted since last call to MC64U/UD */
|
|
kusano |
7d535a |
if (*mod == 1) {
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__1; ++i__) {
|
|
kusano |
7d535a |
arp[i__] = 0;
|
|
kusano |
7d535a |
/* L8: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
num1 = *numx;
|
|
kusano |
7d535a |
num2 = *n - *numx;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
num0 = *num;
|
|
kusano |
7d535a |
/* NUM0 is size of input matching */
|
|
kusano |
7d535a |
/* NUM1 is maximum possible size of matching */
|
|
kusano |
7d535a |
/* NUM2 is maximum allowed number of unassigned rows/columns */
|
|
kusano |
7d535a |
/* NUM is size of current matching */
|
|
kusano |
7d535a |
/* Quick return if possible */
|
|
kusano |
7d535a |
/* IF (NUM.EQ.N) GO TO 199 */
|
|
kusano |
7d535a |
/* NFC is number of rows/columns that could not be assigned */
|
|
kusano |
7d535a |
nfc = 0;
|
|
kusano |
7d535a |
/* Integers ID0+1 to ID0+N are unique numbers for call ID to MC64U/UD, */
|
|
kusano |
7d535a |
/* so 1st call uses 1..N, 2nd call uses N+1..2N, etc */
|
|
kusano |
7d535a |
id0 = (*id - 1) * *n;
|
|
kusano |
7d535a |
/* Main loop. Each pass round this loop either results in a new */
|
|
kusano |
7d535a |
/* assignment or gives a column with no assignment */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (jord = num0 + 1; jord <= i__1; ++jord) {
|
|
kusano |
7d535a |
/* Each pass uses unique number ID1 */
|
|
kusano |
7d535a |
id1 = id0 + jord;
|
|
kusano |
7d535a |
/* J is unmatched column */
|
|
kusano |
7d535a |
j = fc[jord - num0];
|
|
kusano |
7d535a |
pr[j] = -1;
|
|
kusano |
7d535a |
i__2 = jord;
|
|
kusano |
7d535a |
for (k = 1; k <= i__2; ++k) {
|
|
kusano |
7d535a |
/* Look for a cheap assignment */
|
|
kusano |
7d535a |
if (arp[j] >= lenc[j]) {
|
|
kusano |
7d535a |
goto L30;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
in1 = ip[j] + arp[j];
|
|
kusano |
7d535a |
in2 = ip[j] + lenc[j] - 1;
|
|
kusano |
7d535a |
i__3 = in2;
|
|
kusano |
7d535a |
for (ii = in1; ii <= i__3; ++ii) {
|
|
kusano |
7d535a |
i__ = irn[ii];
|
|
kusano |
7d535a |
if (iperm[i__] == 0) {
|
|
kusano |
7d535a |
goto L80;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L20: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* No cheap assignment in row */
|
|
kusano |
7d535a |
arp[j] = lenc[j];
|
|
kusano |
7d535a |
/* Begin looking for assignment chain starting with row J */
|
|
kusano |
7d535a |
L30:
|
|
kusano |
7d535a |
out[j] = lenc[j] - 1;
|
|
kusano |
7d535a |
/* Inner loop. Extends chain by one or backtracks */
|
|
kusano |
7d535a |
i__3 = jord;
|
|
kusano |
7d535a |
for (kk = 1; kk <= i__3; ++kk) {
|
|
kusano |
7d535a |
in1 = out[j];
|
|
kusano |
7d535a |
if (in1 < 0) {
|
|
kusano |
7d535a |
goto L50;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
in2 = ip[j] + lenc[j] - 1;
|
|
kusano |
7d535a |
in1 = in2 - in1;
|
|
kusano |
7d535a |
/* Forward scan */
|
|
kusano |
7d535a |
i__4 = in2;
|
|
kusano |
7d535a |
for (ii = in1; ii <= i__4; ++ii) {
|
|
kusano |
7d535a |
i__ = irn[ii];
|
|
kusano |
7d535a |
if (cv[i__] == id1) {
|
|
kusano |
7d535a |
goto L40;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Column J has not yet been accessed during this pass */
|
|
kusano |
7d535a |
j1 = j;
|
|
kusano |
7d535a |
j = iperm[i__];
|
|
kusano |
7d535a |
cv[i__] = id1;
|
|
kusano |
7d535a |
pr[j] = j1;
|
|
kusano |
7d535a |
out[j1] = in2 - ii - 1;
|
|
kusano |
7d535a |
goto L70;
|
|
kusano |
7d535a |
L40:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Backtracking step. */
|
|
kusano |
7d535a |
L50:
|
|
kusano |
7d535a |
j1 = pr[j];
|
|
kusano |
7d535a |
if (j1 == -1) {
|
|
kusano |
7d535a |
/* No augmenting path exists for column J. */
|
|
kusano |
7d535a |
++nfc;
|
|
kusano |
7d535a |
fc[nfc] = j;
|
|
kusano |
7d535a |
if (nfc > num2) {
|
|
kusano |
7d535a |
/* A matching of maximum size NUM1 is not possible */
|
|
kusano |
7d535a |
last = jord;
|
|
kusano |
7d535a |
goto L101;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L100;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
j = j1;
|
|
kusano |
7d535a |
/* L60: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
L70:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
/* New assignment is made. */
|
|
kusano |
7d535a |
L80:
|
|
kusano |
7d535a |
iperm[i__] = j;
|
|
kusano |
7d535a |
arp[j] = ii - ip[j] + 1;
|
|
kusano |
7d535a |
++(*num);
|
|
kusano |
7d535a |
i__2 = jord;
|
|
kusano |
7d535a |
for (k = 1; k <= i__2; ++k) {
|
|
kusano |
7d535a |
j = pr[j];
|
|
kusano |
7d535a |
if (j == -1) {
|
|
kusano |
7d535a |
goto L95;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
ii = ip[j] + lenc[j] - out[j] - 2;
|
|
kusano |
7d535a |
i__ = irn[ii];
|
|
kusano |
7d535a |
iperm[i__] = j;
|
|
kusano |
7d535a |
/* L90: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
L95:
|
|
kusano |
7d535a |
if (*num == num1) {
|
|
kusano |
7d535a |
/* A matching of maximum size NUM1 is found */
|
|
kusano |
7d535a |
last = jord;
|
|
kusano |
7d535a |
goto L101;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
L100:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* All unassigned columns have been considered */
|
|
kusano |
7d535a |
last = *n;
|
|
kusano |
7d535a |
/* Now, a transversal is computed or is not possible. */
|
|
kusano |
7d535a |
/* Complete FC before returning. */
|
|
kusano |
7d535a |
L101:
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (jord = last + 1; jord <= i__1; ++jord) {
|
|
kusano |
7d535a |
++nfc;
|
|
kusano |
7d535a |
fc[nfc] = fc[jord - num0];
|
|
kusano |
7d535a |
/* L110: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* 199 RETURN */
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} /* mc64ud_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* ********************************************************************** */
|
|
kusano |
7d535a |
/* Subroutine */ int_t mc64wd_(int_t *n, int_t *ne, int_t *ip, int_t *
|
|
kusano |
7d535a |
irn, double *a, int_t *iperm, int_t *num, int_t *jperm,
|
|
kusano |
7d535a |
int_t *out, int_t *pr, int_t *q, int_t *l, double *u,
|
|
kusano |
7d535a |
double *d__)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
/* System generated locals */
|
|
kusano |
7d535a |
int_t i__1, i__2, i__3;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
int_t i__, j, k, i0, k0, k1, k2, q0;
|
|
kusano |
7d535a |
double di;
|
|
kusano |
7d535a |
int_t ii, jj, kk;
|
|
kusano |
7d535a |
double vj;
|
|
kusano |
7d535a |
int_t up;
|
|
kusano |
7d535a |
double dq0;
|
|
kusano |
7d535a |
int_t kk1, kk2;
|
|
kusano |
7d535a |
double csp;
|
|
kusano |
7d535a |
int_t isp, jsp, low;
|
|
kusano |
7d535a |
double dmin__, dnew;
|
|
kusano |
7d535a |
int_t jord, qlen, jdum;
|
|
kusano |
7d535a |
double rinf;
|
|
kusano |
7d535a |
extern /* Subroutine */ int_t mc64dd_(int_t *, int_t *, int_t *,
|
|
kusano |
7d535a |
double *, int_t *, int_t *), mc64ed_(int_t *, int_t *,
|
|
kusano |
7d535a |
int_t *, double *, int_t *, int_t *), mc64fd_(int_t *
|
|
kusano |
7d535a |
, int_t *, int_t *, int_t *, double *, int_t *,
|
|
kusano |
7d535a |
int_t *);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* *** Copyright (c) 1999 Council for the Central Laboratory of the */
|
|
kusano |
7d535a |
/* Research Councils *** */
|
|
kusano |
7d535a |
/* *** Although every effort has been made to ensure robustness and *** */
|
|
kusano |
7d535a |
/* *** reliability of the subroutines in this MC64 suite, we *** */
|
|
kusano |
7d535a |
/* *** disclaim any liability arising through the use or misuse of *** */
|
|
kusano |
7d535a |
/* *** any of the subroutines. *** */
|
|
kusano |
7d535a |
/* *** Any problems? Contact ... */
|
|
kusano |
7d535a |
/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* N, NE, IP, IRN are described in MC64A/AD. */
|
|
kusano |
7d535a |
/* A is a REAL (DOUBLE PRECISION in the D-version) array of length NE. */
|
|
kusano |
7d535a |
/* A(K), K=1..NE, must be set to the value of the entry that */
|
|
kusano |
7d535a |
/* corresponds to IRN(K). It is not altered. */
|
|
kusano |
7d535a |
/* All values A(K) must be non-negative. */
|
|
kusano |
7d535a |
/* IPERM is an INT_T array of length N. On exit, it contains the */
|
|
kusano |
7d535a |
/* weighted matching: IPERM(I) = 0 or row I is matched to column */
|
|
kusano |
7d535a |
/* IPERM(I). */
|
|
kusano |
7d535a |
/* NUM is an INT_T variable. On exit, it contains the cardinality of */
|
|
kusano |
7d535a |
/* the matching stored in IPERM. */
|
|
kusano |
7d535a |
/* IW is an INT_T work array of length 5N. */
|
|
kusano |
7d535a |
/* DW is a REAL (DOUBLE PRECISION in the D-version) array of length 2N. */
|
|
kusano |
7d535a |
/* On exit, U = D(1:N) contains the dual row variable and */
|
|
kusano |
7d535a |
/* V = D(N+1:2N) contains the dual column variable. If the matrix */
|
|
kusano |
7d535a |
/* is structurally nonsingular (NUM = N), the following holds: */
|
|
kusano |
7d535a |
/* U(I)+V(J) <= A(I,J) if IPERM(I) |= J */
|
|
kusano |
7d535a |
/* U(I)+V(J) = A(I,J) if IPERM(I) = J */
|
|
kusano |
7d535a |
/* U(I) = 0 if IPERM(I) = 0 */
|
|
kusano |
7d535a |
/* V(J) = 0 if there is no I for which IPERM(I) = J */
|
|
kusano |
7d535a |
/* Local variables */
|
|
kusano |
7d535a |
/* Local parameters */
|
|
kusano |
7d535a |
/* External subroutines and/or functions */
|
|
kusano |
7d535a |
/* EXTERNAL FD05AD,MC64DD,MC64ED,MC64FD */
|
|
kusano |
7d535a |
/* DOUBLE PRECISION FD05AD */
|
|
kusano |
7d535a |
/* Set RINF to largest positive real number */
|
|
kusano |
7d535a |
/* XSL RINF = FD05AD(5) */
|
|
kusano |
7d535a |
/* Parameter adjustments */
|
|
kusano |
7d535a |
--d__;
|
|
kusano |
7d535a |
--u;
|
|
kusano |
7d535a |
--l;
|
|
kusano |
7d535a |
--q;
|
|
kusano |
7d535a |
--pr;
|
|
kusano |
7d535a |
--out;
|
|
kusano |
7d535a |
--jperm;
|
|
kusano |
7d535a |
--iperm;
|
|
kusano |
7d535a |
--ip;
|
|
kusano |
7d535a |
--a;
|
|
kusano |
7d535a |
--irn;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/* Function Body */
|
|
kusano |
7d535a |
rinf = dlamch_("Overflow");
|
|
kusano |
7d535a |
/* Initialization */
|
|
kusano |
7d535a |
*num = 0;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (k = 1; k <= i__1; ++k) {
|
|
kusano |
7d535a |
u[k] = rinf;
|
|
kusano |
7d535a |
d__[k] = 0.;
|
|
kusano |
7d535a |
iperm[k] = 0;
|
|
kusano |
7d535a |
jperm[k] = 0;
|
|
kusano |
7d535a |
pr[k] = ip[k];
|
|
kusano |
7d535a |
l[k] = 0;
|
|
kusano |
7d535a |
/* L10: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Initialize U(I) */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
if (a[k] > u[i__]) {
|
|
kusano |
7d535a |
goto L20;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
u[i__] = a[k];
|
|
kusano |
7d535a |
iperm[i__] = j;
|
|
kusano |
7d535a |
l[i__] = k;
|
|
kusano |
7d535a |
L20:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L30: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__1; ++i__) {
|
|
kusano |
7d535a |
j = iperm[i__];
|
|
kusano |
7d535a |
if (j == 0) {
|
|
kusano |
7d535a |
goto L40;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Row I is not empty */
|
|
kusano |
7d535a |
iperm[i__] = 0;
|
|
kusano |
7d535a |
if (jperm[j] != 0) {
|
|
kusano |
7d535a |
goto L40;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Assignment of column J to row I */
|
|
kusano |
7d535a |
++(*num);
|
|
kusano |
7d535a |
iperm[i__] = j;
|
|
kusano |
7d535a |
jperm[j] = l[i__];
|
|
kusano |
7d535a |
L40:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*num == *n) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Scan unassigned columns; improve assignment */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
/* JPERM(J) ne 0 iff column J is already assigned */
|
|
kusano |
7d535a |
if (jperm[j] != 0) {
|
|
kusano |
7d535a |
goto L95;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
k1 = ip[j];
|
|
kusano |
7d535a |
k2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
/* Continue only if column J is not empty */
|
|
kusano |
7d535a |
if (k1 > k2) {
|
|
kusano |
7d535a |
goto L95;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
vj = rinf;
|
|
kusano |
7d535a |
i__2 = k2;
|
|
kusano |
7d535a |
for (k = k1; k <= i__2; ++k) {
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
di = a[k] - u[i__];
|
|
kusano |
7d535a |
if (di > vj) {
|
|
kusano |
7d535a |
goto L50;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (di < vj || di == rinf) {
|
|
kusano |
7d535a |
goto L55;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (iperm[i__] != 0 || iperm[i0] == 0) {
|
|
kusano |
7d535a |
goto L50;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L55:
|
|
kusano |
7d535a |
vj = di;
|
|
kusano |
7d535a |
i0 = i__;
|
|
kusano |
7d535a |
k0 = k;
|
|
kusano |
7d535a |
L50:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
d__[j] = vj;
|
|
kusano |
7d535a |
k = k0;
|
|
kusano |
7d535a |
i__ = i0;
|
|
kusano |
7d535a |
if (iperm[i__] == 0) {
|
|
kusano |
7d535a |
goto L90;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__2 = k2;
|
|
kusano |
7d535a |
for (k = k0; k <= i__2; ++k) {
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
if (a[k] - u[i__] > vj) {
|
|
kusano |
7d535a |
goto L60;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
jj = iperm[i__];
|
|
kusano |
7d535a |
/* Scan remaining part of assigned column JJ */
|
|
kusano |
7d535a |
kk1 = pr[jj];
|
|
kusano |
7d535a |
kk2 = ip[jj + 1] - 1;
|
|
kusano |
7d535a |
if (kk1 > kk2) {
|
|
kusano |
7d535a |
goto L60;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__3 = kk2;
|
|
kusano |
7d535a |
for (kk = kk1; kk <= i__3; ++kk) {
|
|
kusano |
7d535a |
ii = irn[kk];
|
|
kusano |
7d535a |
if (iperm[ii] > 0) {
|
|
kusano |
7d535a |
goto L70;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (a[kk] - u[ii] <= d__[jj]) {
|
|
kusano |
7d535a |
goto L80;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L70:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
pr[jj] = kk2 + 1;
|
|
kusano |
7d535a |
L60:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L95;
|
|
kusano |
7d535a |
L80:
|
|
kusano |
7d535a |
jperm[jj] = kk;
|
|
kusano |
7d535a |
iperm[ii] = jj;
|
|
kusano |
7d535a |
pr[jj] = kk + 1;
|
|
kusano |
7d535a |
L90:
|
|
kusano |
7d535a |
++(*num);
|
|
kusano |
7d535a |
jperm[j] = k;
|
|
kusano |
7d535a |
iperm[i__] = j;
|
|
kusano |
7d535a |
pr[j] = k + 1;
|
|
kusano |
7d535a |
L95:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*num == *n) {
|
|
kusano |
7d535a |
goto L1000;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Prepare for main loop */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__1; ++i__) {
|
|
kusano |
7d535a |
d__[i__] = rinf;
|
|
kusano |
7d535a |
l[i__] = 0;
|
|
kusano |
7d535a |
/* L99: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Main loop ... each pass round this loop is similar to Dijkstra's */
|
|
kusano |
7d535a |
/* algorithm for solving the single source shortest path problem */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (jord = 1; jord <= i__1; ++jord) {
|
|
kusano |
7d535a |
if (jperm[jord] != 0) {
|
|
kusano |
7d535a |
goto L100;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* JORD is next unmatched column */
|
|
kusano |
7d535a |
/* DMIN is the length of shortest path in the tree */
|
|
kusano |
7d535a |
dmin__ = rinf;
|
|
kusano |
7d535a |
qlen = 0;
|
|
kusano |
7d535a |
low = *n + 1;
|
|
kusano |
7d535a |
up = *n + 1;
|
|
kusano |
7d535a |
/* CSP is the cost of the shortest augmenting path to unassigned row */
|
|
kusano |
7d535a |
/* IRN(ISP). The corresponding column index is JSP. */
|
|
kusano |
7d535a |
csp = rinf;
|
|
kusano |
7d535a |
/* Build shortest path tree starting from unassigned column (root) JORD */
|
|
kusano |
7d535a |
j = jord;
|
|
kusano |
7d535a |
pr[j] = -1;
|
|
kusano |
7d535a |
/* Scan column J */
|
|
kusano |
7d535a |
i__2 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__2; ++k) {
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
dnew = a[k] - u[i__];
|
|
kusano |
7d535a |
if (dnew >= csp) {
|
|
kusano |
7d535a |
goto L115;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (iperm[i__] == 0) {
|
|
kusano |
7d535a |
csp = dnew;
|
|
kusano |
7d535a |
isp = k;
|
|
kusano |
7d535a |
jsp = j;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
if (dnew < dmin__) {
|
|
kusano |
7d535a |
dmin__ = dnew;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
d__[i__] = dnew;
|
|
kusano |
7d535a |
++qlen;
|
|
kusano |
7d535a |
q[qlen] = k;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L115:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Initialize heap Q and Q2 with rows held in Q(1:QLEN) */
|
|
kusano |
7d535a |
q0 = qlen;
|
|
kusano |
7d535a |
qlen = 0;
|
|
kusano |
7d535a |
i__2 = q0;
|
|
kusano |
7d535a |
for (kk = 1; kk <= i__2; ++kk) {
|
|
kusano |
7d535a |
k = q[kk];
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
if (csp <= d__[i__]) {
|
|
kusano |
7d535a |
d__[i__] = rinf;
|
|
kusano |
7d535a |
goto L120;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (d__[i__] <= dmin__) {
|
|
kusano |
7d535a |
--low;
|
|
kusano |
7d535a |
q[low] = i__;
|
|
kusano |
7d535a |
l[i__] = low;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
++qlen;
|
|
kusano |
7d535a |
l[i__] = qlen;
|
|
kusano |
7d535a |
mc64dd_(&i__, n, &q[1], &d__[1], &l[1], &c__2);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Update tree */
|
|
kusano |
7d535a |
jj = iperm[i__];
|
|
kusano |
7d535a |
out[jj] = k;
|
|
kusano |
7d535a |
pr[jj] = j;
|
|
kusano |
7d535a |
L120:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__2 = *num;
|
|
kusano |
7d535a |
for (jdum = 1; jdum <= i__2; ++jdum) {
|
|
kusano |
7d535a |
/* If Q2 is empty, extract rows from Q */
|
|
kusano |
7d535a |
if (low == up) {
|
|
kusano |
7d535a |
if (qlen == 0) {
|
|
kusano |
7d535a |
goto L160;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__ = q[1];
|
|
kusano |
7d535a |
if (d__[i__] >= csp) {
|
|
kusano |
7d535a |
goto L160;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
dmin__ = d__[i__];
|
|
kusano |
7d535a |
L152:
|
|
kusano |
7d535a |
mc64ed_(&qlen, n, &q[1], &d__[1], &l[1], &c__2);
|
|
kusano |
7d535a |
--low;
|
|
kusano |
7d535a |
q[low] = i__;
|
|
kusano |
7d535a |
l[i__] = low;
|
|
kusano |
7d535a |
if (qlen == 0) {
|
|
kusano |
7d535a |
goto L153;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__ = q[1];
|
|
kusano |
7d535a |
if (d__[i__] > dmin__) {
|
|
kusano |
7d535a |
goto L153;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
goto L152;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Q0 is row whose distance D(Q0) to the root is smallest */
|
|
kusano |
7d535a |
L153:
|
|
kusano |
7d535a |
q0 = q[up - 1];
|
|
kusano |
7d535a |
dq0 = d__[q0];
|
|
kusano |
7d535a |
/* Exit loop if path to Q0 is longer than the shortest augmenting path */
|
|
kusano |
7d535a |
if (dq0 >= csp) {
|
|
kusano |
7d535a |
goto L160;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
--up;
|
|
kusano |
7d535a |
/* Scan column that matches with row Q0 */
|
|
kusano |
7d535a |
j = iperm[q0];
|
|
kusano |
7d535a |
vj = dq0 - a[jperm[j]] + u[q0];
|
|
kusano |
7d535a |
i__3 = ip[j + 1] - 1;
|
|
kusano |
7d535a |
for (k = ip[j]; k <= i__3; ++k) {
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
if (l[i__] >= up) {
|
|
kusano |
7d535a |
goto L155;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* DNEW is new cost */
|
|
kusano |
7d535a |
dnew = vj + a[k] - u[i__];
|
|
kusano |
7d535a |
/* Do not update D(I) if DNEW ge cost of shortest path */
|
|
kusano |
7d535a |
if (dnew >= csp) {
|
|
kusano |
7d535a |
goto L155;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (iperm[i__] == 0) {
|
|
kusano |
7d535a |
/* Row I is unmatched; update shortest path info */
|
|
kusano |
7d535a |
csp = dnew;
|
|
kusano |
7d535a |
isp = k;
|
|
kusano |
7d535a |
jsp = j;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
/* Row I is matched; do not update D(I) if DNEW is larger */
|
|
kusano |
7d535a |
di = d__[i__];
|
|
kusano |
7d535a |
if (di <= dnew) {
|
|
kusano |
7d535a |
goto L155;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (l[i__] >= low) {
|
|
kusano |
7d535a |
goto L155;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
d__[i__] = dnew;
|
|
kusano |
7d535a |
if (dnew <= dmin__) {
|
|
kusano |
7d535a |
if (l[i__] != 0) {
|
|
kusano |
7d535a |
mc64fd_(&l[i__], &qlen, n, &q[1], &d__[1], &l[1],
|
|
kusano |
7d535a |
&c__2);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
--low;
|
|
kusano |
7d535a |
q[low] = i__;
|
|
kusano |
7d535a |
l[i__] = low;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
if (l[i__] == 0) {
|
|
kusano |
7d535a |
++qlen;
|
|
kusano |
7d535a |
l[i__] = qlen;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
mc64dd_(&i__, n, &q[1], &d__[1], &l[1], &c__2);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Update tree */
|
|
kusano |
7d535a |
jj = iperm[i__];
|
|
kusano |
7d535a |
out[jj] = k;
|
|
kusano |
7d535a |
pr[jj] = j;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L155:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L150: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* If CSP = RINF, no augmenting path is found */
|
|
kusano |
7d535a |
L160:
|
|
kusano |
7d535a |
if (csp == rinf) {
|
|
kusano |
7d535a |
goto L190;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* Find augmenting path by tracing backward in PR; update IPERM,JPERM */
|
|
kusano |
7d535a |
++(*num);
|
|
kusano |
7d535a |
i__ = irn[isp];
|
|
kusano |
7d535a |
iperm[i__] = jsp;
|
|
kusano |
7d535a |
jperm[jsp] = isp;
|
|
kusano |
7d535a |
j = jsp;
|
|
kusano |
7d535a |
i__2 = *num;
|
|
kusano |
7d535a |
for (jdum = 1; jdum <= i__2; ++jdum) {
|
|
kusano |
7d535a |
jj = pr[j];
|
|
kusano |
7d535a |
if (jj == -1) {
|
|
kusano |
7d535a |
goto L180;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
k = out[j];
|
|
kusano |
7d535a |
i__ = irn[k];
|
|
kusano |
7d535a |
iperm[i__] = jj;
|
|
kusano |
7d535a |
jperm[jj] = k;
|
|
kusano |
7d535a |
j = jj;
|
|
kusano |
7d535a |
/* L170: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of dummy loop; this point is never reached */
|
|
kusano |
7d535a |
/* Update U for rows in Q(UP:N) */
|
|
kusano |
7d535a |
L180:
|
|
kusano |
7d535a |
i__2 = *n;
|
|
kusano |
7d535a |
for (kk = up; kk <= i__2; ++kk) {
|
|
kusano |
7d535a |
i__ = q[kk];
|
|
kusano |
7d535a |
u[i__] = u[i__] + d__[i__] - csp;
|
|
kusano |
7d535a |
/* L185: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L190:
|
|
kusano |
7d535a |
i__2 = *n;
|
|
kusano |
7d535a |
for (kk = low; kk <= i__2; ++kk) {
|
|
kusano |
7d535a |
i__ = q[kk];
|
|
kusano |
7d535a |
d__[i__] = rinf;
|
|
kusano |
7d535a |
l[i__] = 0;
|
|
kusano |
7d535a |
/* L191: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
i__2 = qlen;
|
|
kusano |
7d535a |
for (kk = 1; kk <= i__2; ++kk) {
|
|
kusano |
7d535a |
i__ = q[kk];
|
|
kusano |
7d535a |
d__[i__] = rinf;
|
|
kusano |
7d535a |
l[i__] = 0;
|
|
kusano |
7d535a |
/* L193: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L100:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* End of main loop */
|
|
kusano |
7d535a |
/* Set dual column variable in D(1:N) */
|
|
kusano |
7d535a |
L1000:
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
k = jperm[j];
|
|
kusano |
7d535a |
if (k != 0) {
|
|
kusano |
7d535a |
d__[j] = a[k] - u[irn[k]];
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
d__[j] = 0.;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (iperm[j] == 0) {
|
|
kusano |
7d535a |
u[j] = 0.;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L200: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (*num == *n) {
|
|
kusano |
7d535a |
goto L1100;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* The matrix is structurally singular, complete IPERM. */
|
|
kusano |
7d535a |
/* JPERM, OUT are work arrays */
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
jperm[j] = 0;
|
|
kusano |
7d535a |
/* L300: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
k = 0;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (i__ = 1; i__ <= i__1; ++i__) {
|
|
kusano |
7d535a |
if (iperm[i__] == 0) {
|
|
kusano |
7d535a |
++k;
|
|
kusano |
7d535a |
out[k] = i__;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
j = iperm[i__];
|
|
kusano |
7d535a |
jperm[j] = i__;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
/* L310: */
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
k = 0;
|
|
kusano |
7d535a |
i__1 = *n;
|
|
kusano |
7d535a |
for (j = 1; j <= i__1; ++j) {
|
|
kusano |
7d535a |
if (jperm[j] != 0) {
|
|
kusano |
7d535a |
goto L320;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
++k;
|
|
kusano |
7d535a |
jdum = out[k];
|
|
kusano |
7d535a |
iperm[jdum] = j;
|
|
kusano |
7d535a |
L320:
|
|
kusano |
7d535a |
;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
L1100:
|
|
kusano |
7d535a |
return 0;
|
|
kusano |
7d535a |
} /* mc64wd_ */
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|