Eine aufbereitete Darstellung der Quelle

 
     
 
 
 
 
 
 

Benutzer

Quelle  polyr.c

  Sprache: C
 


/* Arithmetic operations on polynomials with rational coefficients
 *
 * In the following descriptions a, b, c are polynomials of degree
 * na, nb, nc respectively.  The degree of a polynomial cannot
 * exceed a run-time value MAXPOL.  An operation that attempts
 * to use or generate a polynomial of higher degree may produce a
 * result that suffers truncation at degree MAXPOL.  The value of
 * MAXPOL is set by calling the function
 *
 *     polini( maxpol );
 *
 * where maxpol is the desired maximum degree.  This must be
 * done prior to calling any of the other functions in this module.
 * Memory for internal temporary polynomial storage is allocated
 * by polini().
 *
 * Each polynomial is represented by an array containing its
 * coefficients, together with a separately declared integer equal
 * to the degree of the polynomial.  The coefficients appear in
 * ascending order; that is,
 *
 *                                        2                      na
 * a(x)  =  a[0]  +  a[1] * x  +  a[2] * x   +  ...  +  a[na] * x  .
 *
 *
 *
 * `a', `b', `c' are arrays of fracts.
 * poleva( a, na, &x, &sum ); Evaluate polynomial a(t) at t = x.
 * polprt( a, na, D );  Print the coefficients of a to D digits.
 * polclr( a, na );  Set a identically equal to zero, up to a[na].
 * polmov( a, na, b );  Set b = a.
 * poladd( a, na, b, nb, c ); c = b + a, nc = max(na,nb)
 * polsub( a, na, b, nb, c ); c = b - a, nc = max(na,nb)
 * polmul( a, na, b, nb, c ); c = b * a, nc = na+nb
 *
 *
 * Division:
 *
 * i = poldiv( a, na, b, nb, c ); c = b / a, nc = MAXPOL
 *
 * returns i = the degree of the first nonzero coefficient of a.
 * The computed quotient c must be divided by x^i.  An error message
 * is printed if a is identically zero.
 *
 *
 * Change of variables:
 * If a and b are polynomials, and t = a(x), then
 *     c(t) = b(a(x))
 * is a polynomial found by substituting a(x) for t.  The
 * subroutine call for this is
 *
 * polsbt( a, na, b, nb, c );
 *
 *
 * Notes:
 * poldiv() is an integer routine; poleva() is double.
 * Any of the arguments a, b, c may refer to the same array.
 *
 */


#include <stdio.h>
#include "mconf.h"
#ifndef NULL
#define NULL 0
#endif
typedef struct{
 double n;
 double d;
 }fract;

#ifdef ANSIPROT
extern void radd ( fract *, fract *, fract * );
extern void rsub ( fract *, fract *, fract * );
extern void rmul ( fract *, fract *, fract * );
extern void rdiv ( fract *, fract *, fract * );
void polmov ( fract *, int, fract * );
void polmul ( fract *, int, fract *, int, fract * );
int poldiv ( fract *, int, fract *, int, fract * );
void * malloc ( long );
void free ( void * );
#else
void radd(), rsub(), rmul(), rdiv();
void polmov(), polmul();
int poldiv();
void * malloc();
void free ();
#endif

/* near pointer version of malloc() */
/*
#define malloc _nmalloc
#define free _nfree
*/

/* Pointers to internal arrays.  Note poldiv() allocates
 * and deallocates some temporary arrays every time it is called.
 */

static fract *pt1 = 0;
static fract *pt2 = 0;
static fract *pt3 = 0;

/* Maximum degree of polynomial. */
int MAXPOL = 0;
extern int MAXPOL;

/* Number of bytes (chars) in maximum size polynomial. */
static int psize = 0;


/* Initialize max degree of polynomials
 * and allocate temporary storage.
 */

void polini( maxdeg )
int maxdeg;
{

MAXPOL = maxdeg;
psize = (maxdeg + 1) * sizeof(fract);

/* Release previously allocated memory, if any. */
if( pt3 )
 free(pt3);
if( pt2 )
 free(pt2);
if( pt1 )
 free(pt1);

/* Allocate new arrays */
pt1 = (fract * )malloc(psize); /* used by polsbt */
pt2 = (fract * )malloc(psize); /* used by polsbt */
pt3 = (fract * )malloc(psize); /* used by polmul */

/* Report if failure */
if( (pt1 == NULL) || (pt2 == NULL) || (pt3 == NULL) )
 {
 mtherr( "polini", ERANGE );
 exit(1);
 }
}



