MCPcopy Create free account
hub / github.com/PythonOT/POT / kernel_nystroem

Function kernel_nystroem

ot/lowrank.py:530–587  ·  view source on GitHub ↗

r""" Compute left and right factors corresponding to the Nystroem method on the Gaussian kernel :math:`K(x^s_i, x^t_j) = \exp(-\|x^s_i-x^t_j\|^2/2\sigma^2)`. The Nystroem approximation is computed by sampling :math:`\min(n, \lceil(c / 2))\rceil)` components in each distribution, where :m

(X_s, X_t, anchors=50, sigma=1.0, random_state=None)

Source from the content-addressed store, hash-verified

528
529
530def kernel_nystroem(X_s, X_t, anchors=50, sigma=1.0, random_state=None):
531 r"""
532 Compute left and right factors corresponding to the Nystroem method on the Gaussian kernel :math:`K(x^s_i, x^t_j) = \exp(-\|x^s_i-x^t_j\|^2/2\sigma^2)`.
533 The Nystroem approximation is computed by sampling :math:`\min(n, \lceil(c / 2))\rceil)` components in each distribution,
534 where :math:`n` is the number of samples in the distribution and :math:`c` the total number of anchor points.
535
536 Parameters
537 ----------
538 X_s : array-like, shape (n_samples_a, dim)
539 samples in the source domain
540 X_t : array-like, shape (n_samples_b, dim)
541 samples in the target domain
542 anchors : int, optional
543 The total number of anchors sampled for the Nystroem approximation (anchors/2 in each distribution), default 50.
544 sigma : float, optional
545 The standard deviation parameter for the Gaussian kernel.
546 random_state : int, optional
547 The random state for sampling the components in each distribution.
548
549 Returns
550 -------
551 left_factor : array-like, shape (n_samples_a, dim_r)
552 Left factor of Nystroem
553 right_factor : array-like, shape (n_samples_b, dim_r)
554 Right factor of Nystroem
555 """
556 nx = get_backend(X_s, X_t)
557 if random_state is not None:
558 nx.seed(random_state)
559
560 n, m = X_s.shape[0], X_t.shape[0]
561
562 if not isinstance(anchors, int) or anchors < 2:
563 raise ValueError("anchors must be an integer >= 2")
564
565 n_components_source = min(n, anchors // 2)
566 n_components_target = min(m, anchors // 2)
567 # draw n_components/2 points in each distribution
568 inds_source = nx.randperm(n) # sample n_components_source uniformly
569 basis_source = X_s[inds_source[:n_components_source]]
570
571 inds_target = nx.randperm(m)
572 basis_target = X_t[inds_target[:n_components_target]]
573
574 basis = nx.concatenate((basis_source, basis_target))
575
576 Mzz = dist(basis, metric="sqeuclidean") # compute \|z_i - z_j\|_2^2
577 basis_kernel = nx.exp(-Mzz / (2.0 * sigma**2))
578
579 normalization = nx.pinv(basis_kernel, hermitian=True)
580
581 Mxz = dist(X_s, basis, metric="sqeuclidean")
582 Myz = dist(X_t, basis, metric="sqeuclidean")
583
584 left_factor = nx.exp(-Mxz / (2.0 * sigma**2)) @ normalization
585 right_factor = nx.exp(-Myz / (2.0 * sigma**2))
586
587 return left_factor, right_factor # left_factor @ right_factor.T approx K

Calls 7

get_backendFunction · 0.85
distFunction · 0.70
seedMethod · 0.45
randpermMethod · 0.45
concatenateMethod · 0.45
expMethod · 0.45
pinvMethod · 0.45

Tested by

no test coverage detected