⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i6i.c

📁 calc大数库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* i6I.c */
/* matrix operations using MPI's */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "integer.h"
#include "fun.h"

extern unsigned int HAVASFLAG;
extern unsigned int FPRINTMATIFLAG;
extern unsigned int MLLLVERBOSE;

MPMATI *BUILDMATI(unsigned int m, unsigned int n)
/*
 * Allocates space for an m x n matrix of MPI's.
 */
{
	MPMATI *N;
	unsigned int i;

	N=(MPMATI *)mmalloc(sizeof(MPMATI));
	N->R = m;
	N->C = n;
	N->V = (MPI ***)mmalloc(m * sizeof(MPI **));
	for (i = 0; i < m; i++)
		N->V[i] = (MPI **)mmalloc(n * sizeof(MPI *));
	return (N);
}

MPMATI *COPYMATI(MPMATI *Mptr)
/*
 * a replacement for the assignment *Nptr = *Mptr.
 */
{
	unsigned int i, j, m, n;
	MPMATI *Nptr;

	m = Mptr->R;
	n = Mptr->C;
	Nptr = BUILDMATI(Mptr->R, Mptr->C);
	for (i = 0; i < m; i++)
		for (j = 0; j < n; j++)
			Nptr->V[i][j] = COPYI(Mptr->V[i][j]);
	return (Nptr);
}

void FREEMATI(MPMATI *Mptr)
/*
 * frees the storage allocated to the two-dimensional array Mptr->V.
 */
{
	unsigned int i, j, m, n;

	if (Mptr == NULL)
		return;
	m = Mptr->R;
	n = Mptr->C;
	for (i = 0; i < m; i++)
	{
		for (j = 0; j < n; j++)
			FREEMPI(Mptr->V[i][j]);
		ffree((char *)(Mptr->V[i]), n * sizeof(MPI *));
	}
	ffree((char *)(Mptr->V), m * sizeof(MPI **));
	ffree((char *)Mptr, sizeof(MPMATI));
	return;
}

MPMATI *FINPUTMATI(FILE *infile)
/*
 * Inputs a matrix of MPI's from infile.
 */
{
	MPMATI *Temp;
	unsigned int u, i, j, m, n;
	char *line, *p;

	if (infile == stdin)
	{
		if (HAVASFLAG)
			printf("Enter the number of integers\n");
		else
			printf("Enter the number of rows and number of columns\n");
	}

if (HAVASFLAG)
{
	if (fscanf(infile, "%u", &m) != 1 || m == 0)
	{
		fprintf(stderr, "corrupt input: returning the 1 x 1 zero matrix\n");
		if (infile != stdin)
			exit (1);
		return ZEROMNI(1, 1);
	}
/*
	if (infile != stdin)
	{
		if (fscanf(infile, "%u", &n) != 1 || n == 0)
		{
			fprintf(stderr, "corrupt input: returning the 1 x 1 zero matrix\n");
			if (infile != stdin)
				exit (1);
			return ZEROMNI(1, 1);
		}
	}
	if (infile == stdin)
*/
		n = 1;
}
else
{
	if (fscanf(infile, "%u%u", &m, &n) != 2 || m == 0 || n == 0)
	{
		fprintf(stderr, "corrupt input: returning the 1 x 1 zero matrix\n");
		if (infile != stdin)
			exit (1);
		return ZEROMNI(1, 1);
	}
}
	fgetc(infile);
	Temp = ZEROMNI(m, n);
	for (i = 0; i < m; i++)
	{
		if (infile == stdin)
			printf("Enter row %u:\n", i + 1);
		p = line = Fgets(infile);
		for (j = 0; j < n; j++)
		{
			FREEMPI(Temp->V[i][j]);
			Temp->V[i][j] = INPUTSI(&p, &u);
			if (u == 0)
			{
				free(line);
				fprintf(stderr, "matrix input interrupted prematurely\n");
				if (infile != stdin)
					exit (1);
				GetReturn();
				return Temp;
			}
		}
		free(line);
	}
	return (Temp);
}

MPMATI *INPUTMATI()
/*
 * Input a matrix of MPI's from stdin.
 */
{
	return FINPUTMATI(stdin);
}

