diff --git a/examples/plot_cgls.py b/examples/plot_cgls.py index 9b4ffb63..4d7a6623 100644 --- a/examples/plot_cgls.py +++ b/examples/plot_cgls.py @@ -43,8 +43,8 @@ Aop, y, x0=np.zeros_like(x), niter=10, tol=1e-10, show=True ) -print("x= %s" % x) -print("cgls solution xest= %s" % xest) +print(f"x= {x}") +print(f"cgls solution xest= {xest}") ############################################################################### # And the lsqr solver to invert this matrix @@ -64,8 +64,9 @@ cost_lsqr, ) = pylops.optimization.solver.lsqr(Aop, y, x0=np.zeros_like(x), niter=10, show=True) -print("x= %s" % x) -print("lsqr solution xest= %s" % xest) +print(f"x= {x}") +print(f"lsqr solution xest= {xest}") + ############################################################################### # Finally we show that the L2 norm of the residual of the two solvers decays diff --git a/examples/plot_diagonal.py b/examples/plot_diagonal.py index 0de27cb5..79b742d7 100644 --- a/examples/plot_diagonal.py +++ b/examples/plot_diagonal.py @@ -76,7 +76,7 @@ # simplest case where each element is multipled by a different value nx, ny = 3, 5 x = np.ones((nx, ny)) -print("x =\n%s" % x) +print(f"x =\n{x}") d = np.arange(nx * ny).reshape(nx, ny) Dop = pylops.Diagonal(d) @@ -84,14 +84,14 @@ y = Dop * x.ravel() y1 = Dop.H * x.ravel() -print("y = D*x =\n%s" % y.reshape(nx, ny)) -print("xadj = D'*x =\n%s " % y1.reshape(nx, ny)) +print(f"y = D*x =\n{y.reshape(nx, ny)}") +print(f"xadj = D'*x =\n{y1.reshape(nx, ny)}") ############################################################################### # And we now broadcast nx, ny = 3, 5 x = np.ones((nx, ny)) -print("x =\n%s" % x) +print(f"x =\n{x}") # 1st dim d = np.arange(nx) @@ -100,8 +100,8 @@ y = Dop * x.ravel() y1 = Dop.H * x.ravel() -print("1st dim: y = D*x =\n%s" % y.reshape(nx, ny)) -print("1st dim: xadj = D'*x =\n%s " % y1.reshape(nx, ny)) +print(f"1st dim: y = D*x =\n{y.reshape(nx, ny)}") +print(f"1st dim: xadj = D'*x =\n{y1.reshape(nx, ny)}") # 2nd dim d = np.arange(ny) @@ -110,5 +110,5 @@ y = Dop * x.ravel() y1 = Dop.H * x.ravel() -print("2nd dim: y = D*x =\n%s" % y.reshape(nx, ny)) -print("2nd dim: xadj = D'*x =\n%s " % y1.reshape(nx, ny)) +print(f"2nd dim: y = D*x =\n{y.reshape(nx, ny)}") +print(f"2nd dim: xadj = D'*x =\n{y1.reshape(nx, ny)}") diff --git a/examples/plot_identity.py b/examples/plot_identity.py index 557e2dd9..5d71a8c7 100644 --- a/examples/plot_identity.py +++ b/examples/plot_identity.py @@ -70,9 +70,9 @@ y = Iop * x xadj = Iop.H * y -print("x = %s " % x) -print("I*x = %s " % y) -print("I'*y = %s " % xadj) +print(f"x = {x} ") +print(f"I*x = {y} ") +print(f"I'*y = {xadj} ") ############################################################################### # and model bigger than data @@ -83,9 +83,9 @@ y = Iop * x xadj = Iop.H * y -print("x = %s " % x) -print("I*x = %s " % y) -print("I'*y = %s " % xadj) +print(f"x = {x} ") +print(f"I*x = {y} ") +print(f"I'*y = {xadj} ") ############################################################################### # Note that this operator can be useful in many real-life applications when for example diff --git a/examples/plot_linearregr.py b/examples/plot_linearregr.py index c9be2ee4..8e00f84d 100755 --- a/examples/plot_linearregr.py +++ b/examples/plot_linearregr.py @@ -70,25 +70,26 @@ np.array([t.min(), t.max()]) * x[1] + x[0], "k", lw=4, - label=r"true: $x_0$ = %.2f, $x_1$ = %.2f" % (x[0], x[1]), + label=rf"true: $x_0$ = {x[0]:.2f}, $x_1$ = {x[1]:.2f}", ) plt.plot( np.array([t.min(), t.max()]), np.array([t.min(), t.max()]) * xest[1] + xest[0], "--r", lw=4, - label=r"est noise-free: $x_0$ = %.2f, $x_1$ = %.2f" % (xest[0], xest[1]), + label=rf"est noise-free: $x_0$ = {xest[0]:.2f}, $x_1$ = {xest[1]:.2f}", ) plt.plot( np.array([t.min(), t.max()]), np.array([t.min(), t.max()]) * xnest[1] + xnest[0], "--g", lw=4, - label=r"est noisy: $x_0$ = %.2f, $x_1$ = %.2f" % (xnest[0], xnest[1]), + label=rf"est noisy: $x_0$ = {xnest[0]:.2f}, $x_1$ = {xnest[1]:.2f}", ) plt.scatter(t, y, c="r", s=70) plt.scatter(t, yn, c="g", s=70) plt.legend() +plt.tight_layout() ############################################################################### # Once that we have estimated the best fitting coefficients :math:`\mathbf{x}` @@ -103,6 +104,7 @@ plt.scatter(t, y, c="k", s=70) plt.scatter(t1, y1, c="r", s=40) plt.legend() +plt.tight_layout() ############################################################################### # We consider now the case where some of the observations have large errors. @@ -133,7 +135,7 @@ tolIRLS=tolIRLS, returnhistory=True, ) -print("IRLS converged at %d iterations..." % nouter) +print(f"IRLS converged at {nouter} iterations...") plt.figure(figsize=(5, 7)) plt.plot( @@ -141,25 +143,26 @@ np.array([t.min(), t.max()]) * x[1] + x[0], "k", lw=4, - label=r"true: $x_0$ = %.2f, $x_1$ = %.2f" % (x[0], x[1]), + label=rf"true: $x_0$ = {x[0]:.2f}, $x_1$ = {x[1]:.2f}", ) plt.plot( np.array([t.min(), t.max()]), np.array([t.min(), t.max()]) * xnest[1] + xnest[0], "--r", lw=4, - label=r"L2: $x_0$ = %.2f, $x_1$ = %.2f" % (xnest[0], xnest[1]), + label=rf"L2: $x_0$ = {xnest[0]:.2f}, $x_1$ = {xnest[1]:.2f}", ) plt.plot( np.array([t.min(), t.max()]), np.array([t.min(), t.max()]) * xirls[1] + xirls[0], "--g", lw=4, - label=r"L1 - IRSL: $x_0$ = %.2f, $x_1$ = %.2f" % (xirls[0], xirls[1]), + label=rf"L1 - IRSL: $x_0$ = {xirls[0]:.2f}, $x_1$ = {xirls[1]:.2f}", ) plt.scatter(t, y, c="r", s=70) plt.scatter(t, yn, c="g", s=70) plt.legend() +plt.tight_layout() ############################################################################### # Let's finally take a look at the convergence of IRLS. First we visualize diff --git a/examples/plot_matrixmult.py b/examples/plot_matrixmult.py index 97c5c9b1..68959e69 100644 --- a/examples/plot_matrixmult.py +++ b/examples/plot_matrixmult.py @@ -88,6 +88,7 @@ ax.grid(linewidth=3, color="white") ax.xaxis.set_ticklabels([]) ax.yaxis.set_ticklabels([]) +plt.tight_layout() gs = pltgs.GridSpec(1, 6) fig = plt.figure(figsize=(7, 3)) @@ -126,6 +127,7 @@ ax.grid(linewidth=3, color="white") ax.xaxis.set_ticklabels([]) ax.yaxis.set_ticklabels([]) +plt.tight_layout() ############################################################################### # Let's also plot the matrix eigenvalues @@ -156,6 +158,7 @@ plt.plot(xnest, "--g", lw=2, label="Noisy") plt.title("Matrix inversion", size=16, fontweight="bold") plt.legend() +plt.tight_layout() ############################################################################### # And we can also use a sparse matrix from the :obj:`scipy.sparse` @@ -168,12 +171,12 @@ y = Aop * x xest = Aop / y -print("A= %s" % Aop.A.todense()) -print("A^-1=", Aop.inv().todense()) -print("eigs=", Aop.eigs()) -print("x= %s" % x) -print("y= %s" % y) -print("lsqr solution xest= %s" % xest) +print(f"A= {Aop.A.todense()}") +print(f"A^-1= {Aop.inv().todense()}") +print(f"eigs= {Aop.eigs()}") +print(f"x= {x}") +print(f"y= {y}") +print(f"lsqr solution xest= {xest}") ############################################################################### # Finally, in several circumstances the input model :math:`\mathbf{x}` may @@ -206,7 +209,7 @@ xest, istop, itn, r1norm, r2norm = lsqr(Aop, y, damp=1e-10, iter_lim=10, show=0)[0:5] xest = xest.reshape(3, 2) -print("A= %s" % A) -print("x= %s" % x) -print("y= %s" % y) -print("lsqr solution xest= %s" % xest) +print(f"A= {A}") +print(f"x= {x}") +print(f"y={y}") +print(f"lsqr solution xest= {xest}") diff --git a/examples/plot_pad.py b/examples/plot_pad.py index cbc9bcf5..7d3b1cb8 100644 --- a/examples/plot_pad.py +++ b/examples/plot_pad.py @@ -23,9 +23,9 @@ y = Pop * x xadj = Pop.H * y -print("x = %s " % x) -print("P*x = %s " % y) -print("P'*y = %s " % xadj) +print(f"x = {x}") +print(f"P*x = {y}") +print(f"P'*y = {xadj}") ############################################################################### # We move now to a multi-dimensional case. We pad the input model diff --git a/examples/plot_regr.py b/examples/plot_regr.py index 4f29f089..caf86690 100755 --- a/examples/plot_regr.py +++ b/examples/plot_regr.py @@ -122,7 +122,7 @@ tolIRLS=tolIRLS, returnhistory=True, ) -print("IRLS converged at %d iterations..." % nouter) +print(f"IRLS converged at {nouter} iterations...") plt.figure(figsize=(5, 7)) plt.plot( diff --git a/examples/plot_stacking.py b/examples/plot_stacking.py index 2d8077a4..4bed8921 100755 --- a/examples/plot_stacking.py +++ b/examples/plot_stacking.py @@ -253,12 +253,12 @@ yop = ABop * x xinv = ABop / yop -print("AB = \n", AB) +print(f"AB = \n {AB}") -print("x = ", x) -print("y = ", y) -print("yop = ", yop) -print("xinv = ", x) +print(f"x = {x}") +print(f"y = {y}") +print(f"yop = {yop}") +print(f"xinv = {xinv}") ############################################################################### # We can also use :py:class:`pylops.Kronecker` to do something more diff --git a/examples/plot_zero.py b/examples/plot_zero.py index 55a284ae..ba6e1c99 100755 --- a/examples/plot_zero.py +++ b/examples/plot_zero.py @@ -72,10 +72,9 @@ y = Zop * x xadj = Zop.H * y -print("x = %s" % x) -print("0*x = %s" % y) -print("0'*y = %s" % xadj) - +print(f"x = {x}") +print(f"0*x = {y}") +print(f"0'*y = {xadj}") ############################################################################### # and model bigger than data @@ -86,9 +85,9 @@ y = Zop * x xadj = Zop.H * y -print("x = %s" % x) -print("0*x = %s" % y) -print("0'*y = %s" % xadj) +print(f"x = {x}") +print(f"0*x = {y}") +print(f"0'*y = {xadj}") ############################################################################### # Note that this operator can be useful in many real-life applications when for diff --git a/pylops/optimization/solver.py b/pylops/optimization/solver.py index 6b4ef732..bb0c28ce 100644 --- a/pylops/optimization/solver.py +++ b/pylops/optimization/solver.py @@ -53,8 +53,8 @@ def cg(Op, y, x0, niter=10, damp=0.0, tol=1e-4, show=False, callback=None): print( "CG\n" "-----------------------------------------------------------\n" - "The Operator Op has %d rows and %d cols\n" - "tol = %10e\tniter = %d" % (Op.shape[0], Op.shape[1], tol, niter) + f"The Operator Op has {Op.shape[0]} rows and {Op.shape[1]} cols\n" + f"tol = {tol:10e}\tniter = {niter}" ) print("-----------------------------------------------------------") head1 = " Itn x[0] r2norm" @@ -92,19 +92,13 @@ def cg(Op, y, x0, niter=10, damp=0.0, tol=1e-4, show=False, callback=None): if show: if iiter < 10 or niter - iiter < 10 or iiter % 10 == 0: if not np.iscomplex(x[0]): - msg = "%6g %11.4e %11.4e" % (iiter, x[0], cost[iiter]) + msg = f"{iiter:6g} {x[0]:11.4e} {cost[iiter]:11.4e}" else: - msg = "%6g %4.1e+%4.1ej %11.4e" % ( - iiter, - np.real(x[0]), - np.imag(x[0]), - cost[iiter], - ) + msg = f"{iiter:6g} {np.real(x[0]):4.1e} + {np.imag(x[0]):4.1e}j {cost[iiter]:11.4e}" print(msg) if show: print( - "\nIterations = %d Total time (s) = %.2f" - % (iiter, time.time() - tstart) + f"\nIterations = {iiter} Total time (s) = {time.time() - tstart:.2f}" ) print("-----------------------------------------------------------------\n") return x, iiter, cost[:iiter] @@ -178,9 +172,8 @@ def cgls(Op, y, x0, niter=10, damp=0.0, tol=1e-4, show=False, callback=None): print( "CGLS\n" "-----------------------------------------------------------\n" - "The Operator Op has %d rows and %d cols\n" - "damp = %10e\ttol = %10e\tniter = %d" - % (Op.shape[0], Op.shape[1], damp, tol, niter) + f"The Operator Op has {Op.shape[0]} rows and {Op.shape[1]} cols\n" + f"damp = {damp:10e}\ttol = {tol:10e}\tniter = {niter}" ) print("-----------------------------------------------------------") head1 = " Itn x[0] r1norm r2norm" @@ -226,25 +219,19 @@ def cgls(Op, y, x0, niter=10, damp=0.0, tol=1e-4, show=False, callback=None): if show: if iiter < 10 or niter - iiter < 10 or iiter % 10 == 0: if not np.iscomplex(x[0]): - msg = "%6g %11.4e %11.4e %11.4e" % ( - iiter, - x[0], - cost[iiter], - cost1[iiter], + msg = ( + f"{iiter:6g} {x[0]:11.4e} " + f"{cost[iiter]:11.4e} {cost1[iiter]:11.4e}" ) else: - msg = "%6g %4.1e+%4.1ej %11.4e %11.4e" % ( - iiter, - np.real(x[0]), - np.imag(x[0]), - cost[iiter], - cost1[iiter], + msg = ( + f"{iiter:6g} {np.real(x[0]):4.1e} + {np.imag(x[0]):4.1e}j " + f"{cost[iiter]:11.4e} {cost1[iiter]:11.4e}" ) print(msg) if show: print( - "\nIterations = %d Total time (s) = %.2f" - % (iiter, time.time() - tstart) + f"\nIterations = {iiter} Total time (s) = {time.time() - tstart:.2f}" ) print("-----------------------------------------------------------------\n") @@ -397,10 +384,10 @@ def lsqr( tstart = time.time() print("LSQR") print("-------------------------------------------------") - str1 = "The Operator Op has %d rows and %d cols" % (m, n) - str2 = "damp = %20.14e calc_var = %6g" % (damp, calc_var) - str3 = "atol = %8.2e conlim = %8.2e" % (atol, conlim) - str4 = "btol = %8.2e niter = %8g" % (btol, niter) + str1 = f"The Operator Op has {m} rows and {n} cols" + str2 = f"damp = {damp:20.14e} calc_var = {calc_var:6g}" + str3 = f"atol = {atol:8.2e} conlim = {conlim:8.2e}" + str4 = f"btol = {btol:8.2e} niter = {niter:8g}" print(str1) print(str2) print(str3) @@ -465,9 +452,9 @@ def lsqr( print(head1 + head2) test1 = 1 test2 = alfa / beta - str1 = "%6g %12.5e" % (itn, x[0]) - str2 = " %10.3e %10.3e" % (r1norm, r2norm) - str3 = " %8.1e %8.1e" % (test1, test2) + str1 = f"{itn:6g} {x[0]:12.5e}" + str2 = f" {r1norm:10.3e} {r2norm:10.3e}" + str3 = f" {test1:8.1e} {test2:8.1e}" print(str1 + str2 + str3) # main iteration loop @@ -594,10 +581,10 @@ def lsqr( or test1 <= 10 * rtol or istop != 0 ): - str1 = "%6g %12.5e" % (itn, x[0]) - str2 = " %10.3e %10.3e" % (r1norm, r2norm) - str3 = " %8.1e %8.1e" % (test1, test2) - str4 = " %8.1e %8.1e" % (anorm, acond) + str1 = f"{itn:6g} {x[0]:12.5e}" + str2 = f" {r1norm:10.3e} {r2norm:10.3e}" + str3 = f" {test1:8.1e} {test2:8.1e}" + str4 = f" {anorm:8.1e} {acond:8.1e}" print(str1 + str2 + str3 + str4) if istop > 0: break @@ -605,13 +592,13 @@ def lsqr( # Print the stopping condition. if show: print(" ") - print("LSQR finished, %s" % msg[istop]) + print(f"LSQR finished, {msg[istop]}") print(" ") - str1 = "istop =%8g r1norm =%8.1e" % (istop, r1norm) - str2 = "anorm =%8.1e arnorm =%8.1e" % (anorm, arnorm) - str3 = "itn =%8g r2norm =%8.1e" % (itn, r2norm) - str4 = "acond =%8.1e xnorm =%8.1e" % (acond, xnorm) - str5 = "Total time (s) = %.2f" % (time.time() - tstart) + str1 = f"istop ={istop:8g} r1norm ={r1norm:8.1e}" + str2 = f"anorm ={anorm:8.1e} arnorm ={arnorm:8.1e}" + str3 = f"itn ={itn:8g} r2norm ={r2norm:8.1e}" + str4 = f"acond ={acond:8.1e} xnorm ={xnorm:8.1e}" + str5 = f"Total time (s) = {time.time() - tstart:.2f}" print(str1 + " " + str2) print(str3 + " " + str4) print(str5) diff --git a/pylops/optimization/sparsity.py b/pylops/optimization/sparsity.py index 82a34f8e..83534d48 100644 --- a/pylops/optimization/sparsity.py +++ b/pylops/optimization/sparsity.py @@ -21,7 +21,7 @@ spgl1_message = "Spgl1 not installed. " 'Run "pip install spgl1".' except Exception as e: spgl1 = None - spgl1_message = "Failed to import spgl1 (error:%s)." % e + spgl1_message = f"Failed to import spgl1 (error:{e})." def _hardthreshold(x, thresh): @@ -212,7 +212,7 @@ def _IRLS_data( x0=None, tolIRLS=1e-10, returnhistory=False, - **kwargs_solver + **kwargs_solver, ): r"""Iteratively reweighted least squares with L1 data term""" ncp = get_array_module(data) @@ -274,7 +274,7 @@ def _IRLS_model( x0=None, tolIRLS=1e-10, returnhistory=False, - **kwargs_solver + **kwargs_solver, ): r"""Iteratively reweighted least squares with L1 model term""" ncp = get_array_module(data) @@ -290,15 +290,12 @@ def _IRLS_model( if ncp == np: xinv = Op.H @ lsqr(Op @ Op.H + (epsI ** 2) * Iop, data, **kwargs_solver)[0] else: - xinv = ( - Op.H - @ cgls( - Op @ Op.H + (epsI ** 2) * Iop, - data, - ncp.zeros(int(Op.shape[0]), dtype=Op.dtype), - **kwargs_solver - )[0] - ) + xinv = Op.H @ cgls( + Op @ Op.H + (epsI ** 2) * Iop, + data, + ncp.zeros(int(Op.shape[0]), dtype=Op.dtype), + **kwargs_solver, + )[0] if returnhistory: xinv_hist[0] = xinv for iiter in range(nouter): @@ -321,7 +318,7 @@ def _IRLS_model( Op @ R @ Op.H + epsI ** 2 * Iop, data, ncp.zeros(int(Op.shape[0]), dtype=Op.dtype), - **kwargs_solver + **kwargs_solver, )[0] ) # save history @@ -356,7 +353,7 @@ def IRLS( tolIRLS=1e-10, returnhistory=False, kind="data", - **kwargs_solver + **kwargs_solver, ): r"""Iteratively reweighted least squares. @@ -497,7 +494,7 @@ def IRLS( x0=x0, tolIRLS=tolIRLS, returnhistory=returnhistory, - **kwargs_solver + **kwargs_solver, ) @@ -597,10 +594,9 @@ def OMP( print( algname + "-----------------------------------------------------------------\n" - "The Operator Op has %d rows and %d cols\n" - "sigma = %.2e\tniter_outer = %d\tniter_inner = %d\n" - "normalization=%s" - % (Op.shape[0], Op.shape[1], sigma, niter_outer, niter_inner, normalizecols) + f"The Operator Op has {Op.shape[0]} rows and {Op.shape[1]} cols\n" + f"sigma = {sigma:.2e}\tniter_outer = {niter_outer}\tniter_inner = {niter_inner}\n" + f"normalization={normalizecols}" ) # find normalization factor for each column if normalizecols: @@ -674,14 +670,13 @@ def OMP( cost[iiter] = np.linalg.norm(res) if show: if iiter < 10 or niter_outer - iiter < 10 or iiter % 10 == 0: - msg = "%6g %12.5e" % (iiter + 1, cost[iiter]) + msg = f"{iiter + 1:6g} {cost[iiter]:12.5e}" print(msg) xinv = ncp.zeros(int(Op.shape[1]), dtype=Op.dtype) xinv[cols] = ncp.array(x) if show: print( - "\nIterations = %d Total time (s) = %.2f" - % (iiter, time.time() - tstart) + f"\nIterations = {iiter} Total time (s) = {time.time() - tstart:.2f}" ) print("-----------------------------------------------------------------\n") return xinv, iiter, cost @@ -879,11 +874,10 @@ def ISTA( if show: tstart = time.time() print( - "ISTA optimization (%s thresholding)\n" + f"ISTA optimization ({threshkind} thresholding)\n" "-----------------------------------------------------------\n" - "The Operator Op has %d rows and %d cols\n" - "eps = %10e\ttol = %10e\tniter = %d" - % (threshkind, Op.shape[0], Op.shape[1], eps, tol, niter) + f"The Operator Op has {Op.shape[0]} rows and {Op.shape[1]} cols\n" + f"eps = {eps:10e}\ttol = {tol:10e}\tniter = {niter}" ) # step size if alpha is None: @@ -897,7 +891,7 @@ def ISTA( neigs=1, symmetric=True, niter=eigsiter, - **dict(tol=eigstol, which="LM") + **dict(tol=eigstol, which="LM"), )[0] ) else: @@ -913,9 +907,9 @@ def ISTA( if show: if perc is None: - print("alpha = %10e\tthresh = %10e" % (alpha, thresh)) + print(f"alpha = {alpha:10e}\tthresh = {thresh:10e}") else: - print("alpha = %10e\tperc = %.1f" % (alpha, perc)) + print(f"alpha = {alpha:10e}\tperc = {perc:.1f}") print("-----------------------------------------------------------\n") head1 = " Itn x[0] r2norm r12norm xupdate" print(head1) @@ -951,9 +945,9 @@ def ISTA( normres = np.linalg.norm(res) if normres > normresold: raise ValueError( - "ISTA stopped at iteration %d due to " + f"ISTA stopped at iteration {iiter} due to " "residual increasing, consider modifying " - "eps and/or alpha..." % iiter + "eps and/or alpha..." ) else: normresold = normres @@ -987,18 +981,15 @@ def ISTA( if show: if iiter < 10 or niter - iiter < 10 or iiter % 10 == 0: - msg = "%6g %12.5e %10.3e %9.3e %10.3e" % ( - iiter + 1, - to_numpy(xinv[:2])[0], - costdata, - costdata + costreg, - xupdate, + msg = ( + f"{iiter + 1:6g} {to_numpy(xinv[:2])[0]:12.5e} " + f"{costdata:10.3e} {costdata + costreg:9.3e} {xupdate:10.3e}" ) print(msg) # check tolerance if xupdate < tol: - logging.warning("update smaller that tolerance for " "iteration %d" % iiter) + logging.warning("update smaller that tolerance for " "iteration %d", iiter) niter = iiter break @@ -1007,8 +998,7 @@ def ISTA( if show: print( - "\nIterations = %d Total time (s) = %.2f" - % (niter, time.time() - tstart) + f"\nIterations = {niter} Total time (s) = {time.time() - tstart:.2f}" ) print("---------------------------------------------------------\n") if returninfo: @@ -1184,11 +1174,10 @@ def FISTA( if show: tstart = time.time() print( - "FISTA optimization (%s thresholding)\n" + f"FISTA optimization ({threshkind} thresholding)\n" "-----------------------------------------------------------\n" - "The Operator Op has %d rows and %d cols\n" - "eps = %10e\ttol = %10e\tniter = %d" - % (threshkind, Op.shape[0], Op.shape[1], eps, tol, niter) + f"The Operator Op has {Op.shape[0]} rows and {Op.shape[1]} cols\n" + f"eps = {eps:10e}\ttol = {tol:10e}\tniter = {niter}" ) # step size if alpha is None: @@ -1202,7 +1191,7 @@ def FISTA( neigs=1, symmetric=True, niter=eigsiter, - **dict(tol=eigstol, which="LM") + **dict(tol=eigstol, which="LM"), ) )[0] else: @@ -1218,9 +1207,9 @@ def FISTA( if show: if perc is None: - print("alpha = %10e\tthresh = %10e" % (alpha, thresh)) + print(f"alpha = {alpha:10e}\tthresh = {thresh:10e}") else: - print("alpha = %10e\tperc = %.1f" % (alpha, perc)) + print(f"alpha = {alpha:10e}\tperc = {perc:.1f}") print("-----------------------------------------------------------\n") head1 = " Itn x[0] r2norm r12norm xupdate" print(head1) @@ -1287,12 +1276,9 @@ def FISTA( if show: if iiter < 10 or niter - iiter < 10 or iiter % 10 == 0: - msg = "%6g %12.5e %10.3e %9.3e %10.3e" % ( - iiter + 1, - to_numpy(xinv[:2])[0], - costdata, - costdata + costreg, - xupdate, + msg = ( + f"{iiter + 1:6g} {to_numpy(xinv[:2])[0]:12.5e} " + f"{costdata:10.3e} {costdata + costreg:9.3e} {xupdate:10.3e}" ) print(msg) @@ -1306,8 +1292,7 @@ def FISTA( if show: print( - "\nIterations = %d Total time (s) = %.2f" - % (niter, time.time() - tstart) + f"\nIterations = {niter} Total time (s) = {time.time() - tstart:.2f}" ) print("---------------------------------------------------------\n") if returninfo: @@ -1436,7 +1421,7 @@ def SPGL1(Op, data, SOp=None, tau=0, sigma=0, x0=None, **kwargs_spgl1): tau=tau, sigma=sigma, x0=x0, - **kwargs_spgl1 + **kwargs_spgl1, ) xinv = pinv.copy() if SOp is None else SOp.H * pinv @@ -1459,7 +1444,7 @@ def SplitBregman( x0=None, restart=False, show=False, - **kwargs_lsqr + **kwargs_lsqr, ): r"""Split Bregman for mixed L2-L1 norms. @@ -1591,19 +1576,9 @@ def SplitBregman( print( "Split-Bregman optimization\n" "---------------------------------------------------------\n" - "The Operator Op has %d rows and %d cols\n" - "niter_outer = %3d niter_inner = %3d tol = %2.2e\n" - "mu = %2.2e epsL1 = %s\t epsL2 = %s " - % ( - Op.shape[0], - Op.shape[1], - niter_outer, - niter_inner, - tol, - mu, - str(epsRL1s), - str(epsRL2s), - ) + f"The Operator Op has {Op.shape[0]} rows and {Op.shape[1]} cols\n" + f"niter_outer = {niter_outer:3d} niter_inner = {niter_inner:3d} tol = {tol:2.2e}\n" + f"mu = {mu:2.2e} epsL1 = {epsRL1s}\t epsL2 = {epsRL2s} " ) print("---------------------------------------------------------\n") head1 = " Itn x[0] r2norm r12norm" @@ -1644,7 +1619,7 @@ def SplitBregman( dataregs=dataregs, epsRs=epsRs, x0=x0 if restart else xinv, - **kwargs_lsqr + **kwargs_lsqr, ) # Shrinkage d = [ @@ -1672,18 +1647,15 @@ def SplitBregman( cost = ( costdata + ncp.sum(ncp.array(costregL2)) + ncp.sum(ncp.array(costregL1)) ) - msg = "%6g %12.5e %10.3e %9.3e" % ( - ncp.abs(itn_out), - ncp.real(xinv[0]), - costdata, - cost, + msg = ( + f"{ncp.abs(itn_out):6g} {ncp.real(xinv[0]):12.5e} " + f"{costdata:10.3e} {cost:9.3e}" ) print(msg) if show: print( - "\nIterations = %d Total time (s) = %.2f" - % (itn_out, time.time() - tstart) + f"\nIterations = {itn_out} Total time (s) = {time.time() - tstart:.2f}" ) print("---------------------------------------------------------\n") return xinv, itn_out diff --git a/pylops/signalprocessing/ChirpRadon3D.py b/pylops/signalprocessing/ChirpRadon3D.py index b16616b3..7f824410 100755 --- a/pylops/signalprocessing/ChirpRadon3D.py +++ b/pylops/signalprocessing/ChirpRadon3D.py @@ -19,7 +19,7 @@ ) except Exception as e: pyfftw = None - pyfftw_message = "Failed to import pyfftw (error:%s), use numpy." % e + pyfftw_message = f"Failed to import pyfftw (error:{e}), use numpy." logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.WARNING) @@ -83,7 +83,7 @@ def __init__( pmax, engine="numpy", dtype="float64", - **kwargs_fftw + **kwargs_fftw, ): self.dt = taxis[1] - taxis[0] self.dy = hyaxis[1] - hyaxis[0] diff --git a/pylops/signalprocessing/DWT.py b/pylops/signalprocessing/DWT.py index 0d9fda78..840fb101 100644 --- a/pylops/signalprocessing/DWT.py +++ b/pylops/signalprocessing/DWT.py @@ -19,7 +19,7 @@ ) except Exception as e: pywt = None - pywt_message = "Failed to import pywt (error:%s)." % e + pywt_message = f"Failed to import pywt (error:{e})." logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.WARNING) @@ -28,7 +28,7 @@ def _checkwavelet(wavelet): """Check that wavelet belongs to pywt.wavelist""" wavelist = pywt.wavelist(kind="discrete") if wavelet not in wavelist: - raise ValueError("'%s' not in family set = %s" % (wavelet, wavelist)) + raise ValueError(f"'{wavelet}' not in family set = {wavelist}") def _adjointwavelet(wavelet): diff --git a/pylops/signalprocessing/DWT2D.py b/pylops/signalprocessing/DWT2D.py index 0097cac8..a29fb7a6 100644 --- a/pylops/signalprocessing/DWT2D.py +++ b/pylops/signalprocessing/DWT2D.py @@ -20,7 +20,7 @@ ) except Exception as e: pywt = None - pywt_message = "Failed to import pywt (error:%s)." % e + pywt_message = f"Failed to import pywt (error:{e})." logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.WARNING) diff --git a/pylops/signalprocessing/FFT.py b/pylops/signalprocessing/FFT.py index c17a71f6..cdf6c58d 100644 --- a/pylops/signalprocessing/FFT.py +++ b/pylops/signalprocessing/FFT.py @@ -17,7 +17,7 @@ ) except Exception as e: pyfftw = None - pyfftw_message = "Failed to import pyfftw (error:%s), use numpy." % e + pyfftw_message = f"Failed to import pyfftw (error:{e}), use numpy." logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.WARNING) diff --git a/pylops/signalprocessing/Patch2D.py b/pylops/signalprocessing/Patch2D.py index 8f09739f..76bcd640 100644 --- a/pylops/signalprocessing/Patch2D.py +++ b/pylops/signalprocessing/Patch2D.py @@ -135,27 +135,27 @@ def Patch2D(Op, dims, dimsd, nwin, nover, nop, tapertype="hanning", design=False logging.warning("%d-%d windows required...", nwins0, nwins1) logging.warning( "model wins - start:%s, end:%s / start:%s, end:%s", - str(mwin0_ins), - str(mwin0_ends), - str(mwin1_ins), - str(mwin1_ends), + mwin0_ins, + mwin0_ends, + mwin1_ins, + mwin1_ends, ) logging.warning( "data wins - start:%s, end:%s / start:%s, end:%s", - str(dwin0_ins), - str(dwin0_ends), - str(dwin1_ins), - str(dwin1_ends), + dwin0_ins, + dwin0_ends, + dwin1_ins, + dwin1_ends, ) if nwins0 * nop[0] != dims[0] or nwins1 * nop[1] != dims[1]: raise ValueError( - "Model shape (dims=%s) is not consistent with chosen " - "number of windows. Choose dims[0]=%d and " - "dims[1]=%d for the operator to work with " + f"Model shape (dims={dims}) is not consistent with chosen " + f"number of windows. Choose dims[0]={nwins0 * nop[0]} and " + f"dims[1]={nwins1 * nop[1]} for the operator to work with " "estimated number of windows, or create " "the operator with design=True to find out the" "optimal number of windows for the current " - "model size..." % (str(dims), nwins0 * nop[0], nwins1 * nop[1]) + "model size..." ) # transform to apply if tapertype is None: diff --git a/pylops/signalprocessing/Sliding1D.py b/pylops/signalprocessing/Sliding1D.py index 7b4c1911..2e2bf0d2 100644 --- a/pylops/signalprocessing/Sliding1D.py +++ b/pylops/signalprocessing/Sliding1D.py @@ -85,16 +85,16 @@ def Sliding1D(Op, dim, dimd, nwin, nover, tapertype="hanning", design=False): # check that identified number of windows agrees with mode size if design: logging.warning("%d windows required...", nwins) - logging.warning("model wins - start:%s, end:%s", str(mwin_ins), str(mwin_ends)) - logging.warning("data wins - start:%s, end:%s", str(dwin_ins), str(dwin_ends)) + logging.warning("model wins - start:%s, end:%s", mwin_ins, mwin_ends) + logging.warning("data wins - start:%s, end:%s", dwin_ins, dwin_ends) if nwins * Op.shape[1] != dim: raise ValueError( - "Model shape (dim=%d) is not consistent with chosen " - "number of windows. Choose dim=%d for the " + f"Model shape (dim={dim}) is not consistent with chosen " + f"number of windows. Choose dim={nwins * Op.shape[1]} for the " "operator to work with estimated number of windows, " "or create the operator with design=True to find " "out the optimal number of windows for the current " - "model size..." % (dim, nwins * Op.shape[1]) + "model size..." ) # transform to apply if tapertype is None: diff --git a/pylops/signalprocessing/Sliding2D.py b/pylops/signalprocessing/Sliding2D.py index 5c163859..d08ed744 100644 --- a/pylops/signalprocessing/Sliding2D.py +++ b/pylops/signalprocessing/Sliding2D.py @@ -31,7 +31,7 @@ def _slidingsteps(ntr, nwin, nover): """ if nwin > ntr: - raise ValueError("nwin=%d is bigger than ntr=%d..." % (nwin, ntr)) + raise ValueError(f"nwin={nwin} is bigger than ntr={ntr}...") step = nwin - nover starts = np.arange(0, ntr - nwin + 1, step, dtype=int) ends = starts + nwin @@ -117,16 +117,16 @@ def Sliding2D(Op, dims, dimsd, nwin, nover, tapertype="hanning", design=False): # check that identified number of windows agrees with mode size if design: logging.warning("%d windows required...", nwins) - logging.warning("model wins - start:%s, end:%s", str(mwin_ins), str(mwin_ends)) - logging.warning("data wins - start:%s, end:%s", str(dwin_ins), str(dwin_ends)) + logging.warning("model wins - start:%s, end:%s", mwin_ins, mwin_ends) + logging.warning("data wins - start:%s, end:%s", dwin_ins, dwin_ends) if nwins * Op.shape[1] // dims[1] != dims[0]: raise ValueError( - "Model shape (dims=%s) is not consistent with chosen " - "number of windows. Choose dims[0]=%d for the " + f"Model shape (dims={dims}) is not consistent with chosen " + f"number of windows. Choose dims[0]={nwins * Op.shape[1] // dims[1]} for the " "operator to work with estimated number of windows, " "or create the operator with design=True to find " "out the optimal number of windows for the current " - "model size..." % (str(dims), nwins * Op.shape[1] // dims[1]) + "model size..." ) # transform to apply if tapertype is None: diff --git a/pylops/signalprocessing/Sliding3D.py b/pylops/signalprocessing/Sliding3D.py index ab48ed0d..855aa4fe 100644 --- a/pylops/signalprocessing/Sliding3D.py +++ b/pylops/signalprocessing/Sliding3D.py @@ -93,33 +93,28 @@ def Sliding3D( logging.warning("(%d,%d) windows required...", nwins0, nwins1) logging.warning( "model wins - start0:%s, end0:%s, start1:%s, end1:%s", - str(mwin0_ins), - str(mwin0_ends), - str(mwin1_ins), - str(mwin1_ends), + mwin0_ins, + mwin0_ends, + mwin1_ins, + mwin1_ends, ) logging.warning( "data wins - start0:%s, end0:%s, start1:%s, end1:%s", - str(dwin0_ins), - str(dwin0_ends), - str(dwin1_ins), - str(dwin1_ends), + dwin0_ins, + dwin0_ends, + dwin1_ins, + dwin1_ends, ) if nwins * Op.shape[1] // dims[2] != dims[0] * dims[1]: raise ValueError( - "Model shape (dims=%s) is not consistent with chosen " - "number of windows. Choose dims[0]=%d and " - "dims[1]=%d for the operator to work with " + f"Model shape (dims={dims}) is not consistent with chosen " + f"number of windows. Choose dims[0]={nwins0 * Op.shape[1] // (nop[1] * dims[2])} and " + f"dims[1]={nwins1 * Op.shape[1] // (nop[0] * dims[2])} for the operator to work with " "estimated number of windows, or create " "the operator with design=True to find out the" "optimal number of windows for the current " "model size..." - % ( - str(dims), - nwins0 * Op.shape[1] // (nop[1] * dims[2]), - nwins1 * Op.shape[1] // (nop[0] * dims[2]), - ) ) # transform to apply if tapertype is None: diff --git a/pylops/utils/multiproc.py b/pylops/utils/multiproc.py index 985e0384..556ccdc0 100644 --- a/pylops/utils/multiproc.py +++ b/pylops/utils/multiproc.py @@ -30,7 +30,7 @@ def scalability_test(Op, x, workers=[1, 2, 4], forward=True): compute_times = [] speedup = [] for nworkers in workers: - print("Working with %d workers..." % nworkers) + print(f"Working with {nworkers} workers...") # update number of workers in operator Op.nproc = nworkers # run forward/adjoint computation diff --git a/pylops/utils/tapers.py b/pylops/utils/tapers.py index c4c66825..dc90d688 100644 --- a/pylops/utils/tapers.py +++ b/pylops/utils/tapers.py @@ -23,9 +23,7 @@ def hanningtaper(nmask, ntap): if ntap > 0: if (nmask // ntap) < 2: ntap_min = nmask / 2 if nmask % 2 == 0 else (nmask - 1) / 2 - raise ValueError( - "ntap=%d must be smaller or " "equal than %d" % (ntap, ntap_min) - ) + raise ValueError(f"ntap={ntap} must be smaller or equal than {ntap_min}") han_win = np.hanning(ntap * 2 - 1) st_tpr = han_win[ :ntap, diff --git a/pylops/waveeqprocessing/lsm.py b/pylops/waveeqprocessing/lsm.py index 99553ddf..714f624d 100644 --- a/pylops/waveeqprocessing/lsm.py +++ b/pylops/waveeqprocessing/lsm.py @@ -19,7 +19,7 @@ ) except Exception as e: skfmm = None - skfmm_message = "Failed to import skfmm (error:%s)." % e + skfmm_message = f"Failed to import skfmm (error:{e})." logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.WARNING) diff --git a/pylops/waveeqprocessing/mdd.py b/pylops/waveeqprocessing/mdd.py index 5c6ce650..025d78a9 100644 --- a/pylops/waveeqprocessing/mdd.py +++ b/pylops/waveeqprocessing/mdd.py @@ -90,7 +90,7 @@ def _MDC( nfft = int(np.ceil((nt + 1) / 2)) if nfmax > nfft: nfmax = nfft - logging.warning("nfmax set equal to ceil[(nt+1)/2=%d]" % nfmax) + logging.warning("nfmax set equal to ceil[(nt+1)/2=%d]", nfmax) Fop = _FFT( dims=(nt, nr, nv), @@ -434,7 +434,7 @@ def MDD( # Fix nfmax to be at maximum equal to half of the size of fft samples if nfmax is None or nfmax > nfmax_allowed: nfmax = nfmax_allowed - logging.warning("nfmax set equal to ceil[(nt+1)/2=%d]" % nfmax) + logging.warning("nfmax set equal to ceil[(nt+1)/2=%d]", nfmax) # Add negative part to data and model if twosided and add_negative: diff --git a/pylops/waveeqprocessing/seismicinterpolation.py b/pylops/waveeqprocessing/seismicinterpolation.py index 32032a00..e1340336 100644 --- a/pylops/waveeqprocessing/seismicinterpolation.py +++ b/pylops/waveeqprocessing/seismicinterpolation.py @@ -42,7 +42,7 @@ def SeismicInterpolation( design=False, engine="numba", dottest=False, - **kwargs_solver + **kwargs_solver, ): r"""Seismic interpolation (or regularization). @@ -256,7 +256,7 @@ def SeismicInterpolation( if spataxis is None or spat1axis is None or taxis is None: raise ValueError( "Provide either sampling or spataxis, " - "spat1axis and taxis for kind=%s" % kind + f"spat1axis and taxis for kind=%{kind}" ) else: sampling = ( @@ -271,7 +271,7 @@ def SeismicInterpolation( if spataxis is None or taxis is None: raise ValueError( "Provide either sampling or spataxis, " - "and taxis for kind=%s" % kind + f"and taxis for kind={kind}" ) else: sampling = ( diff --git a/pytests/test_causalintegration.py b/pytests/test_causalintegration.py index b01aebdb..df6287fb 100755 --- a/pytests/test_causalintegration.py +++ b/pytests/test_causalintegration.py @@ -138,7 +138,6 @@ def test_CausalIntegration2d(par): dtype=par["dtype"], ) rf1 = 1 if rf else 0 - print(Cop.shape, (par["nt"] - rf1) * par["nx"], par["nt"] * par["nx"]) assert dottest( Cop, (par["nt"] - rf1) * par["nx"], diff --git a/pytests/test_ffts.py b/pytests/test_ffts.py index 4ccf265b..152f7573 100755 --- a/pytests/test_ffts.py +++ b/pytests/test_ffts.py @@ -1132,7 +1132,6 @@ def test_FFT_3dsignal(par): # check all signal if nx>nfft and only up to nfft if nfft