Source code for foscat.BkBase

import numpy as np


[docs] class BackendBase: def __init__(self, name, mpi_rank=0, all_type="float64", gpupos=0, silent=False): self.BACKEND = name self.mpi_rank = mpi_rank self.all_type = all_type self.gpupos = gpupos self.silent = silent # ---------------------------------------------−--------- # table use to compute the iso orientation rotation self._iso_orient = {} self._iso_orient_T = {} self._iso_orient_C = {} self._iso_orient_C_T = {} # 3-orientation averaging matrix for S4 self._iso_orient3 = {} self._iso_orient3_T = {} self._iso_orient3_C = {} self._iso_orient3_C_T = {} self._fft_1_orient = {} self._fft_1_orient_C = {} self._fft_2_orient = {} self._fft_2_orient_C = {} self._fft_3_orient = {} self._fft_3_orient_C = {} # "angular-FFT" matrices: reorganise by (Δl, l1) then project l1 onto Fourier basis # S3/S3P: [L*L] → [L*nout] (Δl axis kept, l1 axis compressed) # S4: [L*L*L] → [L*L*nout] (Δl12, Δl13 kept, l1 compressed) self._fft_ang2_orient = {} self._fft_ang2_orient_C = {} self._fft_ang3_orient = {} self._fft_ang3_orient_C = {}
[docs] def to_dict(self): return { "name": self.BACKEND, "mpi_rank": self.mpi_rank, "all_type": self.all_type, "gpupos": self.gpupos, "silent": self.silent, }
[docs] def iso_mean(self, x, use_2D=False): shape = list(x.shape) i_orient = 2 if use_2D: i_orient = 3 norient = shape[i_orient] if len(shape) == i_orient + 1: return self.bk_reduce_mean(x, -1) if norient not in self._iso_orient: self.calc_iso_orient(norient) if self.bk_is_complex(x): lmat = self._iso_orient_C[norient] else: lmat = self._iso_orient[norient] oshape = shape[0] for k in range(1, len(shape) - 2): oshape *= shape[k] oshape2 = [shape[k] for k in range(0, len(shape) - 1)] return self.bk_reshape( self.backend.matmul(self.bk_reshape(x, [oshape, norient * norient]), lmat), oshape2, )
[docs] def fft_ang(self, x, nharm=1, imaginary=False, use_2D=False): shape = list(x.shape) i_orient = 2 if use_2D: i_orient = 3 norient = shape[i_orient] nout = 1 + nharm oshape_1 = shape[0] for k in range(1, i_orient): oshape_1 *= shape[k] oshape_2 = norient for k in range(i_orient, len(shape) - 1): oshape_2 *= shape[k] oshape = [oshape_1, oshape_2] if imaginary: nout = 1 + nharm * 2 oshape2 = [shape[k] for k in range(0, i_orient)] + [ nout for k in range(i_orient, len(shape)) ] if (norient, nharm) not in self._fft_1_orient: self.calc_fft_orient(norient, nharm, imaginary) if len(shape) == i_orient + 1: if self.bk_is_complex(x): lmat = self._fft_1_orient_C[(norient, nharm, imaginary)] else: lmat = self._fft_1_orient[(norient, nharm, imaginary)] if len(shape) == i_orient + 2: if self.bk_is_complex(x): lmat = self._fft_2_orient_C[(norient, nharm, imaginary)] else: lmat = self._fft_2_orient[(norient, nharm, imaginary)] if len(shape) == i_orient + 3: if self.bk_is_complex(x): lmat = self._fft_3_orient_C[(norient, nharm, imaginary)] else: lmat = self._fft_3_orient[(norient, nharm, imaginary)] return self.bk_reshape( self.backend.matmul(self.bk_reshape(x, oshape), lmat), oshape2 )
[docs] def calc_iso_orient(self, norient): tmp = np.zeros([norient * norient, norient]) for i in range(norient): for j in range(norient): tmp[j * norient + (j + i) % norient, i] = 0.25 self._iso_orient[norient] = self.bk_constant(self.bk_cast(tmp)) self._iso_orient_T[norient] = self.bk_constant(self.bk_cast(4 * tmp.T)) self._iso_orient_C[norient] = self.bk_complex( self._iso_orient[norient], 0 * self._iso_orient[norient] ) self._iso_orient_C_T[norient] = self.bk_complex( self._iso_orient_T[norient], 0 * self._iso_orient_T[norient] )
[docs] def calc_iso_orient3(self, norient): """Build the averaging matrix for 3-orientation isotropic reduction (S4). S4 has shape [..., L1, L2, L3]. Under a global rotation by δ the three orientation indices shift together: l_k → (l_k + δ) mod L. The only rotationally-invariant quantities are the two *relative* angles Δl12 = (l2 - l1) mod L Δl13 = (l3 - l1) mod L The forward matrix (shape [L^3, L^2]) maps the flat (l1, l2, l3) index to the flat (Δl12, Δl13) index with weight 1/L: output[Δl12, Δl13] = (1/L) Σ_{l1} input[l1, (l1+Δl12)%L, (l1+Δl13)%L] The transpose matrix (shape [L^2, L^3], weight L·tmpᵀ) is the pseudo- inverse used by the ``repeat=True`` path to reconstruct a full [..., L, L, L] tensor from the [..., L, L] isotropic representation. """ L = norient tmp = np.zeros([L * L * L, L * L]) for l1 in range(L): for dl12 in range(L): for dl13 in range(L): l2 = (l1 + dl12) % L l3 = (l1 + dl13) % L tmp[l1 * L * L + l2 * L + l3, dl12 * L + dl13] = 1.0 / L self._iso_orient3[norient] = self.bk_constant(self.bk_cast(tmp)) self._iso_orient3_T[norient] = self.bk_constant(self.bk_cast(L * tmp.T)) self._iso_orient3_C[norient] = self.bk_complex( self._iso_orient3[norient], 0 * self._iso_orient3[norient] ) self._iso_orient3_C_T[norient] = self.bk_complex( self._iso_orient3_T[norient], 0 * self._iso_orient3_T[norient] )
[docs] def calc_fft_orient(self, norient, nharm, imaginary): x = np.arange(norient) / norient * 2 * np.pi if imaginary: tmp = np.zeros([norient, 1 + nharm * 2]) tmp[:, 0] = 1.0 / norient # DC = mean (not sum), consistent with iso_mean for k in range(nharm): tmp[:, k * 2 + 1] = np.cos(x * (k + 1)) tmp[:, k * 2 + 2] = np.sin(x * (k + 1)) self._fft_1_orient[(norient, nharm, imaginary)] = self.bk_cast( self.bk_constant(tmp) ) self._fft_1_orient_C[(norient, nharm, imaginary)] = self.bk_complex( self._fft_1_orient[(norient, nharm, imaginary)], 0 * self._fft_1_orient[(norient, nharm, imaginary)], ) else: tmp = np.zeros([norient, 1 + nharm]) tmp[:, 0] = 1.0 / norient # DC = mean (not sum) for k in range(1, nharm + 1): tmp[:, k] = np.cos(x * k) self._fft_1_orient[(norient, nharm, imaginary)] = self.bk_cast( self.bk_constant(tmp) ) self._fft_1_orient_C[(norient, nharm, imaginary)] = self.bk_complex( self._fft_1_orient[(norient, nharm, imaginary)], 0 * self._fft_1_orient[(norient, nharm, imaginary)], ) x = np.repeat(x, norient).reshape(norient, norient) if imaginary: tmp = np.zeros([norient, norient, (1 + nharm * 2), (1 + nharm * 2)]) tmp[:, :, 0, 0] = 1.0 for k in range(nharm): tmp[:, :, k * 2 + 1, 0] = np.cos(x * (k + 1)) tmp[:, :, k * 2 + 2, 0] = np.sin(x * (k + 1)) tmp[:, :, 0, k * 2 + 1] = np.cos((x.T) * (k + 1)) tmp[:, :, 0, k * 2 + 2] = np.sin((x.T) * (k + 1)) for l_orient in range(nharm): tmp[:, :, k * 2 + 1, l_orient * 2 + 1] = np.cos( x * (k + 1) ) * np.cos((x.T) * (l_orient + 1)) tmp[:, :, k * 2 + 2, l_orient * 2 + 1] = np.sin( x * (k + 1) ) * np.cos((x.T) * (l_orient + 1)) tmp[:, :, k * 2 + 1, l_orient * 2 + 2] = np.cos( x * (k + 1) ) * np.sin((x.T) * (l_orient + 1)) tmp[:, :, k * 2 + 2, l_orient * 2 + 2] = np.sin( x * (k + 1) ) * np.sin((x.T) * (l_orient + 1)) self._fft_2_orient[(norient, nharm, imaginary)] = self.bk_cast( self.bk_constant( tmp.reshape(norient * norient, (1 + 2 * nharm) * (1 + 2 * nharm)) ) ) self._fft_2_orient_C[(norient, nharm, imaginary)] = self.bk_complex( self._fft_2_orient[(norient, nharm, imaginary)], 0 * self._fft_2_orient[(norient, nharm, imaginary)], ) else: tmp = np.zeros([norient, norient, (1 + nharm), (1 + nharm)]) for k in range(nharm + 1): for l_orient in range(nharm + 1): tmp[:, :, k, l_orient] = np.cos(x * k) * np.cos((x.T) * l_orient) self._fft_2_orient[(norient, nharm, imaginary)] = self.bk_cast( self.bk_constant( tmp.reshape(norient * norient, (1 + nharm) * (1 + nharm)) ) ) self._fft_2_orient_C[(norient, nharm, imaginary)] = self.bk_complex( self._fft_2_orient[(norient, nharm, imaginary)], 0 * self._fft_2_orient[(norient, nharm, imaginary)], ) x = np.arange(norient) / norient * 2 * np.pi xx = np.zeros([norient, norient, norient]) yy = np.zeros([norient, norient, norient]) zz = np.zeros([norient, norient, norient]) for i in range(norient): for j in range(norient): xx[:, i, j] = x yy[i, :, j] = x zz[i, j, :] = x if imaginary: tmp = np.ones( [ norient, norient, norient, (1 + nharm * 2), (1 + nharm * 2), (1 + nharm * 2), ] ) for k in range(nharm): tmp[:, :, :, k * 2 + 1, 0, 0] = np.cos(xx * (k + 1)) tmp[:, :, :, 0, k * 2 + 1, 0] = np.cos(yy * (k + 1)) tmp[:, :, :, 0, 0, k * 2 + 1] = np.cos(zz * (k + 1)) tmp[:, :, :, k * 2 + 2, 0, 0] = np.sin(xx * (k + 1)) tmp[:, :, :, 0, k * 2 + 2, 0] = np.sin(yy * (k + 1)) tmp[:, :, :, 0, 0, k * 2 + 2] = np.sin(zz * (k + 1)) for l_orient in range(nharm): tmp[:, :, :, k * 2 + 1, l_orient * 2 + 1, 0] = np.cos( xx * (k + 1) ) * np.cos(yy * (l_orient + 1)) tmp[:, :, :, k * 2 + 1, l_orient * 2 + 2, 0] = np.cos( xx * (k + 1) ) * np.sin(yy * (l_orient + 1)) tmp[:, :, :, k * 2 + 2, l_orient * 2 + 1, 0] = np.sin( xx * (k + 1) ) * np.cos(yy * (l_orient + 1)) tmp[:, :, :, k * 2 + 2, l_orient * 2 + 2, 0] = np.sin( xx * (k + 1) ) * np.sin(yy * (l_orient + 1)) tmp[:, :, :, k * 2 + 1, 0, l_orient * 2 + 1] = np.cos( xx * (k + 1) ) * np.cos(zz * (l_orient + 1)) tmp[:, :, :, k * 2 + 1, 0, l_orient * 2 + 2] = np.cos( xx * (k + 1) ) * np.sin(zz * (l_orient + 1)) tmp[:, :, :, k * 2 + 2, 0, l_orient * 2 + 1] = np.sin( xx * (k + 1) ) * np.cos(zz * (l_orient + 1)) tmp[:, :, :, k * 2 + 2, 0, l_orient * 2 + 2] = np.sin( xx * (k + 1) ) * np.sin(zz * (l_orient + 1)) tmp[:, :, :, 0, k * 2 + 1, l_orient * 2 + 1] = np.cos( yy * (k + 1) ) * np.cos(zz * (l_orient + 1)) tmp[:, :, :, 0, k * 2 + 1, l_orient * 2 + 2] = np.cos( yy * (k + 1) ) * np.sin(zz * (l_orient + 1)) tmp[:, :, :, 0, k * 2 + 2, l_orient * 2 + 1] = np.sin( yy * (k + 1) ) * np.cos(zz * (l_orient + 1)) tmp[:, :, :, 0, k * 2 + 2, l_orient * 2 + 2] = np.sin( yy * (k + 1) ) * np.sin(zz * (l_orient + 1)) for m in range(nharm): tmp[:, :, :, k * 2 + 1, l_orient * 2 + 1, m * 2 + 1] = ( np.cos(xx * (k + 1)) * np.cos(yy * (l_orient + 1)) * np.cos(zz * (m + 1)) ) tmp[:, :, :, k * 2 + 1, l_orient * 2 + 1, m * 2 + 2] = ( np.cos(xx * (k + 1)) * np.cos(yy * (l_orient + 1)) * np.sin(zz * (m + 1)) ) tmp[:, :, :, k * 2 + 1, l_orient * 2 + 2, m * 2 + 1] = ( np.cos(xx * (k + 1)) * np.sin(yy * (l_orient + 1)) * np.cos(zz * (m + 1)) ) tmp[:, :, :, k * 2 + 1, l_orient * 2 + 2, m * 2 + 2] = ( np.cos(xx * (k + 1)) * np.sin(yy * (l_orient + 1)) * np.sin(zz * (m + 1)) ) tmp[:, :, :, k * 2 + 2, l_orient * 2 + 1, m * 2 + 1] = ( np.sin(xx * (k + 1)) * np.cos(yy * (l_orient + 1)) * np.cos(zz * (m + 1)) ) tmp[:, :, :, k * 2 + 2, l_orient * 2 + 1, m * 2 + 2] = ( np.sin(xx * (k + 1)) * np.cos(yy * (l_orient + 1)) * np.sin(zz * (m + 1)) ) tmp[:, :, :, k * 2 + 2, l_orient * 2 + 2, m * 2 + 1] = ( np.sin(xx * (k + 1)) * np.sin(yy * (l_orient + 1)) * np.cos(zz * (m + 1)) ) tmp[:, :, :, k * 2 + 2, l_orient * 2 + 2, m * 2 + 2] = ( np.sin(xx * (k + 1)) * np.sin(yy * (l_orient + 1)) * np.sin(zz * (m + 1)) ) self._fft_3_orient[(norient, nharm, imaginary)] = self.bk_cast( self.bk_constant( tmp.reshape( norient * norient * norient, (1 + nharm * 2) * (1 + nharm * 2) * (1 + nharm * 2), ) ) ) self._fft_3_orient_C[(norient, nharm, imaginary)] = self.bk_complex( self._fft_3_orient[(norient, nharm, imaginary)], 0 * self._fft_3_orient[(norient, nharm, imaginary)], ) else: tmp = np.zeros( [norient, norient, norient, (1 + nharm), (1 + nharm), (1 + nharm)] ) for k in range(nharm + 1): for l_orient in range(nharm + 1): for m in range(nharm + 1): tmp[:, :, :, k, l_orient, m] = ( np.cos(xx * k) * np.cos(yy * l_orient) * np.cos(zz * m) ) self._fft_3_orient[(norient, nharm, imaginary)] = self.bk_cast( self.bk_constant( tmp.reshape( norient * norient * norient, (1 + nharm) * (1 + nharm) * (1 + nharm), ) ) ) self._fft_3_orient_C[(norient, nharm, imaginary)] = self.bk_complex( self._fft_3_orient[(norient, nharm, imaginary)], 0 * self._fft_3_orient[(norient, nharm, imaginary)], )
[docs] def calc_fft_ang_orient(self, norient, nharm, imaginary): """Build projection matrices for the angular-FFT reduction of S3/S4. Unlike the tensor-product ``_fft_2_orient`` / ``_fft_3_orient`` matrices (which apply independent 1-D FFTs on each orientation axis), these matrices first reindex (l1, l2) → (Δl, l1) and then project the l1 axis onto the Fourier basis, keeping the Δl (relative-orientation) axis intact. Results ------- _fft_ang2_orient[(norient, nharm, imaginary)] : shape [L*L, L*nout] Maps S3[l1, l2] (flat [L²]) → out[Δl, k] (flat [L*nout]) where Δl = (l2-l1) % L and k indexes the Fourier basis on l1. _fft_ang3_orient[(norient, nharm, imaginary)] : shape [L*L*L, L*L*nout] Maps S4[l1, l2, l3] (flat [L³]) → out[Δl12, Δl13, k] (flat [L²*nout]) where Δl12 = (l2-l1)%L, Δl13 = (l3-l1)%L. """ L = norient x = np.arange(L) / L * 2 * np.pi # [L] if imaginary: nout = 1 + 2 * nharm basis = np.zeros([L, nout]) basis[:, 0] = 1.0 / L # DC = mean over l1, consistent with iso_mean for k in range(nharm): basis[:, k * 2 + 1] = np.cos(x * (k + 1)) basis[:, k * 2 + 2] = np.sin(x * (k + 1)) else: nout = 1 + nharm basis = np.zeros([L, nout]) basis[:, 0] = 1.0 / L # DC = mean over l1 for k in range(1, nharm + 1): basis[:, k] = np.cos(x * k) # ---- S3/S3P: [L*L] → [L*nout] ---- # out[Δl, k] = Σ_{l1} basis[l1, k] · S3[l1, (l1+Δl)%L] mat2 = np.zeros([L * L, L * nout]) for l1 in range(L): for dl in range(L): l2 = (l1 + dl) % L in_idx = l1 * L + l2 for k in range(nout): out_idx = dl * nout + k mat2[in_idx, out_idx] = basis[l1, k] self._fft_ang2_orient[(norient, nharm, imaginary)] = self.bk_cast( self.bk_constant(mat2) ) self._fft_ang2_orient_C[(norient, nharm, imaginary)] = self.bk_complex( self._fft_ang2_orient[(norient, nharm, imaginary)], 0 * self._fft_ang2_orient[(norient, nharm, imaginary)], ) # ---- S4: [L*L*L] → [L*L*nout] ---- # out[Δl12, Δl13, k] = Σ_{l1} basis[l1, k] · S4[l1, (l1+Δl12)%L, (l1+Δl13)%L] mat3 = np.zeros([L * L * L, L * L * nout]) for l1 in range(L): for dl12 in range(L): for dl13 in range(L): l2 = (l1 + dl12) % L l3 = (l1 + dl13) % L in_idx = l1 * L * L + l2 * L + l3 for k in range(nout): out_idx = dl12 * L * nout + dl13 * nout + k mat3[in_idx, out_idx] = basis[l1, k] self._fft_ang3_orient[(norient, nharm, imaginary)] = self.bk_cast( self.bk_constant(mat3) ) self._fft_ang3_orient_C[(norient, nharm, imaginary)] = self.bk_complex( self._fft_ang3_orient[(norient, nharm, imaginary)], 0 * self._fft_ang3_orient[(norient, nharm, imaginary)], )
# ---------------------------------------------−--------- # -- BACKEND DEFINITION -- # ---------------------------------------------−---------
[docs] def bk_len(self,S): raise NotImplementedError("This is an abstract class.")
[docs] def bk_SparseTensor(self, indice, w, dense_shape=[]): raise NotImplementedError("This is an abstract class.")
[docs] def bk_stack(self, list, axis=0): raise NotImplementedError("This is an abstract class.")
[docs] def bk_sparse_dense_matmul(self, smat, mat): raise NotImplementedError("This is an abstract class.")
[docs] def conv2d(self, x, w, strides=[1, 1, 1, 1], padding="SAME"): raise NotImplementedError("This is an abstract class.")
[docs] def conv1d(self, x, w, strides=[1, 1, 1], padding="SAME"): raise NotImplementedError("This is an abstract class.")
[docs] def bk_threshold(self, x, threshold, greater=True): raise NotImplementedError("This is an abstract class.")
[docs] def bk_maximum(self, x1, x2): raise NotImplementedError("This is an abstract class.")
[docs] def bk_device(self, device_name): raise NotImplementedError("This is an abstract class.")
[docs] def bk_ones(self, shape, dtype=None): raise NotImplementedError("This is an abstract class.")
[docs] def bk_conv1d(self, x, w): raise NotImplementedError("This is an abstract class.")
[docs] def bk_flattenR(self, x): raise NotImplementedError("This is an abstract class.")
[docs] def bk_flatten(self, x): raise NotImplementedError("This is an abstract class.")
[docs] def bk_size(self, x): raise NotImplementedError("This is an abstract class.")
[docs] def bk_resize_image(self, x, shape): raise NotImplementedError("This is an abstract class.")
[docs] def bk_L1(self, x): raise NotImplementedError("This is an abstract class.")
[docs] def bk_square_comp(self, x): raise NotImplementedError("This is an abstract class.")
[docs] def bk_reduce_sum(self, data, axis=None): raise NotImplementedError("This is an abstract class.")
[docs] def bk_reduce_mean(self, data, axis=None): raise NotImplementedError("This is an abstract class.")
[docs] def bk_reduce_min(self, data, axis=None): raise NotImplementedError("This is an abstract class.")
[docs] def bk_random_seed(self, value): raise NotImplementedError("This is an abstract class.")
[docs] def bk_random_uniform(self, shape): raise NotImplementedError("This is an abstract class.")
[docs] def bk_reduce_std(self, data, axis=None): raise NotImplementedError("This is an abstract class.")
[docs] def bk_sqrt(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_abs(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_is_complex(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_distcomp(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_norm(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_square(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_log(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_matmul(self, a, b): raise NotImplementedError("This is an abstract class.")
[docs] def bk_tensor(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_shape_tensor(self, shape): raise NotImplementedError("This is an abstract class.")
[docs] def bk_complex(self, real, imag): raise NotImplementedError("This is an abstract class.")
[docs] def bk_exp(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_min(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_argmin(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_tanh(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_max(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_argmax(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_reshape(self, data, shape): raise NotImplementedError("This is an abstract class.")
[docs] def bk_repeat(self, data, nn, axis=0): raise NotImplementedError("This is an abstract class.")
[docs] def bk_tile(self, data, nn, axis=0): raise NotImplementedError("This is an abstract class.")
[docs] def bk_roll(self, data, nn, axis=0): raise NotImplementedError("This is an abstract class.")
[docs] def bk_expand_dims(self, data, axis=0): raise NotImplementedError("This is an abstract class.")
[docs] def bk_transpose(self, data, thelist): raise NotImplementedError("This is an abstract class.")
[docs] def bk_concat(self, data, axis=None): raise NotImplementedError("This is an abstract class.")
[docs] def bk_zeros(self, shape, dtype=None): raise NotImplementedError("This is an abstract class.")
[docs] def bk_gather(self, data, idx): raise NotImplementedError("This is an abstract class.")
[docs] def bk_reverse(self, data, axis=0): raise NotImplementedError("This is an abstract class.")
[docs] def bk_fft(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_fftn(self, data, dim=None): raise NotImplementedError("This is an abstract class.")
[docs] def bk_ifftn(self, data, dim=None, norm=None): raise NotImplementedError("This is an abstract class.")
[docs] def bk_rfft(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_irfft(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_conjugate(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_real(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_imag(self, data): raise NotImplementedError("This is an abstract class.")
[docs] def bk_relu(self, x): raise NotImplementedError("This is an abstract class.")
[docs] def bk_clip_by_value(self, x, xmin, xmax): raise NotImplementedError("This is an abstract class.")
[docs] def bk_cast(self, x): raise NotImplementedError("This is an abstract class.")
[docs] def bk_variable(self, x): raise NotImplementedError("This is an abstract class.")
[docs] def bk_assign(self, x, y): raise NotImplementedError("This is an abstract class.")
[docs] def bk_constant(self, x): raise NotImplementedError("This is an abstract class.")
[docs] def bk_cos(self, x): raise NotImplementedError("This is an abstract class.")
[docs] def bk_sin(self, x): raise NotImplementedError("This is an abstract class.")
[docs] def bk_arctan2(self, c, s): raise NotImplementedError("This is an abstract class.")
[docs] def bk_empty(self, list): raise NotImplementedError("This is an abstract class.")
[docs] def to_numpy(self, x): raise NotImplementedError("This is an abstract class.")