#include <stdlib.h>
#include <stdio.h>



double* LDR_sol(double** A, double* left_v,int n){
    // Create the L, D, and R matrices
    double** l = (double**)malloc(n * sizeof(double*));
    double** d = (double**)malloc(n * sizeof(double*));
    double** r = (double**)malloc(n * sizeof(double*));
    for (int i = 0; i < n; i++) {
        l[i] = (double*)malloc(n * sizeof(double));
        d[i] = (double*)malloc(n * sizeof(double));
        r[i] = (double*)malloc(n * sizeof(double));
    }

    // Initialize the L, D, and R matrices
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            l[i][j] = 0;
            d[i][j] = 0;
            r[i][j] = 0;
        }
        l[i][i] = 1;
        r[i][i] = 1;
    }
    for (int m = 0;m < n;m++) {
        d[m][m] = A[m][m];
        for (int k = 0;k < m;k++) {
            d[m][m] -= l[m][k] * d[k][k] * r[k][m];
        }
        
        

        for (int j = m+1;j < n;j++) {
            r[m][j] = A[m][j] / d[m][m];
            l[j][m] = A[j][m] / d[m][m];
            for (int k = 0;k < m;k++) {
                r[m][j] -= l[m][k] * d[k][k] * r[k][j]/d[m][m];
                l[j][m] -= l[j][k] * d[k][k] * r[k][m]/d[m][m];
            }
            

        }
    }
    

    double* x = (double*)malloc(n * sizeof(double));
    double* y = (double*)malloc(n * sizeof(double));
    double* z = (double*)malloc(n * sizeof(double));
    // Solve the system Ly = b
    for (int i = 0; i < n; i++) {
        y[i] = left_v[i];
        for (int j = 0; j < i; j++) {
            y[i] -= l[i][j] * y[j];
        }
    }

    // Solve the system Dz = y
    for (int i = 0; i < n; i++) {
        z[i] = y[i] / d[i][i];
    }

    // Solve the system Rz = x
    for (int i = n - 1; i >= 0; i--) {
        x[i] = z[i];
        for (int j = i + 1; j < n; j++) {
            x[i] -= x[j] * r[i][j];
        }
    }
    for (int i = 0;i < n;i++) {
        free(l[i]);
        free(r[i]);
        free(d[i]);
    }
    free(y);
    free(z);
    free(l);
    free(d);
    free(r);
    return x;
}