/*
   Обращение матриц методом окаймления
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <dos.h>
#include <float.h>
#include <conio.h>
#define rnd ((rand()/32767.0)*2-1)
typedef float * FU ;
void prrivet(FU,FU,int,int);
void pechat(FU, int, int, char *);
void handinit(FU, int);
void result(FU, FU, FU, FU, float, int);
void umn(FU, FU, FU, int, int, int);
void umnn(FU, float, int, int);
void sub(FU, FU, FU, int);
void inition(FU, int, int);
void prisv(FU, FU, int, int);
void Test(FU a,int m,int n);
void EdInit(FU a,int m,int n);
float Sled(FU a,int m,int n);
FU memory(int, int);


void main(void)
{
  int t,n,w,i,j,g,v1,v2,dv;char q; long *v;
  float prom1,prom2;
  FU Ann[10],Bnn[10],Enn[10],Pnn[10];

/*  cleardevise();   */
do {  clrscr();
//  printf("\n\t\t Обращение матриц методом [окаймления/разб.клетки]\n");
//  printf("\n\t Введите размер матрицы : ");
//  scanf("%d",&n);
   Ann[9]=memory(4,4);clrscr();
/*Инициализация и печать Аnn*/
//  inition(Ann,n,n);
   Test(Ann[9],4,4);
   pechat(Ann[9],4,4,"Исходная :");
   printf("\n Sled Ann: %f",Sled(Ann[9],4,4));


    Pnn[0]=memory(1,4);

    Enn[0]=memory(4,4);
    EdInit(Enn[0],4,4);

    Ann[0]=memory(4,4);

    Bnn[0]=memory(4,4);

     prisv(Ann[9],Ann[0],4,4);
//     pechat(Ann[0],4,4,"Ann :");

   for(i=0;i<4;i++)
  {
   if(i) {umn(Ann[9],Bnn[0],Ann[0],4,4,4);}
   pechat(Ann[0],4,4,"Ann0 :");getch();
   prom1=Sled(Ann[0],4,4);
   //printf("\t Sled %d = %f",i,prom1);
   *(Pnn[0]+i)=prom1/(i+1);
    printf("\t Sled %d = %f, Pnn %d=%f ",i,prom1,i,*(Pnn[0]+i));
//   pechat(Pnn[0],1,4,"Pnn :");
//   pechat(Enn[0],4,4,"Enn :");getch();

   umnn(Enn[0],*(Pnn[0]+i),4,4);
//    pechat(Enn[0],4,4,"Enn0xA :");getch();
   sub(Ann[0],Enn[0],Bnn[0],4);

   pechat(Bnn[0],4,4,"Bnn0 :");

   EdInit(Enn[0],4,4);
  }
 pechat(Pnn[0],4,1,"Pnn :");


 free(Ann[9]);
 free(Pnn);
 free(Ann[0]);
 free(Bnn[0]);
 free(Enn[0]);


   printf("\n Снова ? :Y/N  ");
   scanf("%s",&q);
   } while( q!='n');
}
/*--Умножение матриц--*/
void umn(FU a,FU b,FU c,int n,int m,int q)
{
  int i,j,k;
  float s;

  for(i=0;i<n;i++)
    for(j=0;j<q;j++)
      {
	for(s=k=0;k<m;k++)
	  s+=*(a+i*m+k)**(b+k*q+j);
	*(c+i*q+j)=s;
      }
 }
/*--Умножение матрицы на число--*/
void umnn(FU a,float l,int m,int n)
{
  int i;

  for(i=0;i<m*n;i++)
    {
      *(a+i)*=l;
    }
}
/*--Вычитание матриц--*/
void sub(FU a,FU b,FU c,int n)
{
  int i,j;

  for(i=0;i<n;i++)
    for(j=0;j<n;j++)
      *(c+i*n+j)=*(a+i*n+j)-*(b+i*n+j);
}
/*Составляем обращенную матрицу OA11 из клеток B11,B12,B21,B22*/
void result(FU B11,FU B12,FU B21,FU RR,float B22,int n)
{
  int i,j,n1;

  n1=n-1;
  for(i=0;i<n1;i++)
    {
      for(j=0;j<n1;j++)
	*(RR+i*n+j)=*(B11+i*n1+j);
      *(RR+i*n+n1)=*(B12+i);
    }
  for(i=n*n1,j=0;j<n1;j++)
    *(RR+i+j)=*(B21+j);
  *(RR+(n*n)-1)=B22;
}
/*--Печать матрицы и текста--*/
void pechat(FU a,int m,int n,char *str)
{
  int i,j;

  puts(str);
  for(i=0;i<m;i++)
    {
      for(j=0;j<n;j++)
	printf("%6.3f ",*(a+i*n+j));
      printf("\n");
    }
}
/*--Выделение памяти--*/
FU memory(int m,int n)
{
  FU mas;

  mas=(FU)malloc(m*n*sizeof(float));
  return(mas);
}
/*--Инициализация матрицы--*/
void inition(FU a,int m,int n)
{
  int j;

  for(j=0;j<m*n;j++)
    *(a+j)=rnd;
}

void Test(FU a,int m,int n)
{
  int j,i;

      *(a)=2;  *(a+1)=-1;  *(a+2)=1;  *(a+3)=2;
    *(a+4)=0;   *(a+5)=1;  *(a+6)=1;  *(a+7)=0;
   *(a+8)=-1;   *(a+9)=1; *(a+10)=1; *(a+11)=1;
   *(a+12)=1;  *(a+13)=1; *(a+14)=1; *(a+15)=0;
}

float Sled(FU a,int m,int n)
{
  int i,j;float sl=0;

  for(i=0;i<m;i++)
    {
      for(j=0;j<n;j++)
      if(i==j) sl+=*(a+i*n+j);
    }
    return (sl);
}

void EdInit(FU a,int m,int n)
{
  int i,j;

  for(i=0;i<m;i++)
    {
      for(j=0;j<n;j++)
      if(i==j) *(a+i*n+j)=1;
      else *(a+i*n+j)=0;

    }
}






/*--Присвоение матрице B значения матрицы A--*/
void prisv(FU a,FU b,int m,int n)
{
  int i;

  for(i=0;i<m*n;i++)
    *(b+i)=*(a+i);
}
/*--Ручной ввод--*/
void handinit(FU a,int n)
{
  int x,y,i,j;
  float p;

  for(i=0,y=3,x=3,j=1;i<n*n;i++,j++)
    {
      x+=8;
      gotoxy(x,y); scanf("%f",&p);
      *(a+i)=p;
      if(j==n) { j=0; x=3; y+=2; }
    }
}
void prrivet(FU a,FU b,int n,int t)
{
  int i,j;
  for(i=0;i<t;i++)
    {
      for(j=0;j<t;j++)
	*(a+i*t+j)=*(b+i*n+j);
    }
}


/* Конец */
