/* MDRVCB.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 mmdrvcb_(ideriv, ndim, ncoeff, courbe, tparam, tabpnt, 
	iercod)
integer *ideriv, *ndim, *ncoeff;
doublereal *courbe, *tparam, *tabpnt;
integer *iercod;
{
    /* System generated locals */
    integer courbe_dim1, tabpnt_dim1, i__1, i__2, i__3;

    /* Local variables */
    static integer ndeg, i__, j, nd, ndgcrb, iptpnt, ibb;
    extern integer mnfndeb_();
    extern /* Subroutine */ int maermsg_(), mgenmsg_(), mvriraz_();



/* < */
/* **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 : */
/*     ---------- */
/*      Calcul des derivees successives de l' equation COURBE au */
/*      parametre TPARAM de l' ordre 0 jusqu' a l' ordre IDERIV inclus. */
/*      Le calcul se fait sans utiliser les coefficients des */
/*      derivees de COURBE. */

/*     MOTS CLES : */
/*     ----------- */
/*      POSITIONNEMENT,PARAMETRE,COURBE,DERIVEE. */

/*     ARGUMENTS D'ENTREE : */
/*     ------------------ */
/*      IDERIV : Ordre maximal de calcul des derivees. */
/*      NDIM   : Dimension de l' espace. */
/*      NCOEFF : Nombre de coefficients de la courbe (degre+1). */
/*      COURBE : Tableau des coefficients de la courbe. */
/*      TPARAM : Valeur du parametre ou la courbe doit etre evaluee. */

/*     ARGUMENTS DE SORTIE : */
/*     ------------------- */
/*      TABPNT : Tableau des valeurs des derivees successives */
/*               au parametre TPARAM. */
/*      IERCOD : 0 = OK, */
/*               1 = Entrees incoherentes. */

/*     COMMONS UTILISES   : */
/*     ---------------- */
/*        Aucun. */

/*     REFERENCES APPELEES   : */
/*     ----------------------- */

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

/*     L' algorithme de calcul des derivees est base sur la */
/*     generalisation du schema de Horner : */
/*                          k             2 */
/*          Soit C(t) = uk.t  + ... + u2.t  + u1.t + u0 . */


/*     On pose a0 = uk, b0 = 0, c0 = 0 et pour 1<=j<=k, on calcule : */

/*          aj = a(j-1).x + u(k-j) */
/*          bj = b(j-1).x + a(j-1) */
/*          cj = c(j-1).x + b(j-1) */

/*     On obtient alors : C(x) = ak, C'(x) = bk, C"(x) = 2.ck  . */

/*     L' algorithme se generalise facilement pour le calcul de */

/*               (n) */
/*              C  (x)   . */
/*             --------- */
/*                n! */

/*      Reference : D. KNUTH, "The Art of Computer Programming" */
/*      ---------              Vol. 2/Seminumerical Algorithms */
/*                             Addison-Wesley Pub. Co. (1969) */
/*                             pages 423-425. */

/* ----> Pour evaluer les derivees en 0 et en 1, il est preferable */
/*      d' utiliser la routine MDRV01.FOR . */

/* $    HISTORIQUE DES MODIFICATIONS   : */
/*     -------------------------------- */
/*     28-06-1988 : Cree par RBD. */

/* > */
/* ********************************************************************** 
*/

/*   Le nom de la routine */

    /* Parameter adjustments */
    tabpnt_dim1 = *ndim;
    --tabpnt;
    courbe_dim1 = *ndim;
    --courbe;

    /* Function Body */
    ibb = mnfndeb_();
    if (ibb >= 2) {
	mgenmsg_("MMDRVCB", 7L);
    }

    if (*ideriv < 0 || *ncoeff < 1) {
	*iercod = 1;
	goto L9999;
    }
    *iercod = 0;

/* ------------------- Initialisation du tableau TABPNT ----------------- 
*/

    ndgcrb = *ncoeff - 1;
    i__1 = *ndim;
    for (nd = 1; nd <= i__1; ++nd) {
	tabpnt[nd] = courbe[nd + ndgcrb * courbe_dim1];
/* L100: */
    }

    if (*ideriv < 1) {
	goto L200;
    }
    iptpnt = *ndim * *ideriv;
    mvriraz_(&iptpnt, &tabpnt[tabpnt_dim1 + 1]);
L200:

/* ------------------------ Calcul au parametre TPARAM ------------------ 
*/

    i__1 = ndgcrb;
    for (ndeg = 1; ndeg <= i__1; ++ndeg) {
	i__2 = *ndim;
	for (nd = 1; nd <= i__2; ++nd) {
	    for (i__ = *ideriv; i__ >= 1; --i__) {
		tabpnt[nd + i__ * tabpnt_dim1] = tabpnt[nd + i__ * 
			tabpnt_dim1] * *tparam + tabpnt[nd + (i__ - 1) * 
			tabpnt_dim1];
/* L700: */
	    }
	    tabpnt[nd] = tabpnt[nd] * *tparam + courbe[nd + (ndgcrb - ndeg) * 
		    courbe_dim1];
/* L600: */
	}
/* L500: */
    }

/* --------------------- Multiplication par factorielle(I) ------------- 
*/

    i__1 = *ideriv;
    for (i__ = 2; i__ <= i__1; ++i__) {
	i__2 = i__;
	for (j = 2; j <= i__2; ++j) {
	    i__3 = *ndim;
	    for (nd = 1; nd <= i__3; ++nd) {
		tabpnt[nd + i__ * tabpnt_dim1] = (doublereal) j * tabpnt[nd + 
			i__ * tabpnt_dim1];
/* L1200: */
	    }
/* L1100: */
	}
/* L1000: */
    }

/* --------------------------- The end --------------------------------- 
*/

L9999:
    if (*iercod > 0) {
	maermsg_("MMDRVCB", iercod, 7L);
    }
    return 0;
} /* mmdrvcb_ */

