2nd_Sem_Bogachev/2025.04.04/dist/Kochubei/add.c
2025-04-02 12:47:26 +03:00

267 lines
5.4 KiB
C

#include <stdio.h>
#include <math.h>
#include "add.h"
#define eps 1e-16
// Âû÷èñëåíèå ìèíèìóìà, ìàêñèìóìà è ìîäóëÿ îò ÖÅËÎÃÎ ÷èñëà
// ÂÀÆÍÎ: Íå ïóòàòü ñ fmax è ò.ä, à òî ñíîâà âñ¸ ÄÇ óëåòèò â FPE...
int max(int a, int b)
{
if (a>=b) return a;
else return b;
}
int min(int a, int b)
{
if (a<=b) return a;
else return b;
}
int abs(int a)
{
if (a>=0) return 0;
else return -a;
}
// Âû÷èñëåíèå ýëåìåíòà ìàòðèöû
// k - íîìåð ôîðìóëû, n, m - ðàçìåðû ìàòðèöû, i, j - èíäåêñû ýëåìåíòà
// Çíà÷åíèÿ k=5 è k=6 íå îïèñàíû â óñëîâèÿõ è íóæíû èñêëþ÷èòåëüíî äëÿ áîëüøåãî êîëè÷åñòâà òåñòîâ
double f(int k, int n, int m, int i, int j)
{
i=i+1;
j=j+1;
if (k==1)
{
return max(n,m)-max(i,j)+1;
}
else if (k==2)
{
return max(i,j);
}
else if (k==3)
{
return abs(i-j);
}
// Ìàòðèöà Ãèëüáåðòà
else if (k==4)
{
return 1.0/(i+j-1);
}
// Ýêñïåðèìåíòû ñ äðóãèìè ìàòðèöàìè
// Ìàòðèöà Ëåìåðà
else if (k==5)
{
return (min(i,j))*1.0/max(i,j);
}
// Ìàòðèöà Ðåäõåôôåðà
else if (k==6)
{
if (j==1 || j%i==0) return 1;
else return 0;
}
else return 0;
}
// ×òåíèå ìàòðèöû
// A - ìàññèâ âûäåëåííûé ïîä ìàòðèöó, n, m - ðàçìåðû ìàòðèöû, name - èìÿ ôàéëà
io_status read_matrix(restrict mat A, int n, int m, char* name)
{
FILE* f=fopen(name, "rt");
if (!f) return ERROR_OPEN;
for (int i=0; i<n*m; i++)
{
if (fscanf(f, "%lf", &A[i])!=1)
{
fclose(f);
return ERROR_READ;
}
}
fclose(f);
return SUCCESS;
}
// Âûâîä ìàòðèöû
// A - ìàòðèöà, n, m - ðàçìåðû ìàòðèöû, p - ìàêñèìàëüíîå êîëè÷åñòâî ñòðîê è ñòîëáöîâ äëÿ âûâîäà
void print_matrix(restrict mat A, int n, int m, int p)
{
for (int i=0; i<n && i<p; i++)
{
for (int j=0; j<m && j<p; j++)
{
printf("%10.3e ", A[i*m+j]);
}
printf("\n");
}
}
// Èíèöèàëèçàöèÿ ìàòðèöû
// A - ìàòðèöà, n, m - ðàçìåðû ìàòðèöû, k - íîìåð ôîðìóëû
// Ïðè íóëåâîì k èç main äîëæíà âûçûâàòüñÿ ôóíêöèÿ read_matrix()
void init_matrix(restrict mat A, int n, int m, int k)
{
for (int i=0; i<n; i++)
{
for (int j=0; j<m; j++)
{
A[i*m+j]=f(k, n, m, i, j);
}
}
}
// Èíèöèàëèçàöèÿ âåêòîðà
// A - çàïîëíåííàÿ ìàòðèöà ðàçìåðà n*n, V - âåêòîð, n - äëèíà âåêòîðà
void init_vector(restrict mat A, restrict mat V, int n)
{
for (int i=0; i<n; i++)
{
double sum=0;
for (int k=0; k<=(n-1)/2; k++)
{
sum=sum+A[i*n+2*k];
}
V[i]=sum;
}
}
// Íîðìà âåêòîðà
// V - âåêòîð, n - äëèíà âåêòîðà
// Âû÷èñëÿåò íîðìó êàê ñóììó ìîäóëåé êîìïîíåíò âåêòîðà
double vector_norm(restrict mat V, int n)
{
double sum=0;
for (int i=0; i<n; i++)
{
sum=sum+fabs(V[i]);
}
return sum;
}
// Âû÷èñëåíèå íåâÿçêè (r1)
// A - ìàòðèöà, X - âåêòîð ÷èñëåííî íàéäåííîãî ðåøåíèÿ, B - ñâîáîäíûé ñòîëáåö, n - ðàçìåð ìàòðèöû è äëèíà âåêòîðà
// ÂÀÆÍÎ: ïîñëå âûçîâà ïîðòèò âåêòîð B
double R1(restrict mat A, restrict mat X, restrict mat B, int n)
{
double norm1=0;
double norm2=0;
norm2=vector_norm(B, n);
if (0<=norm2 && norm2<=0) return 1e300;
for (int i=0; i<n; i++)
{
double sum=0;
for (int j=0; j<n; j++)
{
sum=sum+A[i*n+j]*X[j];
}
B[i]=sum-B[i];
}
norm1=vector_norm(B,n);
return norm1/norm2;
}
// Âû÷èñëåíèå r2
// X - âåêòîð, n - åãî äëèíà
double R2(restrict mat X, int n)
{
double sum1=0;
double sum2=0;
if (n<=0) return 0;
for (int i=1; i<=n; i++)
{
sum1=sum1+fabs(X[i-1]-(i&1));
}
for (int i=1; i<=n; i++)
{
sum2=sum2+(i&1);
}
return sum1/sum2;
}
// Ïðîâåðêà íà ðàâåíñòâî ýëåìåíòà ìàòðèöû íóëþ, îòíîñèòåëüíî åå íîðìû
// x - ýëåìåíò ìàòðèöû, norm - íîðìà ìàòðèöû
int equals_zero(double x, double norm)
{
if (fabs(x)<eps*norm) return 1;
else return 0;
}
// Íîðìà ìàòðèöû A_inf
// A - êâàäðàòíàÿ ìàòðèöà, n - åå ðàçìåð
double matrix_norm(restrict mat A, int n)
{
double norm=0;
for (int i=0; i<n; i++)
{
double sum=0;
for (int j=0; j<n; j++)
{
sum=sum+fabs(A[i*n+j]);
}
if (sum>norm) norm=sum;
}
return norm;
}
// Ýëåìåíòàðíîå ïðåîáðàçîâàíèå äëÿ ìåòîäà Ãàóññà
// A - êâàäðàòíàÿ ìàòðèöà, n - åå ðàçìåð, k - íîìåð ñòðîêè
// ÂÀÆÍÎ: ïðåäïîëàãàåòñÿ, ÷òî ýëåìåíò A[k*n+k] óæå âûáðàí íåíóëåâûì
// ÂÀÆÍÎ: ïðåäïîëàãàåòñÿ, ÷òî ýëåìåíòû, ñòîÿùèå ëåâåå A[k*n+k], óæå ÿâëÿþòñÿ íóëåâûìè
void divide_row(restrict mat A, int n, int k)
{
double el=A[k*n+k];
for (int i=k+1; i<n; i++)
{
A[k*n+i]=A[k*n+i]/el;
}
A[k*n+k]=1;
}
int find_max(restrict mat A, int n, int k)
{
int res=k;
double mx=fabs(A[k*n+k]);
for (int i=k+1; i<n; i++)
{
double tmp=fabs(A[k*n+i]);
if (tmp>mx)
{
res=i;
mx=tmp;
}
}
return res;
}
void subtract_row(restrict mat A, int n, int a, int b)
{
double el=A[a*n+b];
for (int i=b+1; i<n; i++)
{
A[a*n+i]=A[a*n+i]-A[b*n+i]*el;
}
A[a*n+b]=0;
}
void swap(double* a, double* b)
{
double tmp=*a;
*a=*b;
*b=tmp;
}
void swap_int(int* a, int* b)
{
int tmp=*a;
*a=*b;
*b=tmp;
}
void swap_columns(restrict mat A, int n, int a, int b)
{
for (int i=0; i<n; i++)
{
swap(A+i*n+a, A+i*n+b);
}
}