@@ -288,8 +288,20 @@ def __init__(
288288 if len (s .bandwidths ) == 0 :
289289 full = np .zeros ((1 , D ), dtype = np .int32 )
290290
291+ elif self .system == "cos" :
291292
292- else :
293+ local = np .atleast_2d (
294+ s .mode .index_set_without_zeros (
295+ np .array (s .bandwidths , dtype = np .int32 )
296+ )
297+ ).T
298+
299+ full = np .zeros ((local .shape [0 ], D ), dtype = np .int32 )
300+
301+ for i , dim in enumerate (s .u ):
302+ full [:, dim ] = local [:, i ]
303+
304+ else :
293305 local = index_set_without_zeros (
294306 np .array (s .bandwidths , dtype = np .int32 )
295307 ).T
@@ -309,48 +321,102 @@ def __init__(
309321 dtype = torch .float64 ,
310322 device = "cuda"
311323 )
312-
313- def trafo (fhat ):
314- X_i = LazyTensor (X_torch [:, None , :].contiguous ())
315- K_j = LazyTensor (I_torch [None , :, :].contiguous ())
316- phase_fwd = (X_i * K_j ).sum (- 1 )
317- two_pi_phase = - 2 * torch .pi * phase_fwd
318- kernel_fwd = two_pi_phase .cos () + 1j * two_pi_phase .sin ()
319- fhat_torch = torch .tensor (fhat , dtype = torch .complex128 , device = "cuda" )
320- fhat_j = LazyTensor (fhat_torch [None , :, None ].contiguous ())
321-
322- try :
323- result = (kernel_fwd * fhat_j ).sum (dim = 1 )
324- torch .cuda .synchronize ()
325- result = result .squeeze ().cpu ().numpy ()
326- return result
327- except Exception as e :
328- print ("Error in KeOps trafo:" , e )
329- return None
330-
324+
325+ def trafo (fhat ):
326+ if self .system == "cos" or self .system == "cheb" :
327+ mult = np .sqrt (2.0 ) ** np .count_nonzero (freq , axis = 1 )
328+ mult_torch = torch .tensor (mult , dtype = torch .float64 , device = "cuda" )
329+
330+ kernel = 1.0
331+ for i in range (D ):
332+ Xi = LazyTensor (X_torch [:, None , i :i + 1 ].contiguous ())
333+ Ki = LazyTensor (I_torch [None , :, i :i + 1 ].contiguous ())
334+ kernel = kernel * (2 * torch .pi * Xi * Ki ).cos ()
335+
336+ fhat_torch = (
337+ torch .as_tensor (fhat , dtype = torch .float64 , device = "cuda" )
338+ * mult_torch
339+ )
340+ fhat_j = LazyTensor (fhat_torch [None , :, None ].contiguous ())
341+
342+ try :
343+ result = (kernel * fhat_j ).sum (dim = 1 )
344+ torch .cuda .synchronize ()
345+ return result .squeeze ().cpu ().numpy ()
346+ except Exception as e :
347+ print ("Error in KeOps trafo:" , e )
348+ return None
349+ else :
350+ X_i = LazyTensor (X_torch [:, None , :].contiguous ())
351+ K_j = LazyTensor (I_torch [None , :, :].contiguous ())
352+
353+ phase_fwd = (X_i * K_j ).sum (- 1 )
354+ two_pi_phase = - 2 * torch .pi * phase_fwd
355+ kernel = two_pi_phase .cos () + 1j * two_pi_phase .sin ()
356+
357+ fhat_torch = torch .tensor (fhat , dtype = torch .complex128 , device = "cuda" )
358+ fhat_j = LazyTensor (fhat_torch [None , :, None ].contiguous ())
359+
360+ try :
361+ result = (kernel * fhat_j ).sum (dim = 1 )
362+ torch .cuda .synchronize ()
363+ result = result .squeeze ().cpu ().numpy ()
364+ return result
365+ except Exception as e :
366+ print ("Error in KeOps trafo:" , e )
367+ return None
368+
331369 def adjoint (f ):
332- f_torch = torch .tensor (f , dtype = torch .complex128 , device = "cuda" ).contiguous ()
333-
334- X_i = LazyTensor (X_torch [None , :, :].contiguous ())
335- K_j = LazyTensor (I_torch [:, None , :].contiguous ())
370+ if self .system == "cos" or self .system == "cheb" :
371+ mult = np .sqrt (2.0 ) ** np .count_nonzero (freq , axis = 1 )
372+ mult_torch = torch .tensor (mult , dtype = torch .float64 , device = "cuda" )
373+
374+ f_torch = (
375+ torch .as_tensor (f , dtype = torch .float64 , device = "cuda" )
376+ * mult_torch
377+ ).contiguous ()
378+
379+ kernel = 1.0
380+ for i in range (D ):
381+ Ki = LazyTensor (I_torch [:, None , i :i + 1 ].contiguous ())
382+ Xi = LazyTensor (X_torch [None , :, i :i + 1 ].contiguous ())
383+ kernel = kernel * (2 * torch .pi * Xi * Ki ).cos ()
384+
385+ f_i = LazyTensor (f_torch [None , :, None ].contiguous ())
386+
387+ try :
388+ result = (kernel * f_i ).sum (dim = 1 )
389+ torch .cuda .synchronize ()
390+ result = result .squeeze ().cpu ().numpy ()
391+ return result
392+ except Exception as e :
393+ print ("Error in KeOps adjoint:" , e )
394+ return None
395+ else :
396+ f_torch = torch .tensor (f , dtype = torch .complex128 , device = "cuda" ).contiguous ()
336397
337- phase = ( K_j * X_i ). sum ( - 1 )
338- kernel = ( - 2 * torch . pi * phase ). cos () - 1j * ( - 2 * torch . pi * phase ). sin ( )
398+ X_i = LazyTensor ( X_torch [ None , :, :]. contiguous () )
399+ K_j = LazyTensor ( I_torch [:, None , :]. contiguous () )
339400
340- f_i = LazyTensor (f_torch [None , :, None ].contiguous ())
401+ phase = (K_j * X_i ).sum (- 1 )
402+ two_pi_phase = 2 * torch .pi * phase
403+ kernel = two_pi_phase .cos () + 1j * two_pi_phase .sin ()
341404
342- try :
343- result = (kernel * f_i ).sum (dim = 1 )
344- torch .cuda .synchronize ()
345- result = result .squeeze ().cpu ().numpy ()
346-
347- return result
348- except Exception as e :
349- print ("Error in KeOps adjoint:" , e )
350- return None
405+ f_i = LazyTensor (f_torch [None , :, None ].contiguous ())
406+
407+ try :
408+ result = (kernel * f_i ).sum (dim = 1 )
409+ torch .cuda .synchronize ()
410+ result = result .squeeze ().cpu ().numpy ()
411+
412+ return result
413+ except Exception as e :
414+ print ("Error in KeOps adjoint:" , e )
415+ return None
351416
417+ keops_dtype = np .float64 if self .system == "cos" else np .complex128
352418 self .transforms = [DeferredLinearOperator (
353- dtype = np . complex128 , shape = (X .shape [0 ], len (freq )), mfunc = trafo , rmfunc = adjoint
419+ dtype = keops_dtype , shape = (X .shape [0 ], len (freq )), mfunc = trafo , rmfunc = adjoint
354420 )]
355421
356422 else :
0 commit comments