

from typing import Dict, Optional, Tuple

import torch





def 	snake_case_      (__A     :						torch.Tensor     )			->	torch.Tensor:
   __lowerCAmelCase  :			Optional[int]					    =						boundaries[1] - boundaries[0]
   __lowerCAmelCase  :			int					    =						boundaries + step / 2
   __lowerCAmelCase  :			Optional[int]					    =						torch.cat([bin_centers, (bin_centers[-1] + step).unsqueeze(-1     )]					,   dim=0     )
   return bin_centers





def 	snake_case_      (__A     :						torch.Tensor					,   __A     :						torch.Tensor					,   )			->	Tuple[torch.Tensor, torch.Tensor]:
   __lowerCAmelCase  :			Optional[Any]					    =						_calculate_bin_centers(__A     )
   return (
       torch.sum(aligned_distance_error_probs * bin_centers					,   dim=-1     ),
       bin_centers[-1],
   )





def 	snake_case_      (__A     :						torch.Tensor					,   __A     :						int = 3_1					,   __A     :						int = 6_4					,   **__A     :						List[str]					,   )			->	Dict[str, torch.Tensor]:
   __lowerCAmelCase  :			int					    =						torch.linspace(0					,   __A					,   steps=(no_bins - 1)					,   device=logits.device     )

   __lowerCAmelCase  :			Dict					    =						torch.nn.functional.softmax(__A					,   dim=-1     )
   __lowerCAmelCase    ,__lowerCAmelCase  :			int					    =						_calculate_expected_aligned_error(
       alignment_confidence_breaks=__A					,   aligned_distance_error_probs=__A					,   )

   return {
       "aligned_confidence_probs": aligned_confidence_probs,
       "predicted_aligned_error": predicted_aligned_error,
       "max_predicted_aligned_error": max_predicted_aligned_error,
   }





def 	snake_case_      (__A     :						torch.Tensor					,   __A     :						Optional[torch.Tensor] = None					,   __A     :						int = 3_1					,   __A     :						int = 6_4					,   __A     :						float = 1e-8					,   **__A     :						Optional[int]					,   )			->	torch.Tensor:
   if residue_weights is None:
      __lowerCAmelCase  :			str					    =						logits.new_ones(logits.shape[-2]     )

   __lowerCAmelCase  :			int					    =						torch.linspace(0					,   __A					,   steps=(no_bins - 1)					,   device=logits.device     )

   __lowerCAmelCase  :			Any					    =						_calculate_bin_centers(__A     )
   torch.sum(__A     )
   __lowerCAmelCase  :			Optional[Any]					    =						logits.shape[-2]
   __lowerCAmelCase  :			Dict					    =						max(__A					,   1_9     )

   __lowerCAmelCase  :			Union[str, Any]					    =						1.24 * (clipped_n - 1_5) ** (1.0 / 3) - 1.8

   __lowerCAmelCase  :			List[str]					    =						torch.nn.functional.softmax(__A					,   dim=-1     )

   __lowerCAmelCase  :			List[str]					    =						1.0 / (1 + (bin_centers**2) / (da**2))
   __lowerCAmelCase  :			Any					    =						torch.sum(probs * tm_per_bin					,   dim=-1     )

   __lowerCAmelCase  :			Tuple					    =						residue_weights / (eps + residue_weights.sum())
   __lowerCAmelCase  :			str					    =						torch.sum(predicted_tm_term * normed_residue_mask					,   dim=-1     )

   __lowerCAmelCase  :			Optional[Any]					    =						per_alignment * residue_weights

   __lowerCAmelCase  :			List[str]					    =						(weighted == torch.max(__A     )).nonzero()[0]
   return per_alignment[tuple(__A     )]










def    lowerCAmelCase__		(			_a				:	int			):
		if not isinstance(_a     ,					_a			):
				snake_case_ :							Optional[int]         =				F'''Input value of [number={number}] must be an integer'''
				raise TypeError(_a			)
		if number < 1:
				raise ValueError("Input must be a positive integer"			)
		return number * (2 * number - 1)


if __name__ == "__main__":
							import doctest

							doctest.testmod()
