def outer(b, axis:nil)
      b = NArray.cast(b)
      if axis.nil?
        self[false,:new] * ((b.ndim==0) ? b : b[false,:new,true])
      else
        md,nd = [ndim,b.ndim].minmax
        axis = check_axis(axis) - nd
        if axis < -md
          raise ArgumentError,"axis=#{axis} is out of range"
        end
        adim = [true]*ndim
        adim[axis+ndim+1,0] = :new
        bdim = [true]*b.ndim
        bdim[axis+b.ndim,0] = :new
        self[*adim] * b[*bdim]
      end
    end
def outer(b, axis:nil)
      b = NArray.cast(b)
      if axis.nil?
        self[false,:new] * ((b.ndim==0) ? b : b[false,:new,true])
      else
        md,nd = [ndim,b.ndim].minmax
        axis = check_axis(axis) - nd
        if axis < -md
          raise ArgumentError,"axis=#{axis} is out of range"
        end
        adim = [true]*ndim
        adim[axis+ndim+1,0] = :new
        bdim = [true]*b.ndim
        bdim[axis+b.ndim,0] = :new
        self[*adim] * b[*bdim]
      end
    end
Outer product of two arrays.
 Same as `self[false,:new] * b[false,:new,true]`.

 @param b [Numo::NArray]
 @param axis [Integer] applied axis (default=-1)
 @return [Numo::NArray]  return outer product
 @example
   a = Numo::DFloat.ones(5)
   => Numo::DFloat#shape=[5]
   [1, 1, 1, 1, 1]
   b = Numo::DFloat.linspace(-2,2,5)
   => Numo::DFloat#shape=[5]
   [-2, -1, 0, 1, 2]
   a.outer(b)
   => Numo::DFloat#shape=[5,5]
   [[-2, -1, 0, 1, 2],
    [-2, -1, 0, 1, 2],
    [-2, -1, 0, 1, 2],
    [-2, -1, 0, 1, 2],
    [-2, -1, 0, 1, 2]]