行列積から線形変換による方法への書き換え
; 1 2
; 3 4
(let a (input 4)
; 5 6
; 7 8
(let b (input 4)
(let c (const 0)
(rep i 2
(rep j 2
(#= c i,j (rep + 2 (* (# a i,k) (# b k,j))))
)
)
)))todo 写像で書く書き方で書く
行, 列に分ける
li\cj→
↓ 5|7 6|8
1 x----o (k=0)
- | |
2 | o--|-x (k=1)
| | | |
3 o----x |
- | |
4 x----o
- diagonal でくっつける
rep d in 2
let m_d = fold (+) i 2
let j = (i + d) % 2
let line = a[i:*]
let col = b[*:j]
line * col
[ 1| | | ]*[ 5| | | ] [ | 2| | ]*[ | 8| | ]
[ | 4| | ]*[ | 7| | ] [ 3| | | ]*[ 6| | | ]
=
[ 5| | | ][ |16| | ]
[ |28| | ][18| | | ]
[ | 2| | ]*[ | 7| | ] [ 1| | | ]*[ 6| | | ]
[ 3| | | ]*[ 5| | | ] [ | 4| | ]*[ | 8| | ]
=
[ |14| | ] [ 6| | | ]
[15| | | ] [ |32| | ]
- slotに対応する所にシフトする
- Lシフト量:
: diagonal flatten vector
ex.
= [0 1; 1 0]
= [1 0; 0 1]
= [0 1 2; 2 0 1; 1 2 0]
= [2 0 1; 1 2 0; 0 1 2]
rep d in 2
let m_d = fold (+) i 2
let j = (i + d) % 2
let line = a[i:*]
let col = b[*:j]
line * col
[ 5| | | ] [ |16| | ]
[ |28| | ] [18| | | ]
<<(0, -1, -1, 0) => <<(0, -1, -2, -3) = <<(0, 0, -1, -3)
[5 | | | ] [ |16| | ]
[ | |28| ] [ | | |18]
[ |14| | ] [ 6| | | ]
[15| | | ] [ |32| | ]
<<(-1, 0, 0, -1) => <<(0, -1, -2, -3) = <<(1, -1, -2, -2)
[14| | | ] [ | 6| | ]
[ | |15| ] [ | | |32]
[19|22|43|50]
rep u in 2
rep i in 2
let j = (i + u) % 2
# d=0: (0, 0), (1, 1)
# d=1: (0, 1), (1, 0)
let line = a[i:*]
let col = b[*:j]
c[i][j] = fold (+) k 2
line[k] * col[k]
function join_with_u(a, b, d)
c = zeros(d^2)
map(u -> begin
map(i -> begin
# (i, j) is orthogonally
j = (i + u) % d
al = line(a, i + 1, d)
bc = col(b, j + 1, d)
ij = pos(i + 1, j + 1, d) - 1
println("u = $u, ($i, $j) =$ij")
c[ij+1] = sum(al .* bc)
end, 0:d-1)
end, 0:d-1)
c
endとりあえずvalidなSIMDプログラムが書けた
- todo
jがkに依存しているのでkのループを内側に持ってこれず, 要素積を してしまっている