level3cmplx64.go 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748
  1. // Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.
  2. // Copyright ©2019 The Gonum Authors. All rights reserved.
  3. // Use of this source code is governed by a BSD-style
  4. // license that can be found in the LICENSE file.
  5. package gonum
  6. import (
  7. cmplx "gonum.org/v1/gonum/internal/cmplx64"
  8. "gonum.org/v1/gonum/blas"
  9. "gonum.org/v1/gonum/internal/asm/c64"
  10. )
  11. var _ blas.Complex64Level3 = Implementation{}
  12. // Cgemm performs one of the matrix-matrix operations
  13. // C = alpha * op(A) * op(B) + beta * C
  14. // where op(X) is one of
  15. // op(X) = X or op(X) = Xᵀ or op(X) = Xᴴ,
  16. // alpha and beta are scalars, and A, B and C are matrices, with op(A) an m×k matrix,
  17. // op(B) a k×n matrix and C an m×n matrix.
  18. //
  19. // Complex64 implementations are autogenerated and not directly tested.
  20. func (Implementation) Cgemm(tA, tB blas.Transpose, m, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) {
  21. switch tA {
  22. default:
  23. panic(badTranspose)
  24. case blas.NoTrans, blas.Trans, blas.ConjTrans:
  25. }
  26. switch tB {
  27. default:
  28. panic(badTranspose)
  29. case blas.NoTrans, blas.Trans, blas.ConjTrans:
  30. }
  31. switch {
  32. case m < 0:
  33. panic(mLT0)
  34. case n < 0:
  35. panic(nLT0)
  36. case k < 0:
  37. panic(kLT0)
  38. }
  39. rowA, colA := m, k
  40. if tA != blas.NoTrans {
  41. rowA, colA = k, m
  42. }
  43. if lda < max(1, colA) {
  44. panic(badLdA)
  45. }
  46. rowB, colB := k, n
  47. if tB != blas.NoTrans {
  48. rowB, colB = n, k
  49. }
  50. if ldb < max(1, colB) {
  51. panic(badLdB)
  52. }
  53. if ldc < max(1, n) {
  54. panic(badLdC)
  55. }
  56. // Quick return if possible.
  57. if m == 0 || n == 0 {
  58. return
  59. }
  60. // For zero matrix size the following slice length checks are trivially satisfied.
  61. if len(a) < (rowA-1)*lda+colA {
  62. panic(shortA)
  63. }
  64. if len(b) < (rowB-1)*ldb+colB {
  65. panic(shortB)
  66. }
  67. if len(c) < (m-1)*ldc+n {
  68. panic(shortC)
  69. }
  70. // Quick return if possible.
  71. if (alpha == 0 || k == 0) && beta == 1 {
  72. return
  73. }
  74. if alpha == 0 {
  75. if beta == 0 {
  76. for i := 0; i < m; i++ {
  77. for j := 0; j < n; j++ {
  78. c[i*ldc+j] = 0
  79. }
  80. }
  81. } else {
  82. for i := 0; i < m; i++ {
  83. for j := 0; j < n; j++ {
  84. c[i*ldc+j] *= beta
  85. }
  86. }
  87. }
  88. return
  89. }
  90. switch tA {
  91. case blas.NoTrans:
  92. switch tB {
  93. case blas.NoTrans:
  94. // Form C = alpha * A * B + beta * C.
  95. for i := 0; i < m; i++ {
  96. switch {
  97. case beta == 0:
  98. for j := 0; j < n; j++ {
  99. c[i*ldc+j] = 0
  100. }
  101. case beta != 1:
  102. for j := 0; j < n; j++ {
  103. c[i*ldc+j] *= beta
  104. }
  105. }
  106. for l := 0; l < k; l++ {
  107. tmp := alpha * a[i*lda+l]
  108. for j := 0; j < n; j++ {
  109. c[i*ldc+j] += tmp * b[l*ldb+j]
  110. }
  111. }
  112. }
  113. case blas.Trans:
  114. // Form C = alpha * A * Bᵀ + beta * C.
  115. for i := 0; i < m; i++ {
  116. switch {
  117. case beta == 0:
  118. for j := 0; j < n; j++ {
  119. c[i*ldc+j] = 0
  120. }
  121. case beta != 1:
  122. for j := 0; j < n; j++ {
  123. c[i*ldc+j] *= beta
  124. }
  125. }
  126. for l := 0; l < k; l++ {
  127. tmp := alpha * a[i*lda+l]
  128. for j := 0; j < n; j++ {
  129. c[i*ldc+j] += tmp * b[j*ldb+l]
  130. }
  131. }
  132. }
  133. case blas.ConjTrans:
  134. // Form C = alpha * A * Bᴴ + beta * C.
  135. for i := 0; i < m; i++ {
  136. switch {
  137. case beta == 0:
  138. for j := 0; j < n; j++ {
  139. c[i*ldc+j] = 0
  140. }
  141. case beta != 1:
  142. for j := 0; j < n; j++ {
  143. c[i*ldc+j] *= beta
  144. }
  145. }
  146. for l := 0; l < k; l++ {
  147. tmp := alpha * a[i*lda+l]
  148. for j := 0; j < n; j++ {
  149. c[i*ldc+j] += tmp * cmplx.Conj(b[j*ldb+l])
  150. }
  151. }
  152. }
  153. }
  154. case blas.Trans:
  155. switch tB {
  156. case blas.NoTrans:
  157. // Form C = alpha * Aᵀ * B + beta * C.
  158. for i := 0; i < m; i++ {
  159. for j := 0; j < n; j++ {
  160. var tmp complex64
  161. for l := 0; l < k; l++ {
  162. tmp += a[l*lda+i] * b[l*ldb+j]
  163. }
  164. if beta == 0 {
  165. c[i*ldc+j] = alpha * tmp
  166. } else {
  167. c[i*ldc+j] = alpha*tmp + beta*c[i*ldc+j]
  168. }
  169. }
  170. }
  171. case blas.Trans:
  172. // Form C = alpha * Aᵀ * Bᵀ + beta * C.
  173. for i := 0; i < m; i++ {
  174. for j := 0; j < n; j++ {
  175. var tmp complex64
  176. for l := 0; l < k; l++ {
  177. tmp += a[l*lda+i] * b[j*ldb+l]
  178. }
  179. if beta == 0 {
  180. c[i*ldc+j] = alpha * tmp
  181. } else {
  182. c[i*ldc+j] = alpha*tmp + beta*c[i*ldc+j]
  183. }
  184. }
  185. }
  186. case blas.ConjTrans:
  187. // Form C = alpha * Aᵀ * Bᴴ + beta * C.
  188. for i := 0; i < m; i++ {
  189. for j := 0; j < n; j++ {
  190. var tmp complex64
  191. for l := 0; l < k; l++ {
  192. tmp += a[l*lda+i] * cmplx.Conj(b[j*ldb+l])
  193. }
  194. if beta == 0 {
  195. c[i*ldc+j] = alpha * tmp
  196. } else {
  197. c[i*ldc+j] = alpha*tmp + beta*c[i*ldc+j]
  198. }
  199. }
  200. }
  201. }
  202. case blas.ConjTrans:
  203. switch tB {
  204. case blas.NoTrans:
  205. // Form C = alpha * Aᴴ * B + beta * C.
  206. for i := 0; i < m; i++ {
  207. for j := 0; j < n; j++ {
  208. var tmp complex64
  209. for l := 0; l < k; l++ {
  210. tmp += cmplx.Conj(a[l*lda+i]) * b[l*ldb+j]
  211. }
  212. if beta == 0 {
  213. c[i*ldc+j] = alpha * tmp
  214. } else {
  215. c[i*ldc+j] = alpha*tmp + beta*c[i*ldc+j]
  216. }
  217. }
  218. }
  219. case blas.Trans:
  220. // Form C = alpha * Aᴴ * Bᵀ + beta * C.
  221. for i := 0; i < m; i++ {
  222. for j := 0; j < n; j++ {
  223. var tmp complex64
  224. for l := 0; l < k; l++ {
  225. tmp += cmplx.Conj(a[l*lda+i]) * b[j*ldb+l]
  226. }
  227. if beta == 0 {
  228. c[i*ldc+j] = alpha * tmp
  229. } else {
  230. c[i*ldc+j] = alpha*tmp + beta*c[i*ldc+j]
  231. }
  232. }
  233. }
  234. case blas.ConjTrans:
  235. // Form C = alpha * Aᴴ * Bᴴ + beta * C.
  236. for i := 0; i < m; i++ {
  237. for j := 0; j < n; j++ {
  238. var tmp complex64
  239. for l := 0; l < k; l++ {
  240. tmp += cmplx.Conj(a[l*lda+i]) * cmplx.Conj(b[j*ldb+l])
  241. }
  242. if beta == 0 {
  243. c[i*ldc+j] = alpha * tmp
  244. } else {
  245. c[i*ldc+j] = alpha*tmp + beta*c[i*ldc+j]
  246. }
  247. }
  248. }
  249. }
  250. }
  251. }
  252. // Chemm performs one of the matrix-matrix operations
  253. // C = alpha*A*B + beta*C if side == blas.Left
  254. // C = alpha*B*A + beta*C if side == blas.Right
  255. // where alpha and beta are scalars, A is an m×m or n×n hermitian matrix and B
  256. // and C are m×n matrices. The imaginary parts of the diagonal elements of A are
  257. // assumed to be zero.
  258. //
  259. // Complex64 implementations are autogenerated and not directly tested.
  260. func (Implementation) Chemm(side blas.Side, uplo blas.Uplo, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) {
  261. na := m
  262. if side == blas.Right {
  263. na = n
  264. }
  265. switch {
  266. case side != blas.Left && side != blas.Right:
  267. panic(badSide)
  268. case uplo != blas.Lower && uplo != blas.Upper:
  269. panic(badUplo)
  270. case m < 0:
  271. panic(mLT0)
  272. case n < 0:
  273. panic(nLT0)
  274. case lda < max(1, na):
  275. panic(badLdA)
  276. case ldb < max(1, n):
  277. panic(badLdB)
  278. case ldc < max(1, n):
  279. panic(badLdC)
  280. }
  281. // Quick return if possible.
  282. if m == 0 || n == 0 {
  283. return
  284. }
  285. // For zero matrix size the following slice length checks are trivially satisfied.
  286. if len(a) < lda*(na-1)+na {
  287. panic(shortA)
  288. }
  289. if len(b) < ldb*(m-1)+n {
  290. panic(shortB)
  291. }
  292. if len(c) < ldc*(m-1)+n {
  293. panic(shortC)
  294. }
  295. // Quick return if possible.
  296. if alpha == 0 && beta == 1 {
  297. return
  298. }
  299. if alpha == 0 {
  300. if beta == 0 {
  301. for i := 0; i < m; i++ {
  302. ci := c[i*ldc : i*ldc+n]
  303. for j := range ci {
  304. ci[j] = 0
  305. }
  306. }
  307. } else {
  308. for i := 0; i < m; i++ {
  309. ci := c[i*ldc : i*ldc+n]
  310. c64.ScalUnitary(beta, ci)
  311. }
  312. }
  313. return
  314. }
  315. if side == blas.Left {
  316. // Form C = alpha*A*B + beta*C.
  317. for i := 0; i < m; i++ {
  318. atmp := alpha * complex(real(a[i*lda+i]), 0)
  319. bi := b[i*ldb : i*ldb+n]
  320. ci := c[i*ldc : i*ldc+n]
  321. if beta == 0 {
  322. for j, bij := range bi {
  323. ci[j] = atmp * bij
  324. }
  325. } else {
  326. for j, bij := range bi {
  327. ci[j] = atmp*bij + beta*ci[j]
  328. }
  329. }
  330. if uplo == blas.Upper {
  331. for k := 0; k < i; k++ {
  332. atmp = alpha * cmplx.Conj(a[k*lda+i])
  333. c64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ci)
  334. }
  335. for k := i + 1; k < m; k++ {
  336. atmp = alpha * a[i*lda+k]
  337. c64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ci)
  338. }
  339. } else {
  340. for k := 0; k < i; k++ {
  341. atmp = alpha * a[i*lda+k]
  342. c64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ci)
  343. }
  344. for k := i + 1; k < m; k++ {
  345. atmp = alpha * cmplx.Conj(a[k*lda+i])
  346. c64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ci)
  347. }
  348. }
  349. }
  350. } else {
  351. // Form C = alpha*B*A + beta*C.
  352. if uplo == blas.Upper {
  353. for i := 0; i < m; i++ {
  354. for j := n - 1; j >= 0; j-- {
  355. abij := alpha * b[i*ldb+j]
  356. aj := a[j*lda+j+1 : j*lda+n]
  357. bi := b[i*ldb+j+1 : i*ldb+n]
  358. ci := c[i*ldc+j+1 : i*ldc+n]
  359. var tmp complex64
  360. for k, ajk := range aj {
  361. ci[k] += abij * ajk
  362. tmp += bi[k] * cmplx.Conj(ajk)
  363. }
  364. ajj := complex(real(a[j*lda+j]), 0)
  365. if beta == 0 {
  366. c[i*ldc+j] = abij*ajj + alpha*tmp
  367. } else {
  368. c[i*ldc+j] = abij*ajj + alpha*tmp + beta*c[i*ldc+j]
  369. }
  370. }
  371. }
  372. } else {
  373. for i := 0; i < m; i++ {
  374. for j := 0; j < n; j++ {
  375. abij := alpha * b[i*ldb+j]
  376. aj := a[j*lda : j*lda+j]
  377. bi := b[i*ldb : i*ldb+j]
  378. ci := c[i*ldc : i*ldc+j]
  379. var tmp complex64
  380. for k, ajk := range aj {
  381. ci[k] += abij * ajk
  382. tmp += bi[k] * cmplx.Conj(ajk)
  383. }
  384. ajj := complex(real(a[j*lda+j]), 0)
  385. if beta == 0 {
  386. c[i*ldc+j] = abij*ajj + alpha*tmp
  387. } else {
  388. c[i*ldc+j] = abij*ajj + alpha*tmp + beta*c[i*ldc+j]
  389. }
  390. }
  391. }
  392. }
  393. }
  394. }
  395. // Cherk performs one of the hermitian rank-k operations
  396. // C = alpha*A*Aᴴ + beta*C if trans == blas.NoTrans
  397. // C = alpha*Aᴴ*A + beta*C if trans == blas.ConjTrans
  398. // where alpha and beta are real scalars, C is an n×n hermitian matrix and A is
  399. // an n×k matrix in the first case and a k×n matrix in the second case.
  400. //
  401. // The imaginary parts of the diagonal elements of C are assumed to be zero, and
  402. // on return they will be set to zero.
  403. //
  404. // Complex64 implementations are autogenerated and not directly tested.
  405. func (Implementation) Cherk(uplo blas.Uplo, trans blas.Transpose, n, k int, alpha float32, a []complex64, lda int, beta float32, c []complex64, ldc int) {
  406. var rowA, colA int
  407. switch trans {
  408. default:
  409. panic(badTranspose)
  410. case blas.NoTrans:
  411. rowA, colA = n, k
  412. case blas.ConjTrans:
  413. rowA, colA = k, n
  414. }
  415. switch {
  416. case uplo != blas.Lower && uplo != blas.Upper:
  417. panic(badUplo)
  418. case n < 0:
  419. panic(nLT0)
  420. case k < 0:
  421. panic(kLT0)
  422. case lda < max(1, colA):
  423. panic(badLdA)
  424. case ldc < max(1, n):
  425. panic(badLdC)
  426. }
  427. // Quick return if possible.
  428. if n == 0 {
  429. return
  430. }
  431. // For zero matrix size the following slice length checks are trivially satisfied.
  432. if len(a) < (rowA-1)*lda+colA {
  433. panic(shortA)
  434. }
  435. if len(c) < (n-1)*ldc+n {
  436. panic(shortC)
  437. }
  438. // Quick return if possible.
  439. if (alpha == 0 || k == 0) && beta == 1 {
  440. return
  441. }
  442. if alpha == 0 {
  443. if uplo == blas.Upper {
  444. if beta == 0 {
  445. for i := 0; i < n; i++ {
  446. ci := c[i*ldc+i : i*ldc+n]
  447. for j := range ci {
  448. ci[j] = 0
  449. }
  450. }
  451. } else {
  452. for i := 0; i < n; i++ {
  453. ci := c[i*ldc+i : i*ldc+n]
  454. ci[0] = complex(beta*real(ci[0]), 0)
  455. if i != n-1 {
  456. c64.SscalUnitary(beta, ci[1:])
  457. }
  458. }
  459. }
  460. } else {
  461. if beta == 0 {
  462. for i := 0; i < n; i++ {
  463. ci := c[i*ldc : i*ldc+i+1]
  464. for j := range ci {
  465. ci[j] = 0
  466. }
  467. }
  468. } else {
  469. for i := 0; i < n; i++ {
  470. ci := c[i*ldc : i*ldc+i+1]
  471. if i != 0 {
  472. c64.SscalUnitary(beta, ci[:i])
  473. }
  474. ci[i] = complex(beta*real(ci[i]), 0)
  475. }
  476. }
  477. }
  478. return
  479. }
  480. calpha := complex(alpha, 0)
  481. if trans == blas.NoTrans {
  482. // Form C = alpha*A*Aᴴ + beta*C.
  483. cbeta := complex(beta, 0)
  484. if uplo == blas.Upper {
  485. for i := 0; i < n; i++ {
  486. ci := c[i*ldc+i : i*ldc+n]
  487. ai := a[i*lda : i*lda+k]
  488. switch {
  489. case beta == 0:
  490. // Handle the i-th diagonal element of C.
  491. ci[0] = complex(alpha*real(c64.DotcUnitary(ai, ai)), 0)
  492. // Handle the remaining elements on the i-th row of C.
  493. for jc := range ci[1:] {
  494. j := i + 1 + jc
  495. ci[jc+1] = calpha * c64.DotcUnitary(a[j*lda:j*lda+k], ai)
  496. }
  497. case beta != 1:
  498. cii := calpha*c64.DotcUnitary(ai, ai) + cbeta*ci[0]
  499. ci[0] = complex(real(cii), 0)
  500. for jc, cij := range ci[1:] {
  501. j := i + 1 + jc
  502. ci[jc+1] = calpha*c64.DotcUnitary(a[j*lda:j*lda+k], ai) + cbeta*cij
  503. }
  504. default:
  505. cii := calpha*c64.DotcUnitary(ai, ai) + ci[0]
  506. ci[0] = complex(real(cii), 0)
  507. for jc, cij := range ci[1:] {
  508. j := i + 1 + jc
  509. ci[jc+1] = calpha*c64.DotcUnitary(a[j*lda:j*lda+k], ai) + cij
  510. }
  511. }
  512. }
  513. } else {
  514. for i := 0; i < n; i++ {
  515. ci := c[i*ldc : i*ldc+i+1]
  516. ai := a[i*lda : i*lda+k]
  517. switch {
  518. case beta == 0:
  519. // Handle the first i-1 elements on the i-th row of C.
  520. for j := range ci[:i] {
  521. ci[j] = calpha * c64.DotcUnitary(a[j*lda:j*lda+k], ai)
  522. }
  523. // Handle the i-th diagonal element of C.
  524. ci[i] = complex(alpha*real(c64.DotcUnitary(ai, ai)), 0)
  525. case beta != 1:
  526. for j, cij := range ci[:i] {
  527. ci[j] = calpha*c64.DotcUnitary(a[j*lda:j*lda+k], ai) + cbeta*cij
  528. }
  529. cii := calpha*c64.DotcUnitary(ai, ai) + cbeta*ci[i]
  530. ci[i] = complex(real(cii), 0)
  531. default:
  532. for j, cij := range ci[:i] {
  533. ci[j] = calpha*c64.DotcUnitary(a[j*lda:j*lda+k], ai) + cij
  534. }
  535. cii := calpha*c64.DotcUnitary(ai, ai) + ci[i]
  536. ci[i] = complex(real(cii), 0)
  537. }
  538. }
  539. }
  540. } else {
  541. // Form C = alpha*Aᴴ*A + beta*C.
  542. if uplo == blas.Upper {
  543. for i := 0; i < n; i++ {
  544. ci := c[i*ldc+i : i*ldc+n]
  545. switch {
  546. case beta == 0:
  547. for jc := range ci {
  548. ci[jc] = 0
  549. }
  550. case beta != 1:
  551. c64.SscalUnitary(beta, ci)
  552. ci[0] = complex(real(ci[0]), 0)
  553. default:
  554. ci[0] = complex(real(ci[0]), 0)
  555. }
  556. for j := 0; j < k; j++ {
  557. aji := cmplx.Conj(a[j*lda+i])
  558. if aji != 0 {
  559. c64.AxpyUnitary(calpha*aji, a[j*lda+i:j*lda+n], ci)
  560. }
  561. }
  562. c[i*ldc+i] = complex(real(c[i*ldc+i]), 0)
  563. }
  564. } else {
  565. for i := 0; i < n; i++ {
  566. ci := c[i*ldc : i*ldc+i+1]
  567. switch {
  568. case beta == 0:
  569. for j := range ci {
  570. ci[j] = 0
  571. }
  572. case beta != 1:
  573. c64.SscalUnitary(beta, ci)
  574. ci[i] = complex(real(ci[i]), 0)
  575. default:
  576. ci[i] = complex(real(ci[i]), 0)
  577. }
  578. for j := 0; j < k; j++ {
  579. aji := cmplx.Conj(a[j*lda+i])
  580. if aji != 0 {
  581. c64.AxpyUnitary(calpha*aji, a[j*lda:j*lda+i+1], ci)
  582. }
  583. }
  584. c[i*ldc+i] = complex(real(c[i*ldc+i]), 0)
  585. }
  586. }
  587. }
  588. }
  589. // Cher2k performs one of the hermitian rank-2k operations
  590. // C = alpha*A*Bᴴ + conj(alpha)*B*Aᴴ + beta*C if trans == blas.NoTrans
  591. // C = alpha*Aᴴ*B + conj(alpha)*Bᴴ*A + beta*C if trans == blas.ConjTrans
  592. // where alpha and beta are scalars with beta real, C is an n×n hermitian matrix
  593. // and A and B are n×k matrices in the first case and k×n matrices in the second case.
  594. //
  595. // The imaginary parts of the diagonal elements of C are assumed to be zero, and
  596. // on return they will be set to zero.
  597. //
  598. // Complex64 implementations are autogenerated and not directly tested.
  599. func (Implementation) Cher2k(uplo blas.Uplo, trans blas.Transpose, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta float32, c []complex64, ldc int) {
  600. var row, col int
  601. switch trans {
  602. default:
  603. panic(badTranspose)
  604. case blas.NoTrans:
  605. row, col = n, k
  606. case blas.ConjTrans:
  607. row, col = k, n
  608. }
  609. switch {
  610. case uplo != blas.Lower && uplo != blas.Upper:
  611. panic(badUplo)
  612. case n < 0:
  613. panic(nLT0)
  614. case k < 0:
  615. panic(kLT0)
  616. case lda < max(1, col):
  617. panic(badLdA)
  618. case ldb < max(1, col):
  619. panic(badLdB)
  620. case ldc < max(1, n):
  621. panic(badLdC)
  622. }
  623. // Quick return if possible.
  624. if n == 0 {
  625. return
  626. }
  627. // For zero matrix size the following slice length checks are trivially satisfied.
  628. if len(a) < (row-1)*lda+col {
  629. panic(shortA)
  630. }
  631. if len(b) < (row-1)*ldb+col {
  632. panic(shortB)
  633. }
  634. if len(c) < (n-1)*ldc+n {
  635. panic(shortC)
  636. }
  637. // Quick return if possible.
  638. if (alpha == 0 || k == 0) && beta == 1 {
  639. return
  640. }
  641. if alpha == 0 {
  642. if uplo == blas.Upper {
  643. if beta == 0 {
  644. for i := 0; i < n; i++ {
  645. ci := c[i*ldc+i : i*ldc+n]
  646. for j := range ci {
  647. ci[j] = 0
  648. }
  649. }
  650. } else {
  651. for i := 0; i < n; i++ {
  652. ci := c[i*ldc+i : i*ldc+n]
  653. ci[0] = complex(beta*real(ci[0]), 0)
  654. if i != n-1 {
  655. c64.SscalUnitary(beta, ci[1:])
  656. }
  657. }
  658. }
  659. } else {
  660. if beta == 0 {
  661. for i := 0; i < n; i++ {
  662. ci := c[i*ldc : i*ldc+i+1]
  663. for j := range ci {
  664. ci[j] = 0
  665. }
  666. }
  667. } else {
  668. for i := 0; i < n; i++ {
  669. ci := c[i*ldc : i*ldc+i+1]
  670. if i != 0 {
  671. c64.SscalUnitary(beta, ci[:i])
  672. }
  673. ci[i] = complex(beta*real(ci[i]), 0)
  674. }
  675. }
  676. }
  677. return
  678. }
  679. conjalpha := cmplx.Conj(alpha)
  680. cbeta := complex(beta, 0)
  681. if trans == blas.NoTrans {
  682. // Form C = alpha*A*Bᴴ + conj(alpha)*B*Aᴴ + beta*C.
  683. if uplo == blas.Upper {
  684. for i := 0; i < n; i++ {
  685. ci := c[i*ldc+i+1 : i*ldc+n]
  686. ai := a[i*lda : i*lda+k]
  687. bi := b[i*ldb : i*ldb+k]
  688. if beta == 0 {
  689. cii := alpha*c64.DotcUnitary(bi, ai) + conjalpha*c64.DotcUnitary(ai, bi)
  690. c[i*ldc+i] = complex(real(cii), 0)
  691. for jc := range ci {
  692. j := i + 1 + jc
  693. ci[jc] = alpha*c64.DotcUnitary(b[j*ldb:j*ldb+k], ai) + conjalpha*c64.DotcUnitary(a[j*lda:j*lda+k], bi)
  694. }
  695. } else {
  696. cii := alpha*c64.DotcUnitary(bi, ai) + conjalpha*c64.DotcUnitary(ai, bi) + cbeta*c[i*ldc+i]
  697. c[i*ldc+i] = complex(real(cii), 0)
  698. for jc, cij := range ci {
  699. j := i + 1 + jc
  700. ci[jc] = alpha*c64.DotcUnitary(b[j*ldb:j*ldb+k], ai) + conjalpha*c64.DotcUnitary(a[j*lda:j*lda+k], bi) + cbeta*cij
  701. }
  702. }
  703. }
  704. } else {
  705. for i := 0; i < n; i++ {
  706. ci := c[i*ldc : i*ldc+i]
  707. ai := a[i*lda : i*lda+k]
  708. bi := b[i*ldb : i*ldb+k]
  709. if beta == 0 {
  710. for j := range ci {
  711. ci[j] = alpha*c64.DotcUnitary(b[j*ldb:j*ldb+k], ai) + conjalpha*c64.DotcUnitary(a[j*lda:j*lda+k], bi)
  712. }
  713. cii := alpha*c64.DotcUnitary(bi, ai) + conjalpha*c64.DotcUnitary(ai, bi)
  714. c[i*ldc+i] = complex(real(cii), 0)
  715. } else {
  716. for j, cij := range ci {
  717. ci[j] = alpha*c64.DotcUnitary(b[j*ldb:j*ldb+k], ai) + conjalpha*c64.DotcUnitary(a[j*lda:j*lda+k], bi) + cbeta*cij
  718. }
  719. cii := alpha*c64.DotcUnitary(bi, ai) + conjalpha*c64.DotcUnitary(ai, bi) + cbeta*c[i*ldc+i]
  720. c[i*ldc+i] = complex(real(cii), 0)
  721. }
  722. }
  723. }
  724. } else {
  725. // Form C = alpha*Aᴴ*B + conj(alpha)*Bᴴ*A + beta*C.
  726. if uplo == blas.Upper {
  727. for i := 0; i < n; i++ {
  728. ci := c[i*ldc+i : i*ldc+n]
  729. switch {
  730. case beta == 0:
  731. for jc := range ci {
  732. ci[jc] = 0
  733. }
  734. case beta != 1:
  735. c64.SscalUnitary(beta, ci)
  736. ci[0] = complex(real(ci[0]), 0)
  737. default:
  738. ci[0] = complex(real(ci[0]), 0)
  739. }
  740. for j := 0; j < k; j++ {
  741. aji := a[j*lda+i]
  742. bji := b[j*ldb+i]
  743. if aji != 0 {
  744. c64.AxpyUnitary(alpha*cmplx.Conj(aji), b[j*ldb+i:j*ldb+n], ci)
  745. }
  746. if bji != 0 {
  747. c64.AxpyUnitary(conjalpha*cmplx.Conj(bji), a[j*lda+i:j*lda+n], ci)
  748. }
  749. }
  750. ci[0] = complex(real(ci[0]), 0)
  751. }
  752. } else {
  753. for i := 0; i < n; i++ {
  754. ci := c[i*ldc : i*ldc+i+1]
  755. switch {
  756. case beta == 0:
  757. for j := range ci {
  758. ci[j] = 0
  759. }
  760. case beta != 1:
  761. c64.SscalUnitary(beta, ci)
  762. ci[i] = complex(real(ci[i]), 0)
  763. default:
  764. ci[i] = complex(real(ci[i]), 0)
  765. }
  766. for j := 0; j < k; j++ {
  767. aji := a[j*lda+i]
  768. bji := b[j*ldb+i]
  769. if aji != 0 {
  770. c64.AxpyUnitary(alpha*cmplx.Conj(aji), b[j*ldb:j*ldb+i+1], ci)
  771. }
  772. if bji != 0 {
  773. c64.AxpyUnitary(conjalpha*cmplx.Conj(bji), a[j*lda:j*lda+i+1], ci)
  774. }
  775. }
  776. ci[i] = complex(real(ci[i]), 0)
  777. }
  778. }
  779. }
  780. }
  781. // Csymm performs one of the matrix-matrix operations
  782. // C = alpha*A*B + beta*C if side == blas.Left
  783. // C = alpha*B*A + beta*C if side == blas.Right
  784. // where alpha and beta are scalars, A is an m×m or n×n symmetric matrix and B
  785. // and C are m×n matrices.
  786. //
  787. // Complex64 implementations are autogenerated and not directly tested.
  788. func (Implementation) Csymm(side blas.Side, uplo blas.Uplo, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) {
  789. na := m
  790. if side == blas.Right {
  791. na = n
  792. }
  793. switch {
  794. case side != blas.Left && side != blas.Right:
  795. panic(badSide)
  796. case uplo != blas.Lower && uplo != blas.Upper:
  797. panic(badUplo)
  798. case m < 0:
  799. panic(mLT0)
  800. case n < 0:
  801. panic(nLT0)
  802. case lda < max(1, na):
  803. panic(badLdA)
  804. case ldb < max(1, n):
  805. panic(badLdB)
  806. case ldc < max(1, n):
  807. panic(badLdC)
  808. }
  809. // Quick return if possible.
  810. if m == 0 || n == 0 {
  811. return
  812. }
  813. // For zero matrix size the following slice length checks are trivially satisfied.
  814. if len(a) < lda*(na-1)+na {
  815. panic(shortA)
  816. }
  817. if len(b) < ldb*(m-1)+n {
  818. panic(shortB)
  819. }
  820. if len(c) < ldc*(m-1)+n {
  821. panic(shortC)
  822. }
  823. // Quick return if possible.
  824. if alpha == 0 && beta == 1 {
  825. return
  826. }
  827. if alpha == 0 {
  828. if beta == 0 {
  829. for i := 0; i < m; i++ {
  830. ci := c[i*ldc : i*ldc+n]
  831. for j := range ci {
  832. ci[j] = 0
  833. }
  834. }
  835. } else {
  836. for i := 0; i < m; i++ {
  837. ci := c[i*ldc : i*ldc+n]
  838. c64.ScalUnitary(beta, ci)
  839. }
  840. }
  841. return
  842. }
  843. if side == blas.Left {
  844. // Form C = alpha*A*B + beta*C.
  845. for i := 0; i < m; i++ {
  846. atmp := alpha * a[i*lda+i]
  847. bi := b[i*ldb : i*ldb+n]
  848. ci := c[i*ldc : i*ldc+n]
  849. if beta == 0 {
  850. for j, bij := range bi {
  851. ci[j] = atmp * bij
  852. }
  853. } else {
  854. for j, bij := range bi {
  855. ci[j] = atmp*bij + beta*ci[j]
  856. }
  857. }
  858. if uplo == blas.Upper {
  859. for k := 0; k < i; k++ {
  860. atmp = alpha * a[k*lda+i]
  861. c64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ci)
  862. }
  863. for k := i + 1; k < m; k++ {
  864. atmp = alpha * a[i*lda+k]
  865. c64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ci)
  866. }
  867. } else {
  868. for k := 0; k < i; k++ {
  869. atmp = alpha * a[i*lda+k]
  870. c64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ci)
  871. }
  872. for k := i + 1; k < m; k++ {
  873. atmp = alpha * a[k*lda+i]
  874. c64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ci)
  875. }
  876. }
  877. }
  878. } else {
  879. // Form C = alpha*B*A + beta*C.
  880. if uplo == blas.Upper {
  881. for i := 0; i < m; i++ {
  882. for j := n - 1; j >= 0; j-- {
  883. abij := alpha * b[i*ldb+j]
  884. aj := a[j*lda+j+1 : j*lda+n]
  885. bi := b[i*ldb+j+1 : i*ldb+n]
  886. ci := c[i*ldc+j+1 : i*ldc+n]
  887. var tmp complex64
  888. for k, ajk := range aj {
  889. ci[k] += abij * ajk
  890. tmp += bi[k] * ajk
  891. }
  892. if beta == 0 {
  893. c[i*ldc+j] = abij*a[j*lda+j] + alpha*tmp
  894. } else {
  895. c[i*ldc+j] = abij*a[j*lda+j] + alpha*tmp + beta*c[i*ldc+j]
  896. }
  897. }
  898. }
  899. } else {
  900. for i := 0; i < m; i++ {
  901. for j := 0; j < n; j++ {
  902. abij := alpha * b[i*ldb+j]
  903. aj := a[j*lda : j*lda+j]
  904. bi := b[i*ldb : i*ldb+j]
  905. ci := c[i*ldc : i*ldc+j]
  906. var tmp complex64
  907. for k, ajk := range aj {
  908. ci[k] += abij * ajk
  909. tmp += bi[k] * ajk
  910. }
  911. if beta == 0 {
  912. c[i*ldc+j] = abij*a[j*lda+j] + alpha*tmp
  913. } else {
  914. c[i*ldc+j] = abij*a[j*lda+j] + alpha*tmp + beta*c[i*ldc+j]
  915. }
  916. }
  917. }
  918. }
  919. }
  920. }
  921. // Csyrk performs one of the symmetric rank-k operations
  922. // C = alpha*A*Aᵀ + beta*C if trans == blas.NoTrans
  923. // C = alpha*Aᵀ*A + beta*C if trans == blas.Trans
  924. // where alpha and beta are scalars, C is an n×n symmetric matrix and A is
  925. // an n×k matrix in the first case and a k×n matrix in the second case.
  926. //
  927. // Complex64 implementations are autogenerated and not directly tested.
  928. func (Implementation) Csyrk(uplo blas.Uplo, trans blas.Transpose, n, k int, alpha complex64, a []complex64, lda int, beta complex64, c []complex64, ldc int) {
  929. var rowA, colA int
  930. switch trans {
  931. default:
  932. panic(badTranspose)
  933. case blas.NoTrans:
  934. rowA, colA = n, k
  935. case blas.Trans:
  936. rowA, colA = k, n
  937. }
  938. switch {
  939. case uplo != blas.Lower && uplo != blas.Upper:
  940. panic(badUplo)
  941. case n < 0:
  942. panic(nLT0)
  943. case k < 0:
  944. panic(kLT0)
  945. case lda < max(1, colA):
  946. panic(badLdA)
  947. case ldc < max(1, n):
  948. panic(badLdC)
  949. }
  950. // Quick return if possible.
  951. if n == 0 {
  952. return
  953. }
  954. // For zero matrix size the following slice length checks are trivially satisfied.
  955. if len(a) < (rowA-1)*lda+colA {
  956. panic(shortA)
  957. }
  958. if len(c) < (n-1)*ldc+n {
  959. panic(shortC)
  960. }
  961. // Quick return if possible.
  962. if (alpha == 0 || k == 0) && beta == 1 {
  963. return
  964. }
  965. if alpha == 0 {
  966. if uplo == blas.Upper {
  967. if beta == 0 {
  968. for i := 0; i < n; i++ {
  969. ci := c[i*ldc+i : i*ldc+n]
  970. for j := range ci {
  971. ci[j] = 0
  972. }
  973. }
  974. } else {
  975. for i := 0; i < n; i++ {
  976. ci := c[i*ldc+i : i*ldc+n]
  977. c64.ScalUnitary(beta, ci)
  978. }
  979. }
  980. } else {
  981. if beta == 0 {
  982. for i := 0; i < n; i++ {
  983. ci := c[i*ldc : i*ldc+i+1]
  984. for j := range ci {
  985. ci[j] = 0
  986. }
  987. }
  988. } else {
  989. for i := 0; i < n; i++ {
  990. ci := c[i*ldc : i*ldc+i+1]
  991. c64.ScalUnitary(beta, ci)
  992. }
  993. }
  994. }
  995. return
  996. }
  997. if trans == blas.NoTrans {
  998. // Form C = alpha*A*Aᵀ + beta*C.
  999. if uplo == blas.Upper {
  1000. for i := 0; i < n; i++ {
  1001. ci := c[i*ldc+i : i*ldc+n]
  1002. ai := a[i*lda : i*lda+k]
  1003. if beta == 0 {
  1004. for jc := range ci {
  1005. j := i + jc
  1006. ci[jc] = alpha * c64.DotuUnitary(ai, a[j*lda:j*lda+k])
  1007. }
  1008. } else {
  1009. for jc, cij := range ci {
  1010. j := i + jc
  1011. ci[jc] = beta*cij + alpha*c64.DotuUnitary(ai, a[j*lda:j*lda+k])
  1012. }
  1013. }
  1014. }
  1015. } else {
  1016. for i := 0; i < n; i++ {
  1017. ci := c[i*ldc : i*ldc+i+1]
  1018. ai := a[i*lda : i*lda+k]
  1019. if beta == 0 {
  1020. for j := range ci {
  1021. ci[j] = alpha * c64.DotuUnitary(ai, a[j*lda:j*lda+k])
  1022. }
  1023. } else {
  1024. for j, cij := range ci {
  1025. ci[j] = beta*cij + alpha*c64.DotuUnitary(ai, a[j*lda:j*lda+k])
  1026. }
  1027. }
  1028. }
  1029. }
  1030. } else {
  1031. // Form C = alpha*Aᵀ*A + beta*C.
  1032. if uplo == blas.Upper {
  1033. for i := 0; i < n; i++ {
  1034. ci := c[i*ldc+i : i*ldc+n]
  1035. switch {
  1036. case beta == 0:
  1037. for jc := range ci {
  1038. ci[jc] = 0
  1039. }
  1040. case beta != 1:
  1041. for jc := range ci {
  1042. ci[jc] *= beta
  1043. }
  1044. }
  1045. for j := 0; j < k; j++ {
  1046. aji := a[j*lda+i]
  1047. if aji != 0 {
  1048. c64.AxpyUnitary(alpha*aji, a[j*lda+i:j*lda+n], ci)
  1049. }
  1050. }
  1051. }
  1052. } else {
  1053. for i := 0; i < n; i++ {
  1054. ci := c[i*ldc : i*ldc+i+1]
  1055. switch {
  1056. case beta == 0:
  1057. for j := range ci {
  1058. ci[j] = 0
  1059. }
  1060. case beta != 1:
  1061. for j := range ci {
  1062. ci[j] *= beta
  1063. }
  1064. }
  1065. for j := 0; j < k; j++ {
  1066. aji := a[j*lda+i]
  1067. if aji != 0 {
  1068. c64.AxpyUnitary(alpha*aji, a[j*lda:j*lda+i+1], ci)
  1069. }
  1070. }
  1071. }
  1072. }
  1073. }
  1074. }
  1075. // Csyr2k performs one of the symmetric rank-2k operations
  1076. // C = alpha*A*Bᵀ + alpha*B*Aᵀ + beta*C if trans == blas.NoTrans
  1077. // C = alpha*Aᵀ*B + alpha*Bᵀ*A + beta*C if trans == blas.Trans
  1078. // where alpha and beta are scalars, C is an n×n symmetric matrix and A and B
  1079. // are n×k matrices in the first case and k×n matrices in the second case.
  1080. //
  1081. // Complex64 implementations are autogenerated and not directly tested.
  1082. func (Implementation) Csyr2k(uplo blas.Uplo, trans blas.Transpose, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) {
  1083. var row, col int
  1084. switch trans {
  1085. default:
  1086. panic(badTranspose)
  1087. case blas.NoTrans:
  1088. row, col = n, k
  1089. case blas.Trans:
  1090. row, col = k, n
  1091. }
  1092. switch {
  1093. case uplo != blas.Lower && uplo != blas.Upper:
  1094. panic(badUplo)
  1095. case n < 0:
  1096. panic(nLT0)
  1097. case k < 0:
  1098. panic(kLT0)
  1099. case lda < max(1, col):
  1100. panic(badLdA)
  1101. case ldb < max(1, col):
  1102. panic(badLdB)
  1103. case ldc < max(1, n):
  1104. panic(badLdC)
  1105. }
  1106. // Quick return if possible.
  1107. if n == 0 {
  1108. return
  1109. }
  1110. // For zero matrix size the following slice length checks are trivially satisfied.
  1111. if len(a) < (row-1)*lda+col {
  1112. panic(shortA)
  1113. }
  1114. if len(b) < (row-1)*ldb+col {
  1115. panic(shortB)
  1116. }
  1117. if len(c) < (n-1)*ldc+n {
  1118. panic(shortC)
  1119. }
  1120. // Quick return if possible.
  1121. if (alpha == 0 || k == 0) && beta == 1 {
  1122. return
  1123. }
  1124. if alpha == 0 {
  1125. if uplo == blas.Upper {
  1126. if beta == 0 {
  1127. for i := 0; i < n; i++ {
  1128. ci := c[i*ldc+i : i*ldc+n]
  1129. for j := range ci {
  1130. ci[j] = 0
  1131. }
  1132. }
  1133. } else {
  1134. for i := 0; i < n; i++ {
  1135. ci := c[i*ldc+i : i*ldc+n]
  1136. c64.ScalUnitary(beta, ci)
  1137. }
  1138. }
  1139. } else {
  1140. if beta == 0 {
  1141. for i := 0; i < n; i++ {
  1142. ci := c[i*ldc : i*ldc+i+1]
  1143. for j := range ci {
  1144. ci[j] = 0
  1145. }
  1146. }
  1147. } else {
  1148. for i := 0; i < n; i++ {
  1149. ci := c[i*ldc : i*ldc+i+1]
  1150. c64.ScalUnitary(beta, ci)
  1151. }
  1152. }
  1153. }
  1154. return
  1155. }
  1156. if trans == blas.NoTrans {
  1157. // Form C = alpha*A*Bᵀ + alpha*B*Aᵀ + beta*C.
  1158. if uplo == blas.Upper {
  1159. for i := 0; i < n; i++ {
  1160. ci := c[i*ldc+i : i*ldc+n]
  1161. ai := a[i*lda : i*lda+k]
  1162. bi := b[i*ldb : i*ldb+k]
  1163. if beta == 0 {
  1164. for jc := range ci {
  1165. j := i + jc
  1166. ci[jc] = alpha*c64.DotuUnitary(ai, b[j*ldb:j*ldb+k]) + alpha*c64.DotuUnitary(bi, a[j*lda:j*lda+k])
  1167. }
  1168. } else {
  1169. for jc, cij := range ci {
  1170. j := i + jc
  1171. ci[jc] = alpha*c64.DotuUnitary(ai, b[j*ldb:j*ldb+k]) + alpha*c64.DotuUnitary(bi, a[j*lda:j*lda+k]) + beta*cij
  1172. }
  1173. }
  1174. }
  1175. } else {
  1176. for i := 0; i < n; i++ {
  1177. ci := c[i*ldc : i*ldc+i+1]
  1178. ai := a[i*lda : i*lda+k]
  1179. bi := b[i*ldb : i*ldb+k]
  1180. if beta == 0 {
  1181. for j := range ci {
  1182. ci[j] = alpha*c64.DotuUnitary(ai, b[j*ldb:j*ldb+k]) + alpha*c64.DotuUnitary(bi, a[j*lda:j*lda+k])
  1183. }
  1184. } else {
  1185. for j, cij := range ci {
  1186. ci[j] = alpha*c64.DotuUnitary(ai, b[j*ldb:j*ldb+k]) + alpha*c64.DotuUnitary(bi, a[j*lda:j*lda+k]) + beta*cij
  1187. }
  1188. }
  1189. }
  1190. }
  1191. } else {
  1192. // Form C = alpha*Aᵀ*B + alpha*Bᵀ*A + beta*C.
  1193. if uplo == blas.Upper {
  1194. for i := 0; i < n; i++ {
  1195. ci := c[i*ldc+i : i*ldc+n]
  1196. switch {
  1197. case beta == 0:
  1198. for jc := range ci {
  1199. ci[jc] = 0
  1200. }
  1201. case beta != 1:
  1202. for jc := range ci {
  1203. ci[jc] *= beta
  1204. }
  1205. }
  1206. for j := 0; j < k; j++ {
  1207. aji := a[j*lda+i]
  1208. bji := b[j*ldb+i]
  1209. if aji != 0 {
  1210. c64.AxpyUnitary(alpha*aji, b[j*ldb+i:j*ldb+n], ci)
  1211. }
  1212. if bji != 0 {
  1213. c64.AxpyUnitary(alpha*bji, a[j*lda+i:j*lda+n], ci)
  1214. }
  1215. }
  1216. }
  1217. } else {
  1218. for i := 0; i < n; i++ {
  1219. ci := c[i*ldc : i*ldc+i+1]
  1220. switch {
  1221. case beta == 0:
  1222. for j := range ci {
  1223. ci[j] = 0
  1224. }
  1225. case beta != 1:
  1226. for j := range ci {
  1227. ci[j] *= beta
  1228. }
  1229. }
  1230. for j := 0; j < k; j++ {
  1231. aji := a[j*lda+i]
  1232. bji := b[j*ldb+i]
  1233. if aji != 0 {
  1234. c64.AxpyUnitary(alpha*aji, b[j*ldb:j*ldb+i+1], ci)
  1235. }
  1236. if bji != 0 {
  1237. c64.AxpyUnitary(alpha*bji, a[j*lda:j*lda+i+1], ci)
  1238. }
  1239. }
  1240. }
  1241. }
  1242. }
  1243. }
  1244. // Ctrmm performs one of the matrix-matrix operations
  1245. // B = alpha * op(A) * B if side == blas.Left,
  1246. // B = alpha * B * op(A) if side == blas.Right,
  1247. // where alpha is a scalar, B is an m×n matrix, A is a unit, or non-unit,
  1248. // upper or lower triangular matrix and op(A) is one of
  1249. // op(A) = A if trans == blas.NoTrans,
  1250. // op(A) = Aᵀ if trans == blas.Trans,
  1251. // op(A) = Aᴴ if trans == blas.ConjTrans.
  1252. //
  1253. // Complex64 implementations are autogenerated and not directly tested.
  1254. func (Implementation) Ctrmm(side blas.Side, uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int) {
  1255. na := m
  1256. if side == blas.Right {
  1257. na = n
  1258. }
  1259. switch {
  1260. case side != blas.Left && side != blas.Right:
  1261. panic(badSide)
  1262. case uplo != blas.Lower && uplo != blas.Upper:
  1263. panic(badUplo)
  1264. case trans != blas.NoTrans && trans != blas.Trans && trans != blas.ConjTrans:
  1265. panic(badTranspose)
  1266. case diag != blas.Unit && diag != blas.NonUnit:
  1267. panic(badDiag)
  1268. case m < 0:
  1269. panic(mLT0)
  1270. case n < 0:
  1271. panic(nLT0)
  1272. case lda < max(1, na):
  1273. panic(badLdA)
  1274. case ldb < max(1, n):
  1275. panic(badLdB)
  1276. }
  1277. // Quick return if possible.
  1278. if m == 0 || n == 0 {
  1279. return
  1280. }
  1281. // For zero matrix size the following slice length checks are trivially satisfied.
  1282. if len(a) < (na-1)*lda+na {
  1283. panic(shortA)
  1284. }
  1285. if len(b) < (m-1)*ldb+n {
  1286. panic(shortB)
  1287. }
  1288. // Quick return if possible.
  1289. if alpha == 0 {
  1290. for i := 0; i < m; i++ {
  1291. bi := b[i*ldb : i*ldb+n]
  1292. for j := range bi {
  1293. bi[j] = 0
  1294. }
  1295. }
  1296. return
  1297. }
  1298. noConj := trans != blas.ConjTrans
  1299. noUnit := diag == blas.NonUnit
  1300. if side == blas.Left {
  1301. if trans == blas.NoTrans {
  1302. // Form B = alpha*A*B.
  1303. if uplo == blas.Upper {
  1304. for i := 0; i < m; i++ {
  1305. aii := alpha
  1306. if noUnit {
  1307. aii *= a[i*lda+i]
  1308. }
  1309. bi := b[i*ldb : i*ldb+n]
  1310. for j := range bi {
  1311. bi[j] *= aii
  1312. }
  1313. for ja, aij := range a[i*lda+i+1 : i*lda+m] {
  1314. j := ja + i + 1
  1315. if aij != 0 {
  1316. c64.AxpyUnitary(alpha*aij, b[j*ldb:j*ldb+n], bi)
  1317. }
  1318. }
  1319. }
  1320. } else {
  1321. for i := m - 1; i >= 0; i-- {
  1322. aii := alpha
  1323. if noUnit {
  1324. aii *= a[i*lda+i]
  1325. }
  1326. bi := b[i*ldb : i*ldb+n]
  1327. for j := range bi {
  1328. bi[j] *= aii
  1329. }
  1330. for j, aij := range a[i*lda : i*lda+i] {
  1331. if aij != 0 {
  1332. c64.AxpyUnitary(alpha*aij, b[j*ldb:j*ldb+n], bi)
  1333. }
  1334. }
  1335. }
  1336. }
  1337. } else {
  1338. // Form B = alpha*Aᵀ*B or B = alpha*Aᴴ*B.
  1339. if uplo == blas.Upper {
  1340. for k := m - 1; k >= 0; k-- {
  1341. bk := b[k*ldb : k*ldb+n]
  1342. for ja, ajk := range a[k*lda+k+1 : k*lda+m] {
  1343. if ajk == 0 {
  1344. continue
  1345. }
  1346. j := k + 1 + ja
  1347. if noConj {
  1348. c64.AxpyUnitary(alpha*ajk, bk, b[j*ldb:j*ldb+n])
  1349. } else {
  1350. c64.AxpyUnitary(alpha*cmplx.Conj(ajk), bk, b[j*ldb:j*ldb+n])
  1351. }
  1352. }
  1353. akk := alpha
  1354. if noUnit {
  1355. if noConj {
  1356. akk *= a[k*lda+k]
  1357. } else {
  1358. akk *= cmplx.Conj(a[k*lda+k])
  1359. }
  1360. }
  1361. if akk != 1 {
  1362. c64.ScalUnitary(akk, bk)
  1363. }
  1364. }
  1365. } else {
  1366. for k := 0; k < m; k++ {
  1367. bk := b[k*ldb : k*ldb+n]
  1368. for j, ajk := range a[k*lda : k*lda+k] {
  1369. if ajk == 0 {
  1370. continue
  1371. }
  1372. if noConj {
  1373. c64.AxpyUnitary(alpha*ajk, bk, b[j*ldb:j*ldb+n])
  1374. } else {
  1375. c64.AxpyUnitary(alpha*cmplx.Conj(ajk), bk, b[j*ldb:j*ldb+n])
  1376. }
  1377. }
  1378. akk := alpha
  1379. if noUnit {
  1380. if noConj {
  1381. akk *= a[k*lda+k]
  1382. } else {
  1383. akk *= cmplx.Conj(a[k*lda+k])
  1384. }
  1385. }
  1386. if akk != 1 {
  1387. c64.ScalUnitary(akk, bk)
  1388. }
  1389. }
  1390. }
  1391. }
  1392. } else {
  1393. if trans == blas.NoTrans {
  1394. // Form B = alpha*B*A.
  1395. if uplo == blas.Upper {
  1396. for i := 0; i < m; i++ {
  1397. bi := b[i*ldb : i*ldb+n]
  1398. for k := n - 1; k >= 0; k-- {
  1399. abik := alpha * bi[k]
  1400. if abik == 0 {
  1401. continue
  1402. }
  1403. bi[k] = abik
  1404. if noUnit {
  1405. bi[k] *= a[k*lda+k]
  1406. }
  1407. c64.AxpyUnitary(abik, a[k*lda+k+1:k*lda+n], bi[k+1:])
  1408. }
  1409. }
  1410. } else {
  1411. for i := 0; i < m; i++ {
  1412. bi := b[i*ldb : i*ldb+n]
  1413. for k := 0; k < n; k++ {
  1414. abik := alpha * bi[k]
  1415. if abik == 0 {
  1416. continue
  1417. }
  1418. bi[k] = abik
  1419. if noUnit {
  1420. bi[k] *= a[k*lda+k]
  1421. }
  1422. c64.AxpyUnitary(abik, a[k*lda:k*lda+k], bi[:k])
  1423. }
  1424. }
  1425. }
  1426. } else {
  1427. // Form B = alpha*B*Aᵀ or B = alpha*B*Aᴴ.
  1428. if uplo == blas.Upper {
  1429. for i := 0; i < m; i++ {
  1430. bi := b[i*ldb : i*ldb+n]
  1431. for j, bij := range bi {
  1432. if noConj {
  1433. if noUnit {
  1434. bij *= a[j*lda+j]
  1435. }
  1436. bij += c64.DotuUnitary(a[j*lda+j+1:j*lda+n], bi[j+1:n])
  1437. } else {
  1438. if noUnit {
  1439. bij *= cmplx.Conj(a[j*lda+j])
  1440. }
  1441. bij += c64.DotcUnitary(a[j*lda+j+1:j*lda+n], bi[j+1:n])
  1442. }
  1443. bi[j] = alpha * bij
  1444. }
  1445. }
  1446. } else {
  1447. for i := 0; i < m; i++ {
  1448. bi := b[i*ldb : i*ldb+n]
  1449. for j := n - 1; j >= 0; j-- {
  1450. bij := bi[j]
  1451. if noConj {
  1452. if noUnit {
  1453. bij *= a[j*lda+j]
  1454. }
  1455. bij += c64.DotuUnitary(a[j*lda:j*lda+j], bi[:j])
  1456. } else {
  1457. if noUnit {
  1458. bij *= cmplx.Conj(a[j*lda+j])
  1459. }
  1460. bij += c64.DotcUnitary(a[j*lda:j*lda+j], bi[:j])
  1461. }
  1462. bi[j] = alpha * bij
  1463. }
  1464. }
  1465. }
  1466. }
  1467. }
  1468. }
  1469. // Ctrsm solves one of the matrix equations
  1470. // op(A) * X = alpha * B if side == blas.Left,
  1471. // X * op(A) = alpha * B if side == blas.Right,
  1472. // where alpha is a scalar, X and B are m×n matrices, A is a unit or
  1473. // non-unit, upper or lower triangular matrix and op(A) is one of
  1474. // op(A) = A if transA == blas.NoTrans,
  1475. // op(A) = Aᵀ if transA == blas.Trans,
  1476. // op(A) = Aᴴ if transA == blas.ConjTrans.
  1477. // On return the matrix X is overwritten on B.
  1478. //
  1479. // Complex64 implementations are autogenerated and not directly tested.
  1480. func (Implementation) Ctrsm(side blas.Side, uplo blas.Uplo, transA blas.Transpose, diag blas.Diag, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int) {
  1481. na := m
  1482. if side == blas.Right {
  1483. na = n
  1484. }
  1485. switch {
  1486. case side != blas.Left && side != blas.Right:
  1487. panic(badSide)
  1488. case uplo != blas.Lower && uplo != blas.Upper:
  1489. panic(badUplo)
  1490. case transA != blas.NoTrans && transA != blas.Trans && transA != blas.ConjTrans:
  1491. panic(badTranspose)
  1492. case diag != blas.Unit && diag != blas.NonUnit:
  1493. panic(badDiag)
  1494. case m < 0:
  1495. panic(mLT0)
  1496. case n < 0:
  1497. panic(nLT0)
  1498. case lda < max(1, na):
  1499. panic(badLdA)
  1500. case ldb < max(1, n):
  1501. panic(badLdB)
  1502. }
  1503. // Quick return if possible.
  1504. if m == 0 || n == 0 {
  1505. return
  1506. }
  1507. // For zero matrix size the following slice length checks are trivially satisfied.
  1508. if len(a) < (na-1)*lda+na {
  1509. panic(shortA)
  1510. }
  1511. if len(b) < (m-1)*ldb+n {
  1512. panic(shortB)
  1513. }
  1514. if alpha == 0 {
  1515. for i := 0; i < m; i++ {
  1516. for j := 0; j < n; j++ {
  1517. b[i*ldb+j] = 0
  1518. }
  1519. }
  1520. return
  1521. }
  1522. noConj := transA != blas.ConjTrans
  1523. noUnit := diag == blas.NonUnit
  1524. if side == blas.Left {
  1525. if transA == blas.NoTrans {
  1526. // Form B = alpha*inv(A)*B.
  1527. if uplo == blas.Upper {
  1528. for i := m - 1; i >= 0; i-- {
  1529. bi := b[i*ldb : i*ldb+n]
  1530. if alpha != 1 {
  1531. c64.ScalUnitary(alpha, bi)
  1532. }
  1533. for ka, aik := range a[i*lda+i+1 : i*lda+m] {
  1534. k := i + 1 + ka
  1535. if aik != 0 {
  1536. c64.AxpyUnitary(-aik, b[k*ldb:k*ldb+n], bi)
  1537. }
  1538. }
  1539. if noUnit {
  1540. c64.ScalUnitary(1/a[i*lda+i], bi)
  1541. }
  1542. }
  1543. } else {
  1544. for i := 0; i < m; i++ {
  1545. bi := b[i*ldb : i*ldb+n]
  1546. if alpha != 1 {
  1547. c64.ScalUnitary(alpha, bi)
  1548. }
  1549. for j, aij := range a[i*lda : i*lda+i] {
  1550. if aij != 0 {
  1551. c64.AxpyUnitary(-aij, b[j*ldb:j*ldb+n], bi)
  1552. }
  1553. }
  1554. if noUnit {
  1555. c64.ScalUnitary(1/a[i*lda+i], bi)
  1556. }
  1557. }
  1558. }
  1559. } else {
  1560. // Form B = alpha*inv(Aᵀ)*B or B = alpha*inv(Aᴴ)*B.
  1561. if uplo == blas.Upper {
  1562. for i := 0; i < m; i++ {
  1563. bi := b[i*ldb : i*ldb+n]
  1564. if noUnit {
  1565. if noConj {
  1566. c64.ScalUnitary(1/a[i*lda+i], bi)
  1567. } else {
  1568. c64.ScalUnitary(1/cmplx.Conj(a[i*lda+i]), bi)
  1569. }
  1570. }
  1571. for ja, aij := range a[i*lda+i+1 : i*lda+m] {
  1572. if aij == 0 {
  1573. continue
  1574. }
  1575. j := i + 1 + ja
  1576. if noConj {
  1577. c64.AxpyUnitary(-aij, bi, b[j*ldb:j*ldb+n])
  1578. } else {
  1579. c64.AxpyUnitary(-cmplx.Conj(aij), bi, b[j*ldb:j*ldb+n])
  1580. }
  1581. }
  1582. if alpha != 1 {
  1583. c64.ScalUnitary(alpha, bi)
  1584. }
  1585. }
  1586. } else {
  1587. for i := m - 1; i >= 0; i-- {
  1588. bi := b[i*ldb : i*ldb+n]
  1589. if noUnit {
  1590. if noConj {
  1591. c64.ScalUnitary(1/a[i*lda+i], bi)
  1592. } else {
  1593. c64.ScalUnitary(1/cmplx.Conj(a[i*lda+i]), bi)
  1594. }
  1595. }
  1596. for j, aij := range a[i*lda : i*lda+i] {
  1597. if aij == 0 {
  1598. continue
  1599. }
  1600. if noConj {
  1601. c64.AxpyUnitary(-aij, bi, b[j*ldb:j*ldb+n])
  1602. } else {
  1603. c64.AxpyUnitary(-cmplx.Conj(aij), bi, b[j*ldb:j*ldb+n])
  1604. }
  1605. }
  1606. if alpha != 1 {
  1607. c64.ScalUnitary(alpha, bi)
  1608. }
  1609. }
  1610. }
  1611. }
  1612. } else {
  1613. if transA == blas.NoTrans {
  1614. // Form B = alpha*B*inv(A).
  1615. if uplo == blas.Upper {
  1616. for i := 0; i < m; i++ {
  1617. bi := b[i*ldb : i*ldb+n]
  1618. if alpha != 1 {
  1619. c64.ScalUnitary(alpha, bi)
  1620. }
  1621. for j, bij := range bi {
  1622. if bij == 0 {
  1623. continue
  1624. }
  1625. if noUnit {
  1626. bi[j] /= a[j*lda+j]
  1627. }
  1628. c64.AxpyUnitary(-bi[j], a[j*lda+j+1:j*lda+n], bi[j+1:n])
  1629. }
  1630. }
  1631. } else {
  1632. for i := 0; i < m; i++ {
  1633. bi := b[i*ldb : i*ldb+n]
  1634. if alpha != 1 {
  1635. c64.ScalUnitary(alpha, bi)
  1636. }
  1637. for j := n - 1; j >= 0; j-- {
  1638. if bi[j] == 0 {
  1639. continue
  1640. }
  1641. if noUnit {
  1642. bi[j] /= a[j*lda+j]
  1643. }
  1644. c64.AxpyUnitary(-bi[j], a[j*lda:j*lda+j], bi[:j])
  1645. }
  1646. }
  1647. }
  1648. } else {
  1649. // Form B = alpha*B*inv(Aᵀ) or B = alpha*B*inv(Aᴴ).
  1650. if uplo == blas.Upper {
  1651. for i := 0; i < m; i++ {
  1652. bi := b[i*ldb : i*ldb+n]
  1653. for j := n - 1; j >= 0; j-- {
  1654. bij := alpha * bi[j]
  1655. if noConj {
  1656. bij -= c64.DotuUnitary(a[j*lda+j+1:j*lda+n], bi[j+1:n])
  1657. if noUnit {
  1658. bij /= a[j*lda+j]
  1659. }
  1660. } else {
  1661. bij -= c64.DotcUnitary(a[j*lda+j+1:j*lda+n], bi[j+1:n])
  1662. if noUnit {
  1663. bij /= cmplx.Conj(a[j*lda+j])
  1664. }
  1665. }
  1666. bi[j] = bij
  1667. }
  1668. }
  1669. } else {
  1670. for i := 0; i < m; i++ {
  1671. bi := b[i*ldb : i*ldb+n]
  1672. for j, bij := range bi {
  1673. bij *= alpha
  1674. if noConj {
  1675. bij -= c64.DotuUnitary(a[j*lda:j*lda+j], bi[:j])
  1676. if noUnit {
  1677. bij /= a[j*lda+j]
  1678. }
  1679. } else {
  1680. bij -= c64.DotcUnitary(a[j*lda:j*lda+j], bi[:j])
  1681. if noUnit {
  1682. bij /= cmplx.Conj(a[j*lda+j])
  1683. }
  1684. }
  1685. bi[j] = bij
  1686. }
  1687. }
  1688. }
  1689. }
  1690. }
  1691. }