Skip to content

Instantly share code, notes, and snippets.

@Foadsf
Last active August 13, 2018 13:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Foadsf/80abba07ea892e50da3df7e318844f33 to your computer and use it in GitHub Desktop.
Save Foadsf/80abba07ea892e50da3df7e318844f33 to your computer and use it in GitHub Desktop.
Cauchy product of multivariate finite power series (polynomials) represented as discrete convolution of NumPy ndarrays
import numpy as np
def crop(A,D1,D2):
return A[tuple(slice(D1[i], D2[i]) for i in range(A.ndim))]
def sumall(A):
sum1=A
for k in range(A.ndim):
sum1 = np.sum(sum1,axis=0)
return sum1
def xpndzr(A,D):
D1=D-A.shape
T=np.zeros((D.shape[0],2),dtype=D.dtype)
T[:,1]=D1[:]
return np.pad(A, T, 'constant', constant_values=0)
def flipall(A):
return A[[slice(None, None, -1)] * A.ndim]
def conv(A,B,K):
D0=np.zeros(K.shape,dtype=K.dtype)
return sumall(np.multiply(crop(A,np.maximum(D0,np.minimum(A.shape,K-B.shape)),np.minimum(A.shape,K)), \
flipall(crop(B,np.maximum(D0,np.minimum(B.shape,K-A.shape)),np.minimum(B.shape,K)))))
D1=np.array([4,5])
D2=np.array([2,3])
A=np.random.randint(10,size=D1)
B=np.random.randint(10,size=D2)
K=np.array([4,6])+1
print(conv(A,B,K))
@nils-werner
Copy link

What's J?

@nils-werner
Copy link

nils-werner commented Aug 11, 2018

I am trying to parse your formulas and your code, and am trying to come up with an example implementation as simple as possible. I could come up with:

import numpy as np

def crop(A, start=0, stop=-1):
    """
    crop n-dimensional array along all dimensions:

    A -> A[start:stop, start:stop, ..., start:stop]
    """
    return A[[slice(start, stop)] * A.ndim]

def flipall(A):
    """
    flip n-dimensional array along all dimensions:

    A -> A[::-1, ::-1, ..., ::-1]
    """
    return A[[slice(None, None, -1)] * A.ndim]

def conv(A, B, j):
    return np.sum(np.conj(crop(A, stop=j)) * flipall(crop(B, stop=j)))

A=np.random.randint(10,size=(4, 4))
B=np.random.randint(10,size=(4, 4))
print(A)
print(B)
print(conv(A, B, 1))
print(conv(A, B, 2))

does this do what you want?

@Foadsf
Copy link
Author

Foadsf commented Aug 11, 2018

@nils-werner I edited the original post and changed J to Kto be consistent with the original notation. K=[k1,...,kn] where for all 0<j<=n we have 0<=kj<=oj

@Foadsf
Copy link
Author

Foadsf commented Aug 11, 2018

@nils-werner Thanks alot for the sample code, it is awesome. just some questions:

  • the crop function which I have explained here should accept two 1D arrays D1=[d11,...,d1n] and D2=[d21,...,d2n] of non-negative integers, for the last two arguments. where A.ndim=D1.shape[0]=D2.shape[0] and for all 0<j<=n we should have 0<=d1j<=d2j<=A.shape[j]. What I do not understand is how the default values in your code are just integers. shouldn't they be ndarrays?
  • I'm not sure your conv function is same as mine. I'm going to test it now. Former j or J and now K, is an array with the same shape as D1 and D2. but in your code it is an integer.
  • A and B are not necessarily square/cubical. they can have any arbitrary shapes D1 and D2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment