gonum.org/v1/gonum@v0.14.0/mat/index_bound_checks.go (about)

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