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_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	if uint(i) >= uint(m.mat.Rows) {
14		panic(ErrRowAccess)
15	}
16	if uint(j) >= uint(m.mat.Cols) {
17		panic(ErrColAccess)
18	}
19	return m.at(i, j)
20}
21
22func (m *Dense) at(i, j int) float64 {
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	if uint(i) >= uint(m.mat.Rows) {
29		panic(ErrRowAccess)
30	}
31	if uint(j) >= uint(m.mat.Cols) {
32		panic(ErrColAccess)
33	}
34	m.set(i, j, v)
35}
36
37func (m *Dense) set(i, j int, v float64) {
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	if uint(i) >= uint(m.mat.Rows) {
44		panic(ErrRowAccess)
45	}
46	if uint(j) >= uint(m.mat.Cols) {
47		panic(ErrColAccess)
48	}
49	return m.at(i, j)
50}
51
52func (m *CDense) at(i, j int) complex128 {
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	if uint(i) >= uint(m.mat.Rows) {
59		panic(ErrRowAccess)
60	}
61	if uint(j) >= uint(m.mat.Cols) {
62		panic(ErrColAccess)
63	}
64	m.set(i, j, v)
65}
66
67func (m *CDense) set(i, j int, v complex128) {
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 uint(i) >= uint(v.mat.N) {
75		panic(ErrRowAccess)
76	}
77	if j != 0 {
78		panic(ErrColAccess)
79	}
80	return v.at(i)
81}
82
83// AtVec returns the element at row i.
84// It panics if i is out of bounds.
85func (v *VecDense) AtVec(i int) float64 {
86	if uint(i) >= uint(v.mat.N) {
87		panic(ErrRowAccess)
88	}
89	return v.at(i)
90}
91
92func (v *VecDense) at(i int) float64 {
93	return v.mat.Data[i*v.mat.Inc]
94}
95
96// SetVec sets the element at row i to the value val.
97// It panics if i is out of bounds.
98func (v *VecDense) SetVec(i int, val float64) {
99	if uint(i) >= uint(v.mat.N) {
100		panic(ErrVectorAccess)
101	}
102	v.setVec(i, val)
103}
104
105func (v *VecDense) setVec(i int, val float64) {
106	v.mat.Data[i*v.mat.Inc] = val
107}
108
109// At returns the element at row i and column j.
110func (s *SymDense) At(i, j int) float64 {
111	if uint(i) >= uint(s.mat.N) {
112		panic(ErrRowAccess)
113	}
114	if uint(j) >= uint(s.mat.N) {
115		panic(ErrColAccess)
116	}
117	return s.at(i, j)
118}
119
120func (s *SymDense) at(i, j int) float64 {
121	if i > j {
122		i, j = j, i
123	}
124	return s.mat.Data[i*s.mat.Stride+j]
125}
126
127// SetSym sets the elements at (i,j) and (j,i) to the value v.
128func (s *SymDense) SetSym(i, j int, v float64) {
129	if uint(i) >= uint(s.mat.N) {
130		panic(ErrRowAccess)
131	}
132	if uint(j) >= uint(s.mat.N) {
133		panic(ErrColAccess)
134	}
135	s.set(i, j, v)
136}
137
138func (s *SymDense) set(i, j int, v float64) {
139	if i > j {
140		i, j = j, i
141	}
142	s.mat.Data[i*s.mat.Stride+j] = v
143}
144
145// At returns the element at row i, column j.
146func (t *TriDense) At(i, j int) float64 {
147	if uint(i) >= uint(t.mat.N) {
148		panic(ErrRowAccess)
149	}
150	if uint(j) >= uint(t.mat.N) {
151		panic(ErrColAccess)
152	}
153	return t.at(i, j)
154}
155
156func (t *TriDense) at(i, j int) float64 {
157	isUpper := t.triKind()
158	if (isUpper && i > j) || (!isUpper && i < j) {
159		return 0
160	}
161	return t.mat.Data[i*t.mat.Stride+j]
162}
163
164// SetTri sets the element at row i, column j to the value v.
165// It panics if the location is outside the appropriate half of the matrix.
166func (t *TriDense) SetTri(i, j int, v float64) {
167	if uint(i) >= uint(t.mat.N) {
168		panic(ErrRowAccess)
169	}
170	if uint(j) >= uint(t.mat.N) {
171		panic(ErrColAccess)
172	}
173	isUpper := t.isUpper()
174	if (isUpper && i > j) || (!isUpper && i < j) {
175		panic(ErrTriangleSet)
176	}
177	t.set(i, j, v)
178}
179
180func (t *TriDense) set(i, j int, v float64) {
181	t.mat.Data[i*t.mat.Stride+j] = v
182}
183
184// At returns the element at row i, column j.
185func (b *BandDense) At(i, j int) float64 {
186	if uint(i) >= uint(b.mat.Rows) {
187		panic(ErrRowAccess)
188	}
189	if uint(j) >= uint(b.mat.Cols) {
190		panic(ErrColAccess)
191	}
192	return b.at(i, j)
193}
194
195func (b *BandDense) at(i, j int) float64 {
196	pj := j + b.mat.KL - i
197	if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj {
198		return 0
199	}
200	return b.mat.Data[i*b.mat.Stride+pj]
201}
202
203// SetBand sets the element at row i, column j to the value v.
204// It panics if the location is outside the appropriate region of the matrix.
205func (b *BandDense) SetBand(i, j int, v float64) {
206	if uint(i) >= uint(b.mat.Rows) {
207		panic(ErrRowAccess)
208	}
209	if uint(j) >= uint(b.mat.Cols) {
210		panic(ErrColAccess)
211	}
212	pj := j + b.mat.KL - i
213	if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj {
214		panic(ErrBandSet)
215	}
216	b.set(i, j, v)
217}
218
219func (b *BandDense) set(i, j int, v float64) {
220	pj := j + b.mat.KL - i
221	b.mat.Data[i*b.mat.Stride+pj] = v
222}
223
224// At returns the element at row i, column j.
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	return s.at(i, j)
233}
234
235func (s *SymBandDense) at(i, j int) float64 {
236	if i > j {
237		i, j = j, i
238	}
239	pj := j - i
240	if s.mat.K+1 <= pj {
241		return 0
242	}
243	return s.mat.Data[i*s.mat.Stride+pj]
244}
245
246// SetSymBand sets the element at row i, column j to the value v.
247// It panics if the location is outside the appropriate region of the matrix.
248func (s *SymBandDense) SetSymBand(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	s.set(i, j, v)
256}
257
258func (s *SymBandDense) set(i, j int, v float64) {
259	if i > j {
260		i, j = j, i
261	}
262	pj := j - i
263	if s.mat.K+1 <= pj {
264		panic(ErrBandSet)
265	}
266	s.mat.Data[i*s.mat.Stride+pj] = v
267}
268
269func (t *TriBandDense) At(i, j int) float64 {
270	if uint(i) >= uint(t.mat.N) {
271		panic(ErrRowAccess)
272	}
273	if uint(j) >= uint(t.mat.N) {
274		panic(ErrColAccess)
275	}
276	return t.at(i, j)
277}
278
279func (t *TriBandDense) at(i, j int) float64 {
280	// TODO(btracey): Support Diag field, see #692.
281	isUpper := t.isUpper()
282	if (isUpper && i > j) || (!isUpper && i < j) {
283		return 0
284	}
285	kl := t.mat.K
286	ku := 0
287	if isUpper {
288		ku = t.mat.K
289		kl = 0
290	}
291	pj := j + kl - i
292	if pj < 0 || kl+ku+1 <= pj {
293		return 0
294	}
295	return t.mat.Data[i*t.mat.Stride+pj]
296}
297
298func (t *TriBandDense) SetTriBand(i, j int, v float64) {
299	if uint(i) >= uint(t.mat.N) {
300		panic(ErrRowAccess)
301	}
302	if uint(j) >= uint(t.mat.N) {
303		panic(ErrColAccess)
304	}
305	isUpper := t.isUpper()
306	if (isUpper && i > j) || (!isUpper && i < j) {
307		panic(ErrTriangleSet)
308	}
309	kl, ku := t.mat.K, 0
310	if isUpper {
311		kl, ku = 0, t.mat.K
312	}
313	pj := j + kl - i
314	if pj < 0 || kl+ku+1 <= pj {
315		panic(ErrBandSet)
316	}
317	// TODO(btracey): Support Diag field, see #692.
318	t.mat.Data[i*t.mat.Stride+pj] = v
319}
320
321func (t *TriBandDense) setTriBand(i, j int, v float64) {
322	var kl int
323	if !t.isUpper() {
324		kl = t.mat.K
325	}
326	pj := j + kl - i
327	t.mat.Data[i*t.mat.Stride+pj] = v
328}
329
330// At returns the element at row i, column j.
331func (d *DiagDense) At(i, j int) float64 {
332	if uint(i) >= uint(d.mat.N) {
333		panic(ErrRowAccess)
334	}
335	if uint(j) >= uint(d.mat.N) {
336		panic(ErrColAccess)
337	}
338	return d.at(i, j)
339}
340
341func (d *DiagDense) at(i, j int) float64 {
342	if i != j {
343		return 0
344	}
345	return d.mat.Data[i*d.mat.Inc]
346}
347
348// SetDiag sets the element at row i, column i to the value v.
349// It panics if the location is outside the appropriate region of the matrix.
350func (d *DiagDense) SetDiag(i int, v float64) {
351	if uint(i) >= uint(d.mat.N) {
352		panic(ErrRowAccess)
353	}
354	d.setDiag(i, v)
355}
356
357func (d *DiagDense) setDiag(i int, v float64) {
358	d.mat.Data[i*d.mat.Inc] = v
359}
360