1// Copyright ©2014 The Gonum Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// This file must be kept in sync with index_no_bound_checks.go.
6
7// +build bounds
8
9package mat
10
11// At returns the element at row i, column j.
12func (m *Dense) At(i, j int) float64 {
13	return m.at(i, j)
14}
15
16func (m *Dense) at(i, j int) float64 {
17	if uint(i) >= uint(m.mat.Rows) {
18		panic(ErrRowAccess)
19	}
20	if uint(j) >= uint(m.mat.Cols) {
21		panic(ErrColAccess)
22	}
23	return m.mat.Data[i*m.mat.Stride+j]
24}
25
26// Set sets the element at row i, column j to the value v.
27func (m *Dense) Set(i, j int, v float64) {
28	m.set(i, j, v)
29}
30
31func (m *Dense) set(i, j int, v float64) {
32	if uint(i) >= uint(m.mat.Rows) {
33		panic(ErrRowAccess)
34	}
35	if uint(j) >= uint(m.mat.Cols) {
36		panic(ErrColAccess)
37	}
38	m.mat.Data[i*m.mat.Stride+j] = v
39}
40
41// At returns the element at row i, column j.
42func (m *CDense) At(i, j int) complex128 {
43	return m.at(i, j)
44}
45
46func (m *CDense) at(i, j int) complex128 {
47	if uint(i) >= uint(m.mat.Rows) {
48		panic(ErrRowAccess)
49	}
50	if uint(j) >= uint(m.mat.Cols) {
51		panic(ErrColAccess)
52	}
53	return m.mat.Data[i*m.mat.Stride+j]
54}
55
56// Set sets the element at row i, column j to the value v.
57func (m *CDense) Set(i, j int, v complex128) {
58	m.set(i, j, v)
59}
60
61func (m *CDense) set(i, j int, v complex128) {
62	if uint(i) >= uint(m.mat.Rows) {
63		panic(ErrRowAccess)
64	}
65	if uint(j) >= uint(m.mat.Cols) {
66		panic(ErrColAccess)
67	}
68	m.mat.Data[i*m.mat.Stride+j] = v
69}
70
71// At returns the element at row i.
72// It panics if i is out of bounds or if j is not zero.
73func (v *VecDense) At(i, j int) float64 {
74	if j != 0 {
75		panic(ErrColAccess)
76	}
77	return v.at(i)
78}
79
80// AtVec returns the element at row i.
81// It panics if i is out of bounds.
82func (v *VecDense) AtVec(i int) float64 {
83	return v.at(i)
84}
85
86func (v *VecDense) at(i int) float64 {
87	if uint(i) >= uint(v.mat.N) {
88		panic(ErrRowAccess)
89	}
90	return v.mat.Data[i*v.mat.Inc]
91}
92
93// SetVec sets the element at row i to the value val.
94// It panics if i is out of bounds.
95func (v *VecDense) SetVec(i int, val float64) {
96	v.setVec(i, val)
97}
98
99func (v *VecDense) setVec(i int, val float64) {
100	if uint(i) >= uint(v.mat.N) {
101		panic(ErrVectorAccess)
102	}
103	v.mat.Data[i*v.mat.Inc] = val
104}
105
106// At returns the element at row i and column j.
107func (t *SymDense) At(i, j int) float64 {
108	return t.at(i, j)
109}
110
111func (t *SymDense) at(i, j int) float64 {
112	if uint(i) >= uint(t.mat.N) {
113		panic(ErrRowAccess)
114	}
115	if uint(j) >= uint(t.mat.N) {
116		panic(ErrColAccess)
117	}
118	if i > j {
119		i, j = j, i
120	}
121	return t.mat.Data[i*t.mat.Stride+j]
122}
123
124// SetSym sets the elements at (i,j) and (j,i) to the value v.
125func (t *SymDense) SetSym(i, j int, v float64) {
126	t.set(i, j, v)
127}
128
129func (t *SymDense) set(i, j int, v float64) {
130	if uint(i) >= uint(t.mat.N) {
131		panic(ErrRowAccess)
132	}
133	if uint(j) >= uint(t.mat.N) {
134		panic(ErrColAccess)
135	}
136	if i > j {
137		i, j = j, i
138	}
139	t.mat.Data[i*t.mat.Stride+j] = v
140}
141
142// At returns the element at row i, column j.
143func (t *TriDense) At(i, j int) float64 {
144	return t.at(i, j)
145}
146
147func (t *TriDense) at(i, j int) float64 {
148	if uint(i) >= uint(t.mat.N) {
149		panic(ErrRowAccess)
150	}
151	if uint(j) >= uint(t.mat.N) {
152		panic(ErrColAccess)
153	}
154	isUpper := t.isUpper()
155	if (isUpper && i > j) || (!isUpper && i < j) {
156		return 0
157	}
158	return t.mat.Data[i*t.mat.Stride+j]
159}
160
161// SetTri sets the element of the triangular matrix at row i, column j to the value v.
162// It panics if the location is outside the appropriate half of the matrix.
163func (t *TriDense) SetTri(i, j int, v float64) {
164	t.set(i, j, v)
165}
166
167func (t *TriDense) set(i, j int, v float64) {
168	if uint(i) >= uint(t.mat.N) {
169		panic(ErrRowAccess)
170	}
171	if uint(j) >= uint(t.mat.N) {
172		panic(ErrColAccess)
173	}
174	isUpper := t.isUpper()
175	if (isUpper && i > j) || (!isUpper && i < j) {
176		panic(ErrTriangleSet)
177	}
178	t.mat.Data[i*t.mat.Stride+j] = v
179}
180
181// At returns the element at row i, column j.
182func (b *BandDense) At(i, j int) float64 {
183	return b.at(i, j)
184}
185
186func (b *BandDense) at(i, j int) float64 {
187	if uint(i) >= uint(b.mat.Rows) {
188		panic(ErrRowAccess)
189	}
190	if uint(j) >= uint(b.mat.Cols) {
191		panic(ErrColAccess)
192	}
193	pj := j + b.mat.KL - i
194	if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj {
195		return 0
196	}
197	return b.mat.Data[i*b.mat.Stride+pj]
198}
199
200// SetBand sets the element at row i, column j to the value v.
201// It panics if the location is outside the appropriate region of the matrix.
202func (b *BandDense) SetBand(i, j int, v float64) {
203	b.set(i, j, v)
204}
205
206func (b *BandDense) set(i, j int, v float64) {
207	if uint(i) >= uint(b.mat.Rows) {
208		panic(ErrRowAccess)
209	}
210	if uint(j) >= uint(b.mat.Cols) {
211		panic(ErrColAccess)
212	}
213	pj := j + b.mat.KL - i
214	if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj {
215		panic(ErrBandSet)
216	}
217	b.mat.Data[i*b.mat.Stride+pj] = v
218}
219
220// At returns the element at row i, column j.
221func (s *SymBandDense) At(i, j int) float64 {
222	return s.at(i, j)
223}
224
225func (s *SymBandDense) at(i, j int) float64 {
226	if uint(i) >= uint(s.mat.N) {
227		panic(ErrRowAccess)
228	}
229	if uint(j) >= uint(s.mat.N) {
230		panic(ErrColAccess)
231	}
232	if i > j {
233		i, j = j, i
234	}
235	pj := j - i
236	if s.mat.K+1 <= pj {
237		return 0
238	}
239	return s.mat.Data[i*s.mat.Stride+pj]
240}
241
242// SetSymBand sets the element at row i, column j to the value v.
243// It panics if the location is outside the appropriate region of the matrix.
244func (s *SymBandDense) SetSymBand(i, j int, v float64) {
245	s.set(i, j, v)
246}
247
248func (s *SymBandDense) set(i, j int, v float64) {
249	if uint(i) >= uint(s.mat.N) {
250		panic(ErrRowAccess)
251	}
252	if uint(j) >= uint(s.mat.N) {
253		panic(ErrColAccess)
254	}
255	if i > j {
256		i, j = j, i
257	}
258	pj := j - i
259	if s.mat.K+1 <= pj {
260		panic(ErrBandSet)
261	}
262	s.mat.Data[i*s.mat.Stride+pj] = v
263}
264
265func (t *TriBandDense) At(i, j int) float64 {
266	return t.at(i, j)
267}
268
269func (t *TriBandDense) at(i, j int) float64 {
270	// TODO(btracey): Support Diag field, see #692.
271	if uint(i) >= uint(t.mat.N) {
272		panic(ErrRowAccess)
273	}
274	if uint(j) >= uint(t.mat.N) {
275		panic(ErrColAccess)
276	}
277	isUpper := t.isUpper()
278	if (isUpper && i > j) || (!isUpper && i < j) {
279		return 0
280	}
281	kl, ku := t.mat.K, 0
282	if isUpper {
283		kl, ku = 0, t.mat.K
284	}
285	pj := j + kl - i
286	if pj < 0 || kl+ku+1 <= pj {
287		return 0
288	}
289	return t.mat.Data[i*t.mat.Stride+pj]
290}
291
292func (t *TriBandDense) SetTriBand(i, j int, v float64) {
293	t.setTriBand(i, j, v)
294}
295
296func (t *TriBandDense) setTriBand(i, j int, v float64) {
297	if uint(i) >= uint(t.mat.N) {
298		panic(ErrRowAccess)
299	}
300	if uint(j) >= uint(t.mat.N) {
301		panic(ErrColAccess)
302	}
303	isUpper := t.isUpper()
304	if (isUpper && i > j) || (!isUpper && i < j) {
305		panic(ErrTriangleSet)
306	}
307	kl, ku := t.mat.K, 0
308	if isUpper {
309		kl, ku = 0, t.mat.K
310	}
311	pj := j + kl - i
312	if pj < 0 || kl+ku+1 <= pj {
313		panic(ErrBandSet)
314	}
315	// TODO(btracey): Support Diag field, see #692.
316	t.mat.Data[i*t.mat.Stride+pj] = v
317}
318
319// At returns the element at row i, column j.
320func (d *DiagDense) At(i, j int) float64 {
321	return d.at(i, j)
322}
323
324func (d *DiagDense) at(i, j int) float64 {
325	if uint(i) >= uint(d.mat.N) {
326		panic(ErrRowAccess)
327	}
328	if uint(j) >= uint(d.mat.N) {
329		panic(ErrColAccess)
330	}
331	if i != j {
332		return 0
333	}
334	return d.mat.Data[i*d.mat.Inc]
335}
336
337// SetDiag sets the element at row i, column i to the value v.
338// It panics if the location is outside the appropriate region of the matrix.
339func (d *DiagDense) SetDiag(i int, v float64) {
340	d.setDiag(i, v)
341}
342
343func (d *DiagDense) setDiag(i int, v float64) {
344	if uint(i) >= uint(d.mat.N) {
345		panic(ErrRowAccess)
346	}
347	d.mat.Data[i*d.mat.Inc] = v
348}
349