code: def test_cosine_sawtooth(self):
      tail_fn = lr_schedules._CosineSawtoothTail(180, min_value=0.1)
      lr_fn = lr_schedules._BodyAndTail(
          0.3, tail_start=0, tail_fn=tail_fn
      )
  
      # First cycle
      self.assertAlmostEqual(0.29998477, lr_fn(1))
      self.assertAlmostEqual(0.28660254, lr_fn(30))
      self.assertAlmostEqual(0.25, lr_fn(60))
      self.assertAlmostEqual(0.20, lr_fn(90))
      self.assertAlmostEqual(0.15, lr_fn(120))
      self.assertAlmostEqual(0.10001523, lr_fn(179))
  
      # Second cycle
      self.assertEqual(0.3, lr_fn(180))
      self.assertAlmostEqual(0.29998477, lr_fn(181))
      self.assertAlmostEqual(0.28660254, lr_fn(210))
      self.assertAlmostEqual(0.25, lr_fn(240))
      self.assertAlmostEqual(0.20, lr_fn(270))
      self.assertAlmostEqual(0.15, lr_fn(300))
      self.assertAlmostEqual(0.10001523, lr_fn(359))
  
file_path: trax/trax/supervised/lr_schedules_test.py
imports: import math
  from absl.testing import absltest
  from trax.supervised import lr_schedules
label_desc: Use image node_id 4 for calling the LRFunctionsTest obj's underlying member method code with example usage: obj.test_cosine_sawtooth() without return types