[PYTHON] Gefaltete tensorartige Notation

Ich habe einen Weg gefunden, die Faltungsoperation nur durch die Array-Operation von Numpys Ndarray durchzuführen. Ich verwende jedoch die Tensol-ähnliche Klasse meines eigenen Moduls. Variablen und Indizes bedeuten die Elemente einer Menge (allgemeine Definitionen sind nicht untersucht und unklar).

Formel

Es werden jedoch selbst definierte arithmetische Regeln verwendet.

I,J,K,L\subset\mathbb{N}, i\in I,j\in J,k\in K,l\in L , x_{ik}\in\left\\{ i_{i}+k_{k}\right\\} , y_{jl}\in\left\\{ j_{j}+l_{l}\right\\} ,I_{ij}\in\mathbb{R}^{|I|\\times |J|},h^{kl}\in\mathbb{R}^{|K|\\times |L|}

Wird besorgt.


\bar{I}_{ij}	=	I_{x_{ik}y_{jl}}h^{kl}

Beispiel für die Programmimplementierung

Verglichen mit dem Ergebnis von scipy.signal.fftcomvolve.

from scipy.signal import *

def convolve2d_tensorlike(I, h, mode="full"):
    hrows = h.shape[0]
    hcols = h.shape[1]
    add = zeros(h.shape[0]-1)
    rows = I.shape[0]
    cols = I.shape[1]

    add = array(h.shape)-1
    if mode=="full":

        I_zeros = zeros(array(I.shape) + 2*add)
        I_zeros[add[0]:-add[1], add[0]:-add[1]] = I
        I = I_zeros
    elif mode=="valid":
        add = array(h.shape)-1
    else:
        I_zeros = zeros(array(I.shape) + add)
        I_zeros[add[0]/2:-add[0]/2,add[1]/2:-add[1]/2] = I
        I = I_zeros
    
    rows = I.shape[0]
    cols = I.shape[1]
    i = tensor(cols*arange(rows-add[0]), "i", "d")
    j = tensor(arange(cols-add[0]), "j", "d")
    k = tensor(cols*arange(hrows), "k", "d")
    l = tensor(arange(hcols), "l", "d")
    h = tensor(h, "kl", "uu")

    x = (i + j + k + l)

    x.transpose("ijkl") #X in der obigen Formel_{ik}y_{jl}Entspricht
    
    I_bar = tensor(I.flatten()[x.arr.flatten().astype(int)]
                   .reshape(x.arr.shape), "ijkl", "dddd")
    I_bar = I_bar * h
    I_bar.transpose("ij")
    
    return I_bar.arr

I = array([[1,5,99,7,6],
           [6,5,38,7,2],
           [1,6,8,2,6],
           [7,5,2,3,7],
           [3,5,8,7,1]])
h = ones((3,3))
print "fftconvolve(I, h,'full')"
print  convolve2d_tensorlike(I, h,"full") 
print 

print "fftconvolve(I, h,'full')"
print  convolve2d_tensorlike(I, h, 'full')
print 

print "fftconvolve(I, h,'same'')"
print  fftconvolve(I, h,"same") 
print 

print "convolve2d_tensorlike(I, h,'same'')"
print  convolve2d_tensorlike(I, h,"same") 
print 

print "fftconvolve(I, h,'valid'')"
print  fftconvolve(I, h,"valid") 
print 

print "convolve2d_tensorlike(I, h,'valid'')"
print  convolve2d_tensorlike(I, h,"valid") 
print 

Ausführungsergebnis

fftconvolve(I, h,'full')
[[   1.    6.  105.  111.  112.   13.    6.]
 [   7.   17.  154.  161.  159.   22.    8.]
 [   8.   24.  169.  177.  175.   30.   14.]
 [  14.   30.   78.   76.   75.   27.   15.]
 [  11.   27.   45.   46.   44.   26.   14.]
 [  10.   20.   30.   30.   28.   18.    8.]
 [   3.    8.   16.   20.   16.    8.    1.]]

fftconvolve(I, h,'full')
[[   1.    6.  105.  111.  112.   13.    6.]
 [   7.   17.  154.  161.  159.   22.    8.]
 [   8.   24.  169.  177.  175.   30.   14.]
 [  14.   30.   78.   76.   75.   27.   15.]
 [  11.   27.   45.   46.   44.   26.   14.]
 [  10.   20.   30.   30.   28.   18.    8.]
 [   3.    8.   16.   20.   16.    8.    1.]]

fftconvolve(I, h,'same'')
[[  17.  154.  161.  159.   22.]
 [  24.  169.  177.  175.   30.]
 [  30.   78.   76.   75.   27.]
 [  27.   45.   46.   44.   26.]
 [  20.   30.   30.   28.   18.]]

convolve2d_tensorlike(I, h,'same'')
[[  17.  154.  161.  159.   22.]
 [  24.  169.  177.  175.   30.]
 [  30.   78.   76.   75.   27.]
 [  27.   45.   46.   44.   26.]
 [  20.   30.   30.   28.   18.]]

fftconvolve(I, h,'valid'')
[[ 169.  177.  175.]
 [  78.   76.   75.]
 [  45.   46.   44.]]

convolve2d_tensorlike(I, h,'valid'')
[[ 169.  177.  175.]
 [  78.   76.   75.]
 [  45.   46.   44.]]
 
a = arange(9).reshape((3,3))
#a=
#[[0 1 2]
# [3 4 5]
# [6 7 8]]
#
print a[ix_([0,1,2],[2,0,1])] 
#<-Gibt die Elemente der Matrix a als folgende Matrix zurück(Linie,Säule)
#[[(0,2), (0,0), (0,1)]
# [(1,2), (1,0), (1,1)]
# [(1,2), (1,0), (1,1)]]

print a[ix_([0,1],[2,0])] 
#[[(0,2), (0,0)]
# [(1,2), (1,0)]]




#Anwendbar auf N-Dimension
a = arange(27).reshape((3,3,3))
print a
print

print a[ix_([0,1,2],[2,0,1],[0,2,1])] #OK
print 

print a[ix_([0,1,2],[2,0,1])] #Dies ist auch in Ordnung
print 
print a[ix_([0,1,2],[2,0,1],[0,1,2])] #a[ix_([0,1,2],[2,0,1])]Gleichwertig
print 

print a[ix_([0,1,2],[2,0,1],[0,1,2],[0,1,2])] #NG, 

Daher übergibt $ I_ {x_ {ik} y_ {jk}} $ den Tensor zum Indizieren von $ x_ {ik}, y_ {jl} $ von Rang 2 bis $ I \ (x, y ) $ und Rängen. Es bedeutet, $ I $ von 4 zu bekommen, aber ich kann es nicht einfach Python zuweisen. Daher wird oben eine Indizierung durchgeführt, nachdem der Rang mit flatten () auf 1 gesetzt wurde.

Recommended Posts

Gefaltete tensorartige Notation
Einschlussnotation
Formatnotation
Einschlussnotation