@@ -183,7 +183,7 @@ def __init__(
183183 system ,
184184 X ,
185185 settings = [],
186- fastmult = True ,
186+ algorithm = "nfft" ,
187187 parallel = True ,
188188 basis_vect = [],
189189 N = [],
@@ -227,9 +227,9 @@ def __init__(
227227 )
228228
229229 if system in {"chui1" , "chui2" , "chui3" , "chui4" }:
230- fastmult = True
230+ algorithm = "nfft"
231231
232- self .fastmult = fastmult
232+ self .algorithm = algorithm
233233 self .basis_vect = basis_vect
234234 self .system = system
235235 self .X = X
@@ -240,7 +240,7 @@ def __init__(
240240 else :
241241 self .settings = settings
242242
243- if fastmult :
243+ if algorithm == "nfft" :
244244 self .matrix = np .empty ((0 , 0 ), dtype = object )
245245 self .transforms = [
246246 DeferredLinearOperator () for i in range (len (self .settings ))
@@ -265,6 +265,25 @@ def __init__(
265265 self .transforms [idx ] = s .mode .get_transform (
266266 bandwidths = s .bandwidths , X = np .copy (X [:, u ], order = "C" )
267267 )
268+ elif algorithm == "keops" :
269+ self .matrix = np .empty ((0 ,0 ), dtype = object )
270+
271+ self .transforms = [
272+ DeferredLinearOperator ()
273+ for _ in range (len (self .settings ))
274+ ]
275+
276+ for idx , s in enumerate (self .settings ):
277+
278+ if len (s .bandwidths ) == 0 :
279+ u = (0 ,)
280+ else :
281+ u = s .u
282+
283+ self .transforms [idx ] = s .mode .get_transform_keops (
284+ bandwidths = s .bandwidths ,
285+ X = np .copy (X [:,u ], order = "C" )
286+ )
268287 else :
269288 self .transforms = []
270289 s1 = self .settings [0 ]
@@ -321,9 +340,8 @@ def __mul__(self, other):
321340 If other (= f) is an numpy.ndarray, this function
322341 overloads the * notation in order to achieve the adjoint transform `f = F*f`.
323342 """
324-
325343 if isinstance (other , np .ndarray ): # `f = F*f` (f = other)
326- if self .fastmult :
344+ if self .algorithm == "nfft" :
327345 fhat = GroupedCoefficients (self .settings )
328346
329347 def adjoint_worker (i ):
@@ -345,17 +363,26 @@ def adjoint_worker(i):
345363 adjoint_worker (i )
346364
347365 return fhat
348- else :
366+ elif self .algorithm == "keops" :
367+ fhat = GroupedCoefficients (self .settings )
368+
369+ for i in range (len (self .transforms )):
370+ adjoint_result = self .transforms [i ].H @ other
371+ fhat [self .settings [i ].u ] = adjoint_result
372+
373+ return fhat
374+ elif self .algorithm == "direct" :
349375 return GroupedCoefficients (
350376 self .settings , (self .matrix .conj ()).T @ other
351377 )
378+
352379 elif isinstance (other , GC ): # `f = F*fhat` (fhat = other)
353380 if self .settings != other .settings :
354381 raise ValueError (
355382 "The GroupedTransform and the GroupedCoefficients have different settings"
356383 )
357384
358- if self .fastmult :
385+ if self .algorithm == "nfft" :
359386 results = []
360387
361388 def worker (i ):
@@ -376,7 +403,16 @@ def worker(i):
376403 worker (i )
377404
378405 return sum (results )
379- else :
406+ elif self .algorithm == "keops" :
407+ results = []
408+
409+ for i in range (len (self .transforms )):
410+ u = self .settings [i ].u
411+ result = self .transforms [i ] @ other [u ]
412+ results .append (result )
413+
414+ return sum (results )
415+ elif self .algorithm == "direct" :
380416 return self .matrix @ other .data
381417 else :
382418 raise ValueError ("Wrong input data type" )
@@ -412,7 +448,7 @@ def __getitem__(self, u):
412448
413449 if idx is None :
414450 raise ValueError ("This term is not contained" )
415- elif self .fastmult :
451+ elif self .algorithm == "nfft" :
416452 return self .transforms [idx ]
417453 else :
418454 return self .get_matrix ()
0 commit comments