void FPRINTMATI(FILE *outfile, USI i1, USI i2, USI j1, USI j2, MPMATI *Mptr)
/*
 * Modified 8/1/93 using Peter Adams' improvement from, August 1992.
 */
{
	char **str, *buff;
	unsigned int tmp, i, j, nrow, ncol, len, nstr = 0;
	int *colwidth;
	unsigned int ct;
	
	nrow = i2 - i1 + 1;
	ncol = j2 - j1 + 1;
	str = (char **)mmalloc(nrow * ncol * sizeof(char *));
	colwidth=(int *)mmalloc(ncol*sizeof(int));

	for(i=0; i<ncol; i++)
	  colwidth[i]=0;
	for (i = i1; i <= i2; i++)
	{
		for (j = j1; j <= j2; j++)
		{
			tmp = 1 + LENGTHI(Mptr->V[i][j]);
			buff = (char *)mmalloc(tmp * sizeof(char));
			SPRINTI(buff, Mptr->V[i][j]);
		    	if ((len = strlen(buff)) > colwidth[j-j1])
				colwidth[j-j1] = len;
			str[nstr++] = strcpy((char *)mmalloc(len + 1), buff);
			ffree(buff, tmp * sizeof(char));
		}
	}
	if (!FPRINTMATIFLAG)
	{
		if (outfile != stdout)
			fprintf(outfile, "%u %u\n", nrow, ncol);
	}
	ct=0;
	for (i = i1; i <= i2; i++)
	{
		for (j = j1; j <= j2; j++)
		{
	    		fprintf(outfile, "%*s ", colwidth[j-j1], str[ct]);
	    		ffree(str[ct], (unsigned int) (strlen(str[ct]) + 1) * sizeof(char));
	    		if ((ct % ncol) == (ncol - 1))
				fprintf(outfile, "\n");
	    		ct++;
		}
	}
	ffree((char *) str, nrow * ncol * sizeof(char *));
	ffree((char *) colwidth, ncol*sizeof(int));
	return;
}

void PRINTMATI(USI i1, USI i2, USI j1, USI j2, MPMATI *Mptr)
/*
 * prints *Mptr from rows i1 to i2 and cols j1 to j2.
 */
{
	unsigned int i, j;

	if(!Mptr) return;
	i = i2 - i1 + 1;
	j = j2 - j1 + 1;
	if (MAX((int)i, (int)j) > 50)
	{
		printf("(The number of rows or columns to be printed exceeds 50;\n");
		printf("there is no point in printing this matrix on the screen.)\n");
		return;
	}
	FPRINTMATI(stdout, i1, i2, j1, j2, Mptr);
	return;
}

MPMATI *FINPUTMATFILEI_I()
{
	char filename[50];
	MPMATI *Mptr;
	FILE *infile;

	printf("enter the name of your matrix file:");
	fgets(filename,50,stdin);
	printf("filename : %s\n", filename);
	infile = fopen(filename, "r");
	if (infile == NULL)
		execerror("does not exist or cannot be opened", "filename");
	Mptr = FINPUTMATI(infile);
	fclose(infile);
	printf("matrices from file %s successfully inputted\n", filename);
	GetReturn();
	return (Mptr);
}


MPMATI *ZEROMNI(USI m, USI n)
/*
 * returns the zero  m x n matrix.
 */
{
	unsigned int i, j;
	MPMATI *Mptr;

	Mptr = BUILDMATI(m, n);
	for (i = 0; i <= m - 1; i++)
	{
		for (j = 0; j <= n - 1; j++)
			Mptr->V[i][j] = ZEROI();
	}
	return (Mptr);
}

MPMATI *SWAP_ROWSI(USI p, USI q, MPMATI *Mptr)
/*
 * interchange rows p and q (C notation) of *Mptr.
 */
{
	MPI **temp;
	MPMATI *Nptr;

	Nptr = COPYMATI(Mptr);
	temp = Nptr->V[p];
	Nptr->V[p] = Nptr->V[q];
	Nptr->V[q] = temp;
	return (Nptr);
}

MPMATI *SWAP_COLSI(USI p, USI q, MPMATI *Mptr)
/*
 * interchange cols p and q (C notation) of *Mptr.
 */
{
	unsigned int i;
	MPI *Temp;
	MPMATI *Nptr;

	Nptr = COPYMATI(Mptr);
	for (i = 0; i <= Nptr->R - 1; i++)
	{
		Temp = Nptr->V[i][p];
		Nptr->V[i][p] = Nptr->V[i][q];
		Nptr->V[i][q] = Temp;
	}
	return (Nptr);
}

MPMATI *SWAP_ROWSI1(USI p, USI q, MPMATI *Mptr)
/*
 * Updates Mptr by interchange rows p and q (C notation) of *Mptr.
 */
{
	MPI **temp;

	temp = Mptr->V[p];
	Mptr->V[p] = Mptr->V[q];
	Mptr->V[q] = temp;
	return (Mptr);
}

