Sparse Matrix

Epsilon·2022년 10월 16일
0
post-thumbnail
post-custom-banner
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

typedef struct matrix{
    int row[50];
    int col[50];
    int val[50];
} matrix;

matrix zero = {{0, 0, 0},'\0', '\0'};
bool iszero(matrix A);
bool nzero(matrix A, int row, int col);
int getRMid(matrix A, int row, int col);
int getCMid(matrix A, int row, int col);
matrix tp(matrix A);
void printM(matrix X);
int getVal(matrix A, int row, int col);
int inprod(matrix A, matrix B, int row, int col);
matrix Mmult(matrix A, matrix B);

int main() {
    matrix A = {{6, 1, 1, 1, 2, 2, 3, 5, 6}, 
                {6, 1, 4, 6, 2, 3, 5, 1, 3}, 
                {8, 15, 22, -15, 11, 3, -6, 91, 28}
    };
    matrix B, C;
    B = tp(A);
    printM(B);
    C = Mmult(A, B);
    printM(C);

}
bool iszero(matrix A){
    if(A.val[0]==0) return true;
    else return false;
}

int getRMid(matrix A, int row, int col){
    int *s= malloc(sizeof(int)*(A.row[0]+1));
    int *t= malloc(sizeof(int)*(A.row[0]+1));
    for(int i=0; i<A.row[0]+1; i++) s[i]=0;
    for(int i=1; i<A.val[0]+1; i++) {
        s[A.row[i]]=s[A.row[i]]+1;
    }
    t[0]=0; t[1]=1;
    for(int i=2; i<A.row[0]+1;i++){
        t[i]=t[i-1]+s[i-1];
    }
    int index = t[row];
    for(int i=0; i<s[row]; i++){
        if(A.col[t[row]+i]<col){
            index++;
        }
    }
    free(s); free(t);
    return index;
}

int getCMid(matrix A, int row, int col){
    int *s = malloc(sizeof(int)*(A.col[0]+1));
    int *t = malloc(sizeof(int)*(A.col[0]+1));
    for(int i=0; i<A.col[0]+1; i++) s[i]=0;
    for(int i=1; i<A.val[0]+1; i++) {
        s[A.col[i]]=s[A.col[i]]+1;
    }
    t[0]=0; t[1]=1;
    for(int i=2; i<A.col[0]+1;i++){
        t[i]=t[i-1]+s[i-1];
    }
    int index = t[col];
    for(int i=0; i<s[col]; i++){
        if(A.row[t[col]+i]<row){
            index++;
        }
    }
    free(s); free(t);
    return index;
}


int getVal(matrix A, int row, int col){
    int n = getRMid(A, row, col);
    return A.val[n];
}

bool nzero(matrix A, int row, int col){
    int n = getRMid(A, row, col);
    if(A.row[n]==row && A.col[n]==col) return true;
    else return false;
}

matrix tp(matrix A){
    matrix B;
    B.row[0] = A.col[0];
    B.col[0] = A.row[0];
    B.val[0] = A.val[0];
    if(iszero(A)) return A;
    int *s = malloc(sizeof(int)*(A.col[0]+1));
    int *t = malloc(sizeof(int)*(A.col[0]+1));
    for(int i=0; i<A.col[0]+1; i++) s[i]=0;
    for(int i=1; i<A.val[0]+1; i++) {
        s[A.col[i]]=s[A.col[i]]+1;
    } 
    t[0]=0; t[1]=1;
    for(int i=2; i<A.col[0]+1; i++){
        t[i]=t[i-1]+s[i-1];
    }
    for(int i=1; i<B.val[0]+1; i++){
        B.row[t[A.col[i]]] = A.col[i];
        B.col[t[A.col[i]]] = A.row[i];
        B.val[t[A.col[i]]] = A.val[i];
        t[A.col[i]]++;
    }
    free(s); free(t);
    return B;
}

void printM(matrix A){
    printf("\n");
    for(int i=1; i<A.row[0]+1; i++){
        printf("[");
        for(int j=1; j<A.col[0]+1; j++){
            if (nzero(A, i, j)) {
                printf(" %4d ", getVal(A, i, j));
            }
            else printf(" %4d ",0);
        }
        printf("]\n");
    }
}

int inprod(matrix A, matrix B, int row, int col){
    int m = A.col[0], n = B.row[0];
    if(m!=n) {
        printf("invalid inner product");
        return false;
    }
    else{
        int sum = 0;
        for(int i=1; i<m+1; i++){
            if(nzero(A, row, i) && nzero(B, i, col))
                sum = sum + getVal(A, row, i)*getVal(B, i, col);
        }
        return sum;
    }
}

matrix Mmult(matrix A, matrix B){
    matrix C;
    C.row[0] = A.row[0];
    C.col[0] = B.col[0];
    int id =0;
    for(int i=1; i<C.row[0]+1; i++){
        for(int j=1; j<C.col[0]+1; j++){
            int vsum = inprod(A, B, i, j);
            if (vsum !=0){
                id++;
                C.row[id] = i;
                C.col[id] = j;
                C.val[id] = vsum;
            }
        }
    }
    C.val[0] = id;
    return C;
}
profile
컴퓨터 공부하는 수학교사 입실론입니다.
post-custom-banner

0개의 댓글