-
Notifications
You must be signed in to change notification settings - Fork 7
/
solve_lu_serial.c
95 lines (90 loc) · 3.21 KB
/
solve_lu_serial.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdio.h>
#include <stdlib.h>
#include "solve_lu_serial.h"
/* / ____|/ __ \| |\ \ / / ____|/ ____| */
/* | (___ | | | | | \ \ / /| |__ | (___ */
/* \___ \| | | | | \ \/ / | __| \___ \ */
/* ____) | |__| | |___\ / | |____ ____) | */
/* |_____/ \____/|______\/ |______|_____/ */
/* /\ _ \ /\ \ */
/* \ \ \ \ \ __ _ \ \ \____ */
/* \ \ __ \ /\ \/ \ _______ \ \ __ \ */
/* \ \ \/\ \\/> </ /\______\ \ \ \ \ \ */
/* \ \_\ \_\/\_/\_\ \/______/ \ \_ __/ */
/* \/_/\/_/\//\/_/ \/___/ */
/* (_) */
/* _ _ ___ _ _ __ __ _ */
/* | | | / __| | '_ \ / _` | */
/* | |_| \__ \ | | | | (_| | */
/* \__,_|___/_|_| |_|\__, | */
/* __/ | */
/* |___/ */
/* /__/\ */
/* \ \:\ */
/* ___ ___ \ \:\ */
/* /__/\ / /\ ___ \ \:\ */
/* \ \:\ / /:/ /__/\ \__\:\ */
/* \ \:\ /:/ \ \:\ / /:/ */
/* \ \:\/:/ \ \:\ /:/ */
/* \ \::/ \ \:\/:/ */
/* \__\/ \ \::/ */
/* \__\/ */
/*
task : solves Ax=b using LU decomposition already stored in A
and the permutation matrix P. Use lu_serial.c to do LU decomposition first.
The size of A is nxn.
ver : 1.00
ghasemi.arash@gmail.com
*/
int solve_lu_serial(int *P, double *A, double *x, double *b, int n)
{
//allocating local variables
int i,j;
double *Ap = (double *)malloc(n*n*sizeof(double));
double *bp = (double *)malloc(n*sizeof(double));
double *x_bar = (double *)malloc(n*sizeof(double));
//transforming A,b to fully pivotted Ap = P*A=[L][U] and bp = P*b
// so final solution [x] is [Ap][x]=[bp] -> [L][U] [x] = [bp]
// step 1 : forward substitution [U] [x] = [L]^-1 [bp] = [x_bar]
// step 2: backward substitution [x] = [U]^-1 [x_bar]
serial_matrix_mult(P, A, Ap, n, n , n);
serial_matrix_mult(P, b, bp, n, n , 1);
//starting forward substitution
for(i = 0; i < n; i++)
{
x_bar[i] = bp[i];
for(j = 0; j < i; j++)
x_bar[i] -= Ap[i*n+j] * x_bar[j];
}
//starting backward substitution
for(i = (n-1); i >= 0; i--)
{
x[i] = x_bar[i]/Ap[i*n+i];
for(j = (n-1); j > i; j--)
x[i] -= (Ap[i*n+j]/Ap[i*n+i]) * x[j];
}
//clean up
free(Ap);
free(bp);
free(x_bar);
//completed successfully!
return 0;
}
/* the following performs a serial matrix multipication C = A*B
where A=A(m,n) and B=B(n,l) hence C=C(m,l).
NOTE: IT DOESN'T CHECK FOR DIMENSIONAL COMPATIBILITY
SO SPECIAL CARE MUST BE TAKEN BEFORE USING THIS.
*/
void serial_matrix_mult(int *A, double *B,double *C,int m, int n , int l)
{
/* local variables */
int i,j,k;
for ( i= 0; i < m ; i++)
for ( j= 0; j < l ; j++)
{
C[i*l + j] = 0.;
for ( k= 0; k < n ; k++)
C[i*l + j] += ((double)A[i*n+k]) * B[k*l+j];
}
/* simply finished .*/
}