code: def linear(
      x: Union[ivy.Array, ivy.NativeArray],
      weight: Union[ivy.Array, ivy.NativeArray],
      /,
      *,
      bias: Optional[Union[ivy.Array, ivy.NativeArray]] = None,
      out: Optional[ivy.Array] = None,
  ) -> ivy.Array:
      """Apply a linear transformation to the incoming data: y = x * t(weight) + bias.
      The operation also supports batching of the weight matrices. This is useful if a
      batch of different network parameters are to be represented.
  
      Parameters
      ----------
      x
          The input x to compute linear transformation on.
          *[outer_batch_shape,inner_batch_shape,in_features]*
      weight
          The weight matrix. *[outer_batch_shape,out_features,in_features]*
      bias
          The bias vector, default is ``None``. *[outer_batch_shape,out_features]*
      out
          optional output array, for writing the result to. It must have a shape that the
          inputs broadcast to.
  
      Returns
      -------
      ret
          Result array of the linear transformation.
          *[outer_batch_shape,inner_batch_shape,out_features]*
  
      Both the description and the type hints above assumes an array input for simplicity,
      but this function is *nestable*, and therefore also accepts :class:`ivy.Container`
      instances in place of any of the arguments.
  
      Examples
      --------
      With :class:`ivy.Array` input:
  
      >>> x = ivy.array([1., 2., 3.])
      >>> w = ivy.array([[1., 0., 0.]])
      >>> y = ivy.linear(x, w)
      >>> print(y)
      ivy.array([1.])
  
      >>> x = ivy.array([[0.666, -0.4269, 1.911]])
      >>> w = ivy.array([[1., 0., 0.], [0., 0., 1.]])
      >>> y = ivy.zeros((1, 2))
      >>> ivy.linear(x, w, out=y)
      >>> print(y)
      ivy.array([[0.666, 1.91 ]])
  
      >>> x = ivy.array([[1.546, 5.234, 6.487],
      ...                [0.157, 5.753, 4.52],
      ...                [5.165, 3.159, 7.101]])
      >>> w = ivy.array([[1.545, 2.547, 3.124],
      ...                [5.852, 8.753, 6.963]])
      >>> b = ivy.array([-1., 1.])
      >>> y = ivy.zeros((3, 2))
      >>> ivy.linear(x, w, bias=b, out=y)
      >>> print(y)
      ivy.array([[ 34.98495483, 101.0293808 ],
             [ 28.0159359 ,  83.74752808],
             [ 37.20942307, 108.3205719 ]])
  
      With :class:`ivy.Container` input:
  
      >>> x = ivy.Container(a=ivy.array([[1., 2., 3.],
      ...                                [4., 5., 6.]]),
      ...                   b=ivy.array([1.1, 2.2, 3.3]))
      >>> w = ivy.Container(a=ivy.array([[1., 2., 3.],
      ...                                [-1., 1., 2.]]),
      ...                   b=ivy.array([[0., -1., 1.],
      ...                                [0., 1., 1.]]))
      >>> b = ivy.Container(a=ivy.array([1., -1.]), b=ivy.array([1., 1.]))
      >>> y = ivy.linear(x, w, bias=b)
      >>> print(y)
      {
          a: ivy.array([[15., 6.],
                        [33., 12.]]),
          b: ivy.array([2.1, 6.5])
      }
  
      With a mix of :class:`ivy.Array` and :class:`ivy.Container` inputs:
  
      >>> x = ivy.Container(a=ivy.array([[1.1, 2.2, 3.3],
      ...                                [11., 22., 33.]]),
      ...                   b=ivy.array([[1.245, 0.278, 4.105],
      ...                                [7., 13., 17.]]))
      >>> w = ivy.array([[1., 2., 3.],
      ...                [4., 5., 6.],
      ...                [7., 8., 9.]])
      >>> b = ivy.Container(a=ivy.array([1., 0., -1.]),
      ...                   b=ivy.array([1., 1., 0.]))
      >>> ivy.linear(x, w, bias=b, out=x)
      >>> print(x)
      {
          a: ivy.array([[16.4, 35.2, 54.],
                        [155., 352., 549.]]),
          b: ivy.array([[15.1, 32., 47.9],
                        [85., 196., 306.]])
      }
  
      """
      outer_batch_shape = list(weight.shape[:-2])
      num_outer_batch_dims = len(outer_batch_shape)
      inner_batch_shape = list(x.shape[num_outer_batch_dims:-1])
      num_inner_batch_dims = len(inner_batch_shape)
      num_out_feats, num_in_feats = list(weight.shape[-2:])
  
      # OBS x IBS x OF
      y = ivy.matmul(
          x,
          ivy.swapaxes(
              ivy.reshape(
                  weight,
                  outer_batch_shape
                  + [1] * max(num_inner_batch_dims - 1, 0)
                  + [num_out_feats, num_in_feats],
              ),
              -1,
              -2,
          ),
      )
  
      if ivy.exists(bias):
          # OBS x [1]*len(IBS) x OF
          bias_broadcast = ivy.reshape(
              bias,
              outer_batch_shape
              + [1] * num_inner_batch_dims
              + [num_out_feats],
          )
  
          # OBS x IBS x OF
          y = y + bias_broadcast
  
      if ivy.exists(out):
          return ivy.inplace_update(out, y)
      return y
  
imports: from typing import Optional, Tuple, Union, Sequence
  import ivy
  from ivy.utils.backend import current_backend
  from ivy.func_wrapper import handle_array_function, handle_partial_mixed_function, inputs_to_ivy_arrays, to_native_arrays_and_back, inputs_to_native_shapes, 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 3 for calling a global function with example usage: linear() and returns: y, ivy