-
Notifications
You must be signed in to change notification settings - Fork 0
/
g_s_circuit2.m
111 lines (91 loc) · 3.26 KB
/
g_s_circuit2.m
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
%{
MTE 204 Project 1
Gauss-Seidel method for solving square, partially pivoted matrices
2022/10/8
By Isaac Zhang
For Circuit #2
%}
close all;
clear all;
clc;
stopping_num_of_iters = 1000; % to prevent endless looping
stopping_error = 1e-6; % convergence criterion, symbol epsilon_s
relaxation_factor = 0.1; % to adjust convergence rate, symbol omega
%{
0.10 -> 371 iterations
0.25 -> 187 iterations
0.50 -> 201 iterations
0.75 -> Did not converge
%}
% matrix representing unknown currents in the circuit
A = [8 0 0 0 5;
0 10 5 0 -5;
0 1 -1 -1 0;
0 10 0 2 -5;
1 -1 0 0 -1];
% solution vector corresponding to the matrix A
b = [25; 25; 0; 0; 0;];
% variables names corresponding to the unknown currents
unknowns = ["i_1", "i_2", "i_3", "i_4", "i_5"];
% solving for the unknown currents using MATLAB's built-in solver
solved = A\b
% number of iterations thus far
num_of_iters = 0;
% the number of rows of the matrix A
num_of_rows = size(A, 1);
% a vector to store guesses, initialized as all zeros
guesses = zeros(1, num_of_rows);
%{
a vector to store errors, which should all eventually reach below the
convergence criterion; initialized as all ones
%}
errors = ones(1, num_of_rows);
%{
convergence is not reached if there is at least one variable whose
error is more than the convergence criterion; loop until
convergence or the maximum number of iterations is reached
%}
while (any(errors > stopping_error) ...
&& (num_of_iters < stopping_num_of_iters))
% store previous guesses
prev_guess = guesses;
for i = 1:num_of_rows
%{
a summation of elements in a row, multiplied by new or previous
guesses as specified in the formula for a new guess
%}
tally = 0;
% loop until just before the i-th element, the diagonal
for j = 1:(i - 1)
tally = tally + A(i,j) * guesses(j);
end
% loop from just after the i-th element until the last
for j = (i + 1):num_of_rows
tally = tally + A(i,j) * prev_guess(j);
end
% the new guess, with relaxation
guesses(i) = (relaxation_factor / A(i,i)) ...
* (b(i) - tally) ...
+ (1 - relaxation_factor) ...
* prev_guess(i);
% update the error for this current element
errors(i) = abs((guesses(i) - prev_guess(i)) / guesses(i));
end
% update the number of iterations thus far
num_of_iters = num_of_iters + 1;
end
% state if the algorithm converged
if (num_of_iters == stopping_num_of_iters)
fprintf(['The solution did not converge after %d iterations, ' ...
'using a relaxation of %.3f \n'], ...
stopping_num_of_iters, relaxation_factor);
else
% print to console the guesses for currents
fprintf('The unknown currents are as follows... \n');
for i = 1:num_of_rows
fprintf('\t %s = %.3f \n', unknowns(i), guesses(i));
end
fprintf(['\nThe above are found after %d iterations of ' ...
'Gauss-Seidel, using a relxation factor of %.3f \n'], ...
num_of_iters, relaxation_factor);
end