[PYTHON] Notation pliée de type tenseur

J'ai trouvé un moyen de faire l'opération de convolution uniquement par l'opération de tableau du ndarray de numpy. Cependant, j'utilise la classe de type Tensol de mon propre module. Les variables et les indices désignent les éléments d'un ensemble (les définitions générales ne sont ni étudiées ni claires).

Formule

Cependant, il utilise des règles arithmétiques auto-définies.

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|}

ça ira.


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

Exemple de mise en œuvre de programme

Comparé au résultat de 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 dans la formule ci-dessus_{ik}y_{jl}Correspond à
    
    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 

Résultat d'exécution

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])] 
#<-Renvoie les éléments de la matrice a comme la matrice suivante(ligne,Colonne)
#[[(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)]]




#Applicable à la dimension N
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])] #C'est aussi OK
print 
print a[ix_([0,1,2],[2,0,1],[0,1,2])] #a[ix_([0,1,2],[2,0,1])]Équivalent à
print 

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

Par conséquent, $ I_ {x_ {ik} y_ {jk}} $ passe le tenseur d'indexation de $ x_ {ik}, y_ {jl} $ de rang 2 à $ I \ (x, y ) $ et de rangs. Cela signifie obtenir $ I $ de 4, mais je ne peux pas simplement l'attribuer à python. Par conséquent, dans ce qui précède, l'indexation est effectuée après avoir défini le rang sur 1 avec flatten ().

Recommended Posts

Notation pliée de type tenseur
Notation d'inclusion
Notation de format
Notation d'inclusion