code: def adam_step(
      dcdw: Union[ivy.Array, ivy.NativeArray],
      mw: Union[ivy.Array, ivy.NativeArray],
      vw: Union[ivy.Array, ivy.NativeArray],
      step: Union[int, float],
      /,
      *,
      beta1: float = 0.9,
      beta2: float = 0.999,
      epsilon: float = 1e-7,
      out: Optional[ivy.Array] = None,
  ) -> Tuple[ivy.Array, ivy.Array, ivy.Array]:
      """Compute adam step delta, given the derivatives of some cost c with
      respect to weights ws, using ADAM update. `[reference]
  
      <https://en.wikipedia.org/wiki/Stochastic_gradient_descent#Adam>`_
  
      Parameters
      ----------
      dcdw
          Derivates of the cost c with respect to the weights ws, [dc/dw for w in ws].
      mw
          running average of the gradients
      vw
          running average of second moments of the gradients
      step
          training step
      beta1
          gradient forgetting factor (Default value = 0.9)
      beta2
          second moment of gradient forgetting factor (Default value = 0.999)
      epsilon
          divisor during adam update, preventing division by zero (Default value = 1e-7)
      out
          optional output array, for writing the effective grad of adam_step to. It must
          have a shape that the inputs broadcast to.
  
      Returns
      -------
      ret
          The adam step delta.
  
      Examples
      --------
      With :class:`ivy.Array` inputs:
  
      >>> dcdw = ivy.array([1, 2, 3])
      >>> mw = ivy.ones(3)
      >>> vw = ivy.ones(1)
      >>> step = ivy.array(3)
      >>> adam_step_delta = ivy.adam_step(dcdw, mw, vw, step)
      >>> print(adam_step_delta)
      (ivy.array([0.2020105 , 0.22187898, 0.24144873]),
      ivy.array([0.99999998, 1.09999998, 1.19999998]),
      ivy.array([1.00000001, 1.00300001, 1.00800001]))
  
      >>> dcdw = ivy.array([[1., 4., -3.], [2., 3., 0.5]])
      >>> mw = ivy.zeros((2,3))
      >>> vw = ivy.zeros(3)
      >>> step = ivy.array(1)
      >>> beta1 = 0.86
      >>> beta2 = 0.95
      >>> epsilon = 1e-6
      >>> adam_step_delta = ivy.adam_step(dcdw, mw, vw, step, beta1=beta1, beta2=beta2,
      ...                                 epsilon=epsilon)
      >>> print(adam_step_delta)
      (ivy.array([[ 1.,  1., -1.],
                  [ 1.,  1.,  1.]]),
          ivy.array([[ 0.14,  0.56, -0.42],
                     [ 0.28,  0.42,  0.07]]),
       ivy.array([[0.05  , 0.8   , 0.45  ],
                  [0.2   , 0.45  , 0.0125]]))
  
      >>> dcdw = ivy.array([0.1, -0.7, 2])
      >>> mw = ivy.ones(1)
      >>> vw = ivy.ones(1)
      >>> step = ivy.array(3.6)
      >>> out = ivy.zeros_like(dcdw)
      >>> adam_step_delta = ivy.adam_step(dcdw, mw, vw, step, out=out)
      >>> print(out)
      ivy.array([0.17294501, 0.15770318, 0.20863818])
  
      With one :class:`ivy.Container` input:
  
      >>> dcdw = ivy.Container(a=ivy.array([0., 1., 2.]),
      ...                      b=ivy.array([3., 4., 5.]))
      >>> mw = ivy.array([1., 4., 9.])
      >>> vw = ivy.array([0.,])
      >>> step = ivy.array([3.4])
      >>> beta1 = 0.87
      >>> beta2 = 0.976
      >>> epsilon = 1e-5
      >>> adam_step_delta = ivy.adam_step(dcdw, mw, vw, step, beta1=beta1, beta2=beta2,
      ...                                 epsilon=epsilon)
      >>> print(adam_step_delta)
      ({
          a: ivy.array([6.49e+04, 1.74e+01, 1.95e+01]),
          b: ivy.array([2.02, 4.82, 8.17])
      }, {
          a: ivy.array([0.87, 3.61, 8.09]),
          b: ivy.array([1.26, 4., 8.48])
      }, {
          a: ivy.array([0., 0.024, 0.096]),
          b: ivy.array([0.216, 0.384, 0.6])
      })
  
      With multiple :class:`ivy.Container` inputs:
  
      >>> dcdw = ivy.Container(a=ivy.array([0., 1., 2.]),
      ...                      b=ivy.array([3., 4., 5.]))
      >>> mw = ivy.Container(a=ivy.array([0., 0., 0.]),
      ...                    b=ivy.array([0., 0., 0.]))
      >>> vw = ivy.Container(a=ivy.array([0.,]),
      ...                    b=ivy.array([0.,]))
      >>> step = ivy.array([3.4])
      >>> beta1 = 0.87
      >>> beta2 = 0.976
      >>> epsilon = 1e-5
      >>> adam_step_delta = ivy.adam_step(dcdw, mw, vw, step, beta1=beta1, beta2=beta2,
      ...                                 epsilon=epsilon)
      >>> print(adam_step_delta)
      ({
          a: ivy.array([0., 0.626, 0.626]),
          b: ivy.array([0.626, 0.626, 0.626])
      }, {
          a: ivy.array([0., 0.13, 0.26]),
          b: ivy.array([0.39, 0.52, 0.65])
      }, {
          a: ivy.array([0., 0.024, 0.096]),
          b: ivy.array([0.216, 0.384, 0.6])
      })
      """
      step = float(step)
      mw = ivy.add(beta1 * mw, (1 - beta1) * dcdw)
      dcdw_sqrd = dcdw**2
      vw = ivy.add(ivy.multiply(beta2, vw), (1 - beta2) * dcdw_sqrd)
      vw_sqrt = ivy.maximum(vw, 0.0) ** 0.5
      beta1_pow = beta1**step
      beta2_pow = beta2**step
      alpha = (1 - beta2_pow) ** 0.5 / (1 - beta1_pow + epsilon)
      return ivy.divide(alpha * mw, vw_sqrt + epsilon, out=out), mw, vw
  
imports: from typing import Sequence, Union, Optional, Tuple, Callable
  import numpy
  import itertools
  import ivy
  from ivy.utils.backend import current_backend
  from ivy.func_wrapper import handle_array_function, inputs_to_ivy_arrays, to_native_arrays_and_back, handle_out_argument, handle_nestable, handle_array_like_without_promotion, handle_device, handle_backend_invalid
  from ivy.utils.exceptions import handle_exceptions
label_desc: Use image node_id 25 for calling a global function with example usage: adam_step() and returns: ivy,  mw,  vw