/* MLONCV.f -- translated by f2c (version 19960827).
   You must link the resulting object file with the libraries:
	-lf2c -lm   (in that order)
*/

#include "Data_f2c.h"

/* Subroutine */ int mmloncv_(ndimax, ndimen, ncoeff, courbe, tdebut, tfinal, 
	xlongc, iercod)
integer *ndimax, *ndimen, *ncoeff;
doublereal *courbe, *tdebut, *tfinal, *xlongc;
integer *iercod;
{
    /* Initialized data */

    static integer kgar = 0;

    /* System generated locals */
    integer courbe_dim1, courbe_offset, i__1, i__2;

    /* Builtin functions */
    double sqrt();

    /* Local variables */
    static doublereal tran;
    static integer ngaus;
    static doublereal c1, c2, d1, d2, wgaus[20], uroot[20], x1, x2, dd;
    static integer ii, jj, kk;
    extern /* Subroutine */ int mvgaus0_();
    static doublereal som;
    extern /* Subroutine */ int maermsg_();
    static doublereal der1, der2;




/* **NOTICE */
/*  THIS SOFTWARE IS THE PROPERTY OF CISIGRAPH. */
/*  THIS CODE MUST NOT BE DISTRIBUTED OR COPIED WITHOUT THE PRIOR */
/*  WRITTEN PERMISSION OF CISIGRAPH AND IS ONLY TO BE USED ON THE */
/*  SITE WHERE IT IS INSTALLED BY CISIGRAPH */
/* **NOTICE */

/* ********************************************************************** 
*/

/*     FONCTION : Longueur d'un arc de courbe sur un intervalle donne */
/*     ---------- pour une fonction dont la representation mathematique */
/*                est faite un polynome multidimensionnel. */
/*      Le polynome est en fait un ensemble de polynomes dont les coeffi- 
*/
/*      cients sont ranges dans un tableau a 2 indices, chaque ligne */
/*      etant relative a 1 polynome. */
/*      Le polynome est defini par ses coefficients ordonne par les puis- 
*/
/*      sances croissantes de la variable. */
/*      Tous les polynomes ont le meme nombre de coefficients (donc le */
/*      meme degre). */

/*     MOTS CLES : LONGUEUR, COURBE */
/*     ----------- */

/*     ARGUMENTS D'ENTREE : */
/*     -------------------- */

/*      NDIMAX : Nombre de lignes maximum des tableaux */
/*               (nombre maxi de polynomes). */
/*      NDIMEN  : Dimension du polynome (Nombre de polynomes). */
/*      NCOEFF : Nombre de coefficients du polynome (pas de limitation) */
/*               C'est le degre + 1 */
/*      COURBE : Coefficients du polynome ordonne par les puissances */
/*               croissantes. A dimensionner a (NDIMAX,NCOEFF). */
/*      TDEBUT : Bornes inferieure de l'integration pour calcul de la */
/*               longueur. */
/*      TFINAL : Bornes superieure de l'integration pour calcul de la */
/*               longueur. */

/*     ARGUMENTS DE SORTIE : */
/*     --------------------- */
/*      XLONGC : Longueur de l'arc de courbe */

/*      IERCOD : Code d'erreur : */
/*             = 0 ==> Tout est OK */
/*             = 1 ==> NDIMEN ou NCOEFF negatif ou nul */
/*             = 2 ==> Pb chargement racines Legendre et poids de Gauss */
/*                     par MVGAUS0. */

/*     Si erreur => XLONGC = 0 */

/*     COMMONS UTILISES : */
/*     ------------------ */

/*      .Neant. */

/*     REFERENCES APPELEES   : */
/*     ---------------------- */
/*     Type  Name */
/*           MAERMSG         R*8  DSQRT          I*4  MIN */
/*           MVGAUS0 */

/*     DESCRIPTION/REMARQUES/LIMITATIONS : */
/*     ----------------------------------- */

/*      Voir VGAUSS pour bien comprendre la technique. */
/*      On integre en verite SQRT (dpi^2) pour i=1,nbdime */
/*      Le calcul de la derivee est mele dans le code pour ne pas faire */
/*      un appel supplementaire a une routine. */

/*      La fonction que l'on integre est strictement croissante, il */
/*      n'est pas necessaire d'utiliser un haut degre pour la methode */
/*      GAUSS */

/*      Le degre du polynome de LEGENDRE est fonction du degre du */
/*      polynome a integrer. Il peut varier de 4 a 40 (par pas de 4). */

/*      La precision (relative) de l'integration est de l'ordre */
/*      de 1.D-8. */

/*      ATTENTION : si TDEBUT > TFINAL, la longueur est alors NEGATIVE. */

/*      Attention : la precision sur le resultat n'est pas controlee. */
/*      Si vous desirez la controler utiliser plutot MMCGLC1, tout en */
/*      sachant que les performances (en temps) seront quand meme moins */
/*      bonnes. */

/* $    HISTORIQUE DES MODIFICATIONS : */
/*     ------------------------------ */
/*      8-09-1995 : Performance */
/*     08-04-94 : JMC ; Rem: Appeler MMCGLC1 pour controler la precision 
*/
/*     26-04-90 : RBD ; Augmentation du nbre de points KK pour calcul */
/*                      + precis, appel a MXVINIT et MXVSAVE, recup */
/*                      code d'erreur MVGAUS0, ajout commentaires. */
/*      08-06-89 : GD ; Suppression des 2 parties de l'integration, */
/*                      MVGAUS0 est appelle que si le degre a change. */
/*      10-06-88 : GD ; Variation dynamique du degre LEGENDRE */
/*      18-08-87 : GD ; Version originale */

/* >===================================================================== 
*/

/*      ATTENTION : SAUVER KGAR WGAUS et UROOT EVENTUELLEMENT */
/*     ,IERXV */
/*      INTEGER I1,I20 */
/*      PARAMETER (I1=1,I20=20) */

    /* Parameter adjustments */
    courbe_dim1 = *ndimax;
    courbe_offset = courbe_dim1 + 1;
    courbe -= courbe_offset;

    /* Function Body */

/* ****** Initialisation generale ** */

    *iercod = 999999;
    *xlongc = 0.;

/* ****** Initialisation de UROOT, WGAUS, NGAUS et KGAR ** */

/*      CALL MXVINIT(IERXV,'INTEGER',I1,KGAR,'INTEGER',I1,NGAUS */
/*     1    ,'DOUBLE PRECISION',I20,UROOT,'DOUBLE PRECISION',I20,WGAUS) */
/*      IF (IERXV.GT.0) KGAR=0 */

/* ****** Test d'egalite des bornes ** */

    if (*tdebut == *tfinal) {
	*iercod = 0;
	goto L9900;
    }

/* ****** Test de la dimension et du nombre de coefficients ** */

    if (*ndimen <= 0 || *ncoeff <= 0) {
	*iercod = 1;
	goto L9900;
    }

/* ****** Calcul du degre optimum ** */

    kk = *ncoeff / 4 + 1;
    kk = min(kk,10);

/* ****** Recuperation des coefficients pour l'integrale (DEGRE=4*KK) */
/*       si KK <> KGAR. */

    if (kk != kgar) {
	mvgaus0_(&kk, uroot, wgaus, &ngaus, iercod);
	if (*iercod > 0) {
	    kgar = 0;
	    *iercod = 2;
	    goto L9900;
	}
	kgar = kk;
    }

/*      C1 => Point milieu intervalle */
/*      C2 => 1/2 amplitude intervalle */

    c1 = (*tfinal + *tdebut) * .5;
    c2 = (*tfinal - *tdebut) * .5;

/* ----------------------------------------------------------- */
/* ****** Integration - Boucle sur les intervalles de GAUSS ** */
/* ----------------------------------------------------------- */

    som = 0.;

    i__1 = ngaus;
    for (jj = 1; jj <= i__1; ++jj) {

/* ****** Integration en tenant compte de la symetrie ** */

	tran = c2 * uroot[jj - 1];
	x1 = c1 + tran;
	x2 = c1 - tran;

/* ****** Derivation sur la dimension de l'espace ** */

	der1 = 0.;
	der2 = 0.;
	i__2 = *ndimen;
	for (kk = 1; kk <= i__2; ++kk) {
	    d1 = (*ncoeff - 1) * courbe[kk + *ncoeff * courbe_dim1];
	    d2 = d1;
	    for (ii = *ncoeff - 1; ii >= 2; --ii) {
		dd = (ii - 1) * courbe[kk + ii * courbe_dim1];
		d1 = d1 * x1 + dd;
		d2 = d2 * x2 + dd;
/* L100: */
	    }
	    der1 += d1 * d1;
	    der2 += d2 * d2;
/* L200: */
	}

/* ****** Integration ** */

	som += wgaus[jj - 1] * c2 * (sqrt(der1) + sqrt(der2));

/* ****** Fin de boucle dur les intervalles de GAUSS ** */

/* L300: */
    }

/* ****** Travail termine ** */

    *xlongc = som;

/* ****** On force IERCOD  =  0 ** */

    *iercod = 0;

/* ****** Traitement de fin ** */

L9900:

/* ****** Sauvegarde de UROOT, WGAUS, NGAUS et KGAR ** */

/*      CALL MXVSAVE(IERXV,'INTEGER',I1,KGAR,'INTEGER',I1,NGAUS */
/*     1    ,'DOUBLE PRECISION',I20,UROOT,'DOUBLE PRECISION',I20,WGAUS) */
/*      IF (IERXV.GT.0) KGAR=0 */

/* ****** Fin du sous-programme ** */

    if (*iercod != 0) {
	maermsg_("MMLONCV", iercod, 7L);
    }
 return 0 ;
} /* mmloncv_ */

