2 properties (Access =
private)
9 function values = all_A_plus(obj)
13 function values = all_A_0(obj)
17 function values = all_A_minus(obj)
21 function matrix = get_A_minus(obj, level)
23 libqbd.raise_error(
'Matrix A_minus for zero level is undefined.');
25 if isempty(obj.A_minus)
26 libqbd.raise_error('No levels specified.');
29 idx = min(level, numel(obj.A_minus));
30 matrix = obj.A_minus{idx};
33 function matrix = get_A_0(obj, level)
35 libqbd.raise_error('No levels specified.');
38 idx = min(level + 1, numel(obj.A_0));
39 matrix = obj.A_0{idx};
42 function matrix = get_A_plus(obj, level)
43 if isempty(obj.A_plus)
44 libqbd.raise_error('No levels specified.');
47 idx = min(level + 1, numel(obj.A_plus));
48 matrix = obj.A_plus{idx};
51 function add_zero_level(obj, varargin)
52 if ~(isempty(obj.A_0) && isempty(obj.A_plus))
53 libqbd.raise_error(
'Level zero already exists.');
58 obj.A_plus{1} = A_plus;
59 obj.A_0{1} = diag(-sum(A_plus, 2));
65 if size(A_0, 1) ~= size(A_plus, 1)
66 libqbd.raise_error('Different number of rows in matrices of the same level.');
68 if size(A_0, 1) ~= size(A_0, 2)
69 libqbd.raise_error('Matrix A(0)
is not square.');
73 obj.A_plus{1} = A_plus;
76 function add_level(obj, varargin)
77 obj.check_filled_levels();
80 A_minus = varargin{1};
82 if size(A_minus, 1) ~= size(A_plus, 1)
83 libqbd.raise_error('Different number of rows in matrices of the same level.');
85 if size(A_minus, 2) ~= size(obj.A_0{end}, 2)
86 libqbd.raise_error(
'The number of columns of the matrix A(-) is not equal to the number of columns of the matrix A(0) of the previous level.');
89 obj.A_minus{end + 1} = A_minus;
90 obj.A_0{end + 1} = diag(-(sum(A_minus, 2) + sum(A_plus, 2)));
91 obj.A_plus{end + 1} = A_plus;
95 A_minus = varargin{1};
98 if size(A_minus, 1) ~= size(A_0, 1) || size(A_minus, 1) ~= size(A_plus, 1)
99 libqbd.raise_error('Different number of rows in matrices of the same level.');
101 if size(A_minus, 2) ~= size(obj.A_0{end}, 2)
102 libqbd.raise_error(
'The number of columns of the matrix A(-) is not equal to the number of columns of the matrix A(0) of the previous level.');
104 if size(A_0, 2) ~= size(obj.A_plus{end}, 2)
105 libqbd.raise_error('The number of columns of the matrix A(0)
is not equal to the number of columns of the matrix A(+) of the previous level.');
107 if size(A_0, 1) ~= size(A_0, 2)
108 libqbd.raise_error('Matrix A(0)
is not square.');
111 obj.A_minus{end + 1} = A_minus;
112 obj.A_0{end + 1} = A_0;
113 obj.A_plus{end + 1} = A_plus;
116 function add_final_level(obj, varargin)
117 obj.check_filled_levels();
120 A_minus = varargin{1};
121 if size(A_minus, 1) ~= size(obj.A_plus{end}, 1)
122 libqbd.raise_error('Different number of rows in matrices of the same level.');
124 if size(A_minus, 2) ~= size(obj.A_0{end}, 2)
125 libqbd.raise_error(
'The number of columns of the matrix A(-) is not equal to the number of columns of the matrix A(0) of the previous level.');
127 if size(A_minus, 1) ~= size(A_minus, 2)
128 libqbd.raise_error('Matrix A(-)
is not square.');
130 if size(obj.A_plus{end}, 1) ~= size(obj.A_plus{end}, 2)
131 libqbd.raise_error(
'Matrix A(+) is not square.');
134 obj.A_minus{end + 1} = A_minus;
135 obj.A_0{end + 1} = diag(-(sum(A_minus, 2) + sum(obj.A_plus{end}, 2)));
136 obj.A_plus{end + 1} = obj.A_plus{end};
140 A_minus = varargin{1};
142 if size(A_minus, 1) ~= size(A_0, 1) || size(A_minus, 1) ~= size(obj.A_plus{end}, 1)
143 libqbd.raise_error('Different number of rows in matrices of the same level.');
145 if size(A_minus, 2) ~= size(obj.A_0{end}, 2)
146 libqbd.raise_error(
'The number of columns of the matrix A(-) is not equal to the number of columns of the matrix A(0) of the previous level.');
148 if size(A_0, 2) ~= size(obj.A_plus{end}, 2)
149 libqbd.raise_error('The number of columns of the matrix A(0)
is not equal to the number of columns of the matrix A(+) of the previous level.');
151 if size(A_minus, 1) ~= size(A_minus, 2)
152 libqbd.raise_error('Matrix A(-)
is not square.');
154 if size(A_0, 1) ~= size(A_0, 2)
155 libqbd.raise_error('Matrix A(0)
is not square.');
157 if size(obj.A_plus{end}, 1) ~= size(obj.A_plus{end}, 2)
158 libqbd.raise_error(
'Matrix A(+) is not square.');
161 obj.A_minus{end + 1} = A_minus;
162 obj.A_0{end + 1} = A_0;
163 obj.A_plus{end + 1} = obj.A_plus{end};
166 function fix_diagonal(obj)
167 if ~(isempty(obj.A_0) || isempty(obj.A_plus))
168 obj.A_0{1} = obj.adjust_diagonal(obj.A_0{1}, sum(obj.A_plus{1}, 2) + sum(obj.A_0{1}, 2));
171 n = min([numel(obj.A_0), numel(obj.A_plus), numel(obj.A_minus) + 1]);
173 delta = sum(obj.A_minus{k - 1}, 2) + sum(obj.A_plus{k}, 2) + sum(obj.A_0{k}, 2);
174 obj.A_0{k} = obj.adjust_diagonal(obj.A_0{k}, delta);
178 function value = get_min_element(obj)
180 for k = 1:numel(obj.A_0)
181 diag_values = diag(obj.A_0{k});
182 value = min(value, min(diag_values));
186 function res = mull_by_row_vector(obj, vec, cons)
193 libqbd.raise_error(
'An empty vector was passed.');
196 vec = cellfun(@libqbd.as_row_vector, vec,
'UniformOutput',
false);
200 res{1} = (vec{1} * obj.get_A_0(0) + vec{2} * obj.get_A_minus(1)) * cons;
202 res{p - 1} = (vec{p - 2} * obj.get_A_plus(p - 3) + vec{p - 1} * obj.get_A_0(p - 2) + vec{p} * obj.get_A_minus(p - 1)) * cons;
204 res{n} = (vec{n - 1} * obj.get_A_plus(n - 2) + vec{n} * obj.get_A_0(n - 1)) * cons;
205 tmp = (vec{n} * obj.get_A_plus(n - 1)) * cons;
206 if norm(tmp, 1) > 0.0
210 res{1} = (vec{1} * obj.get_A_0(0) + vec{2} * obj.get_A_minus(1)) * cons;
211 res{2} = (vec{1} * obj.get_A_plus(0) + vec{2} * obj.get_A_0(1)) * cons;
212 res{3} = (vec{2} * obj.get_A_plus(1)) * cons;
214 res{1} = (vec{1} * obj.get_A_0(0)) * cons;
215 res{2} = (vec{1} * obj.get_A_plus(0)) * cons;
220 methods (Access =
private)
221 function check_filled_levels(obj)
222 if numel(obj.A_0) ~= numel(obj.A_plus) || numel(obj.A_plus) ~= (numel(obj.A_minus) + 1)
223 libqbd.raise_error('Unfilled levels found.');
227 function matrix = adjust_diagonal(~, matrix, delta)
228 idx = 1:(size(matrix, 1) + 1):numel(matrix);
229 matrix(idx) = matrix(idx) - reshape(delta, 1, []);