


'''simple docstring'''







import inspect
from typing import Callable, List, Optional, Set, Tuple, Union

import torch
from packaging import version
from safetensors.torch import storage_ptr, storage_size
from torch import nn

from .utils import logging


lowercase__     :  Union[str, Any]    					=			[nn.LayerNorm]

lowercase__     :  List[Any]    					=			logging.get_logger(__name__)

lowercase__     :  Dict    					=			version.parse(version.parse(torch.__version__).base_version)

lowercase__     :  List[str]    					=			parsed_torch_version_base >= version.parse('2.0')
lowercase__     :  Optional[Any]    					=			parsed_torch_version_base >= version.parse('1.12')
lowercase__     :  Optional[int]    					=			parsed_torch_version_base >= version.parse('1.11')
lowercase__     :  Dict    					=			parsed_torch_version_base < version.parse('1.11')





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_					,  lowerCAmelCase_					,  lowerCAmelCase_					,  self	):
    from torch import _softmax_backward_data

    if is_torch_less_than_1_11:
        return _softmax_backward_data(lowerCAmelCase_					,  lowerCAmelCase_					,  parent.dim					,  self	)
    else:
        return _softmax_backward_data(lowerCAmelCase_					,  lowerCAmelCase_					,  parent.dim					,  self.dtype	)





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_					,  lowerCAmelCase_ = 0	):
    UpperCamelCase__      =			index.to(layer.weight.device	)
    UpperCamelCase__      =			layer.weight.index_select(lowerCAmelCase_					,  lowerCAmelCase_	).clone().detach()
    if layer.bias is not None:
        if dim == 1:
            UpperCamelCase__      =			layer.bias.clone().detach()
        else:
            UpperCamelCase__      =			layer.bias[index].clone().detach()
    UpperCamelCase__      =			list(layer.weight.size()	)
    UpperCamelCase__      =			len(lowerCAmelCase_	)
    UpperCamelCase__      =			nn.Linear(new_size[1]					,  new_size[0]					,  bias=layer.bias is not None	).to(layer.weight.device	)
    UpperCamelCase__      =			False
    new_layer.weight.copy_(W.contiguous()	)
    UpperCamelCase__      =			True
    if layer.bias is not None:
        UpperCamelCase__      =			False
        new_layer.bias.copy_(b.contiguous()	)
        UpperCamelCase__      =			True
    return new_layer

class       lowerCamelCase_							(	nn.Module  ):






   '''simple docstring'''

   def __init__(  self     ,						__UpperCamelCase     ,						__UpperCamelCase ):
       super().__init__()
       UpperCamelCase__      =			nf
       UpperCamelCase__      =			nn.Parameter(torch.empty(lowerCamelCase__     ,						lowerCamelCase__ ) )
       UpperCamelCase__      =			nn.Parameter(torch.zeros(lowerCamelCase__ ) )
       nn.init.normal_(self.weight     ,						std=0.02 )







   def 	_UpperCamelCase       (  self     ,						__UpperCamelCase ):
       UpperCamelCase__      =			x.size()[:-1] + (self.nf,)
       UpperCamelCase__      =			torch.addmm(self.bias     ,						x.view(-1     ,						x.size(-1 ) )     ,						self.weight )
       UpperCamelCase__      =			x.view(lowerCamelCase__ )
       return x





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_					,  lowerCAmelCase_ = 1	):
    UpperCamelCase__      =			index.to(layer.weight.device	)
    UpperCamelCase__      =			layer.weight.index_select(lowerCAmelCase_					,  lowerCAmelCase_	).clone().detach()
    if dim == 0:
        UpperCamelCase__      =			layer.bias.clone().detach()
    else:
        UpperCamelCase__      =			layer.bias[index].clone().detach()
    UpperCamelCase__      =			list(layer.weight.size()	)
    UpperCamelCase__      =			len(lowerCAmelCase_	)
    UpperCamelCase__      =			ConvaD(new_size[1]					,  new_size[0]	).to(layer.weight.device	)
    UpperCamelCase__      =			False
    new_layer.weight.copy_(W.contiguous()	)
    UpperCamelCase__      =			True
    UpperCamelCase__      =			False
    new_layer.bias.copy_(b.contiguous()	)
    UpperCamelCase__      =			True
    return new_layer





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_					,  lowerCAmelCase_ = None	):
    if isinstance(lowerCAmelCase_					,  nn.Linear	):
        return prune_linear_layer(lowerCAmelCase_					,  lowerCAmelCase_					,  dim=0 if dim is None else dim	)
    elif isinstance(lowerCAmelCase_					,  lowerCAmelCase_	):
        return prune_convad_layer(lowerCAmelCase_					,  lowerCAmelCase_					,  dim=1 if dim is None else dim	)
    else:
        raise ValueError(F'Can\'t prune layer of class {layer.__class__}'	)





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_					,  lowerCAmelCase_					,  *lowerCAmelCase_	):
    assert len(lowerCAmelCase_	) > 0, F'{input_tensors} has to be a tuple/list of tensors'

    # inspect.signature exist since python 3.5 and is a python method -> no problem with backward compatibility
    UpperCamelCase__      =			len(inspect.signature(lowerCAmelCase_	).parameters	)
    if num_args_in_forward_chunk_fn != len(lowerCAmelCase_	):
        raise ValueError(
            F'forward_chunk_fn expects {num_args_in_forward_chunk_fn} arguments, but only {len(lowerCAmelCase_	)} input '
            "tensors are given"	)

    if chunk_size > 0:
        UpperCamelCase__      =			input_tensors[0].shape[chunk_dim]
        for input_tensor in input_tensors:
            if input_tensor.shape[chunk_dim] != tensor_shape:
                raise ValueError(
                    F'All input tenors have to be of the same shape: {tensor_shape}, '
                    F'found shape {input_tensor.shape[chunk_dim]}'	)

        if input_tensors[0].shape[chunk_dim] % chunk_size != 0:
            raise ValueError(
                F'The dimension to be chunked {input_tensors[0].shape[chunk_dim]} has to be a multiple of the chunk '
                F'size {chunk_size}'	)

        UpperCamelCase__      =			input_tensors[0].shape[chunk_dim] // chunk_size

        # chunk input tensor into tuples
        UpperCamelCase__      =			tuple(input_tensor.chunk(lowerCAmelCase_					,  dim=lowerCAmelCase_	) for input_tensor in input_tensors	)
        # apply forward fn to every tuple
        UpperCamelCase__      =			tuple(forward_fn(*lowerCAmelCase_	) for input_tensors_chunk in zip(*lowerCAmelCase_	)	)
        # concatenate output at same dimension
        return torch.cat(lowerCAmelCase_					,  dim=lowerCAmelCase_	)

    return forward_fn(*lowerCAmelCase_	)





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_					,  lowerCAmelCase_					,  lowerCAmelCase_	):
    UpperCamelCase__      =			torch.ones(lowerCAmelCase_					,  lowerCAmelCase_	)
    UpperCamelCase__      =			set(lowerCAmelCase_	) - already_pruned_heads  # Convert to set and remove already pruned heads
    for head in heads:
        # Compute how many pruned heads are before the head and move the index accordingly
        UpperCamelCase__      =			head - sum(1 if h < head else 0 for h in already_pruned_heads	)
        UpperCamelCase__      =			0
    UpperCamelCase__      =			mask.view(-1	).contiguous().eq(1	)
    UpperCamelCase__      =			torch.arange(len(lowerCAmelCase_	)	)[mask].long()
    return heads, index