/* Print the coefficients of a, with d decimal precision.
 */

static char *form = "abcdefghijk";

void polprt( a, na, d )
fract a[];
int na, d;
{
int i, j, d1;
char *p;

/* Create format descriptor string for the printout.
 * Do this partly by hand, since sprintf() may be too
 * bug-ridden to accomplish this feat by itself.
 */

p = form;
*p++ = '%';
d1 = d + 8;
sprintf( p, "%d ", d1 );
p += 1;
if( d1 >= 10 )
 p += 1;
*p++ = '.';
sprintf( p, "%d ", d );
p += 1;
if( d >= 10 )
 p += 1;
*p++ = 'e';
*p++ = ' ';
*p++ = '\0';


/* Now do the printing.
 */

d1 += 1;
j = 0;
for( i=0; i<=na; i++ )
 {
/* Detect end of available line */
 j += d1;
 if( j >= 78 )
  {
  printf( "\n" );
  j = d1;
  }
 printf( form, a[i].n );
 j += d1;
 if( j >= 78 )
  {
  printf( "\n" );
  j = d1;
  }
 printf( form, a[i].d );
 }
printf( "\n" );
}



/* Set a = 0.
 */

void polclr( a, n )
fract a[];
int n;
{
int i;

if( n > MAXPOL )
 n = MAXPOL;
for( i=0; i<=n; i++ )
 {
 a[i].n = 0.0;
 a[i].d = 1.0;
 }
}



/* Set b = a.
 */

void polmov( a, na, b )
fract a[], b[];
int na;
{
int i;

if( na > MAXPOL )
 na = MAXPOL;

for( i=0; i<= na; i++ )
 {
 b[i].n = a[i].n;
 b[i].d = a[i].d;
 }
}


/* c = b * a.
 */

void polmul( a, na, b, nb, c )
fract a[], b[], c[];
int na, nb;
{
int i, j, k, nc;
fract temp;
fract *p;

nc = na + nb;
polclr( pt3, MAXPOL );

p = &a[0];
for( i=0; i<=na; i++ )
 {
 for( j=0; j<=nb; j++ )
  {
  k = i + j;
  if( k > MAXPOL )
   break;
  rmul( p, &b[j], &temp ); /*pt3[k] += a[i] * b[j];*/
  radd( &temp, &pt3[k], &pt3[k] );
  }
 ++p;
 }

if( nc > MAXPOL )
 nc = MAXPOL;
for( i=0; i<=nc; i++ )
 {
 c[i].n = pt3[i].n;
 c[i].d = pt3[i].d;
 }
}



 
/* c = b + a.
 */

void poladd( a, na, b, nb, c )
fract a[], b[], c[];
int na, nb;
{
int i, n;


if( na > nb )
 n = na;
else
 n = nb;

if( n > MAXPOL )
 n = MAXPOL;

for( i=0; i<=n; i++ )
 {
 if( i > na )
  {
  c[i].n = b[i].n;
  c[i].d = b[i].d;
  }
 else if( i > nb )
  {
  c[i].n = a[i].n;
  c[i].d = a[i].d;
  }
 else
  {
  radd( &a[i], &b[i], &c[i] ); /*c[i] = b[i] + a[i];*/
  }
 }
}

/* c = b - a.
 */

void polsub( a, na, b, nb, c )
fract a[], b[], c[];
int na, nb;
{
int i, n;


if( na > nb )
 n = na;
else
 n = nb;

if( n > MAXPOL )
 n = MAXPOL;

for( i=0; i<=n; i++ )
 {
 if( i > na )
  {
  c[i].n = b[i].n;
  c[i].d = b[i].d;
  }
 else if( i > nb )
  {
  c[i].n = -a[i].n;
  c[i].d = a[i].d;
  }
 else
  {
  rsub( &a[i], &b[i], &c[i] ); /*c[i] = b[i] - a[i];*/
  }
 }
}



/* c = b/a
 */

