Inputs:
----------------
x0 : 1d array
Independent axis variable of reference signal (sig0).
sig0 : 1d array
Reference signal.
x1 : 1d array
Independent axis variable of the signal to transform (sig1).
sig1 : 1d array
Signal to transform.
Outputs:
----------------
sig1_hat : 1d array
CDT of input signal sig1.
sig1_hat_old : 1d array
CDT of input signal sig1 using the old definition.
xtilde : 1d array
Independent axis variable of sig1_hat.
Let \(s(x), x\in\Omega_s\subset\mathbb{R}\) be a positive density function (PDF). The CDT of the PDF \(s(x)\) with respect to a reference PDF \(s_0(x), x\in\Omega_{s_0}\subset\mathbb{R}\) is given by the mass preserving function \(\widehat{s}(x)\) that satisfies:
where \(S(x)=\int_{inf(\Omega_s)}^{x}s(u)du\), and \(S_0(x)=\int_{inf(\Omega_{s_0})}^{x}s_0(u)du\). For continuous positive PDFs, \(\widehat{s}\) is a continuous and monotonically increasing function. If \(\widehat{s}\) is differentiable, the above equation can be rewritten as:
The examples will cover the following operations: * Forward and inverse operations of the CDT * CDT Properties - translation, scaling, and linear separability in CDT space
Generate a second signal \(I_2\) which is a shifted version \(I_1\), i.e. \(I_2 = I_1(t-\tau)\). Then convert the signals into PDFs and compute CDT for both signals
[6]:
fromscipy.ndimage.interpolationimportshifttau=0.5I1=1/(sigma*np.sqrt(2*np.pi))*np.exp(-((x-mu)**2)/(2*sigma**2))I2=np.interp(x-tau,x,I1)# Convert signals to strictly positive PDFsI1=abs(I1)+epsilonI1=I1/I1.sum()I2=abs(I2)+epsilonI2=I2/I2.sum()# Create a CDT objectcdt1=CDT()# Compute the forward transformI1_hat,I1_hat_old,xtilde=cdt1.forward(x0,I0,x,I1,rm_edge=False)I2_hat,I2_hat_old,xtilde=cdt1.forward(x0,I0,x+tau,I2,rm_edge=False)#Plot the signals and CDTsfig,ax=plt.subplots(1,2,sharex=False,sharey=False,figsize=(15,7))ax[0].plot(x,I1,'b-')ax[0].plot(x,I2,'r-')ax[0].set_title('Original signals')ax[0].set_yticks([])ax[0].legend([r'$I_1$',r'$I_2$'])ax[1].plot(xtilde,I1_hat,'b-')ax[1].plot(xtilde,I2_hat,'r--')ax[1].set_yticks([])ax[1].set_title('CDTs')ax[1].legend([r'$\hat{I}_1$',r'$\hat{I}_2$'])#ax[2].plot(xtilde, f1_hat, 'b-')#ax[2].plot(xtilde, f2_hat, 'r--')#ax[2].set_yticks([])#ax[2].set_title('Transport map')#ax[2].legend([r'$f_1$',r'$f_2$'])plt.show()
Generating a scaled version of \(I_1\), i.e. \(I_2 = I_1(\alpha t)\), and computing CDTs of both signals.
[7]:
fromscipy.statsimportnormx=np.arange(-10,10,0.001)N=len(x)x0=np.linspace(0,1,round(N/2))I0=np.ones(x0.size)I1=norm.pdf(x,0,1)# create a scaled version of I1; i.e. I2(t) = I1(alpha*t)alpha=0.75I2=np.interp(alpha*x,x,I1)# Convert signals to strictly positive PDFsI0=abs(I0)+epsilonI0=I0/I0.sum()I1=abs(I1)+epsilonI1=I1/I1.sum()I2=abs(I2)+epsilonI2=I2/I2.sum()# Create a CDT objectcdt2=CDT()# Compute the forward transformI1_hat,I1_hat_old,xtilde=cdt2.forward(x0,I0,x,I1,rm_edge=False)I2_hat,I2_hat_old,xtilde=cdt2.forward(x0,I0,x/alpha,I2,rm_edge=False)#Plot the signals and CDTsfig,ax=plt.subplots(1,2,sharex=False,sharey=False,figsize=(15,5))ax[0].plot(x,I1,'b-')ax[0].plot(x,I2,'r-')ax[0].set_title('Original signals')ax[0].set_yticks([])ax[0].legend([r'$I_1$',r'$I_2$'])ax[1].plot(xtilde,I1_hat,'b-')ax[1].plot(xtilde,I2_hat,'r--')ax[1].set_yticks([])ax[1].set_title('CDTs')ax[1].legend([r'$\hat{I}_1$',r'$\hat{I}_2$'])#ax[2].plot(xtilde, f1_hat, 'b-')#ax[2].plot(xtilde, f2_hat, 'r--')#ax[2].set_yticks([])#ax[2].set_title('Transport map')#ax[2].legend([r'$f_1$',r'$f_2$'])plt.show()
Here we are defining three classes of signal, i.e. class \(k \in \{1,2,3\}\). Each class \(k\) consists of translated versions of a \(k\)-modal Gaussian distribution.
[8]:
N=250x=np.arange(N)# Creating reference signal I0x0=np.linspace(0,1,round(N/2))I0=np.ones(x0.size)epsilon=1e-7I0=abs(I0)+epsilonI0=I0/I0.sum()# Creating three classes of translated versions of k-modal Gaussian distribution -- skolouriK=3# Number of classesL=500# Number of datapoints per classrm_edge=Falseifrm_edge:rml=2else:rml=0I=np.zeros((K,L,N))Ihat=np.zeros((K,L,x0.size-rml))kmodal_shift=[]kmodal_shift.append(np.array([0]))kmodal_shift.append(np.array([-15,15]))kmodal_shift.append(np.array([-30,0,30]))sigma=5forkinrange(K):fori,muinenumerate(np.linspace(50,200,L)):forjinrange(k+1):I[k,i,:]+=1/((k+1)*sigma*np.sqrt(2*np.pi))*np.exp(-((x-mu-kmodal_shift[k][j])**2)/(2*sigma**2))I[k,i,:]=abs(I[k,i,:])+epsilonI[k,i,:]=I[k,i,:]/I[k,i,:].sum()Ihat[k,i,:],_,xtilde=cdt.forward(x0,I0,x+mu,I[k,i,:],rm_edge)#Ihat[k,i,:]=cdt.transform(I[k,i,:])fig,ax=plt.subplots(1,3,figsize=(15,5))forcount,indexinenumerate([0,int(L/2),L-1]):forkinrange(K):ax[count].plot(x,I[k,index,:])#templateax[count].set_xticks([])ax[count].set_yticks([])ax[count].legend([r'$I_1\in C_1$',r'$I_2\in C_2$',r'$I_3\in C_3$'])plt.show()fig,ax=plt.subplots(1,3,figsize=(15,5))forcount,indexinenumerate([0,int(L/2),L-1]):forkinrange(K):ax[count].plot(xtilde,Ihat[k,index,:])#templateax[count].set_xticks([])ax[count].set_yticks([])ax[count].legend([r'$\hat{I}_1\in C_1$',r'$\hat{I}_2\in C_2$',r'$\hat{I}_3\in C_3$'])plt.show()
Now we’ll do linear classification in Signal and CDT spaces. LDA is used for visualization.
[9]:
fromsklearn.discriminant_analysisimportLinearDiscriminantAnalysisfromsklearn.svmimportLinearSVCimportwarningswarnings.filterwarnings('ignore')X=np.reshape(I,(K*L,N))#Combine the signals into a features vector XXhat=np.reshape(Ihat,(K*L,x0.size-rml))#Combine the transformed signals into a features vector Xhatdata=[X,Xhat]label=np.concatenate((np.zeros(L,),np.ones(L,),-1*np.ones(L,)))# Define the labels as -1,0,1 for the three classeslda=LinearDiscriminantAnalysis(n_components=2)svm=LinearSVC()title_=['LDA projections in the signal space','LDA projections in the CDT space']fig,ax=plt.subplots(1,2,figsize=(15,5))foriinrange(2):dataLDA=lda.fit_transform(data[i],label)ax[i].plot(dataLDA[:L,0],dataLDA[:L,1],'b*')ax[i].plot(dataLDA[L:2*L,0],dataLDA[L:2*L,1],'ro')ax[i].plot(dataLDA[2*L:,0],dataLDA[2*L:,1],'kx')x_min,x_max=ax[i].get_xlim()y_min,y_max=ax[i].get_ylim()nx,ny=400,200xx,yy=np.meshgrid(np.linspace(x_min,x_max,nx),np.linspace(y_min,y_max,ny))svm.fit(dataLDA,label)Z=svm.predict(np.c_[xx.ravel(),yy.ravel()])Z=Z[:].reshape(xx.shape)ax[i].pcolormesh(xx,yy,Z,cmap='OrRd')ax[i].contour(xx,yy,Z,linewidths=.5,colors='k')ax[i].set_xticks([])ax[i].set_yticks([])ax[i].set_title(title_[i],fontsize=fontSize)plt.show()
Let \(s(\mathbf{x}),\mathbf{x}\in\Omega_s\subset\mathbb{R}^2\) and \(s_0(\mathbf{x}),\mathbf{x}\in\Omega_{s_0}\subset\mathbb{R}^2\) define a given image and a reference image, respectively, which we consider to be appropriately normalized. The forward R-CDT of \(s(\mathbf{x})\) is given by the measure preserving function \(\widehat{s}(t,\theta)\) that satisfies:
np.random.seed(123)# Initialize RadonCDT objectradoncdt=RadonCDT()# Generate 3 classes of k-modal two-dimensional GaussiansN=100# Number of datapoints per classsigma=3# Standard deviation of each Gaussian# Initializex0_range=[0,1]x_range=[0,1]I=np.zeros((3,N,128,128))template=np.ones([128,128])#K, L = radoncdt.forward(template, I[0, 0, :, :]+1e-8).shapeK,L=radoncdt.forward(x0_range,template,x_range,I[0,0,:,:]+1e-8).shapeIhat=np.zeros((3,N,K,L))Ihat=np.random.randn(3,N,K,L)# Generate datasetforcinrange(3):foriinrange(N):for_inrange(c+1):x,y=np.random.uniform(30,98,(2,)).astype('int')I[c,i,x,y]=1I[c,i,:,:]=I[c,i,:,:]/I[c,i,:,:].sum()I[c,i,:,:]=filters.gaussian_filter(I[c,i,:,:],sigma=sigma)#Ihat[c, i, :, :] = radoncdt.forward(template, I[c, i, :, :])Ihat[c,i,:,:]=radoncdt.forward(x0_range,template,x_range,I[c,i,:,:])
[5]:
fig,ax=plt.subplots(2,3,figsize=(12,4))title=['Class 1','Class 2','Class 3']forcinrange(3):ind=np.random.randint(low=0,high=N)ax[0,c].imshow(I[c,ind,:,:])ax[0,c].set_xticks([])ax[0,c].set_yticks([])ax[0,c].set_title(title[c]+' Original space',fontsize=14)ax[1,c].imshow(Ihat[c,ind,:,:])ax[1,c].set_xticks([])ax[1,c].set_yticks([])ax[1,c].set_title(title[c]+' Radon-CDT space',fontsize=14)plt.show()
[6]:
X=np.reshape(I,(3*N,128*128))Xhat=np.reshape(Ihat,(3*N,K*L))label=np.concatenate([np.ones(N),np.ones(N)+1,np.ones(N)+2])lda=LDA(solver='svd',n_components=2)n=N# Apply LDA in Signal SpaceXlda=lda.fit_transform(X,label)svm=LinearSVC()svm.fit(Xlda,label)# Apply LDA in transform spaceXhatlda=lda.fit_transform(Xhat,label)svmhat=LinearSVC()svmhat.fit(Xhatlda,label)# Show classification boundaries in both SpacessvmClassifier=[svm,svmhat]Xdata=[Xlda,Xhatlda]title=['LDA subspace in the original space','LDA subspace in the Radon-CDT space']fig,ax=plt.subplots(1,2,figsize=(10,5))foriinrange(2):ax[i].plot(Xdata[i][:n,0],Xdata[i][:n,1],'b*')ax[i].plot(Xdata[i][n:2*n,0],Xdata[i][n:2*n,1],'ro')ax[i].plot(Xdata[i][2*n:,0],Xdata[i][2*n:,1],'kx')x_min,x_max=ax[i].get_xlim()y_min,y_max=ax[i].get_ylim()nx,ny=400,200xx,yy=np.meshgrid(np.linspace(x_min,x_max,nx),np.linspace(y_min,y_max,ny))Z=svmClassifier[i].predict(np.c_[xx.ravel(),yy.ravel()])Z=Z[:].reshape(xx.shape)ax[i].pcolormesh(xx,yy,Z,cmap='OrRd')ax[i].contour(xx,yy,Z,linewidths=.5,colors='k')ax[i].set_title(title[i],fontsize=14)ax[i].set_xticks([])ax[i].set_yticks([])
/Users/ar3fx/anaconda3/anaconda3/lib/python3.7/site-packages/sklearn/discriminant_analysis.py:388: UserWarning: Variables are collinear.
warnings.warn("Variables are collinear.")
/Users/ar3fx/anaconda3/anaconda3/lib/python3.7/site-packages/sklearn/svm/base.py:929: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.
"the number of iterations.", ConvergenceWarning)
/Users/ar3fx/anaconda3/anaconda3/lib/python3.7/site-packages/sklearn/discriminant_analysis.py:388: UserWarning: Variables are collinear.
warnings.warn("Variables are collinear.")
[ ]:
3D Radon-Cumulative Distribution Transform (3D R-CDT)
This tutorial will demonstrate: how to use the forward and inverse operations of the 3D R-CDT in the PyTransKit package.
Inputs:
----------------
x0_range : 1x2 array
contains lower and upper limits for independent variable of reference signal (sig0). Example: [0,1].
sig0 : 3d array, shape (L, L, L)
Reference signal.
x1_range : 1x2 array
contains lower and upper limits for independent variable of input signal (sig1). Example: [0,1].
sig1 : 3d array, shape (L, L, L)
Signal to transform.
Outputs:
----------------
sig1_hat : 2d array, shape(L, Npoints)
R-CDT of 3D input signal sig1.
use_gpu=False# Set it True if want GPU supportx0_range=[0,1]x_range=[0,1]Npoints=1000# Create an instance of 3D R-CDTrcdt3D=RadonCDT3D(Npoints,use_gpu)tic=time.time()# Forward functionimg3Dhat=rcdt3D.forward(x0_range,i03D/np.sum(img3D),x_range,img3D/np.sum(img3D),rm_edge=False)toc=time.time()Run_time=toc-ticprint("Forward 3D RCDT is done in {} seconds".format(Run_time))
Forward 3D RCDT is done in 19.50796389579773 seconds
tic=time.time()# Inverse functionimg3D_recon=rcdt3D.inverse(img3Dhat,i03D,x_range)toc=time.time()Run_time=toc-ticprint("Inverse 3D RCDT is done in {} seconds".format(Run_time))
Inverse 3D RCDT is done in 20.88492465019226 seconds
Show specific slices from the input 3D phantom image and reconstructed image
[5]:
sliceSel=int(0.5*img3D.shape[0])# plot original 3D imageplt.figure(figsize=(15,5))plt.suptitle('3D Phantom')plt.subplot(131)plt.imshow(img3D[sliceSel,:,:])plt.title('Axial view')plt.subplot(132)plt.imshow(img3D[:,sliceSel,:])plt.title('Coronal view')plt.subplot(133)plt.imshow(img3D[:,:,sliceSel])plt.title('Sagittal view')plt.show()# plot 3D Radon transformfig=plt.figure(figsize=(15,5))plt.imshow(img3Dhat)plt.title('3D R-CDT')plt.show()# plot 3D reconstructionplt.figure(figsize=(15,5))plt.suptitle('Reconstructed 3D Phantom (number of projections = {})'.format(Npoints))plt.subplot(131)plt.imshow(np.log10(.1+img3D_recon[sliceSel,:,:]))plt.title('Axial view')plt.subplot(132)plt.imshow(np.log10(.1+img3D_recon[:,sliceSel,:]))plt.title('Coronal view')plt.subplot(133)plt.imshow(np.log10(.1+img3D_recon[:,:,sliceSel]))plt.title('Sagittal view')plt.show()
[ ]:
Continuous Linear Optimal Transport Transform (CLOT)
This tutorial will demonstrate: how to use the forward and inverse operations of the CLOT in the the PyTransKit package.
Continuous Linear Optimal Transport Transform.
Parameters
----------
lr : float (default=0.01)
Learning rate.
momentum : float (default=0.)
Nesterov accelerated gradient descent momentum.
decay : float (default=0.)
Learning rate decay over each update.
max_iter : int (default=300)
Maximum number of iterations.
tol : float (default=0.001)
Stop iterating when change in cost function is below this threshold.
verbose : int (default=1)
Verbosity during optimization. 0=no output, 1=print cost,
2=print all metrics.
Attributes
-----------
displacements_ : array, shape (2, height, width)
Displacements u. First index denotes direction: displacements_[0] is
y-displacements, and displacements_[1] is x-displacements.
transport_map_ : array, shape (2, height, width)
Transport map f. First index denotes direction: transport_map_[0] is
y-map, and transport_map_[1] is x-map.
displacements_initial_ : array, shape (2, height, width)
Initial displacements computed using the method by Haker et al.
transport_map_initial_ : array, shape (2, height, width)
Initial transport map computed using the method by Haker et al.
cost_ : list of float
Value of cost function at each iteration.
curl_ : list of float
Curl at each iteration.
References
----------
[A continuous linear optimal transport approach for pattern analysis in
image datasets]
(https://www.sciencedirect.com/science/article/pii/S0031320315003507)
[Optimal mass transport for registration and warping]
(https://link.springer.com/article/10.1023/B:VISI.0000036836.66311.97)
Inputs:
----------------
sig0 : array, shape (height, width)
Reference image.
sig1 : array, shape (height, width)
Signal to transform.
Outputs:
----------------
lot : array, shape (2, height, width)
LOT transform of input image sig1. First index denotes direction:
lot[0] is y-LOT, and lot[1] is x-LOT.
Apply forward transport map: sig0_recon = apply_forward_map(transport_map, sig1)
Inputs:
----------------
transport_map : array, shape (2, height, width)
Forward transport map.
sig1 : array, shape (height, width)
Signal to transform.
Outputs:
----------------
sig0_recon : array, shape (height, width)
Reconstructed reference signal sig0.
Apply inverse transport map: sig1_recon = inverse(transport_map, sig0)
Inputs:
----------------
transport_map : array, shape (2, height, width)
Forward transport map. Inverse is computed in this function.
sig0 : array, shape (height, width)
Reference signal.
Outputs:
----------------
sig1_recon : array, shape (height, width)
Reconstructed signal sig1.
The Continuous Linear Optimal Transport (CLOT) transform \(\widehat s\) of a density function \(s(\mathbf x)\) is defined as the optimal transport map from a reference density \(s_0(\mathbf x)\) to \(s(\mathbf x)\). Specifically, let \(s_0(\mathbf x), s(\mathbf x)\) be positive functions defined on domains \(\Omega_{s_0}, \Omega_{s}\subseteq \mathbb R^d\) respectively and such that
\[\int_{\Omega_{s_0}}s_0(\mathbf x) d\mathbf x = \int_{\Omega_{s}}s(\mathbf x) d\mathbf x =1 \quad \text{(normalized)}.\]
Assuming that the density functions \(s_0, s\) have finite second moments, there is an unique solution
to the Monge optimal transport problem:
Any map \(T\) satisfying constraint in (2) is called a transport (mass-preserving) map between \(s_0\) and \(s\). In particular, when \(T\) is bijective and continuously differentiable, the mass-preserving constraint in (2) becomes
The minimizer to the above Monge problem is called an optimal transport map. Given a fixed reference density \(s_0\), the LOT transform \(\widehat s\) of a density function \(s\) is defined to the unique optimal transport map from \(s_0\) to \(s\). Moreover Brenier [1] shows that any optimal transport map can be written as the gradient of a convex function, i.e., \(\widehat s = \nabla \phi\) where \(\phi\) is a convex function. Following the generic approach described
in [2], Kolouri et al. [3] employed an iterative algorithm minimizing (1) with constraint (2) via the gradient descent idea.
[1] Y. Brenier. Polar factorization and monotone rearrangement of vector-valuedfunctions.Commun. Pure Appl. Math., 44(4):375–417, 1991.1 [2] S. Haker, L. Zhu, A. Tannenbaum, and S. Angenent. Optimal mass transport forregistration and warping.Int. J. Comput. Vis., 60(4):225–240, 2004. [3] S. Kolouri, A. Tosun, J. Ozolek, and G. Rohde. A continuous linear optimal trans-port approach for pattern analysis in image datasets.Pattern Recognit., 51:453–462, 2016.
The examples will cover the following operations: * Forward operation of the CLOT * Apply forward map to transport \(I_1\) to \(I_0\) * Apply inverse map to reconstruct \(I_1\) from \(I_0\)
Read and normalize two images \(I_0\) and \(I_1\).
[2]:
importmatplotlib.imageasmpimgimportsyssys.path.append('../')frompytranskit.optrans.utilsimportsignal_to_pdfI0=mpimg.imread('images/I0.bmp')I1=mpimg.imread('images/I1.bmp')# Convert images to PDFsimg0=signal_to_pdf(I0,sigma=1.,total=100.)img1=signal_to_pdf(I1,sigma=1.,total=100.)fig,ax=plt.subplots(1,2,sharex=True,sharey=True,figsize=(5,10))ax[0].imshow(img0,cmap='gray')ax[1].imshow(img1,cmap='gray')ax[0].set_title('$I_0$')ax[1].set_title('$I_1$')ax[0].axis('off')ax[1].axis('off')plt.show()
frompytranskit.optrans.continuous.clotimportCLOTfrompytranskit.optrans.utilsimportplot_displacements2dclot=CLOT(max_iter=500,lr=1e-6,tol=1e-4,verbose=0)# calculate CLOTlot=clot.forward(img0,img1)# transport map and displacement map from I1 to I0tmap10=clot.transport_map_disp=clot.displacements_# apply forward map to transport I1 to I0img0_recon=clot.apply_forward_map(tmap10,img1)fig,ax=plt.subplots(1,4,sharex=True,sharey=True,figsize=(10,20))ax[0].imshow(img0,cmap='gray')ax[0].set_title('$I_0$')ax[1].imshow(img1,cmap='gray')ax[1].set_title('$I_1$')ax[2].imshow(img0_recon,cmap='gray')ax[2].set_title('$f^{\'}I_1\circ f$')plot_displacements2d(disp,ax=ax[3],count=20)ax[3].set_title('Displacement')plt.show()
Inputs:
----------------
num_classes : integer value
totale number of classes in the dataset.
rm_edge : boolean
IF TRUE the first and last points of CDTs will be removed.
Outputs:
----------------
cdt_ns_obj : class object
Instance of the class CDT_NS.
Fit function: cdt_ns_obj.fit(Xtrain, Ytrain, no_deform_model)
Inputs:
----------------
Xtrain : array-like, shape (n_samples, n_columns)
1D data for training.
Ytrain : ndarray of shape (n_samples,)
Labels of the training samples.
no_deform_model : boolean flag; IF TRUE, no deformation model will be added
default = False.
The following example will demonstrate how to: * create and initialize an instance of the class CDT_NS * train the model with training 1D samples * apply the model to predict calss labels of the test 1D samples In this example we have used a synthetic dataset (1D) stored in the data folder. The dataset contains two classes. Class 0: different translated versions of Gaussian signal Class 1: translated versions of summation of two Gaussian signals
For loading data we have used load_data_1D function from the pytranskit/classifier/utils.py script. It takes name and directory of the dataset, and total number of classes as input. Returns both train and test samples in two separate 2d arrays of shape (n_samples, n_columns), and corresponding class labels. User can use there own implementation to load data, just need to make sure that the output arrays are consistent.
[3]:
datadir='./data'dataset='synthetic_1D'num_classes=2# total number of classes in the dataset(x_train,y_train),(x_test,y_test)=load_data_1D(dataset,num_classes,datadir)# load_data function from utils.py
loading data from mat files
x_train.shape (1400, 201) x_test.shape (600, 201)
saved to ./data/synthetic_1D/dataset.hdf5
In this example we have used 512 randomly chosen samples per class to train the model. We have used another function take_train_samples function from utils.py script for this. User can use their own script.
[4]:
n_samples_perclass=512# total number of training samples per class used in this examplex_train_sub,y_train_sub=take_train_samples(x_train,y_train,n_samples_perclass,num_classes,repeat=0)# function from utils.py
This function takes the train samples and labels as input, and stores the basis vectors for corresponding classes in a private variable. This variable will be used in the predict function in the test phase
Inputs:
----------------
num_classes : integer value
totale number of classes in the dataset.
thetas : 1d array
angles in degrees for taking radon projections. Example: thetas=numpy.linspace(0,180,45)
rm_edge : boolean
IF TRUE the first and last points of RCDTs will be removed.
Outputs:
----------------
rcdt_ns_obj : class object
Instance of the class RCDT_NS.
Fit function: rcdt_ns_obj.fit(Xtrain, Ytrain, no_deform_model)
Inputs:
----------------
Xtrain : 3d array, shape (n_samples, n_rows, n_columns)
Image data for training.
Ytrain : 1d array, shape (n_samples,)
Labels of the training images.
no_deform_model : boolean
IF TRUE, no deformation model will be added
Inputs:
----------------
Xtest : 3d array, shape (n_samples, n_rows, n_columns)
Image data for testing.
use_gpu : boolean
IF TRUE, use gpu for calculations.
Outputs:
----------------
preds : 1d array, shape (n_samples,)
Predicted labels for test samples.
The following example will demonstrate how to: * create and initialize an instance of the class RCDT_NS * train the model with training images * apply the model to predict calss labels of the test images In this example we have used MNIST dataset stored in the data folder
For loading data we have used load_data function from the pytranskit/classifier/utils.py script. It takes name and directory of the dataset, and total number of classes as input. Returns both train and test images in two separate 3d arrays of shape (n_samples, n_rows, n_columns), and corresponding class labels. User can use there own implementation to load data, just need to make sure that the output arrays are consistent.
[3]:
datadir='./data'dataset='MNIST'num_classes=10# total number of classes in the dataset(x_train,y_train),(x_test,y_test)=load_data(dataset,num_classes,datadir)# load_data function from utils.py
loading data from mat files
x_train.shape (60000, 28, 28) x_test.shape (10000, 28, 28)
saved to ./data/MNIST/dataset.hdf5
In this example we have used 512 randomly chosen samples per class to train the model. We have used another function take_train_samples function from utils.py script for this. User can use their own script.
[4]:
n_samples_perclass=512# total number of training samples per class used in this examplex_train_sub,y_train_sub=take_train_samples(x_train,y_train,n_samples_perclass,num_classes,repeat=0)# function from utils.py
theta=np.linspace(0,176,45)# choose the angles in degrees that will be used to calculate Radon projectionsrcdt_ns_obj=RCDT_NS(num_classes,theta,rm_edge=True)
This function takes the train samples and labels as input, and stores the basis vectors for corresponding classes in a private variable. This variable will be used in the predict function in the test phase
[6]:
rcdt_ns_obj.fit(x_train_sub,y_train_sub)
Calculating RCDTs for training images ...
Generating basis vectors for each class ...
Inputs:
----------------
num_classes : integer value
totale number of classes in the dataset.
Npoints : scalar; number of radon projections
use_gpu : boolean; IF TRUE, use GPU to calculate 3D RCDT
rm_edge : boolean
IF TRUE, the first and last points of RCDTs will be removed.
Outputs:
----------------
rcdt_ns_obj : class object
Instance of the class RCDT_NS.
Fit function: rcdt_ns_obj.fit(Xtrain, Ytrain, no_deform_model)
Inputs:
----------------
Xtrain : 4d array, shape (n_samples, L, L, L)
3D Image data for training. L is the dimension along X,Y, and Z axes.
Ytrain : 1d array, shape (n_samples,)
Labels of the training images.
no_deform_model : boolean
IF TRUE, no deformation model will be added
Inputs:
----------------
Xtest : 4d array, shape (n_samples, L, L, L)
3D Image data for testing. L is the dimension along X,Y, and Z axes.
use_gpu : boolean
IF TRUE, use gpu for calculations.
Outputs:
----------------
preds : 1d array, shape (n_samples,)
Predicted labels for test samples.
The following example will demonstrate how to: * create and initialize an instance of the class 3D-RCDT_NS * train the model with training images * apply the model to predict calss labels of the test images In this example we have used MNIST dataset stored in the data folder
For loading data we have used load_data_3D function from the pytranskit/classifier/utils.py script. It takes name and directory of the dataset, and total number of classes as input. Returns both train and test images in two separate 4d arrays of shape (n_samples, n_rows, n_columns, n_columns), and corresponding class labels. User can use there own implementation to load data, just need to make sure that the output arrays are consistent. In this example, we have used a synthetic 3D
dataset with two classes: class 0 contains one Gaussian blob in each image, class 1 contains two Gaussian blobs in each image. Note: The 3D RCDT implemented in PyTransKit, 3D images need to be equal shape along all three directions, i.e. n_rows=n_columns=n_columns=L. Therefore, if the original image does not have equal length in all axes, users need to zero pad to make all the dimensions equal.
[3]:
datadir='./data'dataset='synthetic_3D'num_classes=2# total number of classes in the dataset(x_train,y_train),(x_test,y_test)=load_data_3D(dataset,num_classes,datadir)# load_data function from utils.py
loading data from mat files
split training class 0 data.shape (50, 32, 32, 32)
split training class 1 data.shape (50, 32, 32, 32)
split testing class 0 data.shape (50, 32, 32, 32)
split testing class 1 data.shape (50, 32, 32, 32)
x_train.shape (100, 32, 32, 32) x_test.shape (100, 32, 32, 32)
saved to ./data/synthetic_3D/dataset.hdf5
In this example we have used 32 randomly chosen samples per class to train the model. We have used another function take_train_samples function from utils.py script for this. User can use their own script.
[4]:
n_samples_perclass=32# total number of training samples per class used in this examplex_train_sub,y_train_sub=take_train_samples(x_train,y_train,n_samples_perclass,num_classes,repeat=0)# function from utils.py
This function takes the train samples and labels as input, and stores the basis vectors for corresponding classes in a private variable. This variable will be used in the predict function in the test phase
[6]:
rcdt_ns_obj.fit(x_train_sub,y_train_sub)
Calculating RCDTs for training images ...
Generating basis vectors for each class ...
In this example, we are interested in estimating the time delay (\(\tau\)), i.e. \(g_p(t) = t - \tau\). Therefore \(z_g(t)=z(t - \tau)\) and \(s_g(t) = B(z_g)(t)\).
Normalized measured signal with noise \(\eta \sim \mathcal{N}(0,\sigma^2)\) is given by,
importnumpyasnpimportmatplotlib.pyplotasplt# To use the CDT first install the PyTransKit package using:# pip install pytranskitfrompytranskit.optrans.continuous.cdtimportCDTN=400dt=0.025t=np.linspace(-N/2*dt,(N/2-1)*dt,N)f=1epsilon=1e-8# Original signalgwin=np.exp(-t**2/2)z=gwin*np.sin(2*np.pi*f*t)+epsilons=z**2/np.linalg.norm(z)**2# zero mean additive Gaussian noisesigma=0.1# standard deviationSNRdb=10*np.log10(np.mean(z**2)/sigma**2)print('SNR: {} dB'.format(SNRdb))noise=np.random.normal(0,sigma,N)# Signal after delaytau=50.3*dtgwin=np.exp(-(t-tau)**2/2)zg=gwin*np.sin(2*np.pi*f*(t-tau))+noise+epsilonr=zg**2/np.linalg.norm(zg)**2# Plot s and rfontSize=14fig,ax=plt.subplots(1,2,sharex=True,sharey=True,figsize=(10,5))ax[0].plot(t,s,'b-',linewidth=2)ax[0].set_title('$s(t)$',fontsize=fontSize)ax[1].plot(t,r,'r-',linewidth=2)ax[1].set_title('$r(t)$',fontsize=fontSize)plt.show()
\begin{align}
\tilde{S}_g(t) = \frac{E[R(t)]\{\mathcal{E}_z+\sigma^2(t_N-t_1)\}-\sigma^2(t-t_1)}{\mathcal{E}_z}, \quad t_1\leq t \leq t_N
\end{align}
where \(R(t)\) is the CDF associated with \(r(t)\), \(\sigma\) is the standard deviation of noise, and \(\mathcal{E}_z\) is the total energy of the noise free signal.
[22]:
# Calculate the noise-corrected CDFR=np.cumsum(r)# CDF of r(t)Ez=np.mean(z**2)*(t[-1]-t[0])# Energy of the signalStilde=(R*(Ez+sigma**2*(t[-1]-t[0]))-sigma**2*(t-t[0]))/Ez# Preserve the non-decreasing property of CDFsmind=np.argmin(Stilde)Mind=np.argmax(Stilde)Stilde[0:mind]=Stilde[mind]Stilde[Mind:]=Stilde[Mind]foriinrange(len(Stilde)-1):ifStilde[i+1]<=Stilde[i]:Stilde[i+1]=Stilde[i]+epsilonStilde=(Stilde-np.min(Stilde))/(np.max(Stilde)-np.min(Stilde))# Plot R and StildefontSize=14fig,ax=plt.subplots(1,2,sharex=True,sharey=True,figsize=(10,5))ax[0].plot(t,R,'r-',linewidth=2)ax[0].set_title('$R(t)$',fontsize=fontSize)ax[1].plot(t,Stilde,'k--',linewidth=2)ax[1].set_title('$\widetilde{S}(t)$',fontsize=fontSize)plt.show()# Calculate the noise-corrected PDFsg=Stildesg[1:]-=sg[:-1].copy()sg+=epsilon# Plot R and StildefontSize=14fig,ax=plt.subplots(1,2,sharex=True,sharey=True,figsize=(10,5))ax[0].plot(t,r,'r-',linewidth=2)ax[0].set_title('$r(t)$',fontsize=fontSize)ax[1].plot(t,sg,'k--',linewidth=2)ax[1].set_title('$\widetilde{s}_g(t)$',fontsize=fontSize)plt.show()
# Reference signalt0=np.linspace(0,1,N)z0=np.ones(t0.size)+epsilons0=z0**2/np.linalg.norm(z0)**2# Create a CDT objectcdt=CDT()# Compute the forward transforms_hat,s_hat_old,xtilde=cdt.forward(t0,s0,t,s,rm_edge=False)sg_hat,sg_hat_old,xtilde=cdt.forward(t0,s0,t,sg,rm_edge=False)# remove the edgess_hat=s_hat[25:N-25]sg_hat=sg_hat[25:N-25]xtilde=xtilde[25:N-25]# Plot s_hat and sg_hatfontSize=14fig,ax=plt.subplots(1,2,sharex=True,sharey=True,figsize=(10,5))ax[0].plot(xtilde,s_hat,'b-',linewidth=2)ax[0].set_title('$\widehat{s}(t)$',fontsize=fontSize)ax[1].plot(xtilde,sg_hat,'r-',linewidth=2)ax[1].set_title('$\widehat{s}_g(t)$',fontsize=fontSize)plt.show()
estimate=np.mean(sg_hat)-np.mean(s_hat)print('\nTrue value of time delay: '+str(tau)+' seconds')print('Estimated value of time delay: '+str(estimate)+' seconds\n')
True value of time delay: 1.2575 seconds
Estimated value of time delay: 1.2562758076649236 seconds
In this example, we are interested in estimating the time delay (\(\tau\)) and linear dispersion (\(\omega\)) parameters, i.e. \(g_p(t) = \omega t - \tau\). Therefore \(z_g(t)=z(\omega t - \tau)\) and \(s_g(t) = B(z_g)(t)\).
Normalized measured signal with noise \(\eta \sim \mathcal{N}(0,\sigma^2)\) is given by,
Let, \(\vec{p} = [\tau, \omega]^T\), and \(\hat{s}\) and \(\hat{r}\) be the CDTs of \(s(t)\) and \(r(t)\), respectively. The estimates are calculated as,
importnumpyasnpimportmatplotlib.pyplotasplt# To use the CDT first install the PyTransKit package using:# pip install pytranskitfrompytranskit.optrans.continuous.cdtimportCDTN=400dt=0.025t=np.linspace(-N/2*dt,(N/2-1)*dt,N)f=1epsilon=1e-8# Original signalgwin=np.exp(-t**2/2)z=gwin*np.sin(2*np.pi*f*t)+epsilons=z**2/np.linalg.norm(z)**2# zero mean additive Gaussian noisesigma=0.1# standard deviationSNRdb=10*np.log10(np.mean(z**2)/sigma**2)print('SNR: {} dB'.format(SNRdb))noise=np.random.normal(0,sigma,N)# Signal after delay and dispersionomega=0.8tau=10.3*dtgwin=np.exp(-(omega*t-tau)**2/2)zg=gwin*np.sin(2*np.pi*f*(omega*t-tau))+noise+epsilonr=zg**2/np.linalg.norm(zg)**2# Plot s and sgfontSize=14fig,ax=plt.subplots(1,2,sharex=True,sharey=True,figsize=(10,5))ax[0].plot(t,s,'b-',linewidth=2)ax[0].set_title('$s(t)$',fontsize=fontSize)ax[1].plot(t,r,'r-',linewidth=2)ax[1].set_title('$r(t)$',fontsize=fontSize)plt.show()
\begin{align}
\tilde{S}_g(t) = \frac{E[R(t)]\{\mathcal{E}_z+\sigma^2(t_N-t_1)\}-\sigma^2(t-t_1)}{\mathcal{E}_z}, \quad t_1\leq t \leq t_N
\end{align}
where \(R(t)\) is the CDF associated with \(r(t)\), \(\sigma\) is the standard deviation of noise, and \(\mathcal{E}_z\) is the total energy of the noise free signal.
[14]:
# Calculate the noise-corrected CDFR=np.cumsum(r)# CDF of r(t)Ez=np.mean(z**2)*(t[-1]-t[0])# Energy of the signalStilde=(R*(Ez+sigma**2*(t[-1]-t[0]))-sigma**2*(t-t[0]))/Ez# Preserve the non-decreasing property of CDFsmind=np.argmin(Stilde)Mind=np.argmax(Stilde)Stilde[0:mind]=Stilde[mind]Stilde[Mind:]=Stilde[Mind]foriinrange(len(Stilde)-1):ifStilde[i+1]<=Stilde[i]:Stilde[i+1]=Stilde[i]+epsilonStilde=(Stilde-np.min(Stilde))/(np.max(Stilde)-np.min(Stilde))# Plot R and StildefontSize=14fig,ax=plt.subplots(1,2,sharex=True,sharey=True,figsize=(10,5))ax[0].plot(t,R,'r-',linewidth=2)ax[0].set_title('$R(t)$',fontsize=fontSize)ax[1].plot(t,Stilde,'k--',linewidth=2)ax[1].set_title('$\widetilde{S}(t)$',fontsize=fontSize)plt.show()# Calculate the noise-corrected PDFsg=Stildesg[1:]-=sg[:-1].copy()sg+=epsilon# Plot R and StildefontSize=14fig,ax=plt.subplots(1,2,sharex=True,sharey=True,figsize=(10,5))ax[0].plot(t,r,'r-',linewidth=2)ax[0].set_title('$r(t)$',fontsize=fontSize)ax[1].plot(t,sg,'k--',linewidth=2)ax[1].set_title('$\widetilde{s}_g(t)$',fontsize=fontSize)plt.show()
# Reference signalt0=np.linspace(0,1,N)z0=np.ones(t0.size)+epsilons0=z0**2/np.linalg.norm(z0)**2# Create a CDT objectcdt=CDT()# Compute the forward transforms_hat,s_hat_old,xtilde=cdt.forward(t0,s0,t,s,rm_edge=False)sg_hat,sg_hat_old,xtilde=cdt.forward(t0,s0,t,sg,rm_edge=False)# remove the edgess_hat=s_hat[25:N-25]sg_hat=sg_hat[25:N-25]xtilde=xtilde[25:N-25]# Plot s_hat and sg_hatfontSize=14fig,ax=plt.subplots(1,2,sharex=True,sharey=True,figsize=(10,5))ax[0].plot(xtilde,s_hat,'b-',linewidth=2)ax[0].set_title('$\widehat{s}(t)$',fontsize=fontSize)ax[1].plot(xtilde,sg_hat,'r-',linewidth=2)ax[1].set_title('$\widehat{s}_g(t)$',fontsize=fontSize)plt.show()
Calculate time delay and linear dispersion estimates
[16]:
X=-1*np.ones([len(s_hat),2])X[:,0]=np.transpose(sg_hat)estimates=np.linalg.solve(np.matmul(np.transpose(X),X),np.matmul(np.transpose(X),np.transpose(s_hat)))print('\nTrue value of time delay: '+str(tau)+' seconds')print('Estimated value of time delay: '+str(estimates[1])+' seconds\n')print('True value of linear dispersion: '+str(omega))print('Estimated value of linear dispersion: '+str(estimates[0])+'\n')
True value of time delay: 0.2575 seconds
Estimated value of time delay: 0.2694287224582905 seconds
True value of linear dispersion: 0.8
Estimated value of linear dispersion: 0.8408065181070804
ndim (int or None (default=None)) – Number of dimensions that array should have. If None, the dimensions
are not checked
dtype (string, type, list of types or None (default='numeric')) – Data type of result. If None, the dtype of the input is preserved.
If ‘numeric’, dtype is preserved unless array.dtype is object.
If dtype is a list of types, conversion on the first type is only
performed if the dtype of the input is not in the list.
force_all_finite (boolean (default=True)) – Whether to raise an error on np.inf and np.nan in array
force_strictly_positive (boolean (default=False)) – Whether to raise an error if any array elements are <= 0
Returns:
array_converted – The converted and validated array.
img (2d array, shape (height, width)) – Image to interpolate.
f (3d array, shape (2, height, width)) – Coordinates of at which img is defined. First dimension f[0] corresponds
to y-coordinates, second dimension f[1] is x-coordinates.
order (int (default=1)) – Order of the interpolation. Must be in the range 0-2.
fill_value (float (default=0.)) – Value used for points outside the boundaries.
Returns:
Image interpolated on to regular gird defined by: x = 0:(width-1),
y = 0:(height-1).
img (2d array, shape (height, width)) – Image to interpolate. This function assumes a grid of sample points:
x = 0:(width-1), y = 0:(height-1).
f (3d array, shape (2, height, width)) – Coordinates of interpolated points. First dimension f[0] corresponds to
y-coordinates, second dimension f[1] is x-coordinates.
order (int (default=1)) – Order of the spline interpolation. Must be in the range 0-5.
fill_value (float (default=0.)) – Value used for points outside the boundaries.
ndim (int or None (default=None)) – Number of dimensions that array should have. If None, the dimensions
are not checked
dtype (string, type, list of types or None (default='numeric')) – Data type of result. If None, the dtype of the input is preserved.
If ‘numeric’, dtype is preserved unless array.dtype is object.
If dtype is a list of types, conversion on the first type is only
performed if the dtype of the input is not in the list.
force_all_finite (boolean (default=True)) – Whether to raise an error on np.inf and np.nan in array
force_strictly_positive (boolean (default=False)) – Whether to raise an error if any array elements are <= 0
Returns:
array_converted – The converted and validated array.
One-dimensional linear interpolation for monotonically increasing sample points.
Returns the one-dimensional piecewise linear interpolant to a function
with given discrete data points (xp, fp), evaluated at x.
Parameters:
x (array_like) – The x-coordinates at which to evaluate the interpolated values.
xp (1-D sequence of floats) – The x-coordinates of the data points, must be increasing if argument
period is not specified. Otherwise, xp is internally sorted after
normalizing the periodic boundaries with xp=xp%period.
fp (1-D sequence of float or complex) – The y-coordinates of the data points, same length as xp.
left (optional float or complex corresponding to fp) – Value to return for x < xp[0], default is fp[0].
right (optional float or complex corresponding to fp) – Value to return for x > xp[-1], default is fp[-1].
period (None or float, optional) –
A period for the x-coordinates. This parameter allows the proper
interpolation of angular x-coordinates. Parameters left and right
are ignored if period is specified.
New in version 1.10.0.
Returns:
y – The interpolated values, same shape as x.
Return type:
float or complex (corresponding to fp) or ndarray
Raises:
ValueError – If xp and fp have different length
If xp or fp are not 1-D sequences
If period == 0
See also
scipy.interpolate
Warning
The x-coordinate sequence is expected to be increasing, but this is not
explicitly enforced. However, if the sequence xp is non-increasing,
interpolation results are meaningless.
Note that, since NaN is unsortable, xp also cannot contain NaNs.
A simple check for xp being strictly increasing is:
Get the (smoothed) probability density function of a signal.
Performs the following operations:
1. Smooth sigma with a Gaussian filter
2. Normalize signal such that it sums to 1
3. Add epsilon to ensure signal is strictly positive
4. Re-normalize signal such that it sums to total
Parameters:
input (ndarray) – Input array
sigma (scalar) – Standard deviation for Gaussian kernel. The standard deviations of the
Gaussian filter are given for each axis as a sequence, or as a single
number, in which case it is equal for all axes.
epsilon (scalar) – Offset to ensure that signal is strictly positive.
ndim (int or None (default=None)) – Number of dimensions that array should have. If None, the dimensions
are not checked
dtype (string, type, list of types or None (default='numeric')) – Data type of result. If None, the dtype of the input is preserved.
If ‘numeric’, dtype is preserved unless array.dtype is object.
If dtype is a list of types, conversion on the first type is only
performed if the dtype of the input is not in the list.
force_all_finite (boolean (default=True)) – Whether to raise an error on np.inf and np.nan in array
force_strictly_positive (boolean (default=False)) – Whether to raise an error if any array elements are <= 0
Returns:
array_converted – The converted and validated array.
Return the Discrete Cosine Transform of arbitrary type sequence x.
Parameters:
x (array_like) – The input array.
type ({1, 2, 3, 4}, optional) – Type of the DCT (see Notes). Default type is 2.
n (int, optional) – Length of the transform. If n<x.shape[axis], x is
truncated. If n>x.shape[axis], x is zero-padded. The
default results in n=x.shape[axis].
axis (int, optional) – Axis along which the dct is computed; the default is over the
last axis (i.e., axis=-1).
norm ({None, 'ortho'}, optional) – Normalization mode (see Notes). Default is None.
overwrite_x (bool, optional) – If True, the contents of x can be destroyed; the default is False.
For a single dimension array x, dct(x,norm='ortho') is equal to
MATLAB dct(x).
There are, theoretically, 8 types of the DCT, only the first 4 types are
implemented in scipy. ‘The’ DCT generally refers to DCT type 2, and ‘the’
Inverse DCT generally refers to DCT type 3.
Type I
There are several definitions of the DCT-I; we use the following
(for norm=None)
The (unnormalized) DCT-III is the inverse of the (unnormalized) DCT-II, up
to a factor 2N. The orthonormalized DCT-III is exactly the inverse of
the orthonormalized DCT-II.
Type IV
There are several definitions of the DCT-IV; we use the following
(for norm=None)
If norm='ortho', y[k] is multiplied by a scaling factor f
\[f = \frac{1}{\sqrt{2N}}\]
New in version 1.2.0: Support for DCT-IV.
References
Examples
The Type 1 DCT is equivalent to the FFT (though faster) for real,
even-symmetrical inputs. The output is also real and even-symmetrical.
Half of the FFT input is used to generate half of the FFT output:
img (2d array, shape (height, width)) – Image to interpolate.
f (3d array, shape (2, height, width)) – Coordinates of at which img is defined. First dimension f[0] corresponds
to y-coordinates, second dimension f[1] is x-coordinates.
order (int (default=1)) – Order of the interpolation. Must be in the range 0-2.
fill_value (float (default=0.)) – Value used for points outside the boundaries.
Returns:
Image interpolated on to regular gird defined by: x = 0:(width-1),
y = 0:(height-1).
Return the Inverse Discrete Cosine Transform of an arbitrary type sequence.
Parameters:
x (array_like) – The input array.
type ({1, 2, 3, 4}, optional) – Type of the DCT (see Notes). Default type is 2.
n (int, optional) – Length of the transform. If n<x.shape[axis], x is
truncated. If n>x.shape[axis], x is zero-padded. The
default results in n=x.shape[axis].
axis (int, optional) – Axis along which the idct is computed; the default is over the
last axis (i.e., axis=-1).
norm ({None, 'ortho'}, optional) – Normalization mode (see Notes). Default is None.
overwrite_x (bool, optional) – If True, the contents of x can be destroyed; the default is False.
For a single dimension array x, idct(x,norm='ortho') is equal to
MATLAB idct(x).
‘The’ IDCT is the IDCT of type 2, which is the same as DCT of type 3.
IDCT of type 1 is the DCT of type 1, IDCT of type 2 is the DCT of type
3, and IDCT of type 3 is the DCT of type 2. IDCT of type 4 is the DCT
of type 4. For the definition of these types, see dct.
Examples
The Type 1 DCT is equivalent to the DFT for real, even-symmetrical
inputs. The output is also real and even-symmetrical. Half of the IFFT
input is used to generate half of the IFFT output:
img (2d array, shape (height, width)) – Image to interpolate. This function assumes a grid of sample points:
x = 0:(width-1), y = 0:(height-1).
f (3d array, shape (2, height, width)) – Coordinates of interpolated points. First dimension f[0] corresponds to
y-coordinates, second dimension f[1] is x-coordinates.
order (int (default=1)) – Order of the spline interpolation. Must be in the range 0-5.
fill_value (float (default=0.)) – Value used for points outside the boundaries.
Get the (smoothed) probability density function of a signal.
Performs the following operations:
1. Smooth sigma with a Gaussian filter
2. Normalize signal such that it sums to 1
3. Add epsilon to ensure signal is strictly positive
4. Re-normalize signal such that it sums to total
Parameters:
input (ndarray) – Input array
sigma (scalar) – Standard deviation for Gaussian kernel. The standard deviations of the
Gaussian filter are given for each axis as a sequence, or as a single
number, in which case it is equal for all axes.
epsilon (scalar) – Offset to ensure that signal is strictly positive.
ndim (int or None (default=None)) – Number of dimensions that array should have. If None, the dimensions
are not checked
dtype (string, type, list of types or None (default='numeric')) – Data type of result. If None, the dtype of the input is preserved.
If ‘numeric’, dtype is preserved unless array.dtype is object.
If dtype is a list of types, conversion on the first type is only
performed if the dtype of the input is not in the list.
force_all_finite (boolean (default=True)) – Whether to raise an error on np.inf and np.nan in array
force_strictly_positive (boolean (default=False)) – Whether to raise an error if any array elements are <= 0
Returns:
array_converted – The converted and validated array.
Reconstruct an image from the radon transform, using the filtered
back projection algorithm.
Parameters:
radon_image (array) – Image containing radon transform (sinogram). Each column of
the image corresponds to a projection along a different
angle. The tomography rotation axis should lie at the pixel
index radon_image.shape[0]//2 along the 0th dimension of
radon_image.
theta (array_like, optional) – Reconstruction angles (in degrees). Default: m angles evenly spaced
between 0 and 180 (if the shape of radon_image is (N, M)).
output_size (int, optional) – Number of rows and columns in the reconstruction.
filter_name (str, optional) – Filter used in frequency domain filtering. Ramp filter used by default.
Filters available: ramp, shepp-logan, cosine, hamming, hann.
Assign None to use no filter.
interpolation (str, optional) – Interpolation method used in reconstruction. Methods available:
‘linear’, ‘nearest’, and ‘cubic’ (‘cubic’ is slow).
circle (boolean, optional) – Assume the reconstructed image is zero outside the inscribed circle.
Also changes the default output_size to match the behaviour of
radon called with circle=True.
reconstructed (ndarray) – Reconstructed image. The rotation axis will be located in the pixel
with indices
(reconstructed.shape[0]//2,reconstructed.shape[1]//2).
.. versionchanged:: 0.19 – In iradon, filter argument is deprecated in favor of
filter_name.
References
Notes
It applies the Fourier slice theorem to reconstruct an image by
multiplying the frequency domain of the filter with the FFT of the
projection data. This algorithm is called filtered back projection.
Calculates the radon transform of an image given specified
projection angles.
Parameters:
image (array_like) – Input image. The rotation axis will be located in the pixel with
indices (image.shape[0]//2,image.shape[1]//2).
theta (array_like, optional) – Projection angles (in degrees). If None, the value is set to
np.arange(180).
circle (boolean, optional) – Assume image is zero outside the inscribed circle, making the
width of each projection (the first dimension of the sinogram)
equal to min(image.shape).
radon_image – Radon transform (sinogram). The tomography rotation axis will lie
at the pixel index radon_image.shape[0]//2 along the 0th
dimension of radon_image.
Get the (smoothed) probability density function of a signal.
Performs the following operations:
1. Smooth sigma with a Gaussian filter
2. Normalize signal such that it sums to 1
3. Add epsilon to ensure signal is strictly positive
4. Re-normalize signal such that it sums to total
Parameters:
input (ndarray) – Input array
sigma (scalar) – Standard deviation for Gaussian kernel. The standard deviations of the
Gaussian filter are given for each axis as a sequence, or as a single
number, in which case it is equal for all axes.
epsilon (scalar) – Offset to ensure that signal is strictly positive.
ndim (int or None (default=None)) – Number of dimensions that array should have. If None, the dimensions
are not checked
dtype (string, type, list of types or None (default='numeric')) – Data type of result. If None, the dtype of the input is preserved.
If ‘numeric’, dtype is preserved unless array.dtype is object.
If dtype is a list of types, conversion on the first type is only
performed if the dtype of the input is not in the list.
force_all_finite (boolean (default=True)) – Whether to raise an error on np.inf and np.nan in array
force_strictly_positive (boolean (default=False)) – Whether to raise an error if any array elements are <= 0
Returns:
array_converted – The converted and validated array.
n (int, optional) – Length of the Fourier transform. If n<x.shape[axis], x is
truncated. If n>x.shape[axis], x is zero-padded. The
default results in n=x.shape[axis].
axis (int, optional) – Axis along which the fft’s are computed; the default is over the
last axis (i.e., axis=-1).
overwrite_x (bool, optional) – If True, the contents of x can be destroyed; the default is False.
The packing of the result is “standard”: If A=fft(a,n), then
A[0] contains the zero-frequency term, A[1:n/2] contains the
positive-frequency terms, and A[n/2:] contains the negative-frequency
terms, in order of decreasingly negative frequency. So ,for an 8-point
transform, the frequencies of the result are [0, 1, 2, 3, -4, -3, -2, -1].
To rearrange the fft output so that the zero-frequency component is
centered, like [-4, -3, -2, -1, 0, 1, 2, 3], use fftshift.
Both single and double precision routines are implemented. Half precision
inputs will be converted to single precision. Non-floating-point inputs
will be converted to double precision. Long-double precision inputs are
not supported.
This function is most efficient when n is a power of two, and least
efficient when n is prime.
Note that if x is real-valued, then A[j]==A[n-j].conjugate().
If x is real-valued and n is even, then A[n/2] is real.
If the data type of x is real, a “real FFT” algorithm is automatically
used, which roughly halves the computation time. To increase efficiency
a little further, use rfft, which does the same calculation, but only
outputs half of the symmetrical spectrum. If the data is both real and
symmetrical, the dct can again double the efficiency by generating
half of the spectrum from half of the signal.
Examples
>>> fromscipy.fftpackimportfft,ifft>>> x=np.arange(5)>>> np.allclose(fft(ifft(x)),x,atol=1e-15)# within numerical accuracy.True
n (int, optional) – Length of the inverse Fourier transform. If n<x.shape[axis],
x is truncated. If n>x.shape[axis], x is zero-padded.
The default results in n=x.shape[axis].
axis (int, optional) – Axis along which the ifft’s are computed; the default is over the
last axis (i.e., axis=-1).
overwrite_x (bool, optional) – If True, the contents of x can be destroyed; the default is False.
Both single and double precision routines are implemented. Half precision
inputs will be converted to single precision. Non-floating-point inputs
will be converted to double precision. Long-double precision inputs are
not supported.
This function is most efficient when n is a power of two, and least
efficient when n is prime.
If the data type of x is real, a “real IFFT” algorithm is automatically
used, which roughly halves the computation time.
Examples
>>> fromscipy.fftpackimportfft,ifft>>> importnumpyasnp>>> x=np.arange(5)>>> np.allclose(ifft(fft(x)),x,atol=1e-15)# within numerical accuracy.True
Get the (smoothed) probability density function of a signal.
Performs the following operations:
1. Smooth sigma with a Gaussian filter
2. Normalize signal such that it sums to 1
3. Add epsilon to ensure signal is strictly positive
4. Re-normalize signal such that it sums to total
Parameters:
input (ndarray) – Input array
sigma (scalar) – Standard deviation for Gaussian kernel. The standard deviations of the
Gaussian filter are given for each axis as a sequence, or as a single
number, in which case it is equal for all axes.
epsilon (scalar) – Offset to ensure that signal is strictly positive.
itransform calculates the inverse of the CDT. It receives a transport displacement
and the reference, and finds the one dimensional distribution I from it.
input:
Transport displacement map
The reference used for calculating the CDT
stransform calculates the transport transform (CDT) of a signal I for signals that may change sign
input:
The original density I
x -> domain of the density I
output:
The 4 components of the transform of signed signals: the CDT of the positive and the negative
part of I, and the total masses of the positive and the negative part of I
One-dimensional linear interpolation for monotonically increasing sample points.
Returns the one-dimensional piecewise linear interpolant to a function
with given discrete data points (xp, fp), evaluated at x.
Parameters:
x (array_like) – The x-coordinates at which to evaluate the interpolated values.
xp (1-D sequence of floats) – The x-coordinates of the data points, must be increasing if argument
period is not specified. Otherwise, xp is internally sorted after
normalizing the periodic boundaries with xp=xp%period.
fp (1-D sequence of float or complex) – The y-coordinates of the data points, same length as xp.
left (optional float or complex corresponding to fp) – Value to return for x < xp[0], default is fp[0].
right (optional float or complex corresponding to fp) – Value to return for x > xp[-1], default is fp[-1].
period (None or float, optional) –
A period for the x-coordinates. This parameter allows the proper
interpolation of angular x-coordinates. Parameters left and right
are ignored if period is specified.
New in version 1.10.0.
Returns:
y – The interpolated values, same shape as x.
Return type:
float or complex (corresponding to fp) or ndarray
Raises:
ValueError – If xp and fp have different length
If xp or fp are not 1-D sequences
If period == 0
See also
scipy.interpolate
Warning
The x-coordinate sequence is expected to be increasing, but this is not
explicitly enforced. However, if the sequence xp is non-increasing,
interpolation results are meaningless.
Note that, since NaN is unsortable, xp also cannot contain NaNs.
A simple check for xp being strictly increasing is:
X (array, shape (n_samples, n_components)) – Transformed X data.
Y (array, shape (n_samples, n_components) or None (default=None)) – Transformed Y data. If Y=None, only the X data are transformed back
to the original space.
Returns:
X_original (array, shape (n_samples, n_features)) – X data transformed back into original space.
Y_original (array, shape (n_samples, n_targets)) – Y data transformed back into original space. If Y=None, only
X_original is returned.
Return Pearson product-moment correlation coefficients for each
component.
The values of R are between -1 and 1, inclusive.
Note: This is different from sklearn.cross_decomposition.CCA.score(),
which returns the coefficient of determination of the prediction.
Parameters:
X (array, shape (n_samples, n_features)) – Input X data.
Y (array, shape (n_samples, n_targets) or None (default=None)) – Input Y data.
Returns:
score – Pearson product-moment correlation coefficients. If n_components=1,
a single value is returned, else an array of correlation
coefficients is returned.
ndim (int or None (default=None)) – Number of dimensions that array should have. If None, the dimensions
are not checked
dtype (string, type, list of types or None (default='numeric')) – Data type of result. If None, the dtype of the input is preserved.
If ‘numeric’, dtype is preserved unless array.dtype is object.
If dtype is a list of types, conversion on the first type is only
performed if the dtype of the input is not in the list.
force_all_finite (boolean (default=True)) – Whether to raise an error on np.inf and np.nan in array
force_strictly_positive (boolean (default=False)) – Whether to raise an error if any array elements are <= 0
Returns:
array_converted – The converted and validated array.
All estimators should specify all the parameters that can be set
at the class level in their __init__ as explicit keyword
arguments (no *args or **kwargs).
The method works on simple estimators as well as on nested objects
(such as Pipeline). The latter have
parameters of the form <component>__<parameter> so that it’s
possible to update each component of a nested object.
This is both a dimensionality reduction method and a linear classifier.
Parameters:
alpha (scalar (default=1.)) – Parameter that controls the proportion of LDA vs PCA.
If alpha=0, PLDA functions like LDA. If alpha is large, PLDA functions
more like PCA.
n_components (int or None (default=None)) – Number of components to keep. If n_components is not set, all
components are kept: n_components == min(n_samples, n_features).
Proportion of variance explained by each of the selected components.
If n_components is not set then all components are stored and the sum
of explained variance ratios is equal to 1.0.
The confidence score for a sample is the signed distance of that
sample to the hyperplane.
Parameters:
X (array, shape (n_samples, n_features)) – Input data.
Returns:
scores – else (n_samples, n_classes)
Confidence scores per (sample, class) combination. In the binary
case, confidence score for self.classes_[1] where >0 means this
class would be predicted.
Predict class labels for data that have already been transformed by
self.transform(X).
This is useful for plotting classification boundaries.
Note: Due to arithemtic discrepancies, this may return slightly
different class labels to self.predict(X).
Parameters:
X_trans (array, shape (n_samples, n_components)) – Test samples that have already been transformed into PLDA space.
In multilabel classification, this function computes subset accuracy:
the set of labels predicted for a sample must exactly match the
corresponding set of labels in y_true.
Read more in the User Guide.
Parameters:
y_true (1d array-like, or label indicator array / sparse matrix) – Ground truth (correct) labels.
y_pred (1d array-like, or label indicator array / sparse matrix) – Predicted labels, as returned by a classifier.
normalize (bool, default=True) – If False, return the number of correctly classified samples.
Otherwise, return the fraction of correctly classified samples.
sample_weight (array-like of shape (n_samples,), default=None) – Sample weights.
Returns:
score – If normalize==True, return the fraction of correctly
classified samples (float), else returns the number of correctly
classified samples (int).
The best performance is 1 with normalize==True and the number
of samples with normalize==False.
Return type:
float
See also
balanced_accuracy_score
Compute the balanced accuracy to deal with imbalanced datasets.
jaccard_score
Compute the Jaccard similarity coefficient score.
hamming_loss
Compute the average Hamming loss or Hamming distance between two sets of samples.
zero_one_loss
Compute the Zero-one classification loss. By default, the function will return the percentage of imperfectly predicted subsets.
Notes
In binary classification, this function is equal to the jaccard_score
function.
ndim (int or None (default=None)) – Number of dimensions that array should have. If None, the dimensions
are not checked
dtype (string, type, list of types or None (default='numeric')) – Data type of result. If None, the dtype of the input is preserved.
If ‘numeric’, dtype is preserved unless array.dtype is object.
If dtype is a list of types, conversion on the first type is only
performed if the dtype of the input is not in the list.
force_all_finite (boolean (default=True)) – Whether to raise an error on np.inf and np.nan in array
force_strictly_positive (boolean (default=False)) – Whether to raise an error if any array elements are <= 0
Returns:
array_converted – The converted and validated array.
Solve a standard or generalized eigenvalue problem for a complex
Hermitian or real symmetric matrix.
Find eigenvalues array w and optionally eigenvectors array v of
array a, where b is positive definite such that for every
eigenvalue λ (i-th entry of w) and its eigenvector vi (i-th column of
v) satisfies:
a@vi=λ*b@vivi.conj().T@a@vi=λvi.conj().T@b@vi=1
In the standard problem, b is assumed to be the identity matrix.
Parameters:
a ((M, M) array_like) – A complex Hermitian or real symmetric matrix whose eigenvalues and
eigenvectors will be computed.
b ((M, M) array_like, optional) – A complex Hermitian or real symmetric definite positive matrix in.
If omitted, identity matrix is assumed.
lower (bool, optional) – Whether the pertinent array data is taken from the lower or upper
triangle of a and, if applicable, b. (Default: lower)
eigvals_only (bool, optional) – Whether to calculate only eigenvalues and no eigenvectors.
(Default: both are calculated)
subset_by_index (iterable, optional) – If provided, this two-element iterable defines the start and the end
indices of the desired eigenvalues (ascending order and 0-indexed).
To return only the second smallest to fifth smallest eigenvalues,
[1,4] is used. [n-3,n-1] returns the largest three. Only
available with “evr”, “evx”, and “gvx” drivers. The entries are
directly converted to integers via int().
subset_by_value (iterable, optional) – If provided, this two-element iterable defines the half-open interval
(a,b] that, if any, only the eigenvalues between these values
are returned. Only available with “evr”, “evx”, and “gvx” drivers. Use
np.inf for the unconstrained ends.
driver (str, optional) – Defines which LAPACK driver should be used. Valid options are “ev”,
“evd”, “evr”, “evx” for standard problems and “gv”, “gvd”, “gvx” for
generalized (where b is not None) problems. See the Notes section.
type (int, optional) –
For the generalized problems, this keyword specifies the problem type
to be solved for w and v (only takes 1, 2, 3 as possible
inputs):
1=>a@v=w@b@v2=>a@b@v=w@v3=>b@a@v=w@v
This keyword is ignored for standard problems.
overwrite_a (bool, optional) – Whether to overwrite data in a (may improve performance). Default
is False.
overwrite_b (bool, optional) – Whether to overwrite data in b (may improve performance). Default
is False.
check_finite (bool, optional) – Whether to check that the input matrices contain only finite numbers.
Disabling may give a performance gain, but may result in problems
(crashes, non-termination) if the inputs do contain infinities or NaNs.
turbo (bool, optional) – Deprecated since v1.5.0, use ``driver=gvd`` keyword instead.
Use divide and conquer algorithm (faster but expensive in memory, only
for generalized eigenvalue problem and if full set of eigenvalues are
requested.). Has no significant effect if eigenvectors are not
requested.
eigvals (tuple (lo, hi), optional) – Deprecated since v1.5.0, use ``subset_by_index`` keyword instead.
Indexes of the smallest and largest (in ascending order) eigenvalues
and corresponding eigenvectors to be returned: 0 <= lo <= hi <= M-1.
If omitted, all eigenvalues and eigenvectors are returned.
Returns:
w ((N,) ndarray) – The N (1<=N<=M) selected eigenvalues, in ascending order, each
repeated according to its multiplicity.
v ((M, N) ndarray) – (if eigvals_only==False)
Raises:
LinAlgError – If eigenvalue computation does not converge, an error occurred, or
b matrix is not definite positive. Note that if input matrices are
not symmetric or Hermitian, no error will be reported but results will
be wrong.
See also
eigvalsh
eigenvalues of symmetric or Hermitian arrays
eig
eigenvalues and right eigenvectors for non-symmetric arrays
eigh_tridiagonal
eigenvalues and right eiegenvectors for symmetric/Hermitian tridiagonal matrices
Notes
This function does not check the input array for being Hermitian/symmetric
in order to allow for representing arrays with only their upper/lower
triangular parts. Also, note that even though not taken into account,
finiteness check applies to the whole array and unaffected by “lower”
keyword.
This function uses LAPACK drivers for computations in all possible keyword
combinations, prefixed with sy if arrays are real and he if
complex, e.g., a float array with “evr” driver is solved via
“syevr”, complex arrays with “gvx” driver problem is solved via “hegvx”
etc.
As a brief summary, the slowest and the most robust driver is the
classical <sy/he>ev which uses symmetric QR. <sy/he>evr is seen as
the optimal choice for the most general cases. However, there are certain
occasions that <sy/he>evd computes faster at the expense of more
memory usage. <sy/he>evx, while still being faster than <sy/he>ev,
often performs worse than the rest except when very few eigenvalues are
requested for large arrays though there is still no performance guarantee.
For the generalized problem, normalization with respect to the given
type argument:
img (2d array, shape (height, width)) – Image to interpolate.
f (3d array, shape (2, height, width)) – Coordinates of at which img is defined. First dimension f[0] corresponds
to y-coordinates, second dimension f[1] is x-coordinates.
order (int (default=1)) – Order of the interpolation. Must be in the range 0-2.
fill_value (float (default=0.)) – Value used for points outside the boundaries.
Returns:
Image interpolated on to regular gird defined by: x = 0:(width-1),
y = 0:(height-1).
img (2d array, shape (height, width)) – Image to interpolate. This function assumes a grid of sample points:
x = 0:(width-1), y = 0:(height-1).
f (3d array, shape (2, height, width)) – Coordinates of interpolated points. First dimension f[0] corresponds to
y-coordinates, second dimension f[1] is x-coordinates.
order (int (default=1)) – Order of the spline interpolation. Must be in the range 0-5.
fill_value (float (default=0.)) – Value used for points outside the boundaries.
Get the (smoothed) probability density function of a signal.
Performs the following operations:
1. Smooth sigma with a Gaussian filter
2. Normalize signal such that it sums to 1
3. Add epsilon to ensure signal is strictly positive
4. Re-normalize signal such that it sums to total
Parameters:
input (ndarray) – Input array
sigma (scalar) – Standard deviation for Gaussian kernel. The standard deviations of the
Gaussian filter are given for each axis as a sequence, or as a single
number, in which case it is equal for all axes.
epsilon (scalar) – Offset to ensure that signal is strictly positive.
ndim (int or None (default=None)) – Number of dimensions that array should have. If None, the dimensions
are not checked
dtype (string, type, list of types or None (default='numeric')) – Data type of result. If None, the dtype of the input is preserved.
If ‘numeric’, dtype is preserved unless array.dtype is object.
If dtype is a list of types, conversion on the first type is only
performed if the dtype of the input is not in the list.
force_all_finite (boolean (default=True)) – Whether to raise an error on np.inf and np.nan in array
force_strictly_positive (boolean (default=False)) – Whether to raise an error if any array elements are <= 0
Returns:
array_converted – The converted and validated array.
disp (array, shape (2, height, width)) – Pixel displacements. First index denotes direction: disp[0] is
y-displacements, and disp[1] is x-displacements.
ax (matplotlib.axes.Axes object or None (default=None)) – Axes in which to plot the wireframe. If None, a new figure is created.
scale (float (default=1.)) – Exaggeration scale applied to the displacements before visualization.
count (int (default=50)) – Use at most this many rows and columns in the wireframe.
Fit linear model.
:param Xtrain: 1D data for training.
:type Xtrain: array-like, shape (n_samples, n_columns)
:param Ytrain: Labels of the training samples.
:type Ytrain: ndarray of shape (n_samples,)
:param no_deform_model: default = False.
:type no_deform_model: boolean flag; IF TRUE, no deformation model will be added
Predict using the linear model
:param Xtest: 1D data for testing.
:type Xtest: array-like, shape (n_samples, n_columns)
:param use_gpu: default = False.
:type use_gpu: boolean flag; IF TRUE, use gpu for calculations
Fit linear model.
:param Xtrain: Image data for training.
:type Xtrain: array-like, shape (n_samples, n_rows, n_columns, n_width)
:param Ytrain: Labels of the training images.
:type Ytrain: ndarray of shape (n_samples,)
:param no_deform_model: default = False.
:type no_deform_model: boolean flag; IF TRUE, no deformation model will be added
Predict using the linear model
:param Xtest: Image data for testing.
:type Xtest: array-like, shape (n_samples, n_rows, n_columns, n_width)
:param use_gpu: default = False.
:type use_gpu: boolean flag; IF TRUE, use gpu for calculations
fit(X, Y, Ttrain=None, no_local_enrichment=True)[source]
Fit SCDT-NLS.
:param X: 1D data for training.
:type X: array-like, shape (n_samples, n_columns)
:param Y: Labels of the training samples.
:type Y: ndarray of shape (n_samples,)
:param Ttrain: domain for corresponding training signals.
:type Ttrain: [optional] array-like, shape (n_samples, n_columns)
:param no_local_enrichment: IF FALSE, apply deformation while searching k samples
:type no_local_enrichment: [optional] boolean, default TRUE
Predict using SCDT-NLS
:param Xtest: 1D data for testing.
:type Xtest: array-like, shape (n_samples, n_columns)
:param Ttest: domain for corresponding test signals.
:type Ttest: [optional] array-like, shape (n_samples, n_columns)
:param k:
:type k: [pre-tuned parameter] number of closest points to test sample
:param N:
:type N: [pre-tuned parameter] number of sinusoidal bases used for subspace enrrichment
Fit SCDT-NS.
:param Xtrain: 1D data for training.
:type Xtrain: array-like, shape (n_samples, n_columns)
:param Ytrain: Labels of the training samples.
:type Ytrain: ndarray of shape (n_samples,)
:param Ttrain: domain for corresponding training signals.
:type Ttrain: [optional] array-like, shape (n_samples, n_columns)
:param no_deform_model: default = True.
:type no_deform_model: [optional] boolean flag; IF TRUE, no deformation model will be added