def 						snake_case__ (*lowerCAmelCase_					,  lowerCAmelCase_ = None	):
    return torch.meshgrid(*lowerCAmelCase_					,  indexing=lowerCAmelCase_	)





def 						snake_case__ (lowerCAmelCase_	):
    return tensor.device, storage_ptr(lowerCAmelCase_	), storage_size(lowerCAmelCase_	)









'''simple docstring'''







from math import radians as angle_to_radians
from math import sin

# Acceleration Constant on Earth (unit m/s^2)
lowercase__     :  str    					=			9.8_0_6_6_5





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_	):

    # Ensure valid instance
    if not isinstance(lowerCAmelCase_					,  (int, float)	):
        raise TypeError("Invalid velocity. Should be a positive number."	)

    if not isinstance(lowerCAmelCase_					,  (int, float)	):
        raise TypeError("Invalid angle. Range is 1-90 degrees."	)

    # Ensure valid angle
    if angle > 90 or angle < 1:
        raise ValueError("Invalid angle. Range is 1-90 degrees."	)

    # Ensure valid velocity
    if init_velocity < 0:
        raise ValueError("Invalid velocity. Should be a positive number."	)





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_	):
    check_args(lowerCAmelCase_					,  lowerCAmelCase_	)
    UpperCamelCase__      =			angle_to_radians(2 * angle	)
    return round(init_velocity**2 * sin(lowerCAmelCase_	) / g					,  2	)





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_	):
    check_args(lowerCAmelCase_					,  lowerCAmelCase_	)
    UpperCamelCase__      =			angle_to_radians(lowerCAmelCase_	)
    return round(init_velocity**2 * sin(lowerCAmelCase_	) ** 2 / (2 * g)					,  2	)





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_	):
    check_args(lowerCAmelCase_					,  lowerCAmelCase_	)
    UpperCamelCase__      =			angle_to_radians(lowerCAmelCase_	)
    return round(2 * init_velocity * sin(lowerCAmelCase_	) / g					,  2	)





def 						snake_case__ ():
    UpperCamelCase__    ,  UpperCamelCase__      =			25, 20
    assert horizontal_distance(lowerCAmelCase_					,  lowerCAmelCase_	) == 40.97
    assert max_height(lowerCAmelCase_					,  lowerCAmelCase_	) == 3.73
    assert total_time(lowerCAmelCase_					,  lowerCAmelCase_	) == 1.74


if __name__ == "__main__":
      from doctest import testmod

      testmod()

      # Get input from user
      lowercase__     :  Union[str, Any]    					=			float(input('Initial Velocity: ').strip())

      # Get input from user
      lowercase__     :  Any    					=			float(input('angle: ').strip())

      # Print results
      print()
      print('Results: ')
      print(F'''Horizontal Distance: {horizontal_distance(init_vel, angle)!s} [m]''')
      print(F'''Maximum Height: {max_height(init_vel, angle)!s} [m]''')
      print(F'''Total Time: {total_time(init_vel, angle)!s} [s]''')