int poldiv( a, na, b, nb, c )
fract a[], b[], c[];
int na, nb;
{
fract *ta, *tb, *tq;
fract quot;
fract temp;
int i, j, k, sing;

sing = 0;

/* Allocate temporary arrays.  This would be quicker
 * if done automatically on the stack, but stack space
 * may be hard to obtain on a small computer.
 */

ta = (fract * )malloc( psize );
polclr( ta, MAXPOL );
polmov( a, na, ta );

tb = (fract * )malloc( psize );
polclr( tb, MAXPOL );
polmov( b, nb, tb );

tq = (fract * )malloc( psize );
polclr( tq, MAXPOL );

/* What to do if leading (constant) coefficient
 * of denominator is zero.
 */

if( a[0].n == 0.0 )
 {
 for( i=0; i<=na; i++ )
  {
  if( ta[i].n != 0.0 )
   goto nzero;
  }
 mtherr( "poldiv", SING );
 goto done;

nzero:
/* Reduce the degree of the denominator. */
 for( i=0; i<na; i++ )
  {
  ta[i].n = ta[i+1].n;
  ta[i].d = ta[i+1].d;
  }
 ta[na].n = 0.0;
 ta[na].d = 1.0;

 if( b[0].n != 0.0 )
  {
/* Optional message:
  printf( "poldiv singularity, divide quotient by x\n" );
*/

  sing += 1;
  }
 else
  {
/* Reduce degree of numerator. */
  for( i=0; i<nb; i++ )
   {
   tb[i].n = tb[i+1].n;
   tb[i].d = tb[i+1].d;
   }
  tb[nb].n = 0.0;
  tb[nb].d = 1.0;
  }
/* Call self, using reduced polynomials. */
 sing += poldiv( ta, na, tb, nb, c );
 goto done;
 }

/* Long division algorithm.  ta[0] is nonzero.
 */

for( i=0; i<=MAXPOL; i++ )
 {
 rdiv( &ta[0], &tb[i], " ); /*quot = tb[i]/ta[0];*/
 for( j=0; j<=MAXPOL; j++ )
  {
  k = j + i;
  if( k > MAXPOL )
   break;

  rmul( &ta[j], ", &temp ); /*tb[k] -= quot * ta[j];*/
  rsub( &temp, &tb[k], &tb[k] );
  }
 tq[i].n = quot.n;
 tq[i].d = quot.d;
 }
/* Send quotient to output array. */
polmov( tq, MAXPOL, c );

done:

/* Restore allocated memory. */
free(tq);
free(tb);
free(ta);
return( sing );
}




/* Change of variables
 * Substitute a(y) for the variable x in b(x).
 * x = a(y)
 * c(x) = b(x) = b(a(y)).
 */


void polsbt( a, na, b, nb, c )
fract a[], b[], c[];
int na, nb;
{
int i, j, k, n2;
fract temp;
fract *p;

/* 0th degree term:
 */

polclr( pt1, MAXPOL );
pt1[0].n = b[0].n;
pt1[0].d = b[0].d;

polclr( pt2, MAXPOL );
pt2[0].n = 1.0;
pt2[0].d = 1.0;
n2 = 0;
p = &b[1];

for( i=1; i<=nb; i++ )
 {
/* Form ith power of a. */
 polmul( a, na, pt2, n2, pt2 );
 n2 += na;
/* Add the ith coefficient of b times the ith power of a. */
 for( j=0; j<=n2; j++ )
  {
  if( j > MAXPOL )
   break;
  rmul( &pt2[j], p, &temp ); /*pt1[j] += b[i] * pt2[j];*/
  radd( &temp, &pt1[j], &pt1[j] );
  }
 ++p;
 }

k = n2 + nb;
if( k > MAXPOL )
 k = MAXPOL;
for( i=0; i<=k; i++ )
 {
 c[i].n = pt1[i].n;
 c[i].d = pt1[i].d;
 }
}




/* Evaluate polynomial a(t) at t = x.
 */

void poleva( a, na, x, s )
fract a[];
int na;
fract *x;
fract *s;
{
int i;
fract temp;

s->n = a[na].n;
s->d = a[na].d;
for( i=na-1; i>=0; i-- )
 {
 rmul( s, x, &temp ); /*s = s * x + a[i];*/
 radd( &a[i], &temp, s );
 }
}


Messung V0.5 in Prozent
C=93 H=69 G=81

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet am  2026-06-15) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik