Package: alpha-transform
Adaptive transform for manifold-valued dataThis package contains all software developed as part of Workpackage 2.1 (Adaptive transform for manifold-valued data)
of the DEDALE project. For an in-depth description of this workpackage, we refer to the associated technical report.The software consists of three main parts:An implementation of the (bandlimited)α-shearlet transform(inAlphaTransform.py,
in three versions:Afully sampled(non-decimated), translation invariant, fast, but memory-consumingimplementationA fully sampled, translation invariant, slightly slower, but memory-efficientimplementationAsubsampled(decimated),nottranslation invariant, but fast and memory-efficient implementation.Implementations (inAdaptiveAlpha.py) of three criteria that can be used to adaptively choose
the value of α, namely:Theasymptotic approximation rate(AAR),themean approximation error(MAE),thethresholding denoising performance(TDP).Achart-based implementation(inSphereTransform.py) of the α-shearlet transform for
functions defined on the sphere.In the following, we provide brief explanations and hands-on experiments for all of these aspects. The following
table of content can be used for easy navigation:Table of ContentsThe α-shearlet transform: A crash courseAdaptively choosing αa)Asymptotic approximation rate (AAR)b)Mean approximation error (MAE)c)Thresholding denoising performance (TDP)The α-shearlet transform for functions defined on the sphereThe α-shearlet transform: A crash courseThe following demonstrates a very simple use case of the α-shearlet transform: We compute the transform of an example image,
threshold the coefficients, reconstruct and compute the error. The code is longer than strictly necessary, since
along the way give a demonstration of the general usage of the transform.>>># Importing necessary packages>>>fromAlphaTransformimportAlphaShearletTransformasAST>>>importnumpyasnp>>>importmatplotlib.pyplotasplt>>>fromscipyimportmisc>>>im=misc.face(gray=True)>>>im.shape(768,1024)>>># Setting up the transform>>>trafo=AST(im.shape[1],im.shape[0],[0.5]*3)# 1Precomputingshearletsystem:100%|███████████████████████████████████████|52/52[00:05<00:00,8.83it/s]>>># Computing and understanding the α-shearlet coefficients>>>coeff=trafo.transform(im)# 2>>>coeff.shape# 3(53,768,1024)>>>trafo.indices# 4[-1,(0,-1,'r'),(0,0,'r'),(0,1,'r'),(0,1,'t'),(0,0,'t'),(0,-1,'t'),(0,-1,'l'),(0,0,'l'),(0,1,'l'),(0,1,'b'),(0,0,'b'),(0,-1,'b'),(1,-2,'r'),(1,-1,'r'),(1,0,'r'),(1,1,'r'),(1,2,'r'),(1,2,'t'),(1,1,'t'),(1,0,'t'),(1,-1,'t'),(1,-2,'t'),(1,-2,'l'),(1,-1,'l'),(1,0,'l'),(1,1,'l'),(1,2,'l'),(1,2,'b'),(1,1,'b'),(1,0,'b'),(1,-1,'b'),(1,-2,'b'),(2,-2,'r'),(2,-1,'r'),(2,0,'r'),(2,1,'r'),(2,2,'r'),(2,2,'t'),(2,1,'t'),(2,0,'t'),(2,-1,'t'),(2,-2,'t'),(2,-2,'l'),(2,-1,'l'),(2,0,'l'),(2,1,'l'),(2,2,'l'),(2,2,'b'),(2,1,'b'),(2,0,'b'),(2,-1,'b'),(2,-2,'b')]>>># Thresholding the coefficients and reconstructing>>>np.max(np.abs(coeff))# 52041.1017181588547>>>np.sum(np.abs(coeff)>200)/coeff.size# 60.020679905729473761>>>thresh_coeff=coeff*(np.abs(coeff)>200)# 7>>>recon=trafo.inverse_transform(thresh_coeff,real=True)# 8>>>np.linalg.norm(im-recon)/np.linalg.norm(im)# 90.13912540983541383>>>plt.imshow(recon,cmap='gray')<matplotlib.image.AxesImageobjectat0x2b0f568c25c0>>>>plt.show()Importing necessary packagesThe first few (unnumbered) lines import relevant packages and load (a gray scale version of) the following
test image, which has a resolution of 1024 x 768 pixels:Setting up the transformThen, in line 1, we create an instancetrafoof the classAlphaShearletTransform(which is
calledASTabove for brevity).
During construction of this object, the necessary shearlet filters are precomputed. This may take some time
(5 seconds in the example above), but speeds up later computations.The three parameters passed to the constructor oftraforequire some explanation:The first parameter is thewidthof the images which can be analyzed using thetrafoobject.Similarly, the second parameter determines theheight.The third parameter is of the form[alpha] * N, whereNdetermines the number of scales of the transform andalphadetermines the value of α.The reason for this notation is that in principle, one can choose a
different value of α on each scale. Since[0.5] * 3 = [0.5, 0.5, 0.5], one can use this notation to obtain a
system using a single value of α across all scales.All in all, we see that line 1 creates a shearlet system (i.e., α = 0.5) with 3 scale (plus a low-pass)
for images of dimension 1024 x 768.Computing and understanding the α-shearlet coefficientsLine 2 shows that the α-shearlet coefficients of the imageimcan be readily computed using thetransformmethod oftrafo.
As seen in line 3, this results in an array of size53, where each of the elements of the array is an array (an image) of
size 1024 x 768, i.e., of the same size as the input image.To help understand the meaning of each of thesecoefficient imagescoeff[i], fori = 0, ..., 52, the output of line 4
is helpful: Associated to each coefficient imagecoeff[i], there is anindextrafo.indices[i]which encodes themeaningof the coefficient image, i.e., the shearlet used to compute it.The special index-1stands for thelow-pass part. All other indices are of the form(j, k, c), wherejencodes thescale. In the present case,jranges from0to2, since we have 3 scales.kencodes theamount of shearing, ranging from -⌈2j(1 - α)⌉ to ⌈2j(1 - α)⌉ on scalej.cencodes theconeto which the shearlet belongs (in the Fourier domain). Precisely, we have the following correspondence
between the value ofcand the corresponding frequency cones:value ofc'r''t''l''b'Frequency conerighttopleftbottomNote that if we divide the frequency plane into four cones, such that each shearlet has a real-valued Fourier transform
which is supported in one of these cones, then the shearlets themselves (i.e., in space)can notbe real-valued.
Hence, if real-valued shearlets are desired, one can pass the constructor of the classAlphaShearletTransformthe
additional argumentreal=True. In this case, the frequency plane is split into a horizontal (encoded by'h') and
a vertical (encoded by'v') cone, as is indicated by the following example:>>>trafo_real=AST(im.shape[1],im.shape[0],[0.5]*3,real=True)Precomputingshearletsystem:100%|██████████████████████████████████████|26/26[00:03<00:00,5.62it/s]>>>trafo_real.indices[-1,(0,-1,'h'),(0,0,'h'),(0,1,'h'),(0,1,'v'),(0,0,'v'),(0,-1,'v'),(1,-2,'h'),(1,-1,'h'),(1,0,'h'),(1,1,'h'),(1,2,'h'),(1,2,'v'),(1,1,'v'),(1,0,'v'),(1,-1,'v'),(1,-2,'v'),(2,-2,'h'),(2,-1,'h'),(2,0,'h'),(2,1,'h'),(2,2,'h'),(2,2,'v'),(2,1,'v'),(2,0,'v'),(2,-1,'v'),(2,-2,'v')]Thresholding the coefficients & reconstructingWhen called without further parameters, the methodtrafo.transformcomputes anormalizedtransform,
so that effectively all shearlets are normalized to have L² norm 1. With this normalization, line 5 shows
that the largest coefficient has size about 2041. We now (arbitrarily) pick a threshold of 200 and see (in line 6)
that only about 2% of the coefficients are larger than this threshold. Next, we set all coefficients which are smaller
(in absolute value) than 200 to zero and save the resulting thresholded coefficients asthresh_coeff, in line 7.In line 8, we then use the methodinverse_transformof thetrafoobject to compute the inverse transform.
Since we know that the original image was real-valued, we pass the additional argumentreal=True.
This has the same effect as reconstructing without this additional argument and then taking the real part.
Line 9 shows that the relative error is about 13.9%.Finally, the last two lines display the reconstructed image.Changes for the subsampled transformAbove, we showed how our implementation of thefully sampledα-shearlet transform can be used to compute the α-shearlet
transform of an image and reconstruct (with thresholded coefficients). For thesubsampledtransform, this can be
done very similarly; the main difference one has to keep in mind is that for the fully sampled transform,
one obtains an array of "coefficient images" which are all of the same size. In contrast, due to the subsampling,
the "coefficient images" for the subsampled transform are all of different sizes:>>>fromAlphaTransformimportAlphaShearletTransformasAST>>>importmatplotlib.pyplotasplt>>>importnumpyasnp>>>fromscipyimportmisc>>>im=misc.face(gray=True)>>>trafo=AST(im.shape[1],im.shape[0],[0.5]*3,subsampled=True)# 1Precomputingshearlets:100%|████████████████████████████████████████████|52/52[00:00<00:00,69.87it/s]>>>coeff=trafo.transform(im)# 2>>>type(coeff).__name__# 3'list'>>>[c.shapeforcincoeff]# 4[(129,129),(364,161),(364,161),(364,161),(97,257),(97,257),(97,257),(364,161),(364,161),(364,161),(97,257),(97,257),(97,257),(514,321),(514,321),(514,321),(514,321),(514,321),(193,364),(193,364),(193,364),(193,364),(193,364),(514,321),(514,321),(514,321),(514,321),(514,321),(193,364),(193,364),(193,364),(193,364),(193,364),(727,641),(727,641),(727,641),(727,641),(727,641),(385,513),(385,513),(385,513),(385,513),(385,513),(727,641),(727,641),(727,641),(727,641),(727,641),(385,513),(385,513),(385,513),(385,513),(385,513)]>>>np.max([np.max(np.abs(c))forcincoeff])# 52031.0471969998314>>>np.sum([np.sum(np.abs(c)>200)forcincoeff])# 622357>>>np.sum([np.sum(np.abs(c)>200)forcincoeff])/np.sum([c.sizeforcincoeff])# 70.0023520267754635542>>>thresh_coeff=[c*(np.abs(c)>200)forcincoeff]# 8>>>recon=trafo.inverse_transform(thresh_coeff,real=True)# 9>>>np.linalg.norm(im-recon)/np.linalg.norm(im)0.13945789596375507Up to the first marked line, everything is identical to the code for the fully sampled transform.
The only difference in line 1 is the additional argumentsubsampled=Trueto obtain a subsampled transform.
Then, in line 2, the transform of the imageimis computed just as for the fully sampled case.The main difference to the fully sampled transform becomes visible in lines 3 and 4:
In contrast to the fully sampled transform, where the coefficients are a 3-dimensional numpyarray,
the subsampled transform yields alistof 2-dimensional numpy arrays, withvarying shapes.
This shape is constant with respect to the shearkas long as the scalejand the conecare kept fixed,
but varies strongly withjandc. In face, for aquadraticimage, the shape would only depend on the scalej.Since we have a list of numpy arrays instead of a single numpy array, all operations on the coefficients are more
cumbersome to write down (using list comprehensions), but are identical in spirit to the case of the fully sampled
transform, cf. lines 5-8.The actual reconstruction (in line 9) is exactly identical to the fully sampled case. It is interesting to note that
only about 0.24% of the coefficients - and thus much less than the 2% for the fully sampled transform - are larger than
the threshold. Nevertheless, the relative error is essentially the same.Adaptively choosing αIn the following, we show for each of the three optimality criteria (AAR,MAEandTDP) how our
implementation can be used to determine the optimal value of α for a given set of images.Asymptotic approximation rate (AAR)The following code uses a grid search to determine the value of α which yields the bestasymptotic approximation rate(as described in the technical report) for the given set of images:>>>fromAdaptiveAlphaimportoptimize_AAR>>>shearlet_args={'real':True,'verbose':False}# 1>>>images=['./Review/log_dust_test.npy']# 2>>>num_scales=4# 3>>>num_alphas=3# 4>>>optimize_AAR(images,num_scales,1/(num_alphas-1),shearlet_args=shearlet_args)Firststep:Determinethemaximumrelevantvalue...alphaloop:100%|████████████████████████████████████████████████████████|3/3[00:10<00:00,3.48s/it]imageloop:100%|████████████████████████████████████████████████████████|1/1[00:01<00:00,1.60s/it]Maximumrelevantvalue:0.04408709120918954Secondstep:Computingtheapproximationerrors...alphaloop:100%|████████████████████████████████████████████████████████|3/3[01:40<00:00,30.99s/it]Imageloop:100%|████████████████████████████████████████████████████████|1/1[00:46<00:00,46.89s/it]Thresh.loop:100%|██████████████████████████████████████████████████████|50/50[00:45<00:00,1.10it/s]Thirdstep:Computingtheapproximationrates...Commonbreakpoints:[0,4,34,50]Lastcommonlinearpart:[34,50)lastslopes:alpha=1.00:-0.161932+0.012791alpha=0.50:-0.161932+0.000108*alpha=0.00:-0.161932-0.012900Optimalvalue:alpha=0.00In addition to the output shown above, executing this code will display the following plot:We now briefly explain the abovecodeand output:
In the short program above, we first import the functionoptimize_AARwhich will do the actual work.
Then, we define the parameters to be passed to this function:In line 1, we determine the properties of the α-shearlet systems that will be used:'real': Trueensures that real-valued shearlets are used.'verbose': Falsesuppresses some output, e.g. the progress bar for precomputing the shearlet system.Another possible option would be'subsampled': Trueif one wants to use the subsampled transform. Note though
that this is incompatible with the'real': Trueoption.In line 2, we determine the set of images that is to be used. To ensure fast computations, we only take
a single image for this example. Specifically, the used image is the logarithm of one of the 12 faces of cosmic
dust data provided by CEA, as depicted in the following figure:The variablenum_scalesdetermines how many scales the α-shearlet systems should use.Since we are using a grid search (i.e., we are only considering finitely many values of α), the
variablenum_alphasis used to determine how many different values of α should be distinguished.
These are then uniformly spread in the interval [0,1]. Again, to ensure fast computations, we only consider
three different values, namely α=0, α=0.5 and α=1.Finally, we invoke the functionoptimize_AARwith the chosen parameters. As described in the technical report,
this function does the following:It determines a range [0, c0] such that for c≥c0, all α-shearlet transforms yield thesame errorwhen all coefficients of absolute value ≤c are set to zero ("thresholded").It computes the reconstruction errors for the different values of α after thresholding the coefficients with
a threshold of c0·bkfor k=0,...,K-1.The default value is K=50. This can be adjusted by passing e.g. the argumentnum_x_values=40as an
additional argument tooptimize_AAR. Likewise, the baseb(with default valueb=1.25) can be adjusted
by passing e.g.base=1.3as a further argument.It determines a partition of {0, ..., K-1} into at most 4 intervals such that on each of these intervals,
each of the (logarithmic) error curves is almost linear.In the example run above, the end points of the
resulting partition are given byCommon breakpoints: [0, 4, 34, 50]. In this case, the resulting
partition has only three intervals instead of 4, since on each of these intervals, the best linear approximation
is already sufficiently good.For each value of α, the function then determines theslopesof the (logarithmic) error curve on the
last of these intervals and compares these slopes.The optimal value of α (in this case α=0) is the one with the smallest slope, i.e., with the highest
decay of the error. To allow for a visual comparison,optimize_AARalso displays aplotof the
(logarithmic) error curves, including the partition into the almost linear parts.Mean approximation error (MAE)The following code uses a grid search to determine the value of α which yields the bestmean approximation error(as described in the technical report) for the given set of images:>>>fromAdaptiveAlphaimportoptimize_MAE>>>shearlet_args={'real':True,'verbose':False}# 1>>>images=['./Review/log_dust_test.npy']# 2>>>num_scales=4>>>num_alphas=3>>>optimize_MAE(images,num_scales,1/(num_alphas-1),shearlet_args=shearlet_args)Firststep:Determinethemaximumrelevantvalue...alphaloop:100%|████████████████████████████████████████████████████████|3/3[00:11<00:00,3.61s/it]imageloop:100%|████████████████████████████████████████████████████████|1/1[00:01<00:00,1.61s/it]Maximumrelevantvalue:0.006053772894213893Secondstep:Computingtheapproximationerrors...alphaloop:100%|████████████████████████████████████████████████████████|3/3[01:40<00:00,31.13s/it]imageloop:100%|████████████████████████████████████████████████████████|1/1[00:48<00:00,48.25s/it]thresholdingloop:100%|█████████████████████████████████████████████████|50/50[00:46<00:00,1.08it/s]Finalstep:Computingoptimalvalueofalpha...meanerrors:alpha=1.00:+0.024105+0.000258alpha=0.50:+0.024105+0.000015*alpha=0.00:+0.024105-0.000273Optimalvalue:alpha=0.00In addition to the output shown above, executing this code will display the following plot:We now briefly explain the abovecodeand output:
In the short program above, we first import the functionoptimize_MAEwhich will do the actual work.
Then, we define the parameters to be passed to this function:In line 1, we determine the properties of the α-shearlet systems that will be used:'real': Trueensures that real-valued shearlets are used.'verbose': Falsesuppresses some output, e.g. the progress bar for precomputing the shearlet system.Another possible option would be'subsampled': Trueif one wants to use the subsampled transform. Note though
that this is incompatible with the'real': Trueoption.In line 2, we determine the set of images that is to be used. To ensure fast computations, we only take
a single image for this example. Specifically, the used image is the logarithm of one of the 12 faces of cosmic
dust data provided by CEA, as depicted in thefigureabove.The variablenum_scalesdetermines how many scales the α-shearlet systems should use.Since we are using a grid search (i.e., we are only considering finitely many values of α), the
variablenum_alphasis used to determine how many different values of α should be distinguished.
These are then uniformly spread in the interval [0,1]. Again, to ensure fast computations, we only consider
three different values, namely α=0, α=0.5 and α=1.Finally, we invoke the functionoptimize_MAEwith the chosen parameters. As described in the technical report,
this function does the following:It determines a range [0, c0] such that for c≥c0, all α-shearlet transforms yield thesame errorwhen all coefficients of absolute value ≤c are set to zero ("thresholded").It computes the reconstruction errors for the different values of α after thresholding the coefficients with
a threshold of c = c0·i / K for i = 0, ..., K-1.The default value is K=50. This can be adjusted by passing e.g. the argumentnum_x_values=40as an additional
argument tooptimize_MAE.For each value of α, the function then determines themeanof all these approximation errors. The optimal
value of α (in this case α=0) is the one with the smallest mean approximation error.To allow for a visual comparison,optimize_MAEalso displays aplotof the error curves.Thresholding Denoising Performance (TDP)In the following, we show how the denoising performance of an α-shearlet system can be used as an optimality
criterion for adaptively choosing the correct value of α.Since the(logarithmic) dust dataused for the previous experiments does not allow for an
easy visual comparison between the original image and the different denoised versions, we decided to instead
use the following 684 x 684 cartoon image (taken fromSMBC) as a toy example:The following code uses a grid search over different values of α to determine the value with the
optimal denoising performance:>>>fromAdaptiveAlphaimportoptimize_denoising>>>image_paths=['./Review/cartoon_example.png']# 1>>>num_alphas=3# 2>>>num_scales=5# 3>>>num_noise_levels=5# 4>>>shearlet_args={'real':True,'verbose':False}# 5>>>optimize_denoising(image_paths,num_scales,1/(num_alphas-1),num_noise_levels,shearlet_args=shearlet_args)imageloop:100%|██████████████████████████████████████████████████████████|1/1[01:33<00:00,93.16s/it]alphaloop:100%|██████████████████████████████████████████████████████████|3/3[01:33<00:00,28.44s/it]noiseloop:100%|██████████████████████████████████████████████████████████|5/5[00:46<00:00,9.38s/it]Averagederroroverallimagesandallnoiselevels:alpha=1.00:0.0961alpha=0.50:0.0900alpha=0.00:0.0948Optimalvalueonwholeset:alpha=0.50In addition to the output shown above, executing the sample code also displays the following plot:We now briefly explain the abovecodeand output:
First, we import fromAdaptiveAlpha.pythe functionoptimize_denoisingwhich will do the actual work.
We then set the parameters to this function. In the present case, we want toanalyze thecartoon imageshown above,use α-shearlet transforms withreal-valuedshearlets (cf. line 5, the second part of that line suppresses some output),use α-shearlet transforms with 5 scales (line 4),use 5 different noise levels λ (line 4) which are uniformly spaced in [0.02, 0.4],compare three different values of α, which are uniformly spaced in [0,1], i.e, α=1, α=0.5 and α=0.In more realistic experiment, one would of course use a larger set of test images and consider more different values of
α, possibly also with a larger number of different noise levels. But here, we are mainly interested in a quick
execution time, so we keep everything small.Finally, we invoke the functionoptimize_denoisingwhich - briefly summarized - does the following:It normalizes each of the K x K input images to have L² norm equal to 1.
Then, for each image, each value of α  and each noise level λ in [0.02,0.4], a distorted image is calculated
by adding artificial Gaussian noise with standard deviation σ=λ/K to the image.This standard deviation is chosen in such a way that the expected squared L² norm of the noise is λ².One can specify other ranges for the noise level than the default range [0.02, 0.4] by using the paramtersnoise_minandnoise_max.The α-shearlet transform of the distorted image is determined.Hard thresholding is performed on the set of α-shearlet coefficients. The thresholding parameter (i.e., the cutoff value)
c is chosen scale- and noise dependent via c = mσ, with m being a scale-dependentmultiplier.Numerical experiments showed that good results are obtained by taking m=3 for all scales except the highest and m=4
for the highest scale. This is the default choice made inoptimize_denoising. If desired, this default choice can be
modified using the parameterthresh_multiplier.The inverse α-shearlet transform of the thresholded coefficients is determined and the L²-error between this
reconstruction and the original image is calculated.The optimal value of α is the one for which the L²-error averaged over all images and all noise levels is the smallest.Theplotwhich is displayed byoptimize_denoisingdepicts the mean error over all images as a function of
the employed noise level λ for different values of α. In the present case, we are only considering one image (N=1).
Clearly, shearlets (i.e., α=0.5) turn out to be optimal for our toy example.For an eye inspection,optimize_denoisingalso saves the noisy image and the reconstructions for the largest noise level
(λ=0.4) and the different α values to the current working directory.
A small zoomed part of these reconstructions - together with the same part of the original image and the noisy image - can
be seen below:original imagenoisy imageα=0α=0.5α=1The α-shearlet transform for functions defined on the sphereAs described in the technical report, we use achart-basedapproach for computing the
α-shearlet transform of functions defined on the sphere. Precisely, we use the charts provided
by theHEALPixpixelizationof the sphere,
which divides the sphere into 12 faces and provides cartesian charts for each of these faces. The crucial property
of this pixelization is that each pixel has exactly the same spherical area.Now, given a functionfdefined on the sphere (in a discretized version, as a so-calledHEALPix map), one can use
the functionget_all_faces()fromSphereTransform.pyto obtain a family of 12 cartesian images, each of which
represents the functionfrestricted to one of the 12 faces of the sphere. As detailed in the technical report, analyzing
each of these 12 cartesian images and concatenating the coefficients is equivalent to analyzingfusing the sphere-based
α-shearlets.Conversely, one needs a way to reconstruct (a slightly modified version of)f, given the (possibly thresholded or
otherwise modified) α-shearlet coefficients. To this end, one first reconstructs each of the 12 cartesian images using
the usual α-shearlet transform and then concatenates these to obtain a functiongdefined on the sphere, via the
functionput_all_facesdefined inSphereTransform.py.Here, we just briefly indicate howput_all_facescan be used to obtain a plot of certain (randomly selected)
α-shearlets on the sphere. Below, we use an alpha-shearlet system with 6 scales, but only use alpha-shearlets
from the first three scales for plotting, since the alpha-shearlets on higher scales are very small/short
and thus unsuitable for producing a nice plot.>>>importhealpyashp>>>importnumpyasnp>>>importmatplotlib.pyplotasplt>>>fromSphereTransformimportput_all_facesasCartesian2Sphere>>>fromAlphaTransformimportAlphaShearletTransformasAST>>>width=height=512>>>alpha=0.5>>>num_scales=6# we use six scales, so that the shearlets on lower scales are big (good for plotting)>>>trafo=AST(width,height,[alpha]*num_scales,real=True)>>>all_shearlets=trafo.shearlets# get a list of all shearlets>>>cartesian_faces=np.empty((12,height,width))>>># for each of the 12 faces, select a random shearlet from one of the first three scales>>>upper_bound=trafo.scale_slice(3).start>>>shearlet_indices=np.random.choice(np.arange(upper_bound),size=12,replace=False)>>>fori,indexinenumerate(shearlet_indices):cartesian_faces[i]=all_shearlets[index]# normalize, so that the different shearlets are comparable in sizemax_val=np.max(np.abs(cartesian_faces[i]))cartesian_faces[i]/=max_val>>># use HEALPix charts to push the 12 cartesian faces onto the sphere>>>sphere_shearlets=Cartesian2Sphere(cartesian_faces)>>>hp.mollview(sphere_shearlets,cbar=False,hold=True)>>>plt.title(r"Random $\alpha$-shearlets on the sphere",fontsize=20)>>>plt.show()The above code produces a plot similar to the following:Required packagesIn addition to Python 3, the software requires the following Python packages:numpymatplotlibnumexprpyfftwtqdmhealpy(only required forSphereTransform.py)PIL, the Python Imaging Libraryscipy.ndimage