#include "matrici.h"
//costruttore
matrice::matrice(){
r = 0;
c = 0;
}
matrice::matrice(const matrice& o) { //copy constructor
create(o.r,o.c);
for(int x=0;x<r;x++)
for(int y=0;y<c;y++)
m[x][y] = o.m[x][y];
}
//distruttore
matrice::~matrice(){
int x;
if(r > 0){
for(x=0;x<r;x++)
delete[] m[x];
delete[] m;
}
}
//creazione matrice
void matrice::create(int r, int c){ // r = righe, c = colonne
int x,y;
this->r = r;
this->c = c;
m = new double *[r];
for(x=0;x<r;x++)
m[x] = new double[c];
}
void matrice::create_with_value(int r, int c, double value){
int x,y;
this->r = r;
this->c = c;
m = new double *[r];
for(x=0;x<r;x++)
m[x] = new double[c];
for(x=0;x<r;x++)
for(y=0;y<c;y++)
m[x][y] = value;
}
//visualizza matrice
void matrice::print(){
int x,y;
for(x=0;x<r;x++){
for(y=0;y<c;y++)
printf("%12.6f\x20",m[x][y]);
printf("\n");
}
printf("\n");
}
//info matrice
int matrice::rows(){
return r;
}
int matrice::columns(){
return c;
}
double matrice::get_value(int r0, int c0){
if(r0 >= r || c0 >= c)
exit(0);
return m[r0][c0];
}
void matrice::set_value(int r0, int c0, double value){
if(r0 >= r || c0 >= c)
exit(0);
m[r0][c0] = value;
}
double *matrice::operator[](int i){
return m[i];
}
//caricamento - salvataggio matrici
void matrice::load_from_file(char * file){
FILE *stream;
char *buffer, *number;
long filesize, readed;
long x, y=0, mr=0, mc=0, r=0, c=0;
stream = fopen(file,"rb");
fseek(stream,0,SEEK_END);
filesize = ftell(stream);
rewind(stream);
buffer = new char[filesize];
number = new char[100];
readed = fread(buffer,1,filesize,stream);
fclose(stream);
for(x=0; x<filesize ;x++){ //conta colonne
if(buffer[x] == '\x09')
mc++;
if(buffer[x] == '\x0D'){
mc++;
break;
}
}
for(x=0; x<filesize ;x++){ //conta righe
if(buffer[x] == '\x0D')
mr++;
}
create(mr, mc);
for(x=0; x<filesize ;x++){
if(buffer[x] == '\x0A')
continue;
if(buffer[x] == '\x09' || buffer[x] == '\x0D'){
number[y] = '\x00';
this->m[r][c] = atof(number);
y=0;
c++;
if(buffer[x] == '\x0D'){
r++;
c=0;
}
}
else{
number[y] = buffer[x];
y++;
}
}
delete [] buffer;
delete [] number;
}
void matrice::save_in_file(char * file){
int x,y;
FILE * stream;
stream = fopen(file, "w+");
for(x=0;x<r;x++){
for(y=0;y<c;y++){
fprintf(stream,"%.6f",m[x][y]);
if(y<c-1) fprintf(stream,"\x09");
}
fprintf(stream,"\n");
}
fclose(stream);
}
//assignment operator
matrice matrice::operator=(const matrice o) {
int x,y;
if (this == &o) { //per non copiare se stessi :)
return *this;
}
//cancelliamo le cose che ci sono adesso
if(r > 0){
for(x=0;x<r;x++)
delete[] m[x];
delete[] m;
}
//creiamo la nuova matrice e ci copiamo dentro i dati
create(o.r,o.c);
for(int x=0;x<r;x++)
for(int y=0;y<c;y++)
m[x][y] = o.m[x][y];
return *this;
}
//operazioni matrici con matrici
matrice operator+(matrice a,matrice b){
matrice c;
int x,y;
if(a.r != b.r || a.c != b.c)
exit(0);
c.create(a.r, a.c);
for(x=0;x<c.r;x++)
for(y=0;y<c.c;y++)
c.m[x][y] = a.m[x][y]+b.m[x][y];
return c;
}
matrice operator-(matrice a,matrice b){
matrice c;
int x,y;
if(a.r != b.r || a.c != b.c)
exit(0);
c.create(a.r, a.c);
for(x=0;x<c.r;x++)
for(y=0;y<c.c;y++)
c.m[x][y] = a.m[x][y]-b.m[x][y];
return c;
}
matrice operator*(matrice a,matrice b){
matrice c;
int x,y,i;
if(a.c != b.r)
exit(0);
c.create(a.r, b.c);
for(x=0;x<c.r;x++)
for(y=0;y<c.c;y++){
c.m[x][y] = 0;
for(i=0;i<a.c;i++)
c.m[x][y] = c.m[x][y] + a.m[x][i]*b.m[i][y];
}
return c;
}
//operazioni matrici con scalari
matrice operator+(double scal,matrice a){
matrice c;
int x,y;
c.create(a.r, a.c);
for(x=0;x<c.r;x++)
for(y=0;y<c.c;y++)
c.m[x][y] = a.m[x][y]+scal;
return c;
}
matrice operator+(matrice a, double scal){
matrice c;
int x,y;
c.create(a.r, a.c);
for(x=0;x<c.r;x++)
for(y=0;y<c.c;y++)
c.m[x][y] = a.m[x][y]+scal;
return c;
}
matrice operator-(double scal,matrice a){
matrice c;
int x,y;
c.create(a.r, a.c);
for(x=0;x<c.r;x++)
for(y=0;y<c.c;y++)
c.m[x][y] = scal-a.m[x][y];
return c;
}
matrice operator-(matrice a, double scal){
matrice c;
int x,y;
c.create(a.r, a.c);
for(x=0;x<c.r;x++)
for(y=0;y<c.c;y++)
c.m[x][y] = a.m[x][y]-scal;
return c;
}
matrice operator*(double scal,matrice a){
matrice c;
int x,y;
c.create(a.r, a.c);
for(x=0;x<c.r;x++)
for(y=0;y<c.c;y++)
c.m[x][y] = a.m[x][y]*scal;
return c;
}
matrice operator*(matrice a, double scal){
matrice c;
int x,y;
c.create(a.r, a.c);
for(x=0;x<c.r;x++)
for(y=0;y<c.c;y++)
c.m[x][y] = a.m[x][y]*scal;
return c;
}
//altre operazioni
matrice matrici_transpose(matrice a){
int x,y;
matrice c;
c.create(a.c, a.r);
for(x=0;x<a.r;x++)
for(y=0;y<a.c;y++)
c.m[y][x] = a.m[x][y];
return c;
}
double matrici_determinant(matrice a){
long x,y,riga=0;
double determinante=0;
matrice b;
if(a.r != a.c)
exit(0);
if(a.r == 2){
return (a.m[0][0]*a.m[1][1]-a.m[0][1]*a.m[1][0]);
}
else{
for(x=0;x<a.c;x++){
b = matrici_cut(a, MATRICI_CUT_ROW, riga);
b = matrici_cut(b, MATRICI_CUT_COLUMN, x);
determinante = determinante + a.m[riga][x]*matrici_determinant(b)*pow(-1,(x+1)+1);
}
return determinante;
}
}
matrice matrici_invert(matrice a){
long x,y;
double det;
matrice b,c;
det = matrici_determinant(a);
if(det == 0)
return b;
b.create(a.r,a.c);
for(x=0;x<a.r;x++)
for(y=0;y<a.c;y++){
c = matrici_cut(a, MATRICI_CUT_ROW, x);
c = matrici_cut(c, MATRICI_CUT_COLUMN, y);
b.m[x][y] = matrici_determinant(c)*pow(-1,((x+1)+(y+1)))/det;
}
b = matrici_transpose(b);
return b;
}
matrice matrici_cut(matrice a, matrici_cut_mode mode, int pos){
matrice c;
int x,y,x1=0,y1=0;
if(mode == MATRICI_CUT_ROW)
c.create(a.r-1,a.c);
else if(mode == MATRICI_CUT_COLUMN)
c.create(a.r,a.c-1);
else
exit(0);
for(x=0; x<a.r ;x++){
if(mode == MATRICI_CUT_ROW && pos == x) continue;
y1=0;
for(y=0; y<a.c ;y++){
if(mode == MATRICI_CUT_COLUMN && pos == y)continue;
c.m[x1][y1] = a.m[x][y];
if(!(mode == MATRICI_CUT_COLUMN && pos == y))y1++;
}
if(!(mode == MATRICI_CUT_ROW && pos == x)) x1++;
}
return c;
}
matrice matrici_join(matrice a, matrice b, matrici_join_mode mode){
matrice c;
int x,y;
if(mode == MATRICI_JOIN_HORIZONTALLY){
if(a.r != b.r)
exit(0);
c.create(a.r, a.c + b.c);
for(x=0;x<c.r;x++)
for(y=0;y<c.c;y++)
if(y < a.c)
c.m[x][y] = a.m[x][y];
else
c.m[x][y] = b.m[x][y - a.c];
}
else if(mode == MATRICI_JOIN_VERTICALLY){
if(a.c != b.c)
exit(0);
c.create(a.r + b.r, a.c);
for(x=0;x<c.r;x++)
for(y=0;y<c.c;y++)
if(x < a.r)
c.m[x][y] = a.m[x][y];
else
c.m[x][y] = b.m[x - a.r][y];
}
return c;
}