├── LICENSE ├── README.md └── frft.py /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2019 学姐a 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # frft2-python 2 | discrete 1d and 2d fractional fourier transfrom in python 3 | 4 | ## usage: 5 | 6 | ### frft2d(mat,ax,ay) 7 | 8 | - mat: the numberic matrix to be transformed 9 | 10 | - ax,ay: the order of transform along x and y axis 11 | 12 | - returns the frft spectrum of mat 13 | 14 | ### disfrft(f,a;p) 15 | 16 | - f: the discrete signal to be trasformed 17 | 18 | - a: the order of transform 19 | 20 | - p(optional): the order of approximation, equals to half of the length of f by default 21 | 22 | - returns the frft spectrum of f 23 | 24 | ### this code is translated from its matlab version (and i actually dont know how the algorithm works xd), a senpai gave it to me and i dont know its origin. 25 | -------------------------------------------------------------------------------- /frft.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from math import pi 3 | from numba import jit,njit 4 | 5 | lastN=None 6 | lastE=None 7 | 8 | @jit(parallel=True) 9 | def make_E(N,p): 10 | d2 = np.array([1,-2,1]) 11 | d_p = 1 12 | s = 0 13 | st = np.zeros(N) 14 | for k in range(1,int(p/2)+1): 15 | d_p = np.convolve(d2,d_p) 16 | st[N-k:N]=d_p[0:k] 17 | st[0:k+1]=d_p[k:] 18 | st[0]=0 19 | temp=np.matrix([range(1,k+1),range(1,k+1)]) 20 | temp=np.ravel(temp.T)/range(1,2*k+1) 21 | s = s + np.power(-1,k-1)*np.prod(temp)*2*st 22 | 23 | col=np.matrix(range(0,N)).T 24 | row=np.matrix(range(N,0,-1)) 25 | idx=col[:,np.zeros(N).astype(int)]+row[np.zeros(N).astype(int),:]-1 26 | st=np.zeros(2*N-1) 27 | st[0:N-1] = s[N-1:0:-1] 28 | st[N-1:]=s 29 | H=st[idx]+np.diag(np.real(np.fft.fft(s))) 30 | 31 | r=N//2 32 | V1=(np.eye(N-1)+np.flipud(np.eye(N-1)))/np.sqrt(2) 33 | V1[N-r-1:,N-r-1:]=-V1[N-r-1:,N-r-1:] 34 | if N%2==0: 35 | V1[r-1,r-1]=1 36 | V=np.eye(N) 37 | V[1:,1:]=V1 38 | 39 | VHV=V.dot(H).dot(V.T) 40 | E=np.zeros((N,N)) 41 | Ev=VHV[:r+1,:r+1] 42 | Od=VHV[r+1:,r+1:] 43 | ee,ve=np.linalg.eig(Ev) 44 | idx=ee.argsort() 45 | ee=ee[idx] 46 | ve=ve[:,idx] 47 | eo,vo=np.linalg.eig(Od) 48 | idx=eo.argsort() 49 | eo=eo[idx] 50 | vo=vo[:,idx] 51 | 52 | E[:r+1,:r+1]=np.fliplr(ve) 53 | E[r+1:N,r+1:N]=np.fliplr(vo) 54 | E=V.dot(E) 55 | 56 | ind=np.matrix([range(0,r+1),range(r+1,2*r+2)]).T.ravel() 57 | if N%2==0: 58 | ind=np.delete(ind,[N-1,N+1]) 59 | else: 60 | ind=np.delete(ind,N) 61 | 62 | E=E[:,np.ravel(ind)] 63 | return E 64 | 65 | def get_E(N,p): 66 | global lastN,lastE 67 | if lastN==None: 68 | lastN=N 69 | lastE=make_E(N,p) 70 | 71 | return lastE 72 | 73 | @jit(parallel=True) 74 | #f:离散信号 a:阶数 p:近似阶数,默认len(f)/2 75 | def disfrft(f,a,p=-1): 76 | N=len(f) 77 | if p==-1: 78 | p=len(f)/2 79 | even=0 80 | if N%2==0: 81 | even = 1 82 | shft = (np.array(range(0,N))+int(N/2))%N 83 | f = np.matrix(f).T 84 | p = min(max(2,p),N-1) 85 | E = get_E(N,p) 86 | #print(E) 87 | ret = np.zeros(N).astype(complex) 88 | alist=np.append(range(0,N-1),N-1+even) 89 | pt1=np.exp(-1j*pi/2*a*alist) 90 | pt2=np.ravel(E.T.dot(f[shft].astype(complex))) 91 | ret[shft]=E.dot(pt1*pt2) 92 | return ret 93 | 94 | @jit(parallel=True) 95 | def frft2d(mat,ax,ay): 96 | m,n=mat.shape 97 | xspec=np.zeros((m,n)).astype(complex) 98 | ret=np.zeros((m,n)).astype(complex) 99 | for i in range(0,m): 100 | xspec[i,:]=disfrft(mat[i,:],ax) 101 | for j in range(0,n): 102 | ret[:,j]=disfrft(xspec[:,j],ay) 103 | return ret 104 | --------------------------------------------------------------------------------