code: def test_handles_changing_perplexities(self):
      perplexities = [15, 25]
      k_neighbors = perplexities[-1] * 3
  
      ms = Multiscale(self.x, perplexities=perplexities)
      np.testing.assert_equal(ms.perplexities, perplexities)
      np.testing.assert_equal(ms.effective_perplexities_, perplexities)
  
      # Check that the initial `P` matrix is allright
      n_samples = self.x.shape[0]
      original_P = ms.P.copy()
      # Can't check for equality because the matrix is symmetrized therefore
      # each point may have non-zero values in more than just the k neighbors
      self.assertTrue(original_P.nnz >= n_samples * k_neighbors)
  
      # Check that lowering the perplexity properly changes affinity matrix
      new_perplexities = [10, 20]
      k_neighbors = new_perplexities[-1] * 3
      ms.set_perplexities(new_perplexities)
      np.testing.assert_equal(ms.perplexities, new_perplexities)
      np.testing.assert_equal(
          ms.effective_perplexities_, new_perplexities
      )
  
      reduced_P = ms.P.copy()
      self.assertTrue(reduced_P.nnz >= n_samples * k_neighbors)
      self.assertTrue(
          reduced_P.nnz < original_P.nnz,
          "Lower perplexities should consider less neighbors, "
          "resulting in a sparser affinity matrix",
      )
  
      # Raising the perplexity above the initial value would need to recompute
      # the nearest neighbors, so it should raise an error
      with self.assertRaises(RuntimeError):
          ms.set_perplexities([20, 30])
  
imports: import logging
  import unittest
  from functools import partial
  import numpy
  from scipy.spatial.distance import squareform, pdist
  from sklearn import datasets
  from sklearn.model_selection import train_test_split
  from openTSNE import affinity, nearest_neighbors
label_desc: Use image node_id 3 for calling the TestMultiscale obj's underlying member method code with example usage: obj.test_handles_changing_perplexities() without return types