MPMATI *SWAP_COLSI1(USI p, USI q, MPMATI *Mptr)
/*
 * Updates Mptr by interchanging cols p and q (C notation) of *Mptr.
 */
{
	unsigned int i;
	MPI *Temp;

	for (i = 0; i <= Mptr->R - 1; i++)
	{
		Temp = Mptr->V[i][p];
		Mptr->V[i][p] = Mptr->V[i][q];
		Mptr->V[i][q] = Temp;
	}
	return (Mptr);
}

unsigned int *KB_ROW(MPMATI *Aptr, USI *nz)
/*
 * The Kannan-Bachem reduction to column permuted Hermite normal form, for
 * use in their Smith Normal form algorithm.
 */
{
	unsigned int *T, i, j, k, s, m, n, tmp, is_zero;
	MPI *D, *P, *Q, *R, *S, *Tmp0, *Tmp1, *Tmp2 , *Tmp3;

	m = Aptr->R;
	n = Aptr->C;
	T = (unsigned int *)mmalloc(n * sizeof(unsigned int));
	for (i = 0; i < n; i++)
		T[i] = i;
	s = m - 1;
	/* s = index of last row of A not known to be zero. */
	i = 0;
	while (i <= s)
	{
	/*	printf("i = %u\n", i);*/
		for (k = 0; k < i; k++)
		{
			D = EUCLIDI(Aptr->V[k][T[k]], Aptr->V[i][T[k]], &P, &Q);
			Tmp0 = INT(Aptr->V[i][T[k]], D);
			R = MINUSI(Tmp0);
			FREEMPI(Tmp0);
			S = INT(Aptr->V[k][T[k]], D);
			FREEMPI(D);
			for (j = 0; j < n; j++)
			{
				Tmp0 = Aptr->V[k][j];
				Tmp1 = MULTI(P, Aptr->V[k][j]);
				Tmp2 = MULTI(Q, Aptr->V[i][j]);
				Aptr->V[k][j] = ADDI(Tmp1, Tmp2);
				FREEMPI(Tmp1);
				FREEMPI(Tmp2);
				Tmp3 = Aptr->V[i][j];
				Tmp1 = MULTI(R, Tmp0);
				FREEMPI(Tmp0);
				Tmp2 = MULTI(S, Aptr->V[i][j]);
				Aptr->V[i][j] = ADDI(Tmp1, Tmp2);
				FREEMPI(Tmp3);
				FREEMPI(Tmp1);
				FREEMPI(Tmp2);
			}
			FREEMPI(P);
			FREEMPI(Q);
			FREEMPI(R);
			FREEMPI(S);
			RODI(Aptr, T, k);
		}
		is_zero = 1;
		for (j = 0; j < n; j++)
		{
			if ((Aptr->V[i][j])->S)
			{
				is_zero = 0;
				break;
			}
		}
		if (is_zero)
		{
			if (i < s)
				SWAP_ROWSI1(i, s, Aptr);
			s--;
		}
		else
		{
			for (j = 0; j < n; j++)
			{
				if ((Aptr->V[i][T[j]])->S)
					break;
			}
			if (j != i)
			{
				tmp = T[j];
				T[j] = T[i];
				T[i] = tmp;
			}
			RODI(Aptr, T, i);
			i++;
		}
	}
	*nz = s+1;
	return (T);
}
 
 
void RODI(MPMATI *Aptr, USI *T, USI j)
/* Kannan_Bachem subroutine: input an integer j, 0 <= j < Aptr->R such that
 * elt(Aptr, j, T[j]) != 0 and elt(Aptr, j, T[k]) = 0 for 0 <= k < j.
 * entries elt(Aptr, i, T[j]), 0 <= i < j, are reduced mod elt(Aptr, j, T[j]).
 */
{
	unsigned int i, k, n;
	MPI *Q;

	n = Aptr->C;
	if ((Aptr->V[j][T[j]])->S == -1)
	{
		for(k = 0; k < n; k++)
		{
			if ((Aptr->V[j][k])->S != 0)
				(Aptr->V[j][k])->S = -((Aptr->V[j][k])->S);
		}
	}	
	for (i = 0; i < j; i++)
	{
		Q = INTI(Aptr->V[i][T[j]], Aptr->V[j][T[j]]);
		Aptr = ROWSUBI(j, i, Q, Aptr); 
		FREEMPI(Q);
	}
}

void SORTI(USI *T, USI nz)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -