vector.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. // Copyright ©2013 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. package mat
  5. import (
  6. "gonum.org/v1/gonum/blas"
  7. "gonum.org/v1/gonum/blas/blas64"
  8. "gonum.org/v1/gonum/internal/asm/f64"
  9. )
  10. var (
  11. vector *VecDense
  12. _ Matrix = vector
  13. _ Vector = vector
  14. _ Reseter = vector
  15. )
  16. // Vector is a vector.
  17. type Vector interface {
  18. Matrix
  19. AtVec(int) float64
  20. Len() int
  21. }
  22. // TransposeVec is a type for performing an implicit transpose of a Vector.
  23. // It implements the Vector interface, returning values from the transpose
  24. // of the vector within.
  25. type TransposeVec struct {
  26. Vector Vector
  27. }
  28. // At returns the value of the element at row i and column j of the transposed
  29. // matrix, that is, row j and column i of the Vector field.
  30. func (t TransposeVec) At(i, j int) float64 {
  31. return t.Vector.At(j, i)
  32. }
  33. // AtVec returns the element at position i. It panics if i is out of bounds.
  34. func (t TransposeVec) AtVec(i int) float64 {
  35. return t.Vector.AtVec(i)
  36. }
  37. // Dims returns the dimensions of the transposed vector.
  38. func (t TransposeVec) Dims() (r, c int) {
  39. c, r = t.Vector.Dims()
  40. return r, c
  41. }
  42. // T performs an implicit transpose by returning the Vector field.
  43. func (t TransposeVec) T() Matrix {
  44. return t.Vector
  45. }
  46. // Len returns the number of columns in the vector.
  47. func (t TransposeVec) Len() int {
  48. return t.Vector.Len()
  49. }
  50. // TVec performs an implicit transpose by returning the Vector field.
  51. func (t TransposeVec) TVec() Vector {
  52. return t.Vector
  53. }
  54. // Untranspose returns the Vector field.
  55. func (t TransposeVec) Untranspose() Matrix {
  56. return t.Vector
  57. }
  58. func (t TransposeVec) UntransposeVec() Vector {
  59. return t.Vector
  60. }
  61. // VecDense represents a column vector.
  62. type VecDense struct {
  63. mat blas64.Vector
  64. // A BLAS vector can have a negative increment, but allowing this
  65. // in the mat type complicates a lot of code, and doesn't gain anything.
  66. // VecDense must have positive increment in this package.
  67. }
  68. // NewVecDense creates a new VecDense of length n. If data == nil,
  69. // a new slice is allocated for the backing slice. If len(data) == n, data is
  70. // used as the backing slice, and changes to the elements of the returned VecDense
  71. // will be reflected in data. If neither of these is true, NewVecDense will panic.
  72. // NewVecDense will panic if n is zero.
  73. func NewVecDense(n int, data []float64) *VecDense {
  74. if n <= 0 {
  75. if n == 0 {
  76. panic(ErrZeroLength)
  77. }
  78. panic("mat: negative dimension")
  79. }
  80. if len(data) != n && data != nil {
  81. panic(ErrShape)
  82. }
  83. if data == nil {
  84. data = make([]float64, n)
  85. }
  86. return &VecDense{
  87. mat: blas64.Vector{
  88. N: n,
  89. Inc: 1,
  90. Data: data,
  91. },
  92. }
  93. }
  94. // SliceVec returns a new Vector that shares backing data with the receiver.
  95. // The returned matrix starts at i of the receiver and extends k-i elements.
  96. // SliceVec panics with ErrIndexOutOfRange if the slice is outside the capacity
  97. // of the receiver.
  98. func (v *VecDense) SliceVec(i, k int) Vector {
  99. if i < 0 || k <= i || v.Cap() < k {
  100. panic(ErrIndexOutOfRange)
  101. }
  102. return &VecDense{
  103. mat: blas64.Vector{
  104. N: k - i,
  105. Inc: v.mat.Inc,
  106. Data: v.mat.Data[i*v.mat.Inc : (k-1)*v.mat.Inc+1],
  107. },
  108. }
  109. }
  110. // Dims returns the number of rows and columns in the matrix. Columns is always 1
  111. // for a non-Reset vector.
  112. func (v *VecDense) Dims() (r, c int) {
  113. if v.IsZero() {
  114. return 0, 0
  115. }
  116. return v.mat.N, 1
  117. }
  118. // Caps returns the number of rows and columns in the backing matrix. Columns is always 1
  119. // for a non-Reset vector.
  120. func (v *VecDense) Caps() (r, c int) {
  121. if v.IsZero() {
  122. return 0, 0
  123. }
  124. return v.Cap(), 1
  125. }
  126. // Len returns the length of the vector.
  127. func (v *VecDense) Len() int {
  128. return v.mat.N
  129. }
  130. // Cap returns the capacity of the vector.
  131. func (v *VecDense) Cap() int {
  132. if v.IsZero() {
  133. return 0
  134. }
  135. return (cap(v.mat.Data)-1)/v.mat.Inc + 1
  136. }
  137. // T performs an implicit transpose by returning the receiver inside a Transpose.
  138. func (v *VecDense) T() Matrix {
  139. return Transpose{v}
  140. }
  141. // TVec performs an implicit transpose by returning the receiver inside a TransposeVec.
  142. func (v *VecDense) TVec() Vector {
  143. return TransposeVec{v}
  144. }
  145. // Reset zeros the length of the vector so that it can be reused as the
  146. // receiver of a dimensionally restricted operation.
  147. //
  148. // See the Reseter interface for more information.
  149. func (v *VecDense) Reset() {
  150. // No change of Inc or N to 0 may be
  151. // made unless both are set to 0.
  152. v.mat.Inc = 0
  153. v.mat.N = 0
  154. v.mat.Data = v.mat.Data[:0]
  155. }
  156. // Zero sets all of the matrix elements to zero.
  157. func (v *VecDense) Zero() {
  158. for i := 0; i < v.mat.N; i++ {
  159. v.mat.Data[v.mat.Inc*i] = 0
  160. }
  161. }
  162. // CloneVec makes a copy of a into the receiver, overwriting the previous value
  163. // of the receiver.
  164. func (v *VecDense) CloneVec(a Vector) {
  165. if v == a {
  166. return
  167. }
  168. n := a.Len()
  169. v.mat = blas64.Vector{
  170. N: n,
  171. Inc: 1,
  172. Data: use(v.mat.Data, n),
  173. }
  174. if r, ok := a.(RawVectorer); ok {
  175. blas64.Copy(r.RawVector(), v.mat)
  176. return
  177. }
  178. for i := 0; i < a.Len(); i++ {
  179. v.SetVec(i, a.AtVec(i))
  180. }
  181. }
  182. // VecDenseCopyOf returns a newly allocated copy of the elements of a.
  183. func VecDenseCopyOf(a Vector) *VecDense {
  184. v := &VecDense{}
  185. v.CloneVec(a)
  186. return v
  187. }
  188. func (v *VecDense) RawVector() blas64.Vector {
  189. return v.mat
  190. }
  191. // CopyVec makes a copy of elements of a into the receiver. It is similar to the
  192. // built-in copy; it copies as much as the overlap between the two vectors and
  193. // returns the number of elements it copied.
  194. func (v *VecDense) CopyVec(a Vector) int {
  195. n := min(v.Len(), a.Len())
  196. if v == a {
  197. return n
  198. }
  199. if r, ok := a.(RawVectorer); ok {
  200. blas64.Copy(r.RawVector(), v.mat)
  201. return n
  202. }
  203. for i := 0; i < n; i++ {
  204. v.setVec(i, a.AtVec(i))
  205. }
  206. return n
  207. }
  208. // ScaleVec scales the vector a by alpha, placing the result in the receiver.
  209. func (v *VecDense) ScaleVec(alpha float64, a Vector) {
  210. n := a.Len()
  211. if v == a {
  212. if v.mat.Inc == 1 {
  213. f64.ScalUnitary(alpha, v.mat.Data)
  214. return
  215. }
  216. f64.ScalInc(alpha, v.mat.Data, uintptr(n), uintptr(v.mat.Inc))
  217. return
  218. }
  219. v.reuseAs(n)
  220. if rv, ok := a.(RawVectorer); ok {
  221. mat := rv.RawVector()
  222. v.checkOverlap(mat)
  223. if v.mat.Inc == 1 && mat.Inc == 1 {
  224. f64.ScalUnitaryTo(v.mat.Data, alpha, mat.Data)
  225. return
  226. }
  227. f64.ScalIncTo(v.mat.Data, uintptr(v.mat.Inc),
  228. alpha, mat.Data, uintptr(n), uintptr(mat.Inc))
  229. return
  230. }
  231. for i := 0; i < n; i++ {
  232. v.setVec(i, alpha*a.AtVec(i))
  233. }
  234. }
  235. // AddScaledVec adds the vectors a and alpha*b, placing the result in the receiver.
  236. func (v *VecDense) AddScaledVec(a Vector, alpha float64, b Vector) {
  237. if alpha == 1 {
  238. v.AddVec(a, b)
  239. return
  240. }
  241. if alpha == -1 {
  242. v.SubVec(a, b)
  243. return
  244. }
  245. ar := a.Len()
  246. br := b.Len()
  247. if ar != br {
  248. panic(ErrShape)
  249. }
  250. var amat, bmat blas64.Vector
  251. fast := true
  252. aU, _ := untranspose(a)
  253. if rv, ok := aU.(RawVectorer); ok {
  254. amat = rv.RawVector()
  255. if v != a {
  256. v.checkOverlap(amat)
  257. }
  258. } else {
  259. fast = false
  260. }
  261. bU, _ := untranspose(b)
  262. if rv, ok := bU.(RawVectorer); ok {
  263. bmat = rv.RawVector()
  264. if v != b {
  265. v.checkOverlap(bmat)
  266. }
  267. } else {
  268. fast = false
  269. }
  270. v.reuseAs(ar)
  271. switch {
  272. case alpha == 0: // v <- a
  273. if v == a {
  274. return
  275. }
  276. v.CopyVec(a)
  277. case v == a && v == b: // v <- v + alpha * v = (alpha + 1) * v
  278. blas64.Scal(alpha+1, v.mat)
  279. case !fast: // v <- a + alpha * b without blas64 support.
  280. for i := 0; i < ar; i++ {
  281. v.setVec(i, a.AtVec(i)+alpha*b.AtVec(i))
  282. }
  283. case v == a && v != b: // v <- v + alpha * b
  284. if v.mat.Inc == 1 && bmat.Inc == 1 {
  285. // Fast path for a common case.
  286. f64.AxpyUnitaryTo(v.mat.Data, alpha, bmat.Data, amat.Data)
  287. } else {
  288. f64.AxpyInc(alpha, bmat.Data, v.mat.Data,
  289. uintptr(ar), uintptr(bmat.Inc), uintptr(v.mat.Inc), 0, 0)
  290. }
  291. default: // v <- a + alpha * b or v <- a + alpha * v
  292. if v.mat.Inc == 1 && amat.Inc == 1 && bmat.Inc == 1 {
  293. // Fast path for a common case.
  294. f64.AxpyUnitaryTo(v.mat.Data, alpha, bmat.Data, amat.Data)
  295. } else {
  296. f64.AxpyIncTo(v.mat.Data, uintptr(v.mat.Inc), 0,
  297. alpha, bmat.Data, amat.Data,
  298. uintptr(ar), uintptr(bmat.Inc), uintptr(amat.Inc), 0, 0)
  299. }
  300. }
  301. }
  302. // AddVec adds the vectors a and b, placing the result in the receiver.
  303. func (v *VecDense) AddVec(a, b Vector) {
  304. ar := a.Len()
  305. br := b.Len()
  306. if ar != br {
  307. panic(ErrShape)
  308. }
  309. v.reuseAs(ar)
  310. aU, _ := untranspose(a)
  311. bU, _ := untranspose(b)
  312. if arv, ok := aU.(RawVectorer); ok {
  313. if brv, ok := bU.(RawVectorer); ok {
  314. amat := arv.RawVector()
  315. bmat := brv.RawVector()
  316. if v != a {
  317. v.checkOverlap(amat)
  318. }
  319. if v != b {
  320. v.checkOverlap(bmat)
  321. }
  322. if v.mat.Inc == 1 && amat.Inc == 1 && bmat.Inc == 1 {
  323. // Fast path for a common case.
  324. f64.AxpyUnitaryTo(v.mat.Data, 1, bmat.Data, amat.Data)
  325. return
  326. }
  327. f64.AxpyIncTo(v.mat.Data, uintptr(v.mat.Inc), 0,
  328. 1, bmat.Data, amat.Data,
  329. uintptr(ar), uintptr(bmat.Inc), uintptr(amat.Inc), 0, 0)
  330. return
  331. }
  332. }
  333. for i := 0; i < ar; i++ {
  334. v.setVec(i, a.AtVec(i)+b.AtVec(i))
  335. }
  336. }
  337. // SubVec subtracts the vector b from a, placing the result in the receiver.
  338. func (v *VecDense) SubVec(a, b Vector) {
  339. ar := a.Len()
  340. br := b.Len()
  341. if ar != br {
  342. panic(ErrShape)
  343. }
  344. v.reuseAs(ar)
  345. aU, _ := untranspose(a)
  346. bU, _ := untranspose(b)
  347. if arv, ok := aU.(RawVectorer); ok {
  348. if brv, ok := bU.(RawVectorer); ok {
  349. amat := arv.RawVector()
  350. bmat := brv.RawVector()
  351. if v != a {
  352. v.checkOverlap(amat)
  353. }
  354. if v != b {
  355. v.checkOverlap(bmat)
  356. }
  357. if v.mat.Inc == 1 && amat.Inc == 1 && bmat.Inc == 1 {
  358. // Fast path for a common case.
  359. f64.AxpyUnitaryTo(v.mat.Data, -1, bmat.Data, amat.Data)
  360. return
  361. }
  362. f64.AxpyIncTo(v.mat.Data, uintptr(v.mat.Inc), 0,
  363. -1, bmat.Data, amat.Data,
  364. uintptr(ar), uintptr(bmat.Inc), uintptr(amat.Inc), 0, 0)
  365. return
  366. }
  367. }
  368. for i := 0; i < ar; i++ {
  369. v.setVec(i, a.AtVec(i)-b.AtVec(i))
  370. }
  371. }
  372. // MulElemVec performs element-wise multiplication of a and b, placing the result
  373. // in the receiver.
  374. func (v *VecDense) MulElemVec(a, b Vector) {
  375. ar := a.Len()
  376. br := b.Len()
  377. if ar != br {
  378. panic(ErrShape)
  379. }
  380. v.reuseAs(ar)
  381. aU, _ := untranspose(a)
  382. bU, _ := untranspose(b)
  383. if arv, ok := aU.(RawVectorer); ok {
  384. if brv, ok := bU.(RawVectorer); ok {
  385. amat := arv.RawVector()
  386. bmat := brv.RawVector()
  387. if v != a {
  388. v.checkOverlap(amat)
  389. }
  390. if v != b {
  391. v.checkOverlap(bmat)
  392. }
  393. if v.mat.Inc == 1 && amat.Inc == 1 && bmat.Inc == 1 {
  394. // Fast path for a common case.
  395. for i, a := range amat.Data {
  396. v.mat.Data[i] = a * bmat.Data[i]
  397. }
  398. return
  399. }
  400. var ia, ib int
  401. for i := 0; i < ar; i++ {
  402. v.setVec(i, amat.Data[ia]*bmat.Data[ib])
  403. ia += amat.Inc
  404. ib += bmat.Inc
  405. }
  406. return
  407. }
  408. }
  409. for i := 0; i < ar; i++ {
  410. v.setVec(i, a.AtVec(i)*b.AtVec(i))
  411. }
  412. }
  413. // DivElemVec performs element-wise division of a by b, placing the result
  414. // in the receiver.
  415. func (v *VecDense) DivElemVec(a, b Vector) {
  416. ar := a.Len()
  417. br := b.Len()
  418. if ar != br {
  419. panic(ErrShape)
  420. }
  421. v.reuseAs(ar)
  422. aU, _ := untranspose(a)
  423. bU, _ := untranspose(b)
  424. if arv, ok := aU.(RawVectorer); ok {
  425. if brv, ok := bU.(RawVectorer); ok {
  426. amat := arv.RawVector()
  427. bmat := brv.RawVector()
  428. if v != a {
  429. v.checkOverlap(amat)
  430. }
  431. if v != b {
  432. v.checkOverlap(bmat)
  433. }
  434. if v.mat.Inc == 1 && amat.Inc == 1 && bmat.Inc == 1 {
  435. // Fast path for a common case.
  436. for i, a := range amat.Data {
  437. v.setVec(i, a/bmat.Data[i])
  438. }
  439. return
  440. }
  441. var ia, ib int
  442. for i := 0; i < ar; i++ {
  443. v.setVec(i, amat.Data[ia]/bmat.Data[ib])
  444. ia += amat.Inc
  445. ib += bmat.Inc
  446. }
  447. }
  448. }
  449. for i := 0; i < ar; i++ {
  450. v.setVec(i, a.AtVec(i)/b.AtVec(i))
  451. }
  452. }
  453. // MulVec computes a * b. The result is stored into the receiver.
  454. // MulVec panics if the number of columns in a does not equal the number of rows in b
  455. // or if the number of columns in b does not equal 1.
  456. func (v *VecDense) MulVec(a Matrix, b Vector) {
  457. r, c := a.Dims()
  458. br, bc := b.Dims()
  459. if c != br || bc != 1 {
  460. panic(ErrShape)
  461. }
  462. aU, trans := untranspose(a)
  463. var bmat blas64.Vector
  464. fast := true
  465. bU, _ := untranspose(b)
  466. if rv, ok := bU.(RawVectorer); ok {
  467. bmat = rv.RawVector()
  468. if v != b {
  469. v.checkOverlap(bmat)
  470. }
  471. } else {
  472. fast = false
  473. }
  474. v.reuseAs(r)
  475. var restore func()
  476. if v == aU {
  477. v, restore = v.isolatedWorkspace(aU.(*VecDense))
  478. defer restore()
  479. } else if v == b {
  480. v, restore = v.isolatedWorkspace(b)
  481. defer restore()
  482. }
  483. // TODO(kortschak): Improve the non-fast paths.
  484. switch aU := aU.(type) {
  485. case Vector:
  486. if b.Len() == 1 {
  487. // {n,1} x {1,1}
  488. v.ScaleVec(b.AtVec(0), aU)
  489. return
  490. }
  491. // {1,n} x {n,1}
  492. if fast {
  493. if rv, ok := aU.(RawVectorer); ok {
  494. amat := rv.RawVector()
  495. if v != aU {
  496. v.checkOverlap(amat)
  497. }
  498. if amat.Inc == 1 && bmat.Inc == 1 {
  499. // Fast path for a common case.
  500. v.setVec(0, f64.DotUnitary(amat.Data, bmat.Data))
  501. return
  502. }
  503. v.setVec(0, f64.DotInc(amat.Data, bmat.Data,
  504. uintptr(c), uintptr(amat.Inc), uintptr(bmat.Inc), 0, 0))
  505. return
  506. }
  507. }
  508. var sum float64
  509. for i := 0; i < c; i++ {
  510. sum += aU.AtVec(i) * b.AtVec(i)
  511. }
  512. v.setVec(0, sum)
  513. return
  514. case RawSymmetricer:
  515. if fast {
  516. amat := aU.RawSymmetric()
  517. // We don't know that a is a *SymDense, so make
  518. // a temporary SymDense to check overlap.
  519. (&SymDense{mat: amat}).checkOverlap(v.asGeneral())
  520. blas64.Symv(1, amat, bmat, 0, v.mat)
  521. return
  522. }
  523. case RawTriangular:
  524. v.CopyVec(b)
  525. amat := aU.RawTriangular()
  526. // We don't know that a is a *TriDense, so make
  527. // a temporary TriDense to check overlap.
  528. (&TriDense{mat: amat}).checkOverlap(v.asGeneral())
  529. ta := blas.NoTrans
  530. if trans {
  531. ta = blas.Trans
  532. }
  533. blas64.Trmv(ta, amat, v.mat)
  534. case RawMatrixer:
  535. if fast {
  536. amat := aU.RawMatrix()
  537. // We don't know that a is a *Dense, so make
  538. // a temporary Dense to check overlap.
  539. (&Dense{mat: amat}).checkOverlap(v.asGeneral())
  540. t := blas.NoTrans
  541. if trans {
  542. t = blas.Trans
  543. }
  544. blas64.Gemv(t, 1, amat, bmat, 0, v.mat)
  545. return
  546. }
  547. default:
  548. if fast {
  549. for i := 0; i < r; i++ {
  550. var f float64
  551. for j := 0; j < c; j++ {
  552. f += a.At(i, j) * bmat.Data[j*bmat.Inc]
  553. }
  554. v.setVec(i, f)
  555. }
  556. return
  557. }
  558. }
  559. for i := 0; i < r; i++ {
  560. var f float64
  561. for j := 0; j < c; j++ {
  562. f += a.At(i, j) * b.AtVec(j)
  563. }
  564. v.setVec(i, f)
  565. }
  566. }
  567. // reuseAs resizes an empty vector to a r×1 vector,
  568. // or checks that a non-empty matrix is r×1.
  569. func (v *VecDense) reuseAs(r int) {
  570. if r == 0 {
  571. panic(ErrZeroLength)
  572. }
  573. if v.IsZero() {
  574. v.mat = blas64.Vector{
  575. N: r,
  576. Inc: 1,
  577. Data: use(v.mat.Data, r),
  578. }
  579. return
  580. }
  581. if r != v.mat.N {
  582. panic(ErrShape)
  583. }
  584. }
  585. // IsZero returns whether the receiver is zero-sized. Zero-sized vectors can be the
  586. // receiver for size-restricted operations. VecDenses can be zeroed using Reset.
  587. func (v *VecDense) IsZero() bool {
  588. // It must be the case that v.Dims() returns
  589. // zeros in this case. See comment in Reset().
  590. return v.mat.Inc == 0
  591. }
  592. func (v *VecDense) isolatedWorkspace(a Vector) (n *VecDense, restore func()) {
  593. l := a.Len()
  594. if l == 0 {
  595. panic(ErrZeroLength)
  596. }
  597. n = getWorkspaceVec(l, false)
  598. return n, func() {
  599. v.CopyVec(n)
  600. putWorkspaceVec(n)
  601. }
  602. }
  603. // asDense returns a Dense representation of the receiver with the same
  604. // underlying data.
  605. func (v *VecDense) asDense() *Dense {
  606. return &Dense{
  607. mat: v.asGeneral(),
  608. capRows: v.mat.N,
  609. capCols: 1,
  610. }
  611. }
  612. // asGeneral returns a blas64.General representation of the receiver with the
  613. // same underlying data.
  614. func (v *VecDense) asGeneral() blas64.General {
  615. return blas64.General{
  616. Rows: v.mat.N,
  617. Cols: 1,
  618. Stride: v.mat.Inc,
  619. Data: v.mat.Data,
  620. }
  621. }
  622. // ColViewOf reflects the column j of the RawMatrixer m, into the receiver
  623. // backed by the same underlying data. The length of the receiver must either be
  624. // zero or match the number of rows in m.
  625. func (v *VecDense) ColViewOf(m RawMatrixer, j int) {
  626. rm := m.RawMatrix()
  627. if j >= rm.Cols || j < 0 {
  628. panic(ErrColAccess)
  629. }
  630. if !v.IsZero() && v.mat.N != rm.Rows {
  631. panic(ErrShape)
  632. }
  633. v.mat.Inc = rm.Stride
  634. v.mat.Data = rm.Data[j : (rm.Rows-1)*rm.Stride+j+1]
  635. v.mat.N = rm.Rows
  636. }
  637. // RowViewOf reflects the row i of the RawMatrixer m, into the receiver
  638. // backed by the same underlying data. The length of the receiver must either be
  639. // zero or match the number of columns in m.
  640. func (v *VecDense) RowViewOf(m RawMatrixer, i int) {
  641. rm := m.RawMatrix()
  642. if i >= rm.Rows || i < 0 {
  643. panic(ErrRowAccess)
  644. }
  645. if !v.IsZero() && v.mat.N != rm.Cols {
  646. panic(ErrShape)
  647. }
  648. v.mat.Inc = 1
  649. v.mat.Data = rm.Data[i*rm.Stride : i*rm.Stride+rm.Cols]
  650. v.mat.N = rm.Cols
  651. }