agd.Eikonal
The Eikonal package embeds CPU and GPU numerical solvers of (generalized) eikonal equations. These are variants of the fast marching and fast sweeping method, based on suitable discretizations of the PDE, and written and C++.
Please see the illustrative notebooks for detailed usage instructions and examples: https://github.com/Mirebeau/AdaptiveGridDiscretizations
Main object :
- dictIn : a dictionary-like structure, used to gathers the arguments of the eikonal solver, and eventually call it.
1# Copyright 2020 Jean-Marie Mirebeau, University Paris-Sud, CNRS, University Paris-Saclay 2# Distributed WITHOUT ANY WARRANTY. Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 3 4""" 5The Eikonal package embeds CPU and GPU numerical solvers of (generalized) eikonal 6equations. These are variants of the fast marching and fast sweeping method, based on 7suitable discretizations of the PDE, and written and C++. 8 9Please see the illustrative notebooks for detailed usage instructions and examples: 10https://github.com/Mirebeau/AdaptiveGridDiscretizations 11 12Main object : 13- dictIn : a dictionary-like structure, used to gathers the arguments of the 14eikonal solver, and eventually call it. 15""" 16 17import numpy as np 18import importlib 19import functools 20 21from .LibraryCall import GetBinaryDir 22from .run_detail import Cache 23from .DictIn import dictIn,dictOut,CenteredLinspace 24 25 26def _VoronoiDecomposition_noAD(arr,mode=None,steps='Both',*args,**kwargs): 27 """ 28 Calls the FileVDQ library to decompose the provided quadratic form(s), 29 as based on Voronoi's first reduction of quadratic forms. 30 - mode : 'cpu' or 'gpu' or 'gpu_transfer'. 31 Defaults to VoronoiDecomposition.default_mode if specified, or to gpu/cpu adequately. 32 - args,kwargs : passed to gpu decomposition method 33 """ 34 from ..AutomaticDifferentiation.cupy_generic import cupy_set,cupy_get,from_cupy 35 if mode is None: mode = VoronoiDecomposition.default_mode 36 if mode is None: mode = 'gpu' if from_cupy(arr) else 'cpu' 37 if mode in ('gpu','gpu_transfer'): 38 from .HFM_CUDA.VoronoiDecomposition import VoronoiDecomposition as VD 39 if mode=='gpu_transfer': arr = cupy_set(arr) 40 out = VD(arr,*args,steps=steps,**kwargs) 41 if mode=='gpu_transfer': out = cupy_get(out,iterables=(tuple,)) 42 return out 43 elif mode=='cpu': 44 from ..Metrics import misc 45 from . import FileIO 46 bin_dir = GetBinaryDir("FileVDQ",None) 47 dim = arr.shape[0]; shape = arr.shape[2:] 48 if dim==1: # Trivial case 49 from .. import Selling 50 return Selling.Decomposition(arr) 51 arr = arr.reshape( (dim,dim,np.prod(shape,dtype=int)) ) 52 arr = np.moveaxis(misc.flatten_symmetric_matrix(arr),0,-1) 53 vdqIn ={'tensors':arr,'steps':steps} 54 vdqOut = FileIO.WriteCallRead(vdqIn, "FileVDQ", bin_dir) 55 weights = np.moveaxis(vdqOut['weights'],-1,0) 56 offsets = np.moveaxis(vdqOut['offsets'],(-1,-2),(0,1)).astype(int) 57 weights,offsets = (e.reshape(e.shape[:depth]+shape) 58 for (e,depth) in zip((weights,offsets),(1,2))) 59 if steps=='Both': return weights,offsets 60 objective = vdqOut['objective'].reshape(shape) 61 vertex = vdqOut['vertex'].reshape(shape).astype(int) 62 chg = np.moveaxis(vdqOut['chg'],(-1,-2),(0,1)) 63 chg=chg.reshape((dim,dim)+shape) 64 return chg,vertex,objective,weights,offsets 65 else: raise ValueError(f"VoronoiDecomposition unsupported mode {mode}") 66 67def VoronoiDecomposition(arr,*args,**kwargs): 68 """ 69 Voronoi decomposition of arr, an array of dxd symmetric positive definite matrices, 70 with shape (d,d,n1,...nk), and possibly with AD. 71 args,kwargs : see _VoronoiDecomposition_noAD 72 """ 73 from .. import AutomaticDifferentiation as ad 74 from ..Metrics.misc import flatten_symmetric_matrix as fltsym 75 from .. import LinearParallel as lp 76 res = _VoronoiDecomposition_noAD(ad.remove_ad(arr),*args,**kwargs) 77 if not ad.is_ad(arr): return res 78 if len(arr)==4: raise ValueError("AD unsupported in dimension 4, sorry") 79 λ,e = res[-2],res[-1] 80 D_flat = arr if kwargs.get('flattened',False) else fltsym(arr) 81 eet_flat = fltsym(lp.outer_self(res[-1])) 82 λ_ad = lp.solve_AV(eet_flat.astype(D_flat.dtype),D_flat) # e is integer valued 83 return *res[:-2],λ_ad,e 84 85VoronoiDecomposition.default_mode = None
def
VoronoiDecomposition(arr, *args, **kwargs):
68def VoronoiDecomposition(arr,*args,**kwargs): 69 """ 70 Voronoi decomposition of arr, an array of dxd symmetric positive definite matrices, 71 with shape (d,d,n1,...nk), and possibly with AD. 72 args,kwargs : see _VoronoiDecomposition_noAD 73 """ 74 from .. import AutomaticDifferentiation as ad 75 from ..Metrics.misc import flatten_symmetric_matrix as fltsym 76 from .. import LinearParallel as lp 77 res = _VoronoiDecomposition_noAD(ad.remove_ad(arr),*args,**kwargs) 78 if not ad.is_ad(arr): return res 79 if len(arr)==4: raise ValueError("AD unsupported in dimension 4, sorry") 80 λ,e = res[-2],res[-1] 81 D_flat = arr if kwargs.get('flattened',False) else fltsym(arr) 82 eet_flat = fltsym(lp.outer_self(res[-1])) 83 λ_ad = lp.solve_AV(eet_flat.astype(D_flat.dtype),D_flat) # e is integer valued 84 return *res[:-2],λ_ad,e
Voronoi decomposition of arr, an array of dxd symmetric positive definite matrices, with shape (d,d,n1,...nk), and possibly with AD. args,kwargs : see _VoronoiDecomposition_noAD