Note
Go to the end to download the full example code
LDDMM with normalized kernel¶
This notebook illustrates the interest of normalizing the cometric in the LDDMM model. We consider the registration of two spheres that differ by a translation first, and then a more complex registration task with a translation and a deformation.
Without normalization, the carpooling artifact occurs: the sphere is contracted, then translated and finally expanded. in this situation, event if the morphed shape matches the target, the intermediate shapes are not meaningful and the extrapolation is not reliable.
Normalizing the kernel adds regularization to the morphing, leanding to prevention of the carpooling artifact and improvement of the extrapolation to some extent.
Options for normalization are:
“rows”: normalize the rows of the kernel
“columns”: normalize the columns of the kernel
“both”: normalize both the rows and the columns of the kernel (for quare kernels, algorithm 5.7 in https://www.jeanfeydy.com/geometric_data_analysis.pdf)
Further explanation can be found in the p177 and onwards of https://www.jeanfeydy.com/geometric_data_analysis.pdf.
from time import time
import pyvista as pv
import torch
import skshapes as sks
# sphinx_gallery_thumbnail_number = 9
Load data
plot_kwargs = {
"smooth_shading": True,
"pbr": True,
"metallic": 0.7,
"roughness": 0.6,
}
cpos = [(1.6256104086078755, -9.701422233882411, 1.3012755902068773),
(1.191160019984921, 0.01901107976782581, -0.0052552929581526076),
(0.006053690112347382, 0.13347614338229413, 0.9910335372649167)]
source = sks.Sphere()
target = sks.Sphere()
decimation = sks.Decimation(n_points = 200)
source = decimation.fit_transform(source)
target = decimation.transform(target)
target.points = target.points + torch.tensor([2, 0.0, 0.0])
plotter = pv.Plotter()
plotter.add_mesh(source.to_pyvista(), color="teal", opacity=0.8, **plot_kwargs)
plotter.add_mesh(target.to_pyvista(), color="red", opacity=0.8, **plot_kwargs)
plotter.camera_position = cpos
plotter.show()
LDDM without normalization¶
model = sks.ExtrinsicDeformation(
n_steps=4,
kernel="gaussian",
scale=0.3,
)
loss = sks.L2Loss()
task = sks.Registration(
model=model,
loss=loss,
optimizer=sks.LBFGS(),
n_iter=3,
regularization_weight=1e-1,
verbose=True,
)
start = time()
task.fit(source=source, target=target)
print("Elapsed time: ", time() - start)
path = task.path_
plotter = pv.Plotter()
plotter.add_mesh(source.to_pyvista(), color="teal", opacity=0.2, **plot_kwargs)
plotter.add_mesh(target.to_pyvista(), color="red", opacity=0.2, **plot_kwargs)
for i in range(len(path)):
plotter.add_mesh(path[i].to_pyvista(), color="tan", opacity=0.8, **plot_kwargs)
plotter.camera_position = cpos
plotter.show()
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula Exp(-Sum((a-b)**2))*c with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,3,1) ... OK
[pyKeOps] Compiling pykeops cpp 53d8b63c4c module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (-2*((a-b)*(d|c)))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,3,1), d=Var(3,3,0) ... OK
[pyKeOps] Compiling pykeops cpp 42d1c2bb84 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (2*((a-b)*(d|c)))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,3,1), d=Var(3,3,0) ... OK
[pyKeOps] Compiling pykeops cpp 90af7935d4 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula Exp(-Sum((a-b)**2))*d with a=Var(0,3,0), b=Var(1,3,1), d=Var(3,3,0) ... OK
[pyKeOps] Compiling pykeops cpp d78b822b9e module ... OK
Initial loss : 8.04e+02
= 8.04e+02 + 0.1 * 0.00e+00 (fidelity + regularization_weight * regularization)
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (-2*((a-b)*(f|d)))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), d=Var(3,3,0), f=Var(5,3,1) ... OK
[pyKeOps] Compiling pykeops cpp 52e01d1132 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (2*((a-b)*(f|d)))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), d=Var(3,3,0), f=Var(5,3,1) ... OK
[pyKeOps] Compiling pykeops cpp 5c72c5b452 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula Zero(3) with ... OK
[pyKeOps] Compiling pykeops cpp 6b9d40cb88 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula Exp(-Sum((a-b)**2))*f with a=Var(0,3,0), b=Var(1,3,1), f=Var(5,3,1) ... OK
[pyKeOps] Compiling pykeops cpp e221bcfff3 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (2*((d|c)*f)+-4*((a-b)*((d|c)*((a-b)|f))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,3,1), d=Var(3,3,0), f=Var(5,3,1) ... OK
[pyKeOps] Compiling pykeops cpp a44d3d3db5 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (-2*((d|c)*f)+4*((a-b)*((d|c)*((a-b)|f))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,3,1), d=Var(3,3,0), f=Var(5,3,1) ... OK
[pyKeOps] Compiling pykeops cpp 369de12a48 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (2*((f|(a-b))*d))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), d=Var(3,3,0), f=Var(5,3,1) ... OK
[pyKeOps] Compiling pykeops cpp 42e8032490 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (2*((f|(a-b))*c))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,3,1), f=Var(5,3,1) ... OK
[pyKeOps] Compiling pykeops cpp efcd299a74 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (-2*((d|c)*f)+4*((a-b)*((d|c)*((a-b)|f))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,3,1), d=Var(3,3,0), f=Var(5,3,0) ... OK
[pyKeOps] Compiling pykeops cpp c1e554924b module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (2*((d|c)*f)+-4*((a-b)*((d|c)*((a-b)|f))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,3,1), d=Var(3,3,0), f=Var(5,3,0) ... OK
[pyKeOps] Compiling pykeops cpp 234f2ba8f2 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (-2*((f|(a-b))*d))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), d=Var(3,3,0), f=Var(5,3,0) ... OK
[pyKeOps] Compiling pykeops cpp 0538180a79 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (-2*((f|(a-b))*c))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,3,1), f=Var(5,3,0) ... OK
[pyKeOps] Compiling pykeops cpp 2175ab1eb1 module ... OK
Loss after 1 iteration(s) : 1.84e+00
= 1.42e+00 + 0.1 * 4.16e+00 (fidelity + regularization_weight * regularization)
Loss after 2 iteration(s) : 5.25e-01
= 1.21e-01 + 0.1 * 4.04e+00 (fidelity + regularization_weight * regularization)
Loss after 3 iteration(s) : 4.40e-01
= 3.99e-02 + 0.1 * 4.00e+00 (fidelity + regularization_weight * regularization)
Elapsed time: 67.28215527534485
Extrapolation
back = model.morph(
shape=source,
parameter=task.parameter_,
final_time=-1.0,
return_path=True,
).path
model.n_steps = 8
forward = model.morph(
shape=source,
parameter=task.parameter_,
final_time=2.0,
return_path=True,
).path
path = back[::-1] + forward[1:]
plotter = pv.Plotter()
plotter.open_gif("lddmm_no_normalization.gif", fps=4)
for i in range(len(path)):
plotter.clear_actors()
plotter.add_mesh(source.to_pyvista(), color="teal", opacity=0.2, **plot_kwargs)
plotter.add_mesh(target.to_pyvista(), color="red", opacity=0.2, **plot_kwargs)
plotter.add_mesh(path[i].to_pyvista(), color="tan", opacity=0.8, **plot_kwargs)
plotter.camera_position = cpos
plotter.write_frame()
plotter.close()
Normalizing the rows of the kernel¶
model_norm = sks.ExtrinsicDeformation(
n_steps=4,
kernel="gaussian",
scale=0.3,
normalization="rows",
)
task_norm = sks.Registration(
model=model_norm,
loss=loss,
optimizer=sks.LBFGS(),
n_iter=1,
regularization_weight=0.0,
verbose=True,
)
start = time()
task_norm.fit(source=source, target=target)
print("Elapsed time: ", time() - start)
path = task_norm.path_
plotter = pv.Plotter()
plotter.add_mesh(source.to_pyvista(), color="teal", opacity=0.2, **plot_kwargs)
plotter.add_mesh(target.to_pyvista(), color="red", opacity=0.2, **plot_kwargs)
for i in range(len(path)):
plotter.add_mesh(path[i].to_pyvista(), color="tan", opacity=0.8, **plot_kwargs)
plotter.camera_position = cpos
plotter.show()
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1) ... OK
[pyKeOps] Compiling pykeops cpp 86d46fe1aa module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (-2*((a-b)*c))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,0) ... OK
[pyKeOps] Compiling pykeops cpp 70dadc1e68 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (2*((a-b)*c))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,0) ... OK
[pyKeOps] Compiling pykeops cpp 889cb01593 module ... OK
Initial loss : 8.04e+02
= 8.04e+02 + 0 (fidelity + regularization_weight * regularization)
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (2*(c*e)+-4*((a-b)*(c*((a-b)|e))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,0), e=Var(4,3,1) ... OK
[pyKeOps] Compiling pykeops cpp 9098e59e88 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (-2*(c*e)+4*((a-b)*(c*((a-b)|e))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,0), e=Var(4,3,1) ... OK
[pyKeOps] Compiling pykeops cpp 3668ec0b41 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (2*(e|(a-b)))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), e=Var(4,3,1) ... OK
[pyKeOps] Compiling pykeops cpp 4751fc1a9e module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (-2*(c*e)+4*((a-b)*(c*((a-b)|e))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,0), e=Var(4,3,0) ... OK
[pyKeOps] Compiling pykeops cpp d3435b7e0b module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (2*(c*e)+-4*((a-b)*(c*((a-b)|e))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,0), e=Var(4,3,0) ... OK
[pyKeOps] Compiling pykeops cpp fc0560bc9d module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (-2*(e|(a-b)))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), e=Var(4,3,0) ... OK
[pyKeOps] Compiling pykeops cpp e703df3974 module ... OK
Loss after 1 iteration(s) : 1.67e-03
= 1.67e-03 + 0 (fidelity + regularization_weight * regularization)
Elapsed time: 38.07446599006653
Extrapolation
back = model_norm.morph(
shape=source,
parameter=task_norm.parameter_,
final_time=-1.0,
return_path=True,
).path
model_norm.n_steps = 8
forward = model_norm.morph(
shape=source,
parameter=task_norm.parameter_,
final_time=2.0,
return_path=True,
).path
path = back[::-1] + forward[1:]
plotter = pv.Plotter()
plotter.open_gif("lddmm_normalization.gif", fps=4)
for i in range(len(path)):
plotter.clear_actors()
plotter.add_mesh(source.to_pyvista(), color="teal", opacity=0.2, **plot_kwargs)
plotter.add_mesh(target.to_pyvista(), color="red", opacity=0.2, **plot_kwargs)
plotter.add_mesh(path[i].to_pyvista(), color="tan", opacity=0.8, **plot_kwargs)
plotter.camera_position = cpos
plotter.write_frame()
plotter.close()
Normalizing both rows and columns of the kernel¶
model_norm = sks.ExtrinsicDeformation(
n_steps=4,
kernel="gaussian",
scale=0.3,
normalization="both",
)
task_norm = sks.Registration(
model=model_norm,
loss=loss,
optimizer=sks.LBFGS(),
n_iter=1,
regularization_weight=0.0,
verbose=True,
)
start = time()
task_norm.fit(source=source, target=target)
elapsed_time = time() - start
path = task_norm.path_
plotter = pv.Plotter()
plotter.add_mesh(source.to_pyvista(), color="teal", opacity=0.2, **plot_kwargs)
plotter.add_mesh(target.to_pyvista(), color="red", opacity=0.2, **plot_kwargs)
for i in range(len(path)):
plotter.add_mesh(path[i].to_pyvista(), color="tan", opacity=0.8, **plot_kwargs)
plotter.camera_position = cpos
plotter.show()
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula c*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,1) ... OK
[pyKeOps] Compiling pykeops cpp 151acd82c2 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (-2*((a-b)*(d*c)))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,1), d=Var(3,1,0) ... OK
[pyKeOps] Compiling pykeops cpp f15387d04d module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (2*((a-b)*(d*c)))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,1), d=Var(3,1,0) ... OK
[pyKeOps] Compiling pykeops cpp c505e5a190 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula d*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), d=Var(3,1,0) ... OK
[pyKeOps] Compiling pykeops cpp bb78e072a3 module ... OK
Initial loss : 8.04e+02
= 8.04e+02 + 0 (fidelity + regularization_weight * regularization)
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (2*((d*c)*f)+-4*((a-b)*((d*c)*((a-b)|f))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,1), d=Var(3,1,0), f=Var(5,3,1) ... OK
[pyKeOps] Compiling pykeops cpp f7b5a73a8e module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (-2*((d*c)*f)+4*((a-b)*((d*c)*((a-b)|f))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,1), d=Var(3,1,0), f=Var(5,3,1) ... OK
[pyKeOps] Compiling pykeops cpp c59efd8557 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (2*(c*(f|(a-b))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,1), f=Var(5,3,1) ... OK
[pyKeOps] Compiling pykeops cpp 5b9174a19f module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (-2*((d*c)*f)+4*((a-b)*((d*c)*((a-b)|f))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,1), d=Var(3,1,0), f=Var(5,3,0) ... OK
[pyKeOps] Compiling pykeops cpp 80bb359e65 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (2*((d*c)*f)+-4*((a-b)*((d*c)*((a-b)|f))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,1), d=Var(3,1,0), f=Var(5,3,0) ... OK
[pyKeOps] Compiling pykeops cpp 72c5c4a9f3 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (-2*(c*(f|(a-b))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), c=Var(2,1,1), f=Var(5,3,0) ... OK
[pyKeOps] Compiling pykeops cpp 9bac215434 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula (-2*((a-b)*(f*d)))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), d=Var(3,1,0), f=Var(5,1,1) ... OK
[pyKeOps] Compiling pykeops cpp cd3eb7d2f1 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (2*((a-b)*(f*d)))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), d=Var(3,1,0), f=Var(5,1,1) ... OK
[pyKeOps] Compiling pykeops cpp 4e195119f1 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula Zero(1) with ... OK
[pyKeOps] Compiling pykeops cpp 5c239a6aa2 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 0) of formula f*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), f=Var(5,1,1) ... OK
[pyKeOps] Compiling pykeops cpp a097c2198e module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (2*(d*(f|(a-b))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), d=Var(3,1,0), f=Var(5,3,1) ... OK
[pyKeOps] Compiling pykeops cpp 10c2b19683 module ... OK
[KeOps] Generating code for Sum_Reduction reduction (with parameters 1) of formula (-2*(d*(f|(a-b))))*Exp(-Sum((a-b)**2)) with a=Var(0,3,0), b=Var(1,3,1), d=Var(3,1,0), f=Var(5,3,0) ... OK
[pyKeOps] Compiling pykeops cpp 7cfc01571c module ... OK
Loss after 1 iteration(s) : 4.98e-06
= 4.98e-06 + 0 (fidelity + regularization_weight * regularization)
Extrapolation
back = model_norm.morph(
shape=source,
parameter=task_norm.parameter_,
final_time=-1.0,
return_path=True,
).path
model_norm.n_steps = 8
forward = model_norm.morph(
shape=source,
parameter=task_norm.parameter_,
final_time=2.0,
return_path=True,
).path
path = back[::-1] + forward[1:]
plotter = pv.Plotter()
plotter.open_gif("lddmm_normalization.gif", fps=4)
for i in range(len(path)):
plotter.clear_actors()
plotter.add_mesh(source.to_pyvista(), color="teal", opacity=0.2, **plot_kwargs)
plotter.add_mesh(target.to_pyvista(), color="red", opacity=0.2, **plot_kwargs)
plotter.add_mesh(path[i].to_pyvista(), color="tan", opacity=0.8, **plot_kwargs)
plotter.camera_position = cpos
plotter.write_frame()
plotter.close()
Example with a more complex shape¶
n_steps = 3
plot_kwargs = {
"smooth_shading": True,
"pbr": True,
"metallic": 0.7,
"roughness": 0.6,
}
cpos = [(3.6401575998373183, -1.183408993703478, 1.0915912440258628),
(0.7463583722710609, 0.762569822371006, 0.48035204596817493),
(-0.1745415166347431, 0.04933887578777028, 0.9834129012306287)]
# 5 - 8
source = sks.PolyData("../data/cactus/cactus3.ply")
target = sks.PolyData("../data/cactus/cactus11.ply")
target.points += torch.Tensor([0.5, 0.5, 0])
decimation = sks.Decimation(n_points = 500)
source = decimation.fit_transform(source)
target = decimation.transform(target)
model = sks.ExtrinsicDeformation(
n_steps=n_steps,
kernel="gaussian",
scale=0.1,
normalization="both",
)
loss = sks.L2Loss()
Interpolation¶
task = sks.Registration(
model=model,
loss=loss,
optimizer=sks.LBFGS(),
n_iter=1,
verbose=True,
regularization_weight=0.001
)
start = time()
task.fit(source=source, target=target)
print("Elapsed time: ", time() - start)
path = task.path_
plotter = pv.Plotter()
for frame in path:
plotter.add_mesh(frame.to_pyvista(), color="tan", opacity=0.3, **plot_kwargs)
plotter.add_mesh(source.to_pyvista(), color="teal", opacity=0.5, **plot_kwargs)
plotter.add_mesh(target.to_pyvista(), color="red", opacity=0.5, **plot_kwargs)
plotter.camera_position = cpos
plotter.show()
Initial loss : 2.50e+02
= 2.50e+02 + 0.001 * 0.00e+00 (fidelity + regularization_weight * regularization)
Loss after 1 iteration(s) : 1.35e-01
= 9.99e-03 + 0.001 * 1.25e+02 (fidelity + regularization_weight * regularization)
Elapsed time: 14.677480459213257
Extrapolation¶
back = model.morph(
shape=source,
parameter=task.parameter_,
return_path=True,
return_regularization=True,
final_time=-1.0
).path
model.n_steps = 2 * n_steps
forward = model.morph(
shape=source,
parameter=task.parameter_,
return_path=True,
return_regularization=True,
final_time=2.0
).path
path = back[::-1] + forward[1:]
plotter = pv.Plotter()
for frame in path:
plotter.add_mesh(frame.to_pyvista(), color="tan", opacity=0.3, **plot_kwargs)
plotter.add_mesh(source.to_pyvista(), color="teal", opacity=0.5, **plot_kwargs)
plotter.add_mesh(target.to_pyvista(), color="red", opacity=0.5, **plot_kwargs)
plotter.camera_position = cpos
plotter.show()
print(plotter.camera_position)
[(3.6401575998373183, -1.183408993703478, 1.0915912440258628),
(0.7463583722710609, 0.762569822371006, 0.48035204596817493),
(-0.17454151663474313, 0.049338875787770284, 0.9834129012306289)]
Total running time of the script: (3 minutes 18.875 seconds)