diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9580b42f8469f62543b9fedd57a953c56c66659e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/override.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/override.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b0ed80a116c8302f2f16114225693c8eeef1f2b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/override.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/commands/tpu.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/commands/tpu.py new file mode 100644 index 0000000000000000000000000000000000000000..fc0f07bf8697bfdb6484d3bf817f2e18b1313b00 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/commands/tpu.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python + +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import os +import subprocess + +from packaging.version import Version, parse + +from accelerate.commands.config.config_args import default_config_file, load_config_from_file + + +_description = "Run commands across TPU VMs for initial setup before running `accelerate launch`." + + +def tpu_command_parser(subparsers=None): + if subparsers is not None: + parser = subparsers.add_parser("tpu-config", description=_description) + else: + parser = argparse.ArgumentParser("Accelerate tpu-config command", description=_description) + # Core arguments + config_args = parser.add_argument_group( + "Config Arguments", "Arguments that can be configured through `accelerate config`." + ) + config_args.add_argument( + "--config_file", + type=str, + default=None, + help="Path to the config file to use for accelerate.", + ) + config_args.add_argument( + "--tpu_name", + default=None, + help="The name of the TPU to use. If not specified, will use the TPU specified in the config file.", + ) + config_args.add_argument( + "--tpu_zone", + default=None, + help="The zone of the TPU to use. If not specified, will use the zone specified in the config file.", + ) + pod_args = parser.add_argument_group("TPU Arguments", "Arguments for options ran inside the TPU.") + pod_args.add_argument( + "--use_alpha", + action="store_true", + help="Whether to use `gcloud alpha` when running the TPU training script instead of `gcloud`.", + ) + pod_args.add_argument( + "--command_file", + default=None, + help="The path to the file containing the commands to run on the pod on startup.", + ) + pod_args.add_argument( + "--command", + action="append", + nargs="+", + help="A command to run on the pod. Can be passed multiple times.", + ) + pod_args.add_argument( + "--install_accelerate", + action="store_true", + help="Whether to install accelerate on the pod. Defaults to False.", + ) + pod_args.add_argument( + "--accelerate_version", + default="latest", + help="The version of accelerate to install on the pod. If not specified, will use the latest pypi version. Specify 'dev' to install from GitHub.", + ) + pod_args.add_argument( + "--debug", action="store_true", help="If set, will print the command that would be run instead of running it." + ) + + if subparsers is not None: + parser.set_defaults(func=tpu_command_launcher) + return parser + + +def tpu_command_launcher(args): + defaults = None + + # Get the default from the config file if it exists. + if args.config_file is not None or os.path.isfile(default_config_file): + defaults = load_config_from_file(args.config_file) + if not args.command_file and defaults.command_file is not None and not args.command: + args.command_file = defaults.command_file + if not args.command and defaults.commands is not None: + args.command = defaults.commands + if not args.tpu_name: + args.tpu_name = defaults.tpu_name + if not args.tpu_zone: + args.tpu_zone = defaults.tpu_zone + if args.accelerate_version == "dev": + args.accelerate_version = "git+https://github.com/huggingface/accelerate.git" + elif args.accelerate_version == "latest": + args.accelerate_version = "accelerate -U" + elif isinstance(parse(args.accelerate_version), Version): + args.accelerate_version = f"accelerate=={args.accelerate_version}" + + if not args.command_file and not args.command: + raise ValueError("You must specify either a command file or a command to run on the pod.") + + if args.command_file: + with open(args.command_file) as f: + args.command = [f.read().splitlines()] + + # To turn list of lists into list of strings + if isinstance(args.command[0], list): + args.command = [line for cmd in args.command for line in cmd] + # Default to the shared folder and install accelerate + new_cmd = ["cd /usr/share"] + if args.install_accelerate: + new_cmd += [f"pip install {args.accelerate_version}"] + new_cmd += args.command + args.command = "; ".join(new_cmd) + + # Then send it to gcloud + # Eventually try to use google-api-core to do this instead of subprocess + cmd = ["gcloud"] + if args.use_alpha: + cmd += ["alpha"] + cmd += [ + "compute", + "tpus", + "tpu-vm", + "ssh", + args.tpu_name, + "--zone", + args.tpu_zone, + "--command", + args.command, + "--worker", + "all", + ] + if args.debug: + print(f"Running {' '.join(cmd)}") + return + subprocess.run(cmd) + print("Successfully setup pod.") + + +def main(): + parser = tpu_command_parser() + args = parser.parse_args() + + tpu_command_launcher(args) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/test_utils/scripts/external_deps/__pycache__/test_ds_multiple_model.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/test_utils/scripts/external_deps/__pycache__/test_ds_multiple_model.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2b407ec2c1fbc198c3b7a949c5b401c78bc7d5d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/test_utils/scripts/external_deps/__pycache__/test_ds_multiple_model.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9696b1bb2aa5f944e8df4f54b3f4e9201d0d9ba --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/__init__.py @@ -0,0 +1,306 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from ..parallelism_config import ParallelismConfig +from .ao import convert_model_to_fp8_ao, filter_first_and_last_linear_layers, has_ao_layers +from .constants import ( + MITA_PROFILING_AVAILABLE_PYTORCH_VERSION, + MODEL_NAME, + OPTIMIZER_NAME, + PROFILE_PATTERN_NAME, + RNG_STATE_NAME, + SAFE_MODEL_NAME, + SAFE_WEIGHTS_INDEX_NAME, + SAFE_WEIGHTS_NAME, + SAFE_WEIGHTS_PATTERN_NAME, + SAMPLER_NAME, + SCALER_NAME, + SCHEDULER_NAME, + TORCH_DISTRIBUTED_OPERATION_TYPES, + TORCH_LAUNCH_PARAMS, + WEIGHTS_INDEX_NAME, + WEIGHTS_NAME, + WEIGHTS_PATTERN_NAME, + XPU_PROFILING_AVAILABLE_PYTORCH_VERSION, +) +from .dataclasses import ( + AORecipeKwargs, + AutocastKwargs, + BnbQuantizationConfig, + ComputeEnvironment, + CustomDtype, + DataLoaderConfiguration, + DDPCommunicationHookType, + DeepSpeedPlugin, + DeepSpeedSequenceParallelConfig, + DistributedDataParallelKwargs, + DistributedType, + DynamoBackend, + FP8RecipeKwargs, + FullyShardedDataParallelPlugin, + GradientAccumulationPlugin, + GradScalerKwargs, + InitProcessGroupKwargs, + KwargsHandler, + LoggerType, + MegatronLMPlugin, + MSAMPRecipeKwargs, + PrecisionType, + ProfileKwargs, + ProjectConfiguration, + RNGType, + SageMakerDistributedType, + TensorInformation, + TERecipeKwargs, + TorchContextParallelConfig, + TorchDynamoPlugin, + TorchTensorParallelConfig, + TorchTensorParallelPlugin, + add_model_config_to_megatron_parser, +) +from .environment import ( + are_libraries_initialized, + check_cuda_fp8_capability, + check_cuda_p2p_ib_support, + clear_environment, + convert_dict_to_env_variables, + get_cpu_distributed_information, + get_current_device_type, + get_gpu_info, + get_int_from_env, + parse_choice_from_env, + parse_flag_from_env, + patch_environment, + purge_accelerate_environment, + set_numa_affinity, + str_to_bool, +) +from .imports import ( + deepspeed_required, + get_ccl_version, + is_4bit_bnb_available, + is_8bit_bnb_available, + is_aim_available, + is_bf16_available, + is_bitsandbytes_multi_backend_available, + is_bnb_available, + is_boto3_available, + is_ccl_available, + is_clearml_available, + is_comet_ml_available, + is_cuda_available, + is_datasets_available, + is_deepspeed_available, + is_dvclive_available, + is_fp8_available, + is_fp16_available, + is_habana_gaudi1, + is_hpu_available, + is_import_timer_available, + is_ipex_available, + is_lomo_available, + is_matplotlib_available, + is_megatron_lm_available, + is_mlflow_available, + is_mlu_available, + is_mps_available, + is_msamp_available, + is_musa_available, + is_npu_available, + is_pandas_available, + is_peft_available, + is_pippy_available, + is_pynvml_available, + is_pytest_available, + is_rich_available, + is_sagemaker_available, + is_schedulefree_available, + is_sdaa_available, + is_swanlab_available, + is_tensorboard_available, + is_timm_available, + is_torch_xla_available, + is_torchao_available, + is_torchdata_available, + is_torchdata_stateful_dataloader_available, + is_torchvision_available, + is_trackio_available, + is_transformer_engine_available, + is_transformer_engine_mxfp8_available, + is_transformers_available, + is_triton_available, + is_wandb_available, + is_weights_only_available, + is_xccl_available, + is_xpu_available, + torchao_required, +) +from .modeling import ( + align_module_device, + calculate_maximum_sizes, + check_device_map, + check_tied_parameters_in_config, + check_tied_parameters_on_same_device, + compute_module_sizes, + convert_file_size_to_int, + dtype_byte_size, + find_tied_parameters, + get_balanced_memory, + get_grad_scaler, + get_max_layer_size, + get_max_memory, + get_mixed_precision_context_manager, + has_offloaded_params, + id_tensor_storage, + infer_auto_device_map, + is_peft_model, + load_checkpoint_in_model, + load_offloaded_weights, + load_state_dict, + named_module_tensors, + retie_parameters, + set_module_tensor_to_device, +) +from .offload import ( + OffloadedWeightsLoader, + PrefixedDataset, + extract_submodules_state_dict, + load_offloaded_weight, + offload_state_dict, + offload_weight, + save_offload_index, +) +from .operations import ( + CannotPadNestedTensorWarning, + GatheredParameters, + broadcast, + broadcast_object_list, + concatenate, + convert_outputs_to_fp32, + convert_to_fp32, + copy_tensor_to_devices, + find_batch_size, + find_device, + gather, + gather_object, + get_data_structure, + honor_type, + ignorant_find_batch_size, + initialize_tensors, + is_namedtuple, + is_tensor_information, + is_torch_tensor, + listify, + pad_across_processes, + pad_input_tensors, + recursively_apply, + reduce, + send_to_device, + slice_tensors, +) +from .versions import compare_versions, is_torch_version + + +if is_deepspeed_available(): + from .deepspeed import ( + DeepSpeedEngineWrapper, + DeepSpeedOptimizerWrapper, + DeepSpeedSchedulerWrapper, + DummyOptim, + DummyScheduler, + HfDeepSpeedConfig, + get_active_deepspeed_plugin, + map_pytorch_optim_to_deepspeed, + ) + +from .bnb import has_4bit_bnb_layers, load_and_quantize_model +from .fsdp_utils import ( + disable_fsdp_ram_efficient_loading, + enable_fsdp_ram_efficient_loading, + ensure_weights_retied, + fsdp2_apply_ac, + fsdp2_canonicalize_names, + fsdp2_load_full_state_dict, + fsdp2_prepare_model, + fsdp2_switch_optimizer_parameters, + get_fsdp2_grad_scaler, + load_fsdp_model, + load_fsdp_optimizer, + merge_fsdp_weights, + save_fsdp_model, + save_fsdp_optimizer, +) +from .launch import ( + PrepareForLaunch, + _filter_args, + prepare_deepspeed_cmd_env, + prepare_multi_gpu_env, + prepare_sagemager_args_inputs, + prepare_simple_launcher_cmd_env, + prepare_tpu, +) + +# For docs +from .megatron_lm import ( + AbstractTrainStep, + BertTrainStep, + GPTTrainStep, + MegatronLMDummyDataLoader, + MegatronLMDummyScheduler, + T5TrainStep, + avg_losses_across_data_parallel_group, +) + + +if is_megatron_lm_available(): + from .megatron_lm import ( + MegatronEngine, + MegatronLMOptimizerWrapper, + MegatronLMSchedulerWrapper, + gather_across_data_parallel_groups, + ) + from .megatron_lm import initialize as megatron_lm_initialize + from .megatron_lm import prepare_data_loader as megatron_lm_prepare_data_loader + from .megatron_lm import prepare_model_optimizer_scheduler as megatron_lm_prepare_model_optimizer_scheduler + from .megatron_lm import prepare_optimizer as megatron_lm_prepare_optimizer + from .megatron_lm import prepare_scheduler as megatron_lm_prepare_scheduler +from .memory import find_executable_batch_size, release_memory +from .other import ( + check_os_kernel, + clean_state_dict_for_safetensors, + compile_regions, + compile_regions_deepspeed, + convert_bytes, + extract_model_from_parallel, + get_module_children_bottom_up, + get_pretty_name, + has_compiled_regions, + is_compiled_module, + is_port_in_use, + load, + merge_dicts, + model_has_dtensor, + recursive_getattr, + save, + wait_for_everyone, + write_basic_config, +) +from .random import set_seed, synchronize_rng_state, synchronize_rng_states +from .torch_xla import install_xla +from .tqdm import tqdm +from .transformer_engine import ( + apply_fp8_autowrap, + contextual_fp8_autocast, + convert_model, + has_transformer_engine_layers, +) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/ao.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/ao.py new file mode 100644 index 0000000000000000000000000000000000000000..73155615b768a01f709bb8e0857617ba58a6ec83 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/ao.py @@ -0,0 +1,140 @@ +# Copyright 2025 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Needed utilities for torchao FP8 training. +""" + +from functools import partial +from typing import TYPE_CHECKING, Callable, Optional + +import torch + +from .imports import is_torchao_available, torchao_required + + +if TYPE_CHECKING: + if is_torchao_available(): + from torchao.float8.float8_linear import Float8LinearConfig + + +def find_first_last_linear_layers(model: torch.nn.Module): + """ + Finds the first and last linear layer names in a model. + + This is needed during FP8 to avoid issues with instability by keeping the first and last layers unquantized. + + Ref: https://x.com/xariusrke/status/1826669142604141052 + """ + first_linear, last_linear = None, None + for name, module in model.named_modules(): + if isinstance(module, torch.nn.Linear): + if first_linear is None: + first_linear = name + last_linear = name + return first_linear, last_linear + + +def filter_linear_layers(module, fqn: str, layers_to_filter: list[str]) -> bool: + """ + A function which will check if `module` is: + - a `torch.nn.Linear` layer + - has in_features and out_features divisible by 16 + - is not part of `layers_to_filter` + + Args: + module (`torch.nn.Module`): + The module to check. + fqn (`str`): + The fully qualified name of the layer. + layers_to_filter (`List[str]`): + The list of layers to filter. + """ + if isinstance(module, torch.nn.Linear): + if module.in_features % 16 != 0 or module.out_features % 16 != 0: + return False + if fqn in layers_to_filter: + return False + return True + + +def filter_first_and_last_linear_layers(module, fqn: str) -> bool: + """ + A filter function which will filter out all linear layers except the first and last. + + + + For stability reasons, we skip the first and last linear layers Otherwise can lead to the model not training or + converging properly + + + + Args: + module (`torch.nn.Module`): + The module to check. + fqn (`str`): + The fully qualified name of the layer. + """ + first_linear, last_linear = find_first_last_linear_layers(module) + return filter_linear_layers(module, fqn, layers_to_filter=[first_linear, last_linear]) + + +@torchao_required +def has_ao_layers(model: torch.nn.Module): + from torchao.float8.float8_linear import Float8Linear + + for name, module in model.named_modules(): + if isinstance(module, Float8Linear): + return True + return False + + +@torchao_required +def convert_model_to_fp8_ao( + model: torch.nn.Module, + config: Optional["Float8LinearConfig"] = None, + module_filter_func: Optional[Callable] = filter_first_and_last_linear_layers, +): + """ + Converts all `nn.Linear` layers in the model (except the first and last) to torchao's `Float8Linear` layer inplace. + + Args: + model (`torch.nn.Module`): + The model to convert. + config (`torchao.float8.Float8LinearConfig`, *optional*): + The configuration for the FP8 training. Recommended to utilize + `torchao.float8.recipe_name_to_linear_config` to generate this. In general, the default config should be + sufficient (what is passed when set to `None`). + module_filter_func (`Callable`, *optional*, defaults to `filter_linear_layers`): + Optional function that must take in a module and layer name, and returns a boolean indicating whether the + module should be converted to FP8. Defaults to `filter_linear_layers`. See it for an example. + + Example: + + ```python + from accelerate.utils.ao import convert_model_to_fp8_ao + + model = MyModel() + model.to("cuda") + convert_to_float8_training(model) + + model.train() + ``` + """ + from torchao.float8 import convert_to_float8_training + + first_linear, last_linear = find_first_last_linear_layers(model) + if module_filter_func is None: + module_filter_func = partial(filter_linear_layers, layers_to_filter=[first_linear, last_linear]) + convert_to_float8_training(model, module_filter_fn=module_filter_func, config=config) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/bnb.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/bnb.py new file mode 100644 index 0000000000000000000000000000000000000000..5fbd46eb2f1a3cb07adb2ffb1f15e8f63f26fcff --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/bnb.py @@ -0,0 +1,469 @@ +# Copyright 2023 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import logging +import os +from copy import deepcopy +from typing import Optional, Union + +import torch +import torch.nn as nn + +from accelerate.utils.imports import ( + is_4bit_bnb_available, + is_8bit_bnb_available, +) + +from ..big_modeling import dispatch_model, init_empty_weights +from .dataclasses import BnbQuantizationConfig +from .modeling import ( + find_tied_parameters, + get_balanced_memory, + infer_auto_device_map, + load_checkpoint_in_model, + offload_weight, + set_module_tensor_to_device, +) + + +logger = logging.getLogger(__name__) + + +def load_and_quantize_model( + model: torch.nn.Module, + bnb_quantization_config: BnbQuantizationConfig, + weights_location: Optional[Union[str, os.PathLike]] = None, + device_map: Optional[dict[str, Union[int, str, torch.device]]] = None, + no_split_module_classes: Optional[list[str]] = None, + max_memory: Optional[dict[Union[int, str], Union[int, str]]] = None, + offload_folder: Optional[Union[str, os.PathLike]] = None, + offload_state_dict: bool = False, +): + """ + This function will quantize the input model with the associated config passed in `bnb_quantization_config`. If the + model is in the meta device, we will load and dispatch the weights according to the `device_map` passed. If the + model is already loaded, we will quantize the model and put the model on the GPU, + + Args: + model (`torch.nn.Module`): + Input model. The model can be already loaded or on the meta device + bnb_quantization_config (`BnbQuantizationConfig`): + The bitsandbytes quantization parameters + weights_location (`str` or `os.PathLike`): + The folder weights_location to load. It can be: + - a path to a file containing a whole model state dict + - a path to a `.json` file containing the index to a sharded checkpoint + - a path to a folder containing a unique `.index.json` file and the shards of a checkpoint. + - a path to a folder containing a unique pytorch_model.bin file. + device_map (`Dict[str, Union[int, str, torch.device]]`, *optional*): + A map that specifies where each submodule should go. It doesn't need to be refined to each parameter/buffer + name, once a given module name is inside, every submodule of it will be sent to the same device. + no_split_module_classes (`List[str]`, *optional*): + A list of layer class names that should never be split across device (for instance any layer that has a + residual connection). + max_memory (`Dict`, *optional*): + A dictionary device identifier to maximum memory. Will default to the maximum memory available if unset. + offload_folder (`str` or `os.PathLike`, *optional*): + If the `device_map` contains any value `"disk"`, the folder where we will offload weights. + offload_state_dict (`bool`, *optional*, defaults to `False`): + If `True`, will temporarily offload the CPU state dict on the hard drive to avoid getting out of CPU RAM if + the weight of the CPU state dict + the biggest shard does not fit. + + Returns: + `torch.nn.Module`: The quantized model + """ + + load_in_4bit = bnb_quantization_config.load_in_4bit + load_in_8bit = bnb_quantization_config.load_in_8bit + + if load_in_8bit and not is_8bit_bnb_available(): + raise ImportError( + "You have a version of `bitsandbytes` that is not compatible with 8bit quantization," + " make sure you have the latest version of `bitsandbytes` installed." + ) + if load_in_4bit and not is_4bit_bnb_available(): + raise ValueError( + "You have a version of `bitsandbytes` that is not compatible with 4bit quantization," + "make sure you have the latest version of `bitsandbytes` installed." + ) + + modules_on_cpu = [] + # custom device map + if isinstance(device_map, dict) and len(device_map.keys()) > 1: + modules_on_cpu = [key for key, value in device_map.items() if value in ["disk", "cpu"]] + + # We keep some modules such as the lm_head in their original dtype for numerical stability reasons + if bnb_quantization_config.skip_modules is None: + bnb_quantization_config.skip_modules = get_keys_to_not_convert(model) + + # add cpu modules to skip modules only for 4-bit modules + if load_in_4bit: + bnb_quantization_config.skip_modules.extend(modules_on_cpu) + modules_to_not_convert = bnb_quantization_config.skip_modules + + # We add the modules we want to keep in full precision + if bnb_quantization_config.keep_in_fp32_modules is None: + bnb_quantization_config.keep_in_fp32_modules = [] + keep_in_fp32_modules = bnb_quantization_config.keep_in_fp32_modules + modules_to_not_convert.extend(keep_in_fp32_modules) + + # compatibility with peft + model.is_loaded_in_4bit = load_in_4bit + model.is_loaded_in_8bit = load_in_8bit + + model_device = get_parameter_device(model) + if model_device.type != "meta": + # quantization of an already loaded model + logger.warning( + "It is not recommended to quantize a loaded model. " + "The model should be instantiated under the `init_empty_weights` context manager." + ) + model = replace_with_bnb_layers(model, bnb_quantization_config, modules_to_not_convert=modules_to_not_convert) + # convert param to the right dtype + dtype = bnb_quantization_config.torch_dtype + for name, param in model.state_dict().items(): + if any(module_to_keep_in_fp32 in name for module_to_keep_in_fp32 in keep_in_fp32_modules): + param.to(torch.float32) + if param.dtype != torch.float32: + name = name.replace(".weight", "").replace(".bias", "") + param = getattr(model, name, None) + if param is not None: + param.to(torch.float32) + elif torch.is_floating_point(param): + param.to(dtype) + if model_device.type == "cuda": + model.cuda(torch.cuda.current_device()) + torch.cuda.empty_cache() + elif torch.cuda.is_available(): + model.to(torch.cuda.current_device()) + elif torch.xpu.is_available(): + model.to(torch.xpu.current_device()) + else: + raise RuntimeError("No GPU or Intel XPU found. A GPU or Intel XPU is needed for quantization.") + logger.info( + f"The model device type is {model_device.type}. However, gpu or intel xpu is needed for quantization." + "We move the model to it." + ) + return model + + elif weights_location is None: + raise RuntimeError( + f"`weights_location` needs to be the folder path containing the weights of the model, but we found {weights_location} " + ) + + else: + with init_empty_weights(): + model = replace_with_bnb_layers( + model, bnb_quantization_config, modules_to_not_convert=modules_to_not_convert + ) + device_map = get_quantized_model_device_map( + model, + bnb_quantization_config, + device_map, + max_memory=max_memory, + no_split_module_classes=no_split_module_classes, + ) + if offload_state_dict is None and device_map is not None and "disk" in device_map.values(): + offload_state_dict = True + + offload = any(x in list(device_map.values()) for x in ["cpu", "disk"]) + + load_checkpoint_in_model( + model, + weights_location, + device_map, + dtype=bnb_quantization_config.torch_dtype, + offload_folder=offload_folder, + offload_state_dict=offload_state_dict, + keep_in_fp32_modules=bnb_quantization_config.keep_in_fp32_modules, + offload_8bit_bnb=load_in_8bit and offload, + ) + return dispatch_model(model, device_map=device_map, offload_dir=offload_folder) + + +def get_quantized_model_device_map( + model, bnb_quantization_config, device_map=None, max_memory=None, no_split_module_classes=None +): + if device_map is None: + if torch.cuda.is_available(): + device_map = {"": torch.cuda.current_device()} + elif torch.xpu.is_available(): + device_map = {"": torch.xpu.current_device()} + else: + raise RuntimeError("No GPU found. A GPU is needed for quantization.") + logger.info("The device_map was not initialized.Setting device_map to `{'':torch.cuda.current_device()}`.") + + if isinstance(device_map, str): + if device_map not in ["auto", "balanced", "balanced_low_0", "sequential"]: + raise ValueError( + "If passing a string for `device_map`, please choose 'auto', 'balanced', 'balanced_low_0' or " + "'sequential'." + ) + + special_dtypes = {} + special_dtypes.update( + { + name: bnb_quantization_config.torch_dtype + for name, _ in model.named_parameters() + if any(m in name for m in bnb_quantization_config.skip_modules) + } + ) + special_dtypes.update( + { + name: torch.float32 + for name, _ in model.named_parameters() + if any(m in name for m in bnb_quantization_config.keep_in_fp32_modules) + } + ) + + kwargs = {} + kwargs["special_dtypes"] = special_dtypes + kwargs["no_split_module_classes"] = no_split_module_classes + kwargs["dtype"] = bnb_quantization_config.target_dtype + + # get max_memory for each device. + if device_map != "sequential": + max_memory = get_balanced_memory( + model, + low_zero=(device_map == "balanced_low_0"), + max_memory=max_memory, + **kwargs, + ) + + kwargs["max_memory"] = max_memory + device_map = infer_auto_device_map(model, **kwargs) + + if isinstance(device_map, dict): + # check if don't have any quantized module on the cpu + modules_not_to_convert = bnb_quantization_config.skip_modules + bnb_quantization_config.keep_in_fp32_modules + + device_map_without_some_modules = { + key: device_map[key] for key in device_map.keys() if key not in modules_not_to_convert + } + for device in ["cpu", "disk"]: + if device in device_map_without_some_modules.values(): + if bnb_quantization_config.load_in_4bit: + raise ValueError( + """ + Some modules are dispatched on the CPU or the disk. Make sure you have enough GPU RAM to fit + the quantized model. If you want to dispatch the model on the CPU or the disk while keeping + these modules in `torch_dtype`, you need to pass a custom `device_map` to + `load_and_quantize_model`. Check + https://huggingface.co/docs/accelerate/main/en/usage_guides/quantization#offload-modules-to-cpu-and-disk + for more details. + """ + ) + else: + logger.info( + "Some modules are are offloaded to the CPU or the disk. Note that these modules will be converted to 8-bit" + ) + del device_map_without_some_modules + return device_map + + +def replace_with_bnb_layers(model, bnb_quantization_config, modules_to_not_convert=None, current_key_name=None): + """ + A helper function to replace all `torch.nn.Linear` modules by `bnb.nn.Linear8bit` modules or by `bnb.nn.Linear4bit` + modules from the `bitsandbytes`library. The function will be run recursively and replace `torch.nn.Linear` modules. + + Parameters: + model (`torch.nn.Module`): + Input model or `torch.nn.Module` as the function is run recursively. + modules_to_not_convert (`List[str]`): + Names of the modules to not quantize convert. In practice we keep the `lm_head` in full precision for + numerical stability reasons. + current_key_name (`List[str]`, *optional*): + An array to track the current key of the recursion. This is used to check whether the current key (part of + it) is not in the list of modules to not convert. + """ + + if modules_to_not_convert is None: + modules_to_not_convert = [] + + model, has_been_replaced = _replace_with_bnb_layers( + model, bnb_quantization_config, modules_to_not_convert, current_key_name + ) + if not has_been_replaced: + logger.warning( + "You are loading your model in 8bit or 4bit but no linear modules were found in your model." + " this can happen for some architectures such as gpt2 that uses Conv1D instead of Linear layers." + " Please double check your model architecture, or submit an issue on github if you think this is" + " a bug." + ) + return model + + +def _replace_with_bnb_layers( + model, + bnb_quantization_config, + modules_to_not_convert=None, + current_key_name=None, +): + """ + Private method that wraps the recursion for module replacement. + + Returns the converted model and a boolean that indicates if the conversion has been successful or not. + """ + # bitsandbytes will initialize CUDA on import, so it needs to be imported lazily + import bitsandbytes as bnb + + has_been_replaced = False + for name, module in model.named_children(): + if current_key_name is None: + current_key_name = [] + current_key_name.append(name) + if isinstance(module, nn.Linear) and name not in modules_to_not_convert: + # Check if the current key is not in the `modules_to_not_convert` + current_key_name_str = ".".join(current_key_name) + proceed = True + for key in modules_to_not_convert: + if ( + (key in current_key_name_str) and (key + "." in current_key_name_str) + ) or key == current_key_name_str: + proceed = False + break + if proceed: + # Load bnb module with empty weight and replace ``nn.Linear` module + if bnb_quantization_config.load_in_8bit: + bnb_module = bnb.nn.Linear8bitLt( + module.in_features, + module.out_features, + module.bias is not None, + has_fp16_weights=False, + threshold=bnb_quantization_config.llm_int8_threshold, + ) + elif bnb_quantization_config.load_in_4bit: + bnb_module = bnb.nn.Linear4bit( + module.in_features, + module.out_features, + module.bias is not None, + bnb_quantization_config.bnb_4bit_compute_dtype, + compress_statistics=bnb_quantization_config.bnb_4bit_use_double_quant, + quant_type=bnb_quantization_config.bnb_4bit_quant_type, + ) + else: + raise ValueError("load_in_8bit and load_in_4bit can't be both False") + bnb_module.weight.data = module.weight.data + if module.bias is not None: + bnb_module.bias.data = module.bias.data + bnb_module.requires_grad_(False) + setattr(model, name, bnb_module) + has_been_replaced = True + if len(list(module.children())) > 0: + _, _has_been_replaced = _replace_with_bnb_layers( + module, bnb_quantization_config, modules_to_not_convert, current_key_name + ) + has_been_replaced = has_been_replaced | _has_been_replaced + # Remove the last key for recursion + current_key_name.pop(-1) + return model, has_been_replaced + + +def get_keys_to_not_convert(model): + r""" + An utility function to get the key of the module to keep in full precision if any For example for CausalLM modules + we may want to keep the lm_head in full precision for numerical stability reasons. For other architectures, we want + to keep the tied weights of the model. The function will return a list of the keys of the modules to not convert in + int8. + + Parameters: + model (`torch.nn.Module`): + Input model + """ + # Create a copy of the model + with init_empty_weights(): + tied_model = deepcopy(model) # this has 0 cost since it is done inside `init_empty_weights` context manager` + + tied_params = find_tied_parameters(tied_model) + # For compatibility with Accelerate < 0.18 + if isinstance(tied_params, dict): + tied_keys = sum(list(tied_params.values()), []) + list(tied_params.keys()) + else: + tied_keys = sum(tied_params, []) + has_tied_params = len(tied_keys) > 0 + + # Check if it is a base model + is_base_model = False + if hasattr(model, "base_model_prefix"): + is_base_model = not hasattr(model, model.base_model_prefix) + + # Ignore this for base models (BertModel, GPT2Model, etc.) + if (not has_tied_params) and is_base_model: + return [] + + # otherwise they have an attached head + list_modules = list(model.named_children()) + list_last_module = [list_modules[-1][0]] + + # add last module together with tied weights + intersection = set(list_last_module) - set(tied_keys) + list_untouched = list(set(tied_keys)) + list(intersection) + + # remove ".weight" from the keys + names_to_remove = [".weight", ".bias"] + filtered_module_names = [] + for name in list_untouched: + for name_to_remove in names_to_remove: + if name_to_remove in name: + name = name.replace(name_to_remove, "") + filtered_module_names.append(name) + + return filtered_module_names + + +def has_4bit_bnb_layers(model): + """Check if we have `bnb.nn.Linear4bit` or `bnb.nn.Linear8bitLt` layers inside our model""" + # bitsandbytes will initialize CUDA on import, so it needs to be imported lazily + import bitsandbytes as bnb + + for m in model.modules(): + if isinstance(m, bnb.nn.Linear4bit): + return True + return False + + +def get_parameter_device(parameter: nn.Module): + return next(parameter.parameters()).device + + +def quantize_and_offload_8bit(model, param, param_name, new_dtype, offload_folder, offload_index, fp16_statistics): + # if it is not quantized, we quantize and offload the quantized weights and the SCB stats + if fp16_statistics is None: + set_module_tensor_to_device(model, param_name, 0, dtype=new_dtype, value=param) + tensor_name = param_name + module = model + if "." in tensor_name: + splits = tensor_name.split(".") + for split in splits[:-1]: + new_module = getattr(module, split) + if new_module is None: + raise ValueError(f"{module} has no attribute {split}.") + module = new_module + tensor_name = splits[-1] + # offload weights + module._parameters[tensor_name].requires_grad = False + offload_weight(module._parameters[tensor_name], param_name, offload_folder, index=offload_index) + if hasattr(module._parameters[tensor_name], "SCB"): + offload_weight( + module._parameters[tensor_name].SCB, + param_name.replace("weight", "SCB"), + offload_folder, + index=offload_index, + ) + else: + offload_weight(param, param_name, offload_folder, index=offload_index) + offload_weight(fp16_statistics, param_name.replace("weight", "SCB"), offload_folder, index=offload_index) + + set_module_tensor_to_device(model, param_name, "meta", dtype=new_dtype, value=torch.empty(*param.size())) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/constants.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/constants.py new file mode 100644 index 0000000000000000000000000000000000000000..10a381309f9aed121f8e17e1a7464aa58657a785 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/constants.py @@ -0,0 +1,106 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import operator as op + +import torch + + +SCALER_NAME = "scaler.pt" +MODEL_NAME = "pytorch_model" +SAFE_MODEL_NAME = "model" +RNG_STATE_NAME = "random_states" +OPTIMIZER_NAME = "optimizer" +SCHEDULER_NAME = "scheduler" +SAMPLER_NAME = "sampler" +PROFILE_PATTERN_NAME = "profile_{suffix}.json" +WEIGHTS_NAME = f"{MODEL_NAME}.bin" +WEIGHTS_PATTERN_NAME = "pytorch_model{suffix}.bin" +WEIGHTS_INDEX_NAME = f"{WEIGHTS_NAME}.index.json" +SAFE_WEIGHTS_NAME = f"{SAFE_MODEL_NAME}.safetensors" +SAFE_WEIGHTS_PATTERN_NAME = "model{suffix}.safetensors" +SAFE_WEIGHTS_INDEX_NAME = f"{SAFE_WEIGHTS_NAME}.index.json" +SAGEMAKER_PYTORCH_VERSION = "1.10.2" +SAGEMAKER_PYTHON_VERSION = "py38" +SAGEMAKER_TRANSFORMERS_VERSION = "4.17.0" +SAGEMAKER_PARALLEL_EC2_INSTANCES = ["ml.p3.16xlarge", "ml.p3dn.24xlarge", "ml.p4dn.24xlarge"] +FSDP_SHARDING_STRATEGY = ["FULL_SHARD", "SHARD_GRAD_OP", "NO_SHARD", "HYBRID_SHARD", "HYBRID_SHARD_ZERO2"] +FSDP_AUTO_WRAP_POLICY = ["TRANSFORMER_BASED_WRAP", "SIZE_BASED_WRAP", "NO_WRAP"] +FSDP_BACKWARD_PREFETCH = ["BACKWARD_PRE", "BACKWARD_POST", "NO_PREFETCH"] +FSDP_STATE_DICT_TYPE = ["FULL_STATE_DICT", "LOCAL_STATE_DICT", "SHARDED_STATE_DICT"] +FSDP2_STATE_DICT_TYPE = ["SHARDED_STATE_DICT", "FULL_STATE_DICT"] +FSDP_PYTORCH_VERSION = ( + "2.1.0.a0+32f93b1" # Technically should be 2.1.0, but MS-AMP uses this specific prerelease in their Docker image. +) +FSDP2_PYTORCH_VERSION = "2.6.0" +FSDP_MODEL_NAME = "pytorch_model_fsdp" +DEEPSPEED_MULTINODE_LAUNCHERS = ["pdsh", "standard", "openmpi", "mvapich", "mpich", "nossh", "slurm"] +TORCH_DYNAMO_MODES = ["default", "reduce-overhead", "max-autotune"] +ELASTIC_LOG_LINE_PREFIX_TEMPLATE_PYTORCH_VERSION = "2.2.0" +XPU_PROFILING_AVAILABLE_PYTORCH_VERSION = "2.4.0" +MITA_PROFILING_AVAILABLE_PYTORCH_VERSION = "2.1.0" +BETA_TP_AVAILABLE_PYTORCH_VERSION = "2.3.0" + +BETA_TP_AVAILABLE_TRANSFORMERS_VERSION = "4.52.0" +BETA_CP_AVAILABLE_PYTORCH_VERSION = "2.6.0" +BETA_SP_AVAILABLE_DEEPSPEED_VERSION = "0.18.2" + +STR_OPERATION_TO_FUNC = {">": op.gt, ">=": op.ge, "==": op.eq, "!=": op.ne, "<=": op.le, "<": op.lt} + +# These are the args for `torch.distributed.launch` for pytorch < 1.9 +TORCH_LAUNCH_PARAMS = [ + "nnodes", + "nproc_per_node", + "rdzv_backend", + "rdzv_endpoint", + "rdzv_id", + "rdzv_conf", + "standalone", + "max_restarts", + "monitor_interval", + "start_method", + "role", + "module", + "m", + "no_python", + "run_path", + "log_dir", + "r", + "redirects", + "t", + "tee", + "node_rank", + "master_addr", + "master_port", +] + +CUDA_DISTRIBUTED_TYPES = ["DEEPSPEED", "MULTI_GPU", "FSDP", "MEGATRON_LM", "TP"] +TORCH_DISTRIBUTED_OPERATION_TYPES = CUDA_DISTRIBUTED_TYPES + [ + "MULTI_NPU", + "MULTI_MLU", + "MULTI_SDAA", + "MULTI_MUSA", + "MULTI_XPU", + "MULTI_CPU", + "MULTI_HPU", +] +SUPPORTED_PYTORCH_LAYERS_FOR_UPCASTING = ( + torch.nn.Conv1d, + torch.nn.Conv2d, + torch.nn.Conv3d, + torch.nn.ConvTranspose1d, + torch.nn.ConvTranspose2d, + torch.nn.ConvTranspose3d, + torch.nn.Linear, +) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/dataclasses.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/dataclasses.py new file mode 100644 index 0000000000000000000000000000000000000000..b226c25d312fe18022714dcd9af8ac7a90ab2775 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/dataclasses.py @@ -0,0 +1,2985 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +General namespace and dataclass related classes +""" + +import argparse +import copy +import enum +import functools +import logging +import os +import warnings +from collections.abc import Iterable +from contextlib import contextmanager +from dataclasses import dataclass, field +from datetime import timedelta +from typing import TYPE_CHECKING, Any, Callable, Literal, Optional, Union, get_args + +import torch + +from .constants import ( + BETA_CP_AVAILABLE_PYTORCH_VERSION, + BETA_TP_AVAILABLE_PYTORCH_VERSION, + BETA_TP_AVAILABLE_TRANSFORMERS_VERSION, + FSDP2_PYTORCH_VERSION, + FSDP_AUTO_WRAP_POLICY, + FSDP_BACKWARD_PREFETCH, + FSDP_SHARDING_STRATEGY, + MITA_PROFILING_AVAILABLE_PYTORCH_VERSION, + XPU_PROFILING_AVAILABLE_PYTORCH_VERSION, +) +from .environment import parse_flag_from_env, str_to_bool +from .imports import ( + is_cuda_available, + is_hpu_available, + is_mlu_available, + is_msamp_available, + is_musa_available, + is_npu_available, + is_transformer_engine_available, + is_xpu_available, +) +from .versions import compare_versions, is_torch_version + + +if TYPE_CHECKING: + # Mock imports for type checking + from torchao.float8 import Float8LinearConfig + + +logger = logging.getLogger(__name__) + + +class KwargsHandler: + """ + Internal mixin that implements a `to_kwargs()` method for a dataclass. + """ + + def to_dict(self): + return copy.deepcopy(self.__dict__) + + def to_kwargs(self): + """ + Returns a dictionary containing the attributes with values different from the default of this class. + """ + # import clear_environment here to avoid circular import problem + from .environment import clear_environment + + with clear_environment(): + default_dict = self.__class__().to_dict() + this_dict = self.to_dict() + return {k: v for k, v in this_dict.items() if default_dict[k] != v} + + +class EnumWithContains(enum.EnumMeta): + "A metaclass that adds the ability to check if `self` contains an item with the `in` operator" + + def __contains__(cls, item): + try: + cls(item) + except ValueError: + return False + return True + + +class BaseEnum(enum.Enum, metaclass=EnumWithContains): + "An enum class that can get the value of an item with `str(Enum.key)`" + + def __str__(self): + return self.value + + @classmethod + def list(cls): + "Method to list all the possible items in `cls`" + return list(map(str, cls)) + + +@dataclass +class AutocastKwargs(KwargsHandler): + """ + Use this object in your [`Accelerator`] to customize how `torch.autocast` behaves. Please refer to the + documentation of this [context manager](https://pytorch.org/docs/stable/amp.html#torch.autocast) for more + information on each argument. + + Example: + + ```python + from accelerate import Accelerator + from accelerate.utils import AutocastKwargs + + kwargs = AutocastKwargs(cache_enabled=True) + accelerator = Accelerator(kwargs_handlers=[kwargs]) + ``` + """ + + enabled: bool = True + cache_enabled: Optional[bool] = None + + +class DDPCommunicationHookType(BaseEnum): + """ + Represents a type of communication hook used in DDP. + + Values: + + - **NO** -- no communication hook + - **FP16** -- DDP communication hook to compress the gradients in FP16 + - **BF16** -- DDP communication hook to compress the gradients in BF16 + - **POWER_SGD** -- DDP communication hook to use PowerSGD + - **BATCHED_POWER_SGD** -- DDP communication hook to use batched PowerSGD + """ + + NO = "no" + FP16 = "fp16" + BF16 = "bf16" + POWER_SGD = "power_sgd" + BATCHED_POWER_SGD = "batched_power_sgd" + + +@dataclass +class DistributedDataParallelKwargs(KwargsHandler): + """ + Use this object in your [`Accelerator`] to customize how your model is wrapped in a + `torch.nn.parallel.DistributedDataParallel`. Please refer to the documentation of this + [wrapper](https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html) for more + information on each argument. + + + + `gradient_as_bucket_view` is only available in PyTorch 1.7.0 and later versions. + + `static_graph` is only available in PyTorch 1.11.0 and later versions. + + + + Example: + + ```python + from accelerate import Accelerator + from accelerate.utils import DistributedDataParallelKwargs + + kwargs = DistributedDataParallelKwargs(find_unused_parameters=True) + accelerator = Accelerator(kwargs_handlers=[kwargs]) + ``` + """ + + dim: int = 0 + broadcast_buffers: bool = True + bucket_cap_mb: int = 25 + find_unused_parameters: bool = False + check_reduction: bool = False + gradient_as_bucket_view: bool = False + static_graph: bool = False + + comm_hook: DDPCommunicationHookType = DDPCommunicationHookType.NO + comm_wrapper: Literal[ + DDPCommunicationHookType.NO, + DDPCommunicationHookType.FP16, + DDPCommunicationHookType.BF16, + ] = DDPCommunicationHookType.NO + comm_state_option: dict = field(default_factory=dict) + + def to_dict(self, ignore_keys=("comm_hook", "comm_wrapper", "comm_state_option")): + return {k: v for k, v in super().to_dict().items() if k not in ignore_keys} + + def register_comm_hook(self, model): + from torch.distributed.algorithms.ddp_comm_hooks import ( + default_hooks, + powerSGD_hook, + ) + + hook_map: dict[DDPCommunicationHookType, Callable] = { + DDPCommunicationHookType.FP16: default_hooks.fp16_compress_hook, + DDPCommunicationHookType.BF16: default_hooks.bf16_compress_hook, + DDPCommunicationHookType.POWER_SGD: powerSGD_hook.powerSGD_hook, + DDPCommunicationHookType.BATCHED_POWER_SGD: powerSGD_hook.batched_powerSGD_hook, + } + + wrapper_map: dict[DDPCommunicationHookType, Callable] = { + DDPCommunicationHookType.FP16: default_hooks.fp16_compress_wrapper, + DDPCommunicationHookType.BF16: default_hooks.bf16_compress_wrapper, + } + + hook: Optional[Callable] = hook_map.get(self.comm_hook) + wrapper: Optional[Callable] = wrapper_map.get(self.comm_wrapper) + + if hook and wrapper: + hook = wrapper(hook) + + if hook: + state = ( + powerSGD_hook.PowerSGDState(None, **self.comm_state_option) + if self.comm_hook + in ( + DDPCommunicationHookType.POWER_SGD, + DDPCommunicationHookType.BATCHED_POWER_SGD, + ) + else None + ) + model.register_comm_hook( + state=state, + hook=hook, + ) + + +@dataclass +class GradScalerKwargs(KwargsHandler): + """ + Use this object in your [`Accelerator`] to customize the behavior of mixed precision, specifically how the + `torch.amp.GradScaler` or `torch.cuda.amp.GradScaler` used is created. Please refer to the documentation of this + [scaler](https://pytorch.org/docs/stable/amp.html?highlight=gradscaler) for more information on each argument. + + + + `torch.cuda.amp.GradScaler` is only available in PyTorch 1.5.0 and later versions, and `torch.amp.GradScaler` is + only available in PyTorch 2.4.0 and later versions. + + + + Example: + + ```python + from accelerate import Accelerator + from accelerate.utils import GradScalerKwargs + + kwargs = GradScalerKwargs(backoff_factor=0.25) + accelerator = Accelerator(kwargs_handlers=[kwargs]) + ``` + """ + + init_scale: float = 65536.0 + growth_factor: float = 2.0 + backoff_factor: float = 0.5 + growth_interval: int = 2000 + enabled: bool = True + + +@dataclass +class InitProcessGroupKwargs(KwargsHandler): + """ + Use this object in your [`Accelerator`] to customize the initialization of the distributed processes. Please refer + to the documentation of this + [method](https://pytorch.org/docs/stable/distributed.html#torch.distributed.init_process_group) for more + information on each argument. + + Note: If `timeout` is set to `None`, the default will be based upon how `backend` is set. + + ```python + from datetime import timedelta + from accelerate import Accelerator + from accelerate.utils import InitProcessGroupKwargs + + kwargs = InitProcessGroupKwargs(timeout=timedelta(seconds=800)) + accelerator = Accelerator(kwargs_handlers=[kwargs]) + ``` + """ + + backend: Optional[str] = "nccl" + init_method: Optional[str] = None + timeout: Optional[timedelta] = None + + def __post_init__(self): + if self.timeout is None: + seconds = 1800 if self.backend != "nccl" else 600 + self.timeout = timedelta(seconds=seconds) + + +# Literals +Backend = Literal["MSAMP", "TE"] +OptLevel = Literal["O1", "O2"] +FP8Format = Literal["HYBRID", "E4M3", "E5M2"] +AmaxComputeAlgorithm = Literal["max", "most_recent"] + + +# FP8 training recipe kwargs +@dataclass +class AORecipeKwargs(KwargsHandler): + """ + Use this object in your [`Accelerator`] to customize the initialization of the recipe for FP8 mixed precision + training with `torchao` FP8. + + Args: + config (`torchao.float8.Float8LinearConfig`, *optional*, default to `None`): + The configuration for the FP8 training. In general, the default config should be sufficient. + module_filter_func (`Callable`, *optional*, default to `None`): + Optional function that must take in a module and layer name, and returns a boolean indicating whether the + module should be converted to FP8. Defaults to `accelerate.utils.ao.filter_linear_layers`. See it for an + example. + """ + + config: Optional["Float8LinearConfig"] = None + module_filter_func: Optional[Callable] = None + + +@dataclass +class TERecipeKwargs(KwargsHandler): + """ + Use this object in your [`Accelerator`] to customize the initialization of the recipe for FP8 mixed precision + training with `transformer-engine`. + + + + For more information on the args, please refer to the API + [documentation](https://docs.nvidia.com/deeplearning/transformer-engine/user-guide/api/common.html). + + + + ```python + from accelerate import Accelerator + from accelerate.utils import TERecipeKwargs + + kwargs = TERecipeKwargs(fp8_format="HYBRID") + accelerator = Accelerator(mixed_precision="fp8", kwargs_handlers=[kwargs]) + ``` + + Args: + use_autocast_during_eval (`bool`, *optional*, default to `False`): + Whether to use FP8 autocast during eval mode. Generally better metrics are found when this is `False`. + margin (`int`, *optional*, default to 0): + The margin to use for the gradient scaling. + interval (`int`, *optional*, default to 1): + The interval to use for how often the scaling factor is recomputed. + fp8_format (`str`, *optional*, default to "HYBRID"): + The format to use for the FP8 recipe. Must be one of `HYBRID`, `E4M3` or `E5M2`. (Generally `HYBRID` for + training, `E4M3` or `E5M2` for evaluation) + amax_history_len (`int`, *optional*, default to 1024): + The length of the history to use for the scaling factor computation + amax_compute_algo (`str`, *optional*, default to "most_recent"): + The algorithm to use for the scaling factor computation. Must be one of `max` or `most_recent`. + override_linear_precision (`tuple` of three `bool`, *optional*, default to `(False, False, False)`): + Whether or not to execute `fprop`, `dgrad`, and `wgrad` GEMMS in higher precision. + """ + + use_autocast_during_eval: Optional[bool] = None + margin: Optional[int] = None + interval: Optional[int] = None + fp8_format: FP8Format = None + amax_history_len: Optional[int] = None + amax_compute_algo: AmaxComputeAlgorithm = None + override_linear_precision: tuple[bool, bool, bool] = None + use_mxfp8_block_scaling: Optional[bool] = None + + def __post_init__(self): + env_prefix = "ACCELERATE_FP8_" + if not is_transformer_engine_available(): + raise ImportError("TransformerEngine is not available. Please install it or use a different backend.") + if self.use_autocast_during_eval is None: + self.use_autocast_during_eval = parse_flag_from_env(env_prefix + "USE_AUTOCAST_DURING_EVAL") + if self.margin is None: + self.margin = int(os.environ.get(env_prefix + "MARGIN", 0)) + if self.interval is None: + self.interval = int(os.environ.get(env_prefix + "INTERVAL", 1)) + if self.fp8_format is None: + self.fp8_format = os.environ.get(env_prefix + "FORMAT", "HYBRID") + self.fp8_format = self.fp8_format.upper() + if self.fp8_format not in get_args(FP8Format): + raise ValueError(f"`fp8_format` must be one of {' or '.join(get_args(FP8Format))}.") + if self.amax_compute_algo is None: + self.amax_compute_algo = os.environ.get(env_prefix + "AMAX_COMPUTE_ALGO", "most_recent") + self.amax_compute_algo = self.amax_compute_algo.lower() + if self.amax_compute_algo not in get_args(AmaxComputeAlgorithm): + raise ValueError(f"`amax_compute_algo` must be one of {' or '.join(get_args(AmaxComputeAlgorithm))}") + if self.amax_history_len is None: + self.amax_history_len = int(os.environ.get(env_prefix + "AMAX_HISTORY_LEN", 1024)) + if self.override_linear_precision is None: + fprop = parse_flag_from_env(env_prefix + "OVERRIDE_FPROP") + dgrad = parse_flag_from_env(env_prefix + "OVERRIDE_DGRAD") + wgrad = parse_flag_from_env(env_prefix + "OVERRIDE_WGRAD") + self.override_linear_precision = (fprop, dgrad, wgrad) + if self.use_mxfp8_block_scaling is None: + self.use_mxfp8_block_scaling = parse_flag_from_env(env_prefix + "USE_MXFP8_BLOCK_SCALING") + + +@dataclass +class MSAMPRecipeKwargs(KwargsHandler): + """ + Use this object in your [`Accelerator`] to customize the initialization of the recipe for FP8 mixed precision + training with `ms-amp`. + """ + + opt_level: OptLevel = None + + def __post_init__(self): + env_prefix = "ACCELERATE_FP8_" + if self.opt_level is None: + self.opt_level = os.environ.get(env_prefix + "OPT_LEVEL", "O2") + if self.opt_level not in get_args(OptLevel): + raise ValueError(f"`opt_level` must be one of {' or '.join(get_args(OptLevel))}") + + +@dataclass +class FP8RecipeKwargs(TERecipeKwargs, MSAMPRecipeKwargs): + """ + Deprecated. Please use one of the proper FP8 recipe kwargs classes such as `TERecipeKwargs` or `MSAMPRecipeKwargs` + instead. + """ + + backend: Backend = None + + def __post_init__(self): + env_prefix = "ACCELERATE_FP8_" + warnings.warn( + "FP8RecipeKwargs is deprecated and will be removed in Accelerate v2.0.0. " + "Please use one of the proper FP8 recipe kwargs classes such as TERecipeKwargs or MSAMPRecipeKwargs instead.", + FutureWarning, + ) + default_backend = "msamp" if is_msamp_available() else "te" + if self.backend is None: + self.backend = os.environ.get(env_prefix + "BACKEND", default_backend) + self.backend = self.backend.upper() + if self.backend not in get_args(Backend): + raise ValueError("`backend` must be 'MSAMP' or 'TE' (TransformerEngine) to use `FP8RecipeKwargs`.") + super().__post_init__() + + +# Literal +ProfilerActivity = Literal["cpu", "xpu", "mtia", "cuda", "hpu"] + + +@dataclass +class ProfileKwargs(KwargsHandler): + """ + Use this object in your [`Accelerator`] to customize the initialization of the profiler. Please refer to the + documentation of this [context manager](https://pytorch.org/docs/stable/profiler.html#torch.profiler.profile) for + more information on each argument. + + + + `torch.profiler` is only available in PyTorch 1.8.1 and later versions. + + + + Example: + + ```python + from accelerate import Accelerator + from accelerate.utils import ProfileKwargs + + kwargs = ProfileKwargs(activities=["cpu", "cuda"]) + accelerator = Accelerator(kwargs_handlers=[kwargs]) + ``` + + Args: + activities (`List[str]`, *optional*, default to `None`): + The list of activity groups to use in profiling. Must be one of `"cpu"`, `"xpu"`, `"mtia"`, "hpu" or + `"cuda"`. + schedule_option (`Dict[str, int]`, *optional*, default to `None`): + The schedule option to use for the profiler. Available keys are `wait`, `warmup`, `active`, `repeat` and + `skip_first`. The profiler will skip the first `skip_first` steps, then wait for `wait` steps, then do the + warmup for the next `warmup` steps, then do the active recording for the next `active` steps and then + repeat the cycle starting with `wait` steps. The optional number of cycles is specified with the `repeat` + parameter, the zero value means that the cycles will continue until the profiling is finished. + on_trace_ready (`Callable`, *optional*, default to `None`): + Callable that is called at each step when schedule returns `ProfilerAction.RECORD_AND_SAVE` during the + profiling. + record_shapes (`bool`, *optional*, default to `False`): + Save information about operator’s input shapes. + profile_memory (`bool`, *optional*, default to `False`): + Track tensor memory allocation/deallocation + with_stack (`bool`, *optional*, default to `False`): + Record source information (file and line number) for the ops. + with_flops (`bool`, *optional*, default to `False`): + Use formula to estimate the FLOPS of specific operators + with_modules (`bool`, *optional*, default to `False`): + Record module hierarchy (including function names) corresponding to the callstack of the op. + output_trace_dir (`str`, *optional*, default to `None`): + Exports the collected trace in Chrome JSON format. Chrome use 'chrome://tracing' view json file. Defaults + to None, which means profiling does not store json files. + """ + + activities: Optional[list[ProfilerActivity]] = None + schedule_option: Optional[dict[str, int]] = None + on_trace_ready: Optional[Callable] = None + record_shapes: bool = False + profile_memory: bool = False + with_stack: bool = False + with_flops: bool = False + with_modules: bool = False + output_trace_dir: Optional[str] = None + + def _get_profiler_activity(self, activity: ProfilerActivity) -> torch.profiler.ProfilerActivity: + """Get the profiler activity from the string. + + Args: + activity (str): The profiler activity name. + + Returns: + torch.profiler.ProfilerActivity: The profiler activity. + """ + + profiler_activity_map: dict[str, torch.profiler.ProfilerActivity] = { + "cpu": torch.profiler.ProfilerActivity.CPU, + "cuda": torch.profiler.ProfilerActivity.CUDA, + } + + if is_hpu_available(): + profiler_activity_map["hpu"] = torch.profiler.ProfilerActivity.HPU + + if is_torch_version(">=", XPU_PROFILING_AVAILABLE_PYTORCH_VERSION): + if torch.xpu.is_available(): + profiler_activity_map["xpu"] = torch.profiler.ProfilerActivity.XPU + + if is_torch_version(">=", MITA_PROFILING_AVAILABLE_PYTORCH_VERSION): + if torch.mtia.is_available(): + profiler_activity_map["mtia"] = torch.profiler.ProfilerActivity.MTIA + + if activity not in profiler_activity_map: + raise ValueError(f"Invalid profiler activity: {activity}. Must be one of {list(profiler_activity_map)}.") + return profiler_activity_map[activity] + + def build(self) -> torch.profiler.profile: + """ + Build a profiler object with the current configuration. + + Returns: + torch.profiler.profile: The profiler object. + """ + activities: Optional[list[ProfilerActivity]] = None + if self.activities is not None: + activities = [self._get_profiler_activity(activity) for activity in self.activities] + schedule: Optional[torch.profiler.schedule] = None + if self.schedule_option is not None: + schedule = torch.profiler.schedule(**self.schedule_option) + + return torch.profiler.profile( + activities=activities, + schedule=schedule, + on_trace_ready=self.on_trace_ready, + record_shapes=self.record_shapes, + profile_memory=self.profile_memory, + with_stack=self.with_stack, + with_flops=self.with_flops, + with_modules=self.with_modules, + ) + + +class DistributedType(str, enum.Enum): + """ + Represents a type of distributed environment. + + Values: + + - **NO** -- Not a distributed environment, just a single process. + - **MULTI_CPU** -- Distributed on multiple CPU nodes. + - **MULTI_GPU** -- Distributed on multiple GPUs. + - **MULTI_MLU** -- Distributed on multiple MLUs. + - **MULTI_SDAA** -- Distributed on multiple SDAAs. + - **MULTI_MUSA** -- Distributed on multiple MUSAs. + - **MULTI_NPU** -- Distributed on multiple NPUs. + - **MULTI_XPU** -- Distributed on multiple XPUs. + - **MULTI_HPU** -- Distributed on multiple HPUs. + - **DEEPSPEED** -- Using DeepSpeed. + - **XLA** -- Using TorchXLA. + """ + + # Subclassing str as well as Enum allows the `DistributedType` to be JSON-serializable out of the box. + NO = "NO" + MULTI_CPU = "MULTI_CPU" + MULTI_GPU = "MULTI_GPU" + MULTI_NPU = "MULTI_NPU" + MULTI_MLU = "MULTI_MLU" + MULTI_SDAA = "MULTI_SDAA" + MULTI_MUSA = "MULTI_MUSA" + MULTI_XPU = "MULTI_XPU" + DEEPSPEED = "DEEPSPEED" + FSDP = "FSDP" + XLA = "XLA" + MEGATRON_LM = "MEGATRON_LM" + MULTI_HPU = "MULTI_HPU" + + +class SageMakerDistributedType(str, enum.Enum): + """ + Represents a type of distributed environment. + + Values: + + - **NO** -- Not a distributed environment, just a single process. + - **DATA_PARALLEL** -- using sagemaker distributed data parallelism. + - **MODEL_PARALLEL** -- using sagemaker distributed model parallelism. + """ + + # Subclassing str as well as Enum allows the `SageMakerDistributedType` to be JSON-serializable out of the box. + NO = "NO" + DATA_PARALLEL = "DATA_PARALLEL" + MODEL_PARALLEL = "MODEL_PARALLEL" + + +class FP8BackendType(str, enum.Enum): + """ + Represents the backend used for FP8. + + Values: + + - **TE** -- using TransformerEngine. + - **MSAMP** -- using msamp. + """ + + # Subclassing str as well as Enum allows the `FP8BackendType` to be JSON-serializable out of the box. + NO = "NO" + TE = "TE" + MSAMP = "MSAMP" + AO = "AO" + + +class ComputeEnvironment(str, enum.Enum): + """ + Represents a type of the compute environment. + + Values: + + - **LOCAL_MACHINE** -- private/custom cluster hardware. + - **AMAZON_SAGEMAKER** -- Amazon SageMaker as compute environment. + """ + + # Subclassing str as well as Enum allows the `ComputeEnvironment` to be JSON-serializable out of the box. + LOCAL_MACHINE = "LOCAL_MACHINE" + AMAZON_SAGEMAKER = "AMAZON_SAGEMAKER" + + +class DynamoBackend(str, BaseEnum): + """ + Represents a dynamo backend (see https://pytorch.org/docs/stable/torch.compiler.html). + + Values: + + - **NO** -- Do not use torch dynamo. + - **EAGER** -- Uses PyTorch to run the extracted GraphModule. This is quite useful in debugging TorchDynamo + issues. + - **AOT_EAGER** -- Uses AotAutograd with no compiler, i.e, just using PyTorch eager for the AotAutograd's + extracted forward and backward graphs. This is useful for debugging, and unlikely to give speedups. + - **INDUCTOR** -- Uses TorchInductor backend with AotAutograd and cudagraphs by leveraging codegened Triton + kernels. [Read + more](https://dev-discuss.pytorch.org/t/torchinductor-a-pytorch-native-compiler-with-define-by-run-ir-and-symbolic-shapes/747) + - **AOT_TS_NVFUSER** -- nvFuser with AotAutograd/TorchScript. [Read + more](https://dev-discuss.pytorch.org/t/tracing-with-primitives-update-1-nvfuser-and-its-primitives/593) + - **NVPRIMS_NVFUSER** -- nvFuser with PrimTorch. [Read + more](https://dev-discuss.pytorch.org/t/tracing-with-primitives-update-1-nvfuser-and-its-primitives/593) + - **CUDAGRAPHS** -- cudagraphs with AotAutograd. [Read more](https://github.com/pytorch/torchdynamo/pull/757) + - **OFI** -- Uses Torchscript optimize_for_inference. Inference only. [Read + more](https://pytorch.org/docs/stable/generated/torch.jit.optimize_for_inference.html) + - **FX2TRT** -- Uses Nvidia TensorRT for inference optimizations. Inference only. [Read + more](https://github.com/pytorch/TensorRT/blob/master/docsrc/tutorials/getting_started_with_fx_path.rst) + - **ONNXRT** -- Uses ONNXRT for inference on CPU/GPU. Inference only. [Read more](https://onnxruntime.ai/) + - **TENSORRT** -- Uses ONNXRT to run TensorRT for inference optimizations. [Read + more](https://github.com/onnx/onnx-tensorrt) + - **AOT_TORCHXLA_TRACE_ONCE** -- Uses Pytorch/XLA with TorchDynamo optimization, for training. [Read + more](https://github.com/pytorch/xla/blob/r2.0/docs/dynamo.md) + - **TORCHXLA_TRACE_ONCE** -- Uses Pytorch/XLA with TorchDynamo optimization, for inference. [Read + more](https://github.com/pytorch/xla/blob/r2.0/docs/dynamo.md) + - **IPEX** -- Uses IPEX for inference on CPU. Inference only. [Read + more](https://github.com/intel/intel-extension-for-pytorch). + - **TVM** -- Uses Apache TVM for inference optimizations. [Read more](https://tvm.apache.org/) + - **HPU_BACKEND** -- Uses HPU backend for inference optimizations. + + """ + + # Subclassing str as well as Enum allows the `SageMakerDistributedType` to be JSON-serializable out of the box. + NO = "NO" + EAGER = "EAGER" + AOT_EAGER = "AOT_EAGER" + INDUCTOR = "INDUCTOR" + AOT_TS_NVFUSER = "AOT_TS_NVFUSER" + NVPRIMS_NVFUSER = "NVPRIMS_NVFUSER" + CUDAGRAPHS = "CUDAGRAPHS" + OFI = "OFI" + FX2TRT = "FX2TRT" + ONNXRT = "ONNXRT" + TENSORRT = "TENSORRT" + AOT_TORCHXLA_TRACE_ONCE = "AOT_TORCHXLA_TRACE_ONCE" + TORCHXLA_TRACE_ONCE = "TORCHXLA_TRACE_ONCE" + IPEX = "IPEX" + TVM = "TVM" + HPU_BACKEND = "HPU_BACKEND" + + +class LoggerType(BaseEnum): + """Represents a type of supported experiment tracker + + Values: + + - **ALL** -- all available trackers in the environment that are supported + - **TENSORBOARD** -- TensorBoard as an experiment tracker + - **WANDB** -- wandb as an experiment tracker + - **TRACKIO** -- trackio as an experiment tracker + - **COMETML** -- comet_ml as an experiment tracker + - **MLFLOW** -- mlflow as an experiment tracker + - **CLEARML** -- clearml as an experiment tracker + - **DVCLIVE** -- dvclive as an experiment tracker + - **SWANLAB** -- swanlab as an experiment tracker + """ + + ALL = "all" + AIM = "aim" + TENSORBOARD = "tensorboard" + WANDB = "wandb" + TRACKIO = "trackio" + COMETML = "comet_ml" + MLFLOW = "mlflow" + CLEARML = "clearml" + DVCLIVE = "dvclive" + SWANLAB = "swanlab" + + +class PrecisionType(str, BaseEnum): + """Represents a type of precision used on floating point values + + Values: + + - **NO** -- using full precision (FP32) + - **FP16** -- using half precision + - **BF16** -- using brain floating point precision + """ + + NO = "no" + FP8 = "fp8" + FP16 = "fp16" + BF16 = "bf16" + + +class RNGType(BaseEnum): + TORCH = "torch" + CUDA = "cuda" + MLU = "mlu" + SDAA = "sdaa" + MUSA = "musa" + NPU = "npu" + XLA = "xla" + XPU = "xpu" + HPU = "hpu" + GENERATOR = "generator" + + +class CustomDtype(enum.Enum): + r""" + An enum that contains multiple custom dtypes that can be used for `infer_auto_device_map`. + """ + + FP8 = "fp8" + INT4 = "int4" + INT2 = "int2" + + +# data classes + + +@dataclass +class TensorInformation: + shape: torch.Size + dtype: torch.dtype + + +@dataclass +class DataLoaderConfiguration: + """ + Configuration for dataloader-related items when calling `accelerator.prepare`. + + Args: + split_batches (`bool`, defaults to `False`): + Whether or not the accelerator should split the batches yielded by the dataloaders across the devices. If + `True`, the actual batch size used will be the same on any kind of distributed processes, but it must be a + round multiple of `num_processes` you are using. If `False`, actual batch size used will be the one set in + your script multiplied by the number of processes. + dispatch_batches (`bool`, defaults to `None`): + If set to `True`, the dataloader prepared by the Accelerator is only iterated through on the main process + and then the batches are split and broadcast to each process. Will default to `True` for `DataLoader` whose + underlying dataset is an `IterableDataset`, `False` otherwise. + even_batches (`bool`, defaults to `True`): + If set to `True`, in cases where the total batch size across all processes does not exactly divide the + dataset, samples at the start of the dataset will be duplicated so the batch can be divided equally among + all workers. + use_seedable_sampler (`bool`, defaults to `False`): + Whether or not use a fully seedable random sampler ([`data_loader.SeedableRandomSampler`]). Ensures + training results are fully reproducible using a different sampling technique. While seed-to-seed results + may differ, on average the differences are negligible when using multiple different seeds to compare. + Should also be ran with [`~utils.set_seed`] for the best results. + data_seed (`int`, defaults to `None`): + The seed to use for the underlying generator when using `use_seedable_sampler`. If `None`, the generator + will use the current default seed from torch. + non_blocking (`bool`, defaults to `False`): + If set to `True`, the dataloader prepared by the Accelerator will utilize non-blocking host-to-device + transfers, allowing for better overlap between dataloader communication and computation. Recommended that + the prepared dataloader has `pin_memory` set to `True` to work properly. + use_stateful_dataloader (`bool`, defaults to `False`): + If set to `True`, the dataloader prepared by the Accelerator will be backed by + [torchdata.StatefulDataLoader](https://github.com/pytorch/data/tree/main/torchdata/stateful_dataloader). + This requires `torchdata` version 0.8.0 or higher that supports StatefulDataLoader to be installed. + """ + + split_batches: bool = field( + default=False, + metadata={ + "help": "Whether or not the accelerator should split the batches yielded by the dataloaders across the devices. If" + " `True` the actual batch size used will be the same on any kind of distributed processes, but it must be a" + " round multiple of the `num_processes` you are using. If `False`, actual batch size used will be the one set" + " in your script multiplied by the number of processes." + }, + ) + dispatch_batches: bool = field( + default=None, + metadata={ + "help": "If set to `True`, the dataloader prepared by the Accelerator is only iterated through on the main process" + " and then the batches are split and broadcast to each process. Will default to `True` for `DataLoader` whose" + " underlying dataset is an `IterableDataset`, `False` otherwise." + }, + ) + even_batches: bool = field( + default=True, + metadata={ + "help": "If set to `True`, in cases where the total batch size across all processes does not exactly divide the" + " dataset, samples at the start of the dataset will be duplicated so the batch can be divided equally among" + " all workers." + }, + ) + use_seedable_sampler: bool = field( + default=False, + metadata={ + "help": "Whether or not use a fully seedable random sampler ([`data_loader.SeedableRandomSampler`])." + "Ensures training results are fully reproducible using a different sampling technique. " + "While seed-to-seed results may differ, on average the differences are negligible when using" + "multiple different seeds to compare. Should also be ran with [`~utils.set_seed`] for the best results." + }, + ) + data_seed: int = field( + default=None, + metadata={ + "help": "The seed to use for the underlying generator when using `use_seedable_sampler`. If `None`, the generator" + " will use the current default seed from torch." + }, + ) + non_blocking: bool = field( + default=False, + metadata={ + "help": "If set to `True`, the dataloader prepared by the Accelerator will utilize non-blocking host-to-device" + " transfers, allowing for better overlap between dataloader communication and computation. Recommended that the" + " prepared dataloader has `pin_memory` set to `True` to work properly." + }, + ) + use_stateful_dataloader: bool = field( + default=False, + metadata={ + "help": "If set to `True`, the dataloader prepared by the Accelerator will be backed by " + "[torchdata.StatefulDataLoader](https://github.com/pytorch/data/tree/main/torchdata/stateful_dataloader). This requires `torchdata` version 0.8.0 or higher that supports StatefulDataLoader to be installed." + }, + ) + + +@dataclass +class ProjectConfiguration: + """ + Configuration for the Accelerator object based on inner-project needs. + + Args: + project_dir (`str`, defaults to `None`): + A path to a directory for storing data. + logging_dir (`str`, defaults to `None`): + A path to a directory for storing logs of locally-compatible loggers. If None, defaults to `project_dir`. + automatic_checkpoint_naming (`bool`, defaults to `False`): + Whether saved states should be automatically iteratively named. + total_limit (`int`, defaults to `None`): + The maximum number of total saved states to keep. + iteration (`int`, defaults to `0`): + The current save iteration. + save_on_each_node (`bool`, defaults to `False`): + When doing multi-node distributed training, whether to save models and checkpoints on each node, or only on + the main one. + """ + + project_dir: str = field(default=None, metadata={"help": "A path to a directory for storing data."}) + logging_dir: str = field( + default=None, + metadata={ + "help": "A path to a directory for storing logs of locally-compatible loggers. If None, defaults to `project_dir`." + }, + ) + automatic_checkpoint_naming: bool = field( + default=False, + metadata={"help": "Whether saved states should be automatically iteratively named."}, + ) + + total_limit: int = field( + default=None, + metadata={"help": "The maximum number of total saved states to keep."}, + ) + + iteration: int = field( + default=0, + metadata={"help": "The current save iteration."}, + ) + + save_on_each_node: bool = field( + default=False, + metadata={ + "help": ( + "When doing multi-node distributed training, whether to save models and checkpoints on each node, or" + " only on the main one" + ) + }, + ) + + def set_directories(self, project_dir: Optional[str] = None): + "Sets `self.project_dir` and `self.logging_dir` to the appropriate values." + self.project_dir = project_dir + if self.logging_dir is None: + self.logging_dir = project_dir + + def __post_init__(self): + self.set_directories(self.project_dir) + + +@dataclass +class GradientAccumulationPlugin(KwargsHandler): + """ + A plugin to configure gradient accumulation behavior. You can only pass one of `gradient_accumulation_plugin` or + `gradient_accumulation_steps` to [`Accelerator`]. Passing both raises an error. + + Parameters: + num_steps (`int`): + The number of steps to accumulate gradients for. + adjust_scheduler (`bool`, *optional*, defaults to `True`): + Whether to adjust the scheduler steps to account for the number of steps being accumulated. Should be + `True` if the used scheduler was not adjusted for gradient accumulation. + sync_with_dataloader (`bool`, *optional*, defaults to `True`): + Whether to synchronize setting the gradients when at the end of the dataloader. + sync_each_batch (`bool`, *optional*): + Whether to synchronize setting the gradients at each data batch. Setting to `True` may reduce memory + requirements when using gradient accumulation with distributed training, at expense of speed. + + Example: + + ```python + from accelerate.utils import GradientAccumulationPlugin + + gradient_accumulation_plugin = GradientAccumulationPlugin(num_steps=2) + accelerator = Accelerator(gradient_accumulation_plugin=gradient_accumulation_plugin) + ``` + """ + + num_steps: int = field( + default=None, + metadata={"help": "The number of steps to accumulate gradients for."}, + ) + adjust_scheduler: bool = field( + default=True, + metadata={ + "help": "Whether to adjust the scheduler steps to account for the number of steps being accumulated. Should be `True` if the used scheduler was not adjusted for gradient accumulation." + }, + ) + sync_with_dataloader: bool = field( + default=True, + metadata={ + "help": "Whether to synchronize setting the gradients when at the end of the dataloader. Should only be set to `False` if you know what you're doing." + }, + ) + sync_each_batch: bool = field( + default=False, + metadata={ + "help": "Whether to synchronize setting the gradients at each data batch. Setting to `True` may reduce memory requirements when using gradient accumulation with distributed training, at expense of speed." + }, + ) + + +@dataclass +class TorchDynamoPlugin(KwargsHandler): + """ + This plugin is used to compile a model with PyTorch 2.0 + + Args: + backend (`DynamoBackend`, defaults to `None`): + A valid Dynamo backend. See https://pytorch.org/docs/stable/torch.compiler.html for more details. + mode (`str`, defaults to `None`): + Possible options are 'default', 'reduce-overhead' or 'max-autotune'. + fullgraph (`bool`, defaults to `None`): + Whether it is ok to break model into several subgraphs. + dynamic (`bool`, defaults to `None`): + Whether to use dynamic shape for tracing. + options (`Any`, defaults to `None`): + A dictionary of options to pass to the backend. + disable (`bool`, defaults to `False`): + Turn torch.compile() into a no-op for testing + use_regional_compilation (`bool`, defaults to `None`): + Use it to reduce the cold start compilation time of torch.compile() by targeting repeated blocks of the + same class and compiling them sequentially to hit the compiler's cache. For example, in `GPT2LMHeadModel`, + the repeated block/class is `GPT2Block`, and can be accessed as `model.transformer.h[0]`. The rest of the + model (e.g model.lm_head) is compiled separately. + """ + + backend: DynamoBackend = field( + default=None, + metadata={"help": f"Possible options are {[b.value.lower() for b in DynamoBackend]}"}, + ) + mode: str = field( + default=None, + metadata={"help": "Possible options are 'default', 'reduce-overhead' or 'max-autotune'"}, + ) + fullgraph: bool = field( + default=None, + metadata={"help": "Whether it is ok to break model into several subgraphs"}, + ) + dynamic: bool = field(default=None, metadata={"help": "Whether to use dynamic shape for tracing"}) + options: Any = field( + default=None, + metadata={"help": "A dictionary of options to pass to the backend."}, + ) + disable: bool = field( + default=False, + metadata={"help": "Turn torch.compile() into a no-op for testing"}, + ) + + use_regional_compilation: bool = field( + default=None, + metadata={ + "help": ( + # https://pytorch.org/tutorials/recipes/regional_compilation.html + "Use it to reduce the cold start compilation time of torch.compile() by targeting repeated " + "blocks of the same class and compiling them sequentially to hit the compiler's cache. For " + "example, in `GPT2LMHeadModel`, the repeated block/class is `GPT2Block`, and can be accessed " + "as `model.transformer.h[0]`. The rest of the model (e.g model.lm_head) is compiled separately." + ) + }, + ) + + def __post_init__(self): + prefix = "ACCELERATE_DYNAMO_" + if self.backend is None: + self.backend = os.environ.get(prefix + "BACKEND", "no") + self.backend = DynamoBackend(self.backend.upper()) + + if self.mode is None: + self.mode = os.environ.get(prefix + "MODE", "default") + if self.fullgraph is None: + self.fullgraph = str_to_bool(os.environ.get(prefix + "USE_FULLGRAPH", "False")) == 1 + if self.use_regional_compilation is None: + self.use_regional_compilation = ( + str_to_bool(os.environ.get(prefix + "USE_REGIONAL_COMPILATION", "False")) == 1 + ) + + if self.dynamic is None and os.environ.get(prefix + "USE_DYNAMIC", None) is not None: + self.dynamic = str_to_bool(os.environ.get(prefix + "USE_DYNAMIC", "False")) == 1 + + def to_dict(self): + dynamo_config = copy.deepcopy(self.__dict__) + dynamo_config["backend"] = dynamo_config["backend"].value.lower() + return dynamo_config + + def to_kwargs(self): + kwargs = super().to_kwargs() + kwargs.pop("use_regional_compilation", None) + return kwargs + + +@dataclass +class DeepSpeedPlugin: + """ + This plugin is used to integrate DeepSpeed. + + Args: + hf_ds_config (`Any`, defaults to `None`): + Path to DeepSpeed config file or dict or an object of class `accelerate.utils.deepspeed.HfDeepSpeedConfig`. + gradient_accumulation_steps (`int`, defaults to `None`): + Number of steps to accumulate gradients before updating optimizer states. If not set, will use the value + from the `Accelerator` directly. + gradient_clipping (`float`, defaults to `None`): + Enable gradient clipping with value. + zero_stage (`int`, defaults to `None`): + Possible options are 0, 1, 2, 3. Default will be taken from environment variable. + is_train_batch_min (`bool`, defaults to `True`): + If both train & eval dataloaders are specified, this will decide the `train_batch_size`. + offload_optimizer_device (`str`, defaults to `None`): + Possible options are none|cpu|nvme. Only applicable with ZeRO Stages 2 and 3. + offload_param_device (`str`, defaults to `None`): + Possible options are none|cpu|nvme. Only applicable with ZeRO Stage 3. + offload_optimizer_nvme_path (`str`, defaults to `None`): + Possible options are /nvme|/local_nvme. Only applicable with ZeRO Stage 3. + offload_param_nvme_path (`str`, defaults to `None`): + Possible options are /nvme|/local_nvme. Only applicable with ZeRO Stage 3. + zero3_init_flag (`bool`, defaults to `None`): + Flag to indicate whether to save 16-bit model. Only applicable with ZeRO Stage-3. + zero3_save_16bit_model (`bool`, defaults to `None`): + Flag to indicate whether to save 16-bit model. Only applicable with ZeRO Stage-3. + transformer_moe_cls_names (`str`, defaults to `None`): + Comma-separated list of Transformers MoE layer class names (case-sensitive). For example, + `MixtralSparseMoeBlock`, `Qwen2MoeSparseMoeBlock`, `JetMoEAttention`, `JetMoEBlock`, etc. + enable_msamp (`bool`, defaults to `None`): + Flag to indicate whether to enable MS-AMP backend for FP8 training. + msasmp_opt_level (`Optional[Literal["O1", "O2"]]`, defaults to `None`): + Optimization level for MS-AMP (defaults to 'O1'). Only applicable if `enable_msamp` is True. Should be one + of ['O1' or 'O2']. + """ + + hf_ds_config: Any = field( + default=None, + metadata={ + "help": "path to DeepSpeed config file or dict or an object of class `accelerate.utils.deepspeed.HfDeepSpeedConfig`." + }, + ) + gradient_accumulation_steps: int = field( + default=None, + metadata={ + "help": "Number of steps to accumulate gradients before updating optimizer states. If not set, will use the value from the `Accelerator` directly." + }, + ) + gradient_clipping: float = field(default=None, metadata={"help": "Enable gradient clipping with value"}) + zero_stage: int = field( + default=None, + metadata={"help": "Possible options are 0,1,2,3; Default will be taken from environment variable"}, + ) + is_train_batch_min: bool = field( + default=True, + metadata={"help": "If both train & eval dataloaders are specified, this will decide the train_batch_size"}, + ) + offload_optimizer_device: str = field( + default=None, + metadata={"help": "Possible options are none|cpu|nvme. Only applicable with ZeRO Stages 2 and 3."}, + ) + offload_param_device: str = field( + default=None, + metadata={"help": "Possible options are none|cpu|nvme. Only applicable with ZeRO Stage 3."}, + ) + offload_optimizer_nvme_path: str = field( + default=None, + metadata={"help": "Possible options are /nvme|/local_nvme. Only applicable with ZeRO Stage 3."}, + ) + offload_param_nvme_path: str = field( + default=None, + metadata={"help": "Possible options are /nvme|/local_nvme. Only applicable with ZeRO Stage 3."}, + ) + zero3_init_flag: bool = field( + default=None, + metadata={ + "help": "Flag to indicate whether to enable `deepspeed.zero.Init` for constructing massive models." + "Only applicable with ZeRO Stage-3." + }, + ) + zero3_save_16bit_model: bool = field( + default=None, + metadata={"help": "Flag to indicate whether to save 16-bit model. Only applicable with ZeRO Stage-3."}, + ) + transformer_moe_cls_names: str = field( + default=None, + metadata={ + "help": "comma-separated list of transformers MoE layer class names (case-sensitive), e.g : " + " `MixtralSparseMoeBlock`, `Qwen2MoeSparseMoeBlock`, `JetMoEAttention,JetMoEBlock` ..." + }, + ) + enable_msamp: bool = field( + default=None, + metadata={"help": "Flag to indicate whether to enable MS-AMP backend for FP8 training."}, + ) + msamp_opt_level: Optional[Literal["O1", "O2"]] = field( + default=None, + metadata={ + "help": "Optimization level for MS-AMP (defaults to 'O1'). Only applicable if `enable_msamp` is True. Should be one of ['O1' or 'O2']." + }, + ) + + def __post_init__(self): + from .deepspeed import HfDeepSpeedConfig + + if self.gradient_accumulation_steps is None: + gas = os.environ.get("ACCELERATE_GRADIENT_ACCUMULATION_STEPS", "auto") + self.gradient_accumulation_steps = int(gas) if gas.isdigit() else gas + + if self.gradient_clipping is None: + gradient_clipping = os.environ.get("ACCELERATE_GRADIENT_CLIPPING", "auto") + self.gradient_clipping = gradient_clipping if gradient_clipping == "auto" else float(gradient_clipping) + + if self.zero_stage is None: + self.zero_stage = int(os.environ.get("ACCELERATE_DEEPSPEED_ZERO_STAGE", 2)) + + if self.offload_optimizer_device is None: + self.offload_optimizer_device = os.environ.get("ACCELERATE_DEEPSPEED_OFFLOAD_OPTIMIZER_DEVICE", "none") + + if self.offload_param_device is None: + self.offload_param_device = os.environ.get("ACCELERATE_DEEPSPEED_OFFLOAD_PARAM_DEVICE", "none") + + if self.offload_optimizer_nvme_path is None: + self.offload_optimizer_nvme_path = os.environ.get( + "ACCELERATE_DEEPSPEED_OFFLOAD_OPTIMIZER_NVME_PATH", "none" + ) + + if self.offload_param_nvme_path is None: + self.offload_param_nvme_path = os.environ.get("ACCELERATE_DEEPSPEED_OFFLOAD_PARAM_NVME_PATH", "none") + + if self.zero3_save_16bit_model is None: + self.zero3_save_16bit_model = ( + os.environ.get("ACCELERATE_DEEPSPEED_ZERO3_SAVE_16BIT_MODEL", "false").lower() == "true" + ) + if self.enable_msamp is None: + self.enable_msamp = os.environ.get("ACCELERATE_FP8_BACKEND", None) == "MSAMP" + + if self.msamp_opt_level is None: + self.msamp_opt_level = os.environ.get("ACCELERATE_FP8_OPT_LEVEL", "O1") + + if self.hf_ds_config is None: + self.hf_ds_config = os.environ.get("ACCELERATE_DEEPSPEED_CONFIG_FILE", "none") + + if ( + isinstance(self.hf_ds_config, dict) + or (isinstance(self.hf_ds_config, str) and self.hf_ds_config != "none") + or isinstance(self.hf_ds_config, HfDeepSpeedConfig) + ): + if not isinstance(self.hf_ds_config, HfDeepSpeedConfig): + self.hf_ds_config = HfDeepSpeedConfig(self.hf_ds_config) + if "gradient_accumulation_steps" not in self.hf_ds_config.config: + self.hf_ds_config.config["gradient_accumulation_steps"] = 1 + if "zero_optimization" not in self.hf_ds_config.config: + raise ValueError("Please specify the ZeRO optimization config in the DeepSpeed config.") + + self._deepspeed_config_checks() + plugin_to_config_mapping = { + "gradient_accumulation_steps": "gradient_accumulation_steps", + "gradient_clipping": "gradient_clipping", + "zero_stage": "zero_optimization.stage", + "offload_optimizer_device": "zero_optimization.offload_optimizer.device", + "offload_param_device": "zero_optimization.offload_param.device", + "offload_param_nvme_path": "zero_optimization.offload_param.nvme_path", + "offload_optimizer_nvme_path": "zero_optimization.offload_optimizer.nvme_path", + "zero3_save_16bit_model": "zero_optimization.stage3_gather_16bit_weights_on_model_save", + } + kwargs = {v: getattr(self, k) for k, v in plugin_to_config_mapping.items() if getattr(self, k) is not None} + for key in kwargs.keys(): + self.fill_match(key, **kwargs, must_match=False) + self.hf_ds_config.set_stage_and_offload() + + # filling the missing values in the class attributes from the DeepSpeed config + # when using the DeepSpeed config file. + for key, value in plugin_to_config_mapping.items(): + config_value = self.hf_ds_config.get_value(value) + if config_value is not None and config_value != "auto": + setattr(self, key, config_value) + else: + config = { + "train_batch_size": "auto", + "train_micro_batch_size_per_gpu": "auto", + "gradient_accumulation_steps": self.gradient_accumulation_steps, + "zero_optimization": { + "stage": self.zero_stage, + "offload_optimizer": { + "device": self.offload_optimizer_device, + "nvme_path": ( + self.offload_optimizer_nvme_path if self.offload_optimizer_device == "nvme" else None + ), + }, + "offload_param": { + "device": self.offload_param_device, + "nvme_path": (self.offload_param_nvme_path if self.offload_param_device == "nvme" else None), + }, + "stage3_gather_16bit_weights_on_model_save": self.zero3_save_16bit_model, + }, + } + if self.gradient_clipping: + config["gradient_clipping"] = self.gradient_clipping + self.hf_ds_config = HfDeepSpeedConfig(config) + + self.deepspeed_config = self.hf_ds_config.config + self.deepspeed_config["steps_per_print"] = float("inf") # this will stop deepspeed from logging @ stdout + if self.zero3_init_flag is None: + self.zero3_init_flag = ( + str_to_bool( + os.environ.get( + "ACCELERATE_DEEPSPEED_ZERO3_INIT", + str(self.hf_ds_config.is_zero3()), + ) + ) + == 1 + ) + if self.zero3_init_flag and not self.hf_ds_config.is_zero3(): + warnings.warn("DeepSpeed Zero3 Init flag is only applicable for ZeRO Stage 3. Setting it to False.") + self.zero3_init_flag = False + # NOTE: Set to False by default, will be set to `True` automatically if it's the first plugin passed + # to the `Accelerator`'s `deepspeed_plugin` param, *or* `AcceleratorState().enable_deepspeed_plugin(plugin_key)` is manually called + self._set_selected(False) + + # Ignore if it's already set + if self.enable_msamp and "msamp" not in self.deepspeed_config: + if self.zero_stage == 3: + raise NotImplementedError( + "MS-AMP is not supported for ZeRO Stage 3. Please use ZeRO Stage 0, 1, or 2 instead." + ) + if self.msamp_opt_level not in ["O1", "O2"]: + raise ValueError("Invalid optimization level for MS-AMP. Please use one of ['O1' or'O2'].") + self.deepspeed_config["msamp"] = { + "enabled": True, + "opt_level": self.msamp_opt_level, + } + + def fill_match(self, ds_key_long, mismatches=None, must_match=True, **kwargs): + mismatches = [] if mismatches is None else mismatches + config, ds_key = self.hf_ds_config.find_config_node(ds_key_long) + if config is None: + return + + if config.get(ds_key) == "auto": + if ds_key_long in kwargs: + config[ds_key] = kwargs[ds_key_long] + return + else: + raise ValueError( + f"`{ds_key_long}` not found in kwargs. " + f"Please specify `{ds_key_long}` without `auto` (set to correct value) in the DeepSpeed config file or " + "pass it in kwargs." + ) + + if not must_match: + return + + ds_val = config.get(ds_key) + if ds_val is not None and ds_key_long in kwargs: + if ds_val != kwargs[ds_key_long]: + mismatches.append(f"- ds {ds_key_long}={ds_val} vs arg {ds_key_long}={kwargs[ds_key_long]}") + + def is_auto(self, ds_key_long): + val = self.hf_ds_config.get_value(ds_key_long) + if val is None: + return False + else: + return val == "auto" + + def get_value(self, ds_key_long, default=None): + return self.hf_ds_config.get_value(ds_key_long, default) + + def deepspeed_config_process(self, prefix="", mismatches=None, config=None, must_match=True, **kwargs): + """Process the DeepSpeed config with the values from the kwargs.""" + mismatches = [] if mismatches is None else mismatches + if config is None: + config = self.deepspeed_config + for key, value in config.items(): + if isinstance(value, dict): + self.deepspeed_config_process( + prefix=prefix + key + ".", + mismatches=mismatches, + config=value, + must_match=must_match, + **kwargs, + ) + else: + self.fill_match(prefix + key, mismatches, must_match=must_match, **kwargs) + if len(mismatches) > 0 and prefix == "": + mismatches_msg = "\n".join(mismatches) + raise ValueError( + "Please correct the following DeepSpeed config values that mismatch kwargs " + f" values:\n{mismatches_msg}\nThe easiest method is to set these DeepSpeed config values to 'auto'." + ) + + def set_mixed_precision(self, mixed_precision): + ds_config = self.deepspeed_config + kwargs = { + "fp16.enabled": mixed_precision == "fp16", + # When training in fp8, we still rely on bf16 autocast for the core mixed precision + "bf16.enabled": mixed_precision in ("bf16", "fp8"), + } + if mixed_precision == "fp16": + if "fp16" not in ds_config: + ds_config["fp16"] = {"enabled": True, "auto_cast": True} + elif mixed_precision in ("bf16", "fp8"): + if "bf16" not in ds_config: + ds_config["bf16"] = {"enabled": True} + + if mixed_precision == "fp8" and self.enable_msamp: + if "msamp" not in ds_config: + ds_config["msamp"] = { + "enabled": True, + "opt_level": self.msamp_opt_level, + } + + if mixed_precision != "no": + diff_dtype = "bf16" if mixed_precision == "fp16" else "fp16" + if str(ds_config.get(diff_dtype, {}).get("enabled", "False")).lower() == "true": + raise ValueError( + f"`--mixed_precision` arg cannot be set to `{mixed_precision}` when `{diff_dtype}` is set in the DeepSpeed config file." + ) + for dtype in ["fp16", "bf16"]: + if dtype not in ds_config: + ds_config[dtype] = {"enabled": False} + self.fill_match("fp16.enabled", must_match=False, **kwargs) + self.fill_match("bf16.enabled", must_match=False, **kwargs) + + def set_deepspeed_weakref(self): + from .imports import is_transformers_available + + ds_config = copy.deepcopy(self.deepspeed_config) + if self.zero3_init_flag: + if not is_transformers_available(): + raise Exception( + "When `zero3_init_flag` is set, it requires Transformers to be installed. " + "Please run `pip install transformers`." + ) + if "gradient_accumulation_steps" not in ds_config or ds_config["gradient_accumulation_steps"] == "auto": + ds_config["gradient_accumulation_steps"] = 1 + if "train_micro_batch_size_per_gpu" not in ds_config or ds_config["train_micro_batch_size_per_gpu"] == "auto": + ds_config["train_micro_batch_size_per_gpu"] = 1 + if ds_config.get("train_batch_size", None) == "auto": + del ds_config["train_batch_size"] + + if compare_versions("transformers", "<", "4.46"): + from transformers.deepspeed import ( + HfDeepSpeedConfig, + unset_hf_deepspeed_config, + ) + else: + from transformers.integrations import ( + HfDeepSpeedConfig, + unset_hf_deepspeed_config, + ) + + unset_hf_deepspeed_config() + self.dschf = HfDeepSpeedConfig(ds_config) # keep this object alive # noqa + + def is_zero3_init_enabled(self): + return self.zero3_init_flag + + @contextmanager + def zero3_init_context_manager(self, enable=False): + old = self.zero3_init_flag + if old == enable: + yield + else: + self.zero3_init_flag = enable + self.dschf = None + self.set_deepspeed_weakref() + yield + self.zero3_init_flag = old + self.dschf = None + self.set_deepspeed_weakref() + + def _deepspeed_config_checks(self): + env_variable_names_to_ignore = [ + "ACCELERATE_GRADIENT_ACCUMULATION_STEPS", + "ACCELERATE_GRADIENT_CLIPPING", + "ACCELERATE_DEEPSPEED_ZERO_STAGE", + "ACCELERATE_DEEPSPEED_OFFLOAD_OPTIMIZER_DEVICE", + "ACCELERATE_DEEPSPEED_OFFLOAD_PARAM_DEVICE", + "ACCELERATE_DEEPSPEED_OFFLOAD_PARAM_NVME_PATH", + "ACCELERATE_DEEPSPEED_OFFLOAD_OPTIMIZER_NVME_PATH", + "ACCELERATE_DEEPSPEED_ZERO3_SAVE_16BIT_MODEL", + "ACCELERATE_MIXED_PRECISION", + ] + env_variable_names_to_ignore = [ + name.replace("ACCELERATE_", "").replace("DEEPSPEED_", "").lower() for name in env_variable_names_to_ignore + ] + + deepspeed_fields_from_accelerate_config = os.environ.get("ACCELERATE_CONFIG_DS_FIELDS", "").split(",") + + if any(name in env_variable_names_to_ignore for name in deepspeed_fields_from_accelerate_config): + raise ValueError( + f"When using `deepspeed_config_file`, the following accelerate config variables will be ignored: {env_variable_names_to_ignore}.\n" + "Please specify them appropriately in the DeepSpeed config file.\n" + "If you are using an accelerate config file, remove others config variables mentioned in the above specified list.\n" + "The easiest method is to create a new config following the questionnaire via `accelerate config`.\n" + "It will only ask for the necessary config variables when using `deepspeed_config_file`." + ) + + def set_moe_leaf_modules(self, model): + if self.transformer_moe_cls_names is None: + self.transformer_moe_cls_names = os.environ.get("ACCELERATE_DEEPSPEED_MOE_LAYER_CLS_NAMES", None) + if self.transformer_moe_cls_names is not None: + if compare_versions("deepspeed", "<", "0.14.0"): + raise ImportError("DeepSpeed version must be >= 0.14.0 to use MOE support. Please update DeepSpeed.") + from deepspeed.utils import set_z3_leaf_modules + + class_names = self.transformer_moe_cls_names.split(",") + transformer_moe_cls = [] + for layer_class in class_names: + transformer_cls = get_module_class_from_name(model, layer_class) + if transformer_cls is None: + raise Exception( + f"Could not find a transformer layer class called '{layer_class}' to wrap in the model." + ) + else: + transformer_moe_cls.append(transformer_cls) + set_z3_leaf_modules(model, transformer_moe_cls) # z3_leaf + + def select(self, _from_accelerator_state: bool = False): + """ + Sets the HfDeepSpeedWeakref to use the current deepspeed plugin configuration + """ + if not _from_accelerator_state: + raise ValueError( + "A `DeepSpeedPlugin` object must be enabled manually by calling `AcceleratorState().enable_deepspeed_plugin(plugin_key)`." + ) + self.set_deepspeed_weakref() + self._set_selected(True) + + def _unselect(self): + self._set_selected(False) + + def _set_selected(self, value: bool): + """ + Private setter for the 'enabled' attribute. + """ + self._selected = value + + @property + def selected(self): + return self._selected + + @selected.setter + def selected(self, value): + raise NotImplementedError( + "'enabled' can only be set through calling 'AcceleratorState().enable_deepspeed_plugin(key)'." + ) + + +@dataclass +class FullyShardedDataParallelPlugin: + """ + This plugin is used to enable fully sharded data parallelism. + + Args: + fsdp_version (`int`, defaults to `1`): + The version of FSDP to use. Defaults to 1. If set to 2, launcher expects the config to be converted to + FSDP2 format. + sharding_strategy (`Union[str, torch.distributed.fsdp.ShardingStrategy]`, defaults to `'FULL_SHARD'`): + Sharding strategy to use. Should be either a `str` or an instance of + `torch.distributed.fsdp.fully_sharded_data_parallel.ShardingStrategy`. Is deprecated in favor of + `reshard_after_forward`. + reshard_after_forward (`Union[str, torch.distributed.fsdp.ShardingStrategy, bool]`, defaults to `'FULL_SHARD'` for `fsdp_version=1` and `True` for `fsdp_version=2`): + Sharding strategy to use. Should be a bool if `fsdp_version` is set to 2 else a `str` or an instance of + `torch.distributed.fsdp.fully_sharded_data_parallel.ShardingStrategy`. + backward_prefetch (`Union[str, torch.distributed.fsdp.BackwardPrefetch]`, defaults to `'NO_PREFETCH'`): + Backward prefetch strategy to use. Should be either a `str` or an instance of + `torch.distributed.fsdp.fully_sharded_data_parallel.BackwardPrefetch`. + mixed_precision_policy (`Optional[Union[dict, str, torch.distributed.fsdp.MixedPrecision, torch.distributed.fsdp.MixedPrecisionPolicy]]`, defaults to `None`): + A config to enable mixed precision training with FullyShardedDataParallel. If passing in a `dict`, it + should have the following keys: `param_dtype`, `reduce_dtype`, and `buffer_dtype`, can be an instance of + `torch.distributed.fsdp.MixedPrecisionPolicy` if `fsdp_version` is set to 2. If passing in a `str`, it + should be one of the following values: fp8, fp16, bf16, fp32, and used to set `param_dtype`, + `reduce_dtype`, and `buffer_dtype`. + auto_wrap_policy (`Optional(Union[Callable, Literal["transformer_based_wrap", "size_based_wrap", "no_wrap"]]), defaults to `NO_WRAP`): + A callable or string specifying a policy to recursively wrap layers with FSDP. If a string, it must be one + of `transformer_based_wrap`, `size_based_wrap`, or `no_wrap`. See + `torch.distributed.fsdp.wrap.size_based_wrap_policy` for a direction on what it should look like. + cpu_offload (`Union[bool, torch.distributed.fsdp.CPUOffload, torch.distributed.fsdp.CPUOffloadPolicy]`, defaults to `False`): + Whether to offload parameters to CPU. Should be either a `bool` or an instance of + `torch.distributed.fsdp.fully_sharded_data_parallel.CPUOffload` or + `torch.distributed.fsdp.fully_sharded_data_parallel.CPUOffloadPolicy` if `fsdp_version` is set to 2. + ignored_modules (`Optional[Union[Iterable[torch.nn.Module], str]]`, defaults to `None`): + A list of modules to ignore when wrapping with FSDP. When passing a string, will match the modules by name + using regex fullmatch. If `fsdp_version` is set to 2, the modules are converted to parameters and used. + state_dict_type (`Union[str, torch.distributed.fsdp.StateDictType]`, defaults to `'FULL_STATE_DICT'`): + State dict type to use. If a string, it must be one of `full_state_dict`, `local_state_dict`, or + `sharded_state_dict`. + state_dict_config (`Optional[Union[torch.distributed.fsdp.FullStateDictConfig, torch.distributed.fsdp.ShardedStateDictConfig]`, defaults to `None`): + State dict config to use. Is determined based on the `state_dict_type` if not passed in. + optim_state_dict_config (`Optional[Union[torch.distributed.fsdp.FullOptimStateDictConfig, torch.distributed.fsdp.ShardedOptimStateDictConfig]`, defaults to `None`): + Optim state dict config to use. Is determined based on the `state_dict_type` if not passed in. + limit_all_gathers (`bool`, defaults to `True`): + Whether to have FSDP explicitly synchronizes the CPU thread to prevent too many in-flight all-gathers. This + bool only affects the sharded strategies that schedule all-gathers. Enabling this can help lower the number + of CUDA malloc retries. + use_orig_params (`bool`, defaults to `False`): + Whether to use the original parameters for the optimizer. + param_init_fn (`Optional[Callable[[torch.nn.Module], None]`, defaults to `None`): + A `Callable[torch.nn.Module] -> None` that specifies how modules that are currently on the meta device + should be initialized onto an actual device. Only applicable when `sync_module_states` is `True`. By + default is a `lambda` which calls `to_empty` on the module. + sync_module_states (`bool`, defaults to `False`): + Whether each individually wrapped FSDP unit should broadcast module parameters from rank 0 to ensure they + are the same across all ranks after initialization. Defaults to `False` unless `cpu_ram_efficient_loading` + is `True`, then will be forcibly enabled. + forward_prefetch (`bool`, defaults to `False`): + Whether to have FSDP explicitly prefetches the next upcoming all-gather while executing in the forward + pass. only use with Static graphs. + activation_checkpointing (`bool`, defaults to `False`): + A technique to reduce memory usage by clearing activations of certain layers and recomputing them during a + backward pass. Effectively, this trades extra computation time for reduced memory usage. + cpu_ram_efficient_loading (`bool`, defaults to `None`): + If True, only the first process loads the pretrained model checkoint while all other processes have empty + weights. Only applicable for Transformers. When using this, `sync_module_states` needs to be `True`. + transformer_cls_names_to_wrap (`Optional[List[str]]`, defaults to `None`): + A list of transformer layer class names to wrap. Only applicable when `auto_wrap_policy` is + `transformer_based_wrap`. + min_num_params (`Optional[int]`, defaults to `None`): + The minimum number of parameters a module must have to be wrapped. Only applicable when `auto_wrap_policy` + is `size_based_wrap`. + """ + + fsdp_version: int = field( + default=None, + metadata={ + "help": "The version of FSDP to use. Defaults to 1. If set to 2, launcher expects the config to be converted to FSDP2 format." + }, + ) + + sharding_strategy: Union[str, "torch.distributed.fsdp.ShardingStrategy"] = field( + default=None, + metadata={ + "help": "Sharding strategy to use. Should be either a `str` or an instance of `torch.distributed.fsdp.fully_sharded_data_parallel.ShardingStrategy`. Defaults to 'FULL_SHARD'. Is deprecated in favor of `reshard_after_forward` " + }, + ) + + reshard_after_forward: Union[str, "torch.distributed.fsdp.ShardingStrategy", bool] = field( + default=None, + metadata={ + "help": "Sharding strategy to use. Should be a bool if `fsdp_version` is set to 2 else a `str` or an instance of `torch.distributed.fsdp.fully_sharded_data_parallel.ShardingStrategy`. Defaults to 'FULL_SHARD'" + }, + ) + backward_prefetch: Optional[Union[str, "torch.distributed.fsdp.BackwardPrefetch"]] = field( + default=None, + metadata={ + "help": "Backward prefetch strategy to use. Should be either a `str` or an instance of `torch.distributed.fsdp.fully_sharded_data_parallel.BackwardPrefetch`. Defaults to 'NO_PREFETCH'. This becomes obsolete in FSDP2." + }, + ) + mixed_precision_policy: Optional[ + Union[ + dict, + str, + "torch.distributed.fsdp.MixedPrecision", + "torch.distributed.fsdp.MixedPrecisionPolicy", + ] + ] = field( + default=None, + metadata={ + "help": "A config to enable mixed precision training with FullyShardedDataParallel. " + "If passing in a `dict`, it should have the following keys: `param_dtype`, `reduce_dtype`, and `buffer_dtype`." + "Can also be an instance of `torch.distributed.fsdp.MixedPrecisionPolicy` if `fsdp_version` is set to 2." + }, + ) + auto_wrap_policy: Optional[Union[Callable, Literal["transformer_based_wrap", "size_based_wrap", "no_wrap"]]] = ( + field( + default=None, + metadata={ + "help": "A callable or string specifying a policy to recursively wrap layers with FSDP. If a string, it must be one of `transformer_based_wrap`, `size_based_wrap`, or `no_wrap`. " + "Defaults to `NO_WRAP`. See `torch.distributed.fsdp.wrap.size_based_wrap_policy` for a direction on what it should look like" + }, + ) + ) + cpu_offload: Union[ + bool, + "torch.distributed.fsdp.CPUOffload", + "torch.distributed.fsdp.CPUOffloadPolicy", + ] = field( + default=None, + metadata={ + "help": "Whether to offload parameters to CPU. Should be either a `bool` or an instance of `torch.distributed.fsdp.fully_sharded_data_parallel.CPUOffload` or `torch.distributed.fsdp.fully_sharded_data_parallel.CPUOffloadPolicy` if `fsdp_version` is set to 2. Defaults to `False`" + }, + ) + ignored_modules: Optional[Union[Iterable[torch.nn.Module], str]] = field( + default=None, + metadata={"help": "A list of modules to ignore when wrapping with FSDP."}, + ) + + state_dict_type: Union[str, "torch.distributed.fsdp.StateDictType"] = field( + default=None, + metadata={ + "help": "State dict type to use. If a string, it must be one of `full_state_dict`, `local_state_dict`, or `sharded_state_dict`. Defaults to `FULL_STATE_DICT`" + }, + ) + state_dict_config: Optional[ + Union[ + "torch.distributed.fsdp.FullStateDictConfig", + "torch.distributed.fsdp.ShardedStateDictConfig", + ] + ] = field( + default=None, + metadata={"help": "State dict config to use. Is determined based on the `state_dict_type` if not passed in."}, + ) + optim_state_dict_config: Optional[ + Union[ + "torch.distributed.fsdp.FullOptimStateDictConfig", + "torch.distributed.fsdp.ShardedOptimStateDictConfig", + ] + ] = field( + default=None, + metadata={ + "help": "Optim state dict config to use. Is determined based on the `state_dict_type` if not passed in." + }, + ) + limit_all_gathers: bool = field( + default=True, + metadata={ + "help": "Whether to have FSDP explicitly synchronizes the CPU thread to prevent " + "too many in-flight all-gathers. This bool only affects the sharded strategies that schedule all-gathers. " + "Enabling this can help lower the number of CUDA malloc retries." + }, + ) + use_orig_params: Optional[bool] = field( + default=None, + metadata={ + "help": "Whether to use the original parameters for the optimizer. Defaults to `False`. This becomes obsolete in FSDP2." + }, + ) + param_init_fn: Optional[Callable[[torch.nn.Module], None]] = field( + default=None, + metadata={ + "help": "A Callable[torch.nn.Module] -> None that specifies how modules " + "that are currently on the meta device should be initialized onto an actual device. " + "Only applicable when `sync_module_states` is `True`. By default is a `lambda` which calls `to_empty` on the module." + }, + ) + sync_module_states: Optional[bool] = field( + default=None, + metadata={ + "help": "Whether each individually wrapped FSDP unit should broadcast module parameters from rank 0 " + "to ensure they are the same across all ranks after initialization. Defaults to `False` unless " + "`cpu_ram_efficient_loading` is `True`, then will be forcibly enabled. This becomes obsolete in FSDP2." + }, + ) + forward_prefetch: bool = field( + default=None, + metadata={ + "help": "Whether to have FSDP explicitly prefetches the next upcoming " + "all-gather while executing in the forward pass. only use with Static graphs. Defaults to `False`" + }, + ) + activation_checkpointing: bool = field( + default=None, + metadata={ + "help": "A technique to reduce memory usage by clearing activations of " + "certain layers and recomputing them during a backward pass. Effectively, this trades extra computation time " + "for reduced memory usage. Defaults to `False`" + }, + ) + cpu_ram_efficient_loading: bool = field( + default=None, + metadata={ + "help": "If True, only the first process loads the pretrained model checkoint while all other processes have empty weights. " + "Only applicable for 🤗 Transformers. When using this, `sync_module_states` needs to be `True`. Defaults to `False`." + }, + ) + transformer_cls_names_to_wrap: Optional[list[str]] = field( + default=None, + metadata={ + "help": "A list of transformer layer class names to wrap. Only applicable when `auto_wrap_policy` is `transformer_based_wrap`." + }, + ) + min_num_params: Optional[int] = field( + default=None, + metadata={ + "help": "The minimum number of parameters a module must have to be wrapped. Only applicable when `auto_wrap_policy` is `size_based_wrap`." + }, + ) + + def __post_init__(self): + from torch.distributed.fsdp import BackwardPrefetch, ShardingStrategy + + _fsdp2_warnings = set() + + env_prefix = "FSDP_" + # Strategy: By default we should always assume that values are passed in, else we check the environment variables + if self.fsdp_version is None: + self.fsdp_version = int(os.environ.get(env_prefix + "VERSION", "1")) + + if self.fsdp_version == 2: + if not is_torch_version(">=", FSDP2_PYTORCH_VERSION): + raise ImportError(f"FSDP2 requires PyTorch >= {FSDP2_PYTORCH_VERSION}") + + if self.sharding_strategy is not None: + # We cannot properly detect all of the cases, as by default `args.fsdp_sharding_strategy` is set to `fully_shard` + # Therefore we issue a warning only if the user has explicitly set it inside their plugin + _fsdp2_warnings.add( + "sharding_strategy is deprecated in favor of reshard_after_forward. " + "This will be removed in a future version of Accelerate." + ) + if self.fsdp_version == 1: + if self.sharding_strategy is None: + self.sharding_strategy = os.environ.get(env_prefix + "SHARDING_STRATEGY", "FULL_SHARD") + if isinstance(self.sharding_strategy, str): + if self.sharding_strategy.upper() in FSDP_SHARDING_STRATEGY: + self.sharding_strategy = FSDP_SHARDING_STRATEGY.index(self.sharding_strategy.upper()) + 1 + if isinstance(self.sharding_strategy, int) or self.sharding_strategy.isdigit(): + self.sharding_strategy = ShardingStrategy(int(self.sharding_strategy)) + else: + self.sharding_strategy = ShardingStrategy[self.sharding_strategy.upper()] + + # Fallback to `reshard_after_forward` in FSDP1 if `sharding_strategy` is not set + if self.reshard_after_forward is None and self.sharding_strategy is None: + reshard_after_forward = os.environ.get( + env_prefix + "RESHARD_AFTER_FORWARD", + "true" if self.fsdp_version == 2 else "FULL_SHARD", + ) + if self.fsdp_version == 2: + self.reshard_after_forward = str_to_bool(reshard_after_forward.lower(), to_bool=True) + else: + self.reshard_after_forward = reshard_after_forward + if isinstance(self.reshard_after_forward, str): + if self.fsdp_version == 2: + self.reshard_after_forward = str_to_bool(self.reshard_after_forward.lower(), to_bool=True) + else: + # We need to remap based on custom enum values for user readability + if self.reshard_after_forward.upper() in FSDP_SHARDING_STRATEGY: + self.reshard_after_forward = FSDP_SHARDING_STRATEGY.index(self.reshard_after_forward.upper()) + 1 + if isinstance(self.reshard_after_forward, int) or self.reshard_after_forward.isdigit(): + self.reshard_after_forward = ShardingStrategy(int(self.reshard_after_forward)) + else: + self.reshard_after_forward = ShardingStrategy[self.reshard_after_forward.upper()] + + if self.fsdp_version == 2 and not isinstance(self.reshard_after_forward, bool): + raise ValueError( + f"reshard_after_forward set to {self.reshard_after_forward}. This is not supported with FSDP2, please set to a `bool`" + ) + if self.fsdp_version == 1 and isinstance(self.reshard_after_forward, bool): + raise ValueError( + f"reshard_after_forward set to {self.reshard_after_forward}. This is not supported with FSDP1, please set to a `str` or an instance of `torch.distributed.fsdp.fully_sharded_data_parallel.ShardingStrategy`" + ) + + if self.cpu_offload is None: + self.cpu_offload = str_to_bool(os.environ.get(env_prefix + "OFFLOAD_PARAMS", "False")) == 1 + + self.set_cpu_offload() # abstracted away to hide imports due to version checks + self.validate_cpu_offload() + + if self.backward_prefetch is None: + self.backward_prefetch = os.environ.get(env_prefix + "BACKWARD_PREFETCH", None) + if isinstance(self.backward_prefetch, str) and self.backward_prefetch.upper() == "NO_PREFETCH": + self.backward_prefetch = None + if self.backward_prefetch is not None and not isinstance(self.backward_prefetch, BackwardPrefetch): + if isinstance(self.backward_prefetch, str) and self.backward_prefetch.upper() in FSDP_BACKWARD_PREFETCH: + self.backward_prefetch = FSDP_BACKWARD_PREFETCH.index(self.backward_prefetch.upper()) + 1 + if isinstance(self.backward_prefetch, int) or self.backward_prefetch.isdigit(): + self.backward_prefetch = BackwardPrefetch(int(self.backward_prefetch)) + else: + self.backward_prefetch = BackwardPrefetch[self.backward_prefetch.upper()] + if self.fsdp_version == 2 and self.backward_prefetch is not None: + _fsdp2_warnings.add("backward_prefetch is not supported in FSDP2. Setting backward prefetch to None.") + self.backward_prefetch = None + + self.set_state_dict_type() + + if self.auto_wrap_policy is None: + self.auto_wrap_policy = os.environ.get(env_prefix + "AUTO_WRAP_POLICY", "NO_WRAP") + if isinstance(self.auto_wrap_policy, str): + if self.auto_wrap_policy.upper() not in FSDP_AUTO_WRAP_POLICY: + raise ValueError( + f"Invalid auto wrap policy: {self.auto_wrap_policy}. Must be one of {FSDP_AUTO_WRAP_POLICY}" + ) + from torch.distributed.fsdp.wrap import ( + size_based_auto_wrap_policy, + transformer_auto_wrap_policy, + ) + + if self.auto_wrap_policy.upper() == "TRANSFORMER_BASED_WRAP": + self.auto_wrap_policy = transformer_auto_wrap_policy + if self.transformer_cls_names_to_wrap is None: + self.transformer_cls_names_to_wrap = os.environ.get(env_prefix + "TRANSFORMER_CLS_TO_WRAP", None) + if isinstance(self.transformer_cls_names_to_wrap, str): + self.transformer_cls_names_to_wrap = self.transformer_cls_names_to_wrap.split(",") + elif self.auto_wrap_policy.upper() == "SIZE_BASED_WRAP": + self.auto_wrap_policy = size_based_auto_wrap_policy + if self.min_num_params is None: + self.min_num_params = int(os.environ.get(env_prefix + "MIN_NUM_PARAMS", 0)) + elif not isinstance(self.min_num_params, int): + raise ValueError( + f"`min_num_params` must be an integer. Got {self.min_num_params} of type {type(self.min_num_params)}" + ) + elif self.auto_wrap_policy.upper() == "NO_WRAP": + self.auto_wrap_policy = None + + if self.use_orig_params is None and self.fsdp_version == 1: + self.use_orig_params = str_to_bool(os.environ.get(env_prefix + "USE_ORIG_PARAMS", "False")) == 1 + if self.fsdp_version == 2 and self.use_orig_params is not None: + _fsdp2_warnings.add("use_orig_params is obsolete in FSDP2, as FSDP2 always uses the original parameters.") + self.use_orig_params = None + + if self.sync_module_states is None and self.fsdp_version == 1: + self.sync_module_states = str_to_bool(os.environ.get(env_prefix + "SYNC_MODULE_STATES", "False")) == 1 + if self.fsdp_version == 2 and self.sync_module_states is not None: + _fsdp2_warnings.add( + "sync_module_states is obsolete in FSDP2, as it is not needed anymore." + "Setting sync_module_states to None." + ) + self.sync_module_states = None + + if self.forward_prefetch is None and self.fsdp_version == 1: + self.forward_prefetch = str_to_bool(os.environ.get(env_prefix + "FORWARD_PREFETCH", "False")) == 1 + if self.fsdp_version == 2 and self.forward_prefetch is not None: + raise ValueError("forward_prefetch is not yet implemented in FSDP2, set to None or use `fsdp_version=1`") + + if self.activation_checkpointing is None: + self.activation_checkpointing = ( + str_to_bool(os.environ.get(env_prefix + "ACTIVATION_CHECKPOINTING", "False")) == 1 + ) + + if self.ignored_modules is None: + self.ignored_modules = os.environ.get(env_prefix + "IGNORED_MODULES", None) + + if self.cpu_ram_efficient_loading is None: + self.cpu_ram_efficient_loading = ( + str_to_bool(os.environ.get(env_prefix + "CPU_RAM_EFFICIENT_LOADING", "False")) == 1 + ) + else: + # We still need to set it for transformers + os.environ[env_prefix + "CPU_RAM_EFFICIENT_LOADING"] = str(self.cpu_ram_efficient_loading) + # There's no need to specify sync_module_states in FSDP2 + if self.fsdp_version == 1 and self.cpu_ram_efficient_loading and not self.sync_module_states: + warnings.warn( + "sync_module_states cannot be False since efficient cpu ram loading enabled. " + "Setting sync_module_states to True." + ) + self.sync_module_states = True + if isinstance(self.mixed_precision_policy, str): + # override is True since self.mixed_precision_policy is not None + # has to be overwritten with the correct mixed precision object + self.set_mixed_precision(self.mixed_precision_policy, override=True) + elif isinstance(self.mixed_precision_policy, dict): + self.set_mixed_precision(self.mixed_precision_policy) + if self.mixed_precision_policy is not None: + self.validate_mixed_precision_policy() + + if self.sync_module_states: + if is_npu_available(): + device = torch.npu.current_device() + elif is_mlu_available(): + device = torch.mlu.current_device() + elif is_musa_available(): + device = torch.musa.current_device() + elif is_cuda_available(): + device = torch.cuda.current_device() + elif is_xpu_available(): + device = torch.xpu.current_device() + elif is_hpu_available(): + device = torch.hpu.current_device() + else: + raise RuntimeError( + "There are currently no available devices found, must be one of 'XPU', 'CUDA', 'MLU', 'NPU', 'MUSA', or 'HPU'." + ) + # Create a function that will be used to initialize the parameters of the model + # when using `sync_module_states` + self.param_init_fn = lambda x: x.to_empty(device=device, recurse=False) + if is_torch_version("<", "2.7.0") and self.fsdp_version == 2 and self.ignored_modules is not None: + _fsdp2_warnings.add( + "FSDP2 ignored_params/ignored_modules is not available for torch version < 2.7.0" + "Setting ignored_modules to None." + ) + self.ignored_modules = None + # Single warning for all deprecation warnings due to FSDP2 conversion + if _fsdp2_warnings: + logger.warning("Multiple deprecation warnings due to FSDP2 conversion:\n".join(_fsdp2_warnings)) + + def set_state_dict_type(self, state_dict_type=None): + """ + Set the state dict config based on the `StateDictType`. + """ + from torch.distributed.fsdp.fully_sharded_data_parallel import ( + FullOptimStateDictConfig, + FullStateDictConfig, + ShardedOptimStateDictConfig, + ShardedStateDictConfig, + StateDictType, + ) + + # Override the state_dict_type if provided, typical use case: + # user trains with sharded, but final save is with full + if state_dict_type is not None: + self.state_dict_type = state_dict_type + + if self.state_dict_type is None: + self.state_dict_type = os.environ.get( + "FSDP_STATE_DICT_TYPE", + "FULL_STATE_DICT" if self.fsdp_version == 1 else "SHARDED_STATE_DICT", + ) + if isinstance(self.state_dict_type, str): + if self.state_dict_type.isdigit(): + self.state_dict_type = StateDictType(int(self.state_dict_type)) + else: + self.state_dict_type = StateDictType[self.state_dict_type.upper()] + + if self.state_dict_type == StateDictType.FULL_STATE_DICT: + if self.state_dict_config is None: + self.state_dict_config = FullStateDictConfig(offload_to_cpu=True, rank0_only=True) + if self.optim_state_dict_config is None: + self.optim_state_dict_config = FullOptimStateDictConfig(offload_to_cpu=True, rank0_only=True) + elif self.state_dict_type == StateDictType.SHARDED_STATE_DICT: + if self.state_dict_config is None: + self.state_dict_config = ShardedStateDictConfig(offload_to_cpu=True) + if self.optim_state_dict_config is None: + self.optim_state_dict_config = ShardedOptimStateDictConfig(offload_to_cpu=True) + + if self.fsdp_version == 2 and self.state_dict_type == StateDictType.LOCAL_STATE_DICT: + raise ValueError( + "FSDP2 does not support LOCAL_STATE_DICT. " + "Please set `fsdp_state_dict_type` to `SHARDED_STATE_DICT` or `FULL_STATE_DICT`." + ) + + def set_auto_wrap_policy(self, model): + """ + Given `model`, creates an `auto_wrap_policy` based on the passed in policy and if we can use the + `transformer_cls_to_wrap` + """ + from torch.distributed.fsdp.wrap import ( + size_based_auto_wrap_policy, + transformer_auto_wrap_policy, + ) + + # First base off of `_no_split_modules` + no_split_modules = getattr(model, "_no_split_modules", None) + default_transformer_cls_names_to_wrap = list(no_split_modules) if no_split_modules is not None else [] + if self.auto_wrap_policy == transformer_auto_wrap_policy: + if self.transformer_cls_names_to_wrap is None: + self.transformer_cls_names_to_wrap = default_transformer_cls_names_to_wrap + transformer_cls_to_wrap = set() + for layer_class in self.transformer_cls_names_to_wrap: + transformer_cls = get_module_class_from_name(model, layer_class) + if transformer_cls is None: + raise ValueError(f"Could not find the transformer layer class {layer_class} in the model.") + transformer_cls_to_wrap.add(transformer_cls) + # Finally we set the auto_wrap_policy to a callable + self.auto_wrap_policy = functools.partial( + self.auto_wrap_policy, transformer_layer_cls=transformer_cls_to_wrap + ) + + elif self.auto_wrap_policy == size_based_auto_wrap_policy: + # If zero, we silently ignore it. + if self.min_num_params > 0: + self.auto_wrap_policy = functools.partial(self.auto_wrap_policy, min_num_params=self.min_num_params) + else: + self.auto_wrap_policy = None + + def set_mixed_precision(self, mixed_precision, buffer_autocast=False, override=False): + "Sets the mixed precision policy for FSDP" + mixed_precision_mapping = { + "fp8": torch.bfloat16, + "fp16": torch.float16, + "bf16": torch.bfloat16, + "fp32": torch.float32, + } + dtype = mixed_precision + if isinstance(mixed_precision, str): + dtype = mixed_precision_mapping.get(mixed_precision, None) + if dtype is None: + raise ValueError( + f"Invalid mixed precision: {mixed_precision}. Must be one of {list(mixed_precision_mapping.keys())}" + ) + elif isinstance(mixed_precision, torch.dtype) and mixed_precision not in mixed_precision_mapping.values(): + raise ValueError( + f"Invalid mixed precision: {mixed_precision}. Must be one of {list(mixed_precision_mapping.values())}" + ) + + buffer_type = torch.float32 if buffer_autocast else dtype + + if self.fsdp_version == 1: + from torch.distributed.fsdp import MixedPrecision + elif self.fsdp_version == 2: + from torch.distributed.fsdp import MixedPrecisionPolicy as MixedPrecision + + if override or self.mixed_precision_policy is None: + dtype_args = {"param_dtype": dtype, "reduce_dtype": dtype} + if self.fsdp_version == 1: + dtype_args["buffer_dtype"] = buffer_type + else: + dtype_args["output_dtype"] = dtype + # TODO(s1ro1): `cast_forward_inputs` for FSDP2? + self.mixed_precision_policy = MixedPrecision(**dtype_args) + elif isinstance(self.mixed_precision_policy, dict): + # Check for incompatible types + valid_keys = ["param_dtype", "reduce_dtype"] + ( + ["buffer_dtype"] if self.fsdp_version == 1 else ["output_dtype"] + ) + missing_keys = [k for k in valid_keys if k not in self.mixed_precision_policy] + invalid_values = [ + k for k, v in self.mixed_precision_policy.items() if v not in mixed_precision_mapping.values() + ] + if missing_keys or invalid_values: + raise ValueError( + f"Invalid mixed precision policy: {self.mixed_precision_policy}. " + f"Must be a `dict` with keys {valid_keys}." + f"Values must be one of {list(mixed_precision_mapping.values())}" + ) + self.mixed_precision_policy = MixedPrecision(**self.mixed_precision_policy) + + def validate_mixed_precision_policy(self): + """ + Validates the mixed precision policy, abstracted away to not bring in the imports if not needed. + """ + if self.fsdp_version == 2: + from torch.distributed.fsdp import MixedPrecisionPolicy as MixedPrecision + else: + from torch.distributed.fsdp import MixedPrecision + + if not isinstance(self.mixed_precision_policy, MixedPrecision): + required_type = ( + "`torch.distributed.fsdp.MixedPrecisionPolicy`" + if self.fsdp_version == 2 + else "`torch.distributed.fsdp.MixedPrecision`" + ) + raise ValueError(f"mixed_precision_policy must be an instance of {required_type}.") + + def set_cpu_offload(self): + if self.fsdp_version == 2: + from torch.distributed.fsdp import CPUOffloadPolicy, OffloadPolicy + else: + from torch.distributed.fsdp import CPUOffload + + if isinstance(self.cpu_offload, bool): + if self.fsdp_version == 2: + if not self.cpu_offload: + self.cpu_offload = OffloadPolicy() + else: + self.cpu_offload = CPUOffloadPolicy() + else: + self.cpu_offload = CPUOffload(offload_params=self.cpu_offload) + + def validate_cpu_offload(self): + if self.fsdp_version == 2: + from torch.distributed.fsdp import OffloadPolicy + else: + from torch.distributed.fsdp import CPUOffload + + if self.fsdp_version == 2 and not isinstance(self.cpu_offload, OffloadPolicy): + raise ValueError( + f"`cpu_offload` must be an instance of `torch.distributed.fsdp.OffloadPolicy` in FSDP2, got {self.cpu_offload}" + ) + if self.fsdp_version == 1 and not isinstance(self.cpu_offload, CPUOffload): + raise ValueError( + f"`cpu_offload` must be an instance of `torch.distributed.fsdp.CPUOffload` in FSDP1, got {self.cpu_offload}" + ) + + +@dataclass +class TorchTensorParallelPlugin: + """ + This plugin is used to enable tensor parallelism using PyTorch >= 2.0. + """ + + tp_size: int = field( + default=1, + metadata={"help": "tensor parallel size will be used in the device mesh preparation"}, + ) + + # torch_device_mesh is of type "torch.distributed.DeviceMesh" + torch_device_mesh: Optional["torch.distributed.DeviceMesh"] = field(default=None) + + +@dataclass +class TorchContextParallelConfig: + """ + This class holds the configuration for context parallelism in PyTorch. + """ + + cp_comm_strategy: Optional[str] = field( + default=None, + metadata={ + "help": "Communication strategy for context parallelism. Can be one of 'allgather' or 'alltoall'. Defaults to 'allgather'." + }, + ) + + def __post_init__(self): + if not is_torch_version(">=", BETA_CP_AVAILABLE_PYTORCH_VERSION): + raise ValueError( + f"FSDP2-based Context parallelism is only available in PyTorch {BETA_CP_AVAILABLE_PYTORCH_VERSION} and later versions. " + "Please upgrade your PyTorch version." + ) + + if self.cp_comm_strategy is None: + self.cp_comm_strategy = os.environ.get("PARALLELISM_CONFIG_CP_COMM_STRATEGY", "allgather") + if self.cp_comm_strategy not in ["allgather", "alltoall"]: + raise ValueError( + f"Invalid cp_comm_strategy: {self.cp_comm_strategy}. Must be one of 'allgather' or 'alltoall'." + ) + + +@dataclass +class DeepSpeedSequenceParallelConfig: + sp_seq_length: Optional[int] = field( + default=None, + metadata={ + "help": "Sequence length for when batches are all of the same length. For variable sequence lengths across batches set `sp_seq_length_is_variable=True` and leave this field unset" + }, + ) + sp_seq_length_is_variable: Optional[bool] = field( + default=None, + metadata={ + "help": "If `True` will work with a sequence length that may change between batches, in which case `sp_seq_length` value can be set to anything divisible by cp size or remain unset. If `False` then `sp_seq_length` needs to match the batch's sequence length dimension. The default is `True`." + }, + ) + sp_attn_implementation: Optional[str] = field( + default=None, + metadata={ + "help": "Attention implementation to use. Can be one of 'flash_attention_2', 'flash_attention_3' or 'sdpa'. Defaults to `sdpa`." + }, + ) + + def __post_init__(self): + # sp_seq_length_is_variable and sp_seq_length are interconnected + if self.sp_seq_length_is_variable is None: + self.sp_seq_length_is_variable = ( + os.environ.get("PARALLELISM_CONFIG_SP_SEQ_LENGTH_IS_VARIABLE", "true").lower() == "true" + ) + + if not self.sp_seq_length_is_variable and self.sp_seq_length is None: + if "PARALLELISM_CONFIG_SP_SEQ_LENGTH" not in os.environ: + raise ValueError( + "when `sp_seq_length_is_variable` is `False` `sp_seq_length` must be provided either through the constructor or the environment variable PARALLELISM_CONFIG_SP_SEQ_LENGTH" + ) + else: + self.sp_seq_length = os.environ.get("PARALLELISM_CONFIG_SP_SEQ_LENGTH") + self.sp_seq_length = None if self.sp_seq_length == "None" else int(self.sp_seq_length) + + if self.sp_attn_implementation is None: + self.sp_attn_implementation = os.environ.get("PARALLELISM_CONFIG_SP_ATTN_IMPLEMENTATION", None) + + if self.sp_attn_implementation is not None and self.sp_attn_implementation not in [ + "flash_attention_2", + "flash_attention_3", + "sdpa", + ]: + raise ValueError( + f"Invalid sp_attn_implementation: {self.sp_attn_implementation}. Must be one of 'flash_attention_2', 'flash_attention_3' or 'sdpa'." + ) + + +@dataclass +class TorchTensorParallelConfig: + """ + Use this object in your [`Accelerator`] to customize your torch tensor parallelism. + """ + + enable_async_tp: bool = False + + def __post_init__(self): + if not is_torch_version(">=", BETA_TP_AVAILABLE_PYTORCH_VERSION): + raise ValueError( + f"Torch tensor parallelism is only available in PyTorch {BETA_TP_AVAILABLE_PYTORCH_VERSION} and later versions. " + "Please upgrade your PyTorch version." + ) + + if not compare_versions("transformers", ">=", BETA_TP_AVAILABLE_TRANSFORMERS_VERSION): + raise ValueError(f"TP requires transformers >= {BETA_TP_AVAILABLE_TRANSFORMERS_VERSION}") + + if self.enable_async_tp: + warnings.warn("Async tensor parallelism is currently not supported, ignoring this option.") + + +@dataclass +class MegatronLMPlugin: + """ + Plugin for Megatron-LM to enable tensor, pipeline, sequence and data parallelism. Also to enable selective + activation recomputation and optimized fused kernels. + + Args: + tp_degree (`int`, defaults to `None`): + Tensor parallelism degree. + pp_degree (`int`, defaults to `None`): + Pipeline parallelism degree. + num_micro_batches (`int`, defaults to `None`): + Number of micro-batches. + gradient_clipping (`float`, defaults to `None`): + Gradient clipping value based on global L2 Norm (0 to disable). + sequence_parallelism (`bool`, defaults to `None`): + Enable sequence parallelism. + recompute_activations (`bool`, defaults to `None`): + Enable selective activation recomputation. + use_distributed_optimizr (`bool`, defaults to `None`): + Enable distributed optimizer. + pipeline_model_parallel_split_rank (`int`, defaults to `None`): + Rank where encoder and decoder should be split. + num_layers_per_virtual_pipeline_stage (`int`, defaults to `None`): + Number of layers per virtual pipeline stage. + is_train_batch_min (`str`, defaults to `True`): + If both tran & eval dataloaders are specified, this will decide the `micro_batch_size`. + train_iters (`int`, defaults to `None`): + Total number of samples to train over all training runs. Note that either train-iters or train-samples + should be provided when using `MegatronLMDummyScheduler`. + train_samples (`int`, defaults to `None`): + Total number of samples to train over all training runs. Note that either train-iters or train-samples + should be provided when using `MegatronLMDummyScheduler`. + weight_decay_incr_style (`str`, defaults to `'constant'`): + Weight decay increment function. choices=["constant", "linear", "cosine"]. + start_weight_decay (`float`, defaults to `None`): + Initial weight decay coefficient for L2 regularization. + end_weight_decay (`float`, defaults to `None`): + End of run weight decay coefficient for L2 regularization. + lr_decay_style (`str`, defaults to `'linear'`): + Learning rate decay function. choices=['constant', 'linear', 'cosine']. + lr_decay_iters (`int`, defaults to `None`): + Number of iterations for learning rate decay. If None defaults to `train_iters`. + lr_decay_samples (`int`, defaults to `None`): + Number of samples for learning rate decay. If None defaults to `train_samples`. + lr_warmup_iters (`int`, defaults to `None`): + Number of iterations to linearly warmup learning rate over. + lr_warmup_samples (`int`, defaults to `None`): + Number of samples to linearly warmup learning rate over. + lr_warmup_fraction (`float`, defaults to `None`): + Fraction of lr-warmup-(iters/samples) to linearly warmup learning rate over. + min_lr (`float`, defaults to `0`): + Minimum value for learning rate. The scheduler clip values below this threshold. + consumed_samples (`List`, defaults to `None`): + Number of samples consumed in the same order as the dataloaders to `accelerator.prepare` call. + no_wd_decay_cond (`Optional`, defaults to `None`): + Condition to disable weight decay. + scale_lr_cond (`Optional`, defaults to `None`): + Condition to scale learning rate. + lr_mult (`float`, defaults to `1.0`): + Learning rate multiplier. + megatron_dataset_flag (`bool`, defaults to `False`): + Whether the format of dataset follows Megatron-LM Indexed/Cached/MemoryMapped format. + seq_length (`int`, defaults to `None`): + Maximum sequence length to process. + encoder_seq_length (`int`, defaults to `None`): + Maximum sequence length to process for the encoder. + decoder_seq_length (`int`, defaults to `None`): + Maximum sequence length to process for the decoder. + tensorboard_dir (`str`, defaults to `None`): + Path to save tensorboard logs. + set_all_logging_options (`bool`, defaults to `False`): + Whether to set all logging options. + eval_iters (`int`, defaults to `100`): + Number of iterations to run for evaluation validation/test for. + eval_interval (`int`, defaults to `1000`): + Interval between running evaluation on validation set. + return_logits (`bool`, defaults to `False`): + Whether to return logits from the model. + custom_train_step_class (`Optional`, defaults to `None`): + Custom train step class. + custom_train_step_kwargs (`Optional`, defaults to `None`): + Custom train step kwargs. + custom_model_provider_function (`Optional`, defaults to `None`): + Custom model provider function. + custom_prepare_model_function (`Optional`, defaults to `None`): + Custom prepare model function. + custom_megatron_datasets_provider_function (`Optional`, defaults to `None`): + Custom megatron train_valid_test datasets provider function. + custom_get_batch_function (`Optional`, defaults to `None`): + Custom get batch function. + custom_loss_function (`Optional`, defaults to `None`): + Custom loss function. + other_megatron_args (`Optional`, defaults to `None`): + Other Megatron-LM arguments. Please refer Megatron-LM. + """ + + tp_degree: int = field(default=None, metadata={"help": "tensor parallelism degree."}) + pp_degree: int = field(default=None, metadata={"help": "pipeline parallelism degree."}) + num_micro_batches: int = field(default=None, metadata={"help": "number of micro-batches."}) + gradient_clipping: float = field( + default=None, + metadata={"help": "gradient clipping value based on global L2 Norm (0 to disable)"}, + ) + sequence_parallelism: bool = field( + default=None, + metadata={"help": "enable sequence parallelism"}, + ) + recompute_activations: bool = field( + default=None, + metadata={"help": "enable selective activation recomputation"}, + ) + use_distributed_optimizer: bool = field( + default=None, + metadata={"help": "enable distributed optimizer"}, + ) + pipeline_model_parallel_split_rank: int = field( + default=None, + metadata={"help": "Rank where encoder and decoder should be split."}, + ) + num_layers_per_virtual_pipeline_stage: int = field( + default=None, metadata={"help": "Number of layers per virtual pipeline stage."} + ) + is_train_batch_min: str = field( + default=True, + metadata={"help": "If both train & eval dataloaders are specified, this will decide the micro_batch_size"}, + ) + train_iters: int = field( + default=None, + metadata={ + "help": "Total number of iterations to train over all training runs. " + "Note that either train-iters or train-samples should be provided when using `MegatronLMDummyScheduler`" + }, + ) + train_samples: int = field( + default=None, + metadata={ + "help": "Total number of samples to train over all training runs. " + "Note that either train-iters or train-samples should be provided when using `MegatronLMDummyScheduler`" + }, + ) + weight_decay_incr_style: str = field( + default="constant", + metadata={"help": 'Weight decay increment function. choices=["constant", "linear", "cosine"]. '}, + ) + start_weight_decay: float = field( + default=None, + metadata={"help": "Initial weight decay coefficient for L2 regularization."}, + ) + end_weight_decay: float = field( + default=None, + metadata={"help": "End of run weight decay coefficient for L2 regularization."}, + ) + lr_decay_style: str = field( + default="linear", + metadata={"help": "Learning rate decay function. choices=['constant', 'linear', 'cosine']."}, + ) + lr_decay_iters: int = field( + default=None, + metadata={"help": "Number of iterations for learning rate decay. If None defaults to `train_iters`."}, + ) + lr_decay_samples: int = field( + default=None, + metadata={"help": "Number of samples for learning rate decay. If None defaults to `train_samples`."}, + ) + lr_warmup_iters: int = field( + default=None, + metadata={"help": "number of iterations to linearly warmup learning rate over."}, + ) + lr_warmup_samples: int = field( + default=None, + metadata={"help": "number of samples to linearly warmup learning rate over."}, + ) + lr_warmup_fraction: float = field( + default=None, + metadata={"help": "fraction of lr-warmup-(iters/samples) to linearly warmup learning rate over."}, + ) + min_lr: float = field( + default=0, + metadata={"help": "Minimum value for learning rate. The scheduler clip values below this threshold."}, + ) + consumed_samples: list[int] = field( + default=None, + metadata={ + "help": "Number of samples consumed in the same order as the dataloaders to `accelerator.prepare` call." + }, + ) + no_wd_decay_cond: Optional[Callable] = field(default=None, metadata={"help": "Condition to disable weight decay."}) + scale_lr_cond: Optional[Callable] = field(default=None, metadata={"help": "Condition to scale learning rate."}) + lr_mult: float = field(default=1.0, metadata={"help": "Learning rate multiplier."}) + megatron_dataset_flag: bool = field( + default=False, + metadata={"help": "Whether the format of dataset follows Megatron-LM Indexed/Cached/MemoryMapped format."}, + ) + seq_length: int = field( + default=None, + metadata={"help": "Maximum sequence length to process."}, + ) + encoder_seq_length: int = field( + default=None, + metadata={"help": "Maximum sequence length to process for the encoder."}, + ) + decoder_seq_length: int = field( + default=None, + metadata={"help": "Maximum sequence length to process for the decoder."}, + ) + tensorboard_dir: str = field( + default=None, + metadata={"help": "Path to save tensorboard logs."}, + ) + set_all_logging_options: bool = field( + default=False, + metadata={"help": "Whether to set all logging options."}, + ) + eval_iters: int = field( + default=100, + metadata={"help": "Number of iterations to run for evaluation validation/test for."}, + ) + eval_interval: int = field( + default=1000, + metadata={"help": "Interval between running evaluation on validation set."}, + ) + return_logits: bool = field( + default=False, + metadata={"help": "Whether to return logits from the model."}, + ) + + # custom train step args + custom_train_step_class: Optional[Any] = field( + default=None, + metadata={"help": "Custom train step class."}, + ) + custom_train_step_kwargs: Optional[dict[str, Any]] = field( + default=None, + metadata={"help": "Custom train step kwargs."}, + ) + + # custom model args + custom_model_provider_function: Optional[Callable] = field( + default=None, + metadata={"help": "Custom model provider function."}, + ) + custom_prepare_model_function: Optional[Callable] = field( + default=None, + metadata={"help": "Custom prepare model function."}, + ) + custom_megatron_datasets_provider_function: Optional[Callable] = field( + default=None, + metadata={"help": "Custom megatron train_valid_test datasets provider function."}, + ) + custom_get_batch_function: Optional[Callable] = field( + default=None, + metadata={"help": "Custom get batch function."}, + ) + custom_loss_function: Optional[Callable] = field( + default=None, + metadata={"help": "Custom loss function."}, + ) + + # remaining args such as enabling Alibi/ROPE positional embeddings, + # wandb logging, Multi-Query Attention, etc. + other_megatron_args: Optional[dict[str, Any]] = field( + default=None, + metadata={"help": "Other Megatron-LM arguments. Please refer Megatron-LM"}, + ) + + def __post_init__(self): + prefix = "MEGATRON_LM_" + if self.tp_degree is None: + self.tp_degree = int(os.environ.get(prefix + "TP_DEGREE", 1)) + if self.pp_degree is None: + self.pp_degree = int(os.environ.get(prefix + "PP_DEGREE", 1)) + if self.num_micro_batches is None: + self.num_micro_batches = int(os.environ.get(prefix + "NUM_MICRO_BATCHES", 1)) + if self.gradient_clipping is None: + self.gradient_clipping = float(os.environ.get(prefix + "GRADIENT_CLIPPING", 1.0)) + if self.recompute_activations is None: + self.recompute_activations = str_to_bool(os.environ.get(prefix + "RECOMPUTE_ACTIVATIONS", "False")) == 1 + if self.use_distributed_optimizer is None: + self.use_distributed_optimizer = ( + str_to_bool(os.environ.get(prefix + "USE_DISTRIBUTED_OPTIMIZER", "False")) == 1 + ) + if self.sequence_parallelism is None: + self.sequence_parallelism = str_to_bool(os.environ.get(prefix + "SEQUENCE_PARALLELISM", "False")) == 1 + + if self.pp_degree > 1 or self.use_distributed_optimizer: + self.DDP_impl = "local" + else: + self.DDP_impl = "torch" + + if self.consumed_samples is not None: + if len(self.consumed_samples) == 1: + self.consumed_samples.extend([0, 0]) + elif len(self.consumed_samples) == 2: + self.consumed_samples.append(0) + + self.megatron_lm_default_args = { + "tensor_model_parallel_size": self.tp_degree, + "pipeline_model_parallel_size": self.pp_degree, + "pipeline_model_parallel_split_rank": self.pipeline_model_parallel_split_rank, + "num_layers_per_virtual_pipeline_stage": self.num_layers_per_virtual_pipeline_stage, + "DDP_impl": self.DDP_impl, + "use_distributed_optimizer": self.use_distributed_optimizer, + "sequence_parallel": self.sequence_parallelism, + "clip_grad": self.gradient_clipping, + "num_micro_batches": self.num_micro_batches, + "consumed_samples": self.consumed_samples, + "no_wd_decay_cond": self.no_wd_decay_cond, + "scale_lr_cond": self.scale_lr_cond, + "lr_mult": self.lr_mult, + "megatron_dataset_flag": self.megatron_dataset_flag, + "eval_iters": self.eval_iters, + "eval_interval": self.eval_interval, + } + if self.recompute_activations: + self.megatron_lm_default_args["recompute_granularity"] = "selective" + if self.tensorboard_dir is not None: + self.megatron_lm_default_args["tensorboard_dir"] = self.tensorboard_dir + if self.set_all_logging_options: + self.set_tensorboard_logging_options() + if self.other_megatron_args is not None: + self.megatron_lm_default_args.update(self.other_megatron_args) + + def set_network_size_args(self, model, batch_data=None): + model_config_type = model.config.model_type.lower() + for model_type in MODEL_CONFIGS_TO_MEGATRON_PARSERS.keys(): + if model_type in model_config_type: + MODEL_CONFIGS_TO_MEGATRON_PARSERS[model_type](self, model, batch_data) + return + raise ValueError( + f"Accelerate Megatron-LM integration not supports {model_config_type} model. " + "You can add your own model config parser." + ) + + def set_mixed_precision(self, mixed_precision): + if mixed_precision == "fp16": + self.megatron_lm_default_args["fp16"] = True + elif mixed_precision == "bf16": + self.megatron_lm_default_args["bf16"] = True + self.DDP_impl = "local" + self.megatron_lm_default_args["DDP_impl"] = self.DDP_impl + + def set_training_args(self, micro_batch_size, dp_degree): + self.data_parallel_size = dp_degree + self.micro_batch_size = micro_batch_size + self.global_batch_size = dp_degree * micro_batch_size * self.num_micro_batches + self.megatron_lm_default_args["data_parallel_size"] = self.data_parallel_size + self.megatron_lm_default_args["micro_batch_size"] = self.micro_batch_size + self.megatron_lm_default_args["global_batch_size"] = self.global_batch_size + + def set_optimizer_type(self, optimizer): + optimizer_name = optimizer.__class__.__name__.lower() + if "adam" in optimizer_name: + self.megatron_lm_default_args["optimizer"] = "adam" + self.megatron_lm_default_args["adam_beta1"] = optimizer.defaults["betas"][0] + self.megatron_lm_default_args["adam_beta2"] = optimizer.defaults["betas"][1] + self.megatron_lm_default_args["adam_eps"] = optimizer.defaults["eps"] + elif "sgd" in optimizer_name: + self.megatron_lm_default_args["optimizer"] = "sgd" + self.megatron_lm_default_args["sgd_momentum"] = optimizer.defaults["momentum"] + else: + raise ValueError(f"Optimizer {optimizer_name} is not supported by Megatron-LM") + + self.megatron_lm_default_args["lr"] = optimizer.defaults["lr"] + self.megatron_lm_default_args["weight_decay"] = optimizer.defaults["weight_decay"] + + def set_scheduler_args(self, scheduler): + if self.train_iters is None: + self.train_iters = scheduler.total_num_steps // self.megatron_lm_default_args["data_parallel_size"] + if self.train_samples is not None: + self.train_samples = None + warnings.warn( + "Ignoring `train_samples` as `train_iters` based on scheduler is being used for training." + ) + if self.lr_warmup_iters is None: + self.lr_warmup_iters = scheduler.warmup_num_steps // self.megatron_lm_default_args["data_parallel_size"] + if self.lr_warmup_samples is not None: + warnings.warn( + "Ignoring `lr_warmup_samples` as `lr_warmup_iters` based on scheduler is being used for training." + ) + self.lr_warmup_samples = 0 + + self.megatron_lm_default_args["train_iters"] = self.train_iters + self.megatron_lm_default_args["lr_warmup_iters"] = self.lr_warmup_iters + self.megatron_lm_default_args["train_samples"] = self.train_samples + self.megatron_lm_default_args["lr_warmup_samples"] = self.lr_warmup_samples + self.megatron_lm_default_args["lr_decay_iters"] = self.lr_decay_iters + self.megatron_lm_default_args["lr_decay_samples"] = self.lr_decay_samples + self.megatron_lm_default_args["lr_warmup_fraction"] = self.lr_warmup_fraction + self.megatron_lm_default_args["lr_decay_style"] = self.lr_decay_style + self.megatron_lm_default_args["weight_decay_incr_style"] = self.weight_decay_incr_style + self.megatron_lm_default_args["start_weight_decay"] = self.start_weight_decay + self.megatron_lm_default_args["end_weight_decay"] = self.end_weight_decay + self.megatron_lm_default_args["min_lr"] = self.min_lr + + def set_tensorboard_logging_options(self): + from megatron.training.arguments import _add_logging_args + + parser = argparse.ArgumentParser() + parser = _add_logging_args(parser) + logging_args = parser.parse_known_args() + self.dataset_args = vars(logging_args[0]) + for key, value in self.dataset_args.items(): + if key.startswith("log_"): + self.megatron_lm_default_args[key] = True + elif key.startswith("no_log_"): + self.megatron_lm_default_args[key.replace("no_", "")] = True + + +MODEL_CONFIGS_TO_MEGATRON_PARSERS = {} + + +def add_model_config_to_megatron_parser(model_type: str): + def add_model_config_parser_helper(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + return func(*args, **kwargs) + + MODEL_CONFIGS_TO_MEGATRON_PARSERS[model_type] = func + return wrapper + + return add_model_config_parser_helper + + +@add_model_config_to_megatron_parser("megatron-bert") +def parse_bert_config(megatron_lm_plugin, model, batch_data): + model_type_name = "bert" + num_layers = model.config.num_hidden_layers + hidden_size = model.config.hidden_size + num_attention_heads = model.config.num_attention_heads + max_position_embeddings = model.config.max_position_embeddings + num_labels = model.config.num_labels + orig_vocab_size = model.config.vocab_size + pretraining_flag = False + if "maskedlm" in model.__class__.__name__.lower(): + pretraining_flag = True + if megatron_lm_plugin.seq_length is not None: + if megatron_lm_plugin.encoder_seq_length is not None: + warnings.warn("Both `seq_length` and `encoder_seq_length` are set. Using `encoder_seq_length`.") + megatron_lm_plugin.seq_length = megatron_lm_plugin.encoder_seq_length + elif megatron_lm_plugin.encoder_seq_length is not None: + megatron_lm_plugin.seq_length = megatron_lm_plugin.encoder_seq_length + elif batch_data is not None: + megatron_lm_plugin.seq_length = batch_data["input_ids"].shape[1] + else: + megatron_lm_plugin.seq_length = max_position_embeddings + megatron_lm_plugin.megatron_lm_default_args["seq_length"] = megatron_lm_plugin.seq_length + megatron_lm_plugin.megatron_lm_default_args["model_type_name"] = model_type_name + megatron_lm_plugin.megatron_lm_default_args["num_layers"] = num_layers + megatron_lm_plugin.megatron_lm_default_args["hidden_size"] = hidden_size + megatron_lm_plugin.megatron_lm_default_args["num_attention_heads"] = num_attention_heads + megatron_lm_plugin.megatron_lm_default_args["max_position_embeddings"] = max_position_embeddings + megatron_lm_plugin.megatron_lm_default_args["pretraining_flag"] = pretraining_flag + megatron_lm_plugin.megatron_lm_default_args["orig_vocab_size"] = orig_vocab_size + megatron_lm_plugin.megatron_lm_default_args["model_return_dict"] = model.config.return_dict + megatron_lm_plugin.megatron_lm_default_args["num_labels"] = num_labels + + +@add_model_config_to_megatron_parser("gpt2") +def parse_gpt2_config(megatron_lm_plugin, model, batch_data): + model_type_name = "gpt" + num_layers = model.config.n_layer + hidden_size = model.config.n_embd + num_attention_heads = model.config.n_head + max_position_embeddings = model.config.n_positions + orig_vocab_size = model.config.vocab_size + pretraining_flag = True + if megatron_lm_plugin.seq_length is not None: + if megatron_lm_plugin.decoder_seq_length is not None: + warnings.warn("Both `seq_length` and `decoder_seq_length` are set. Using `decoder_seq_length`.") + megatron_lm_plugin.seq_length = megatron_lm_plugin.decoder_seq_length + elif megatron_lm_plugin.decoder_seq_length is not None: + megatron_lm_plugin.seq_length = megatron_lm_plugin.decoder_seq_length + elif batch_data is not None: + megatron_lm_plugin.seq_length = batch_data["input_ids"].shape[1] + else: + megatron_lm_plugin.seq_length = max_position_embeddings + megatron_lm_plugin.megatron_lm_default_args["seq_length"] = megatron_lm_plugin.seq_length + megatron_lm_plugin.megatron_lm_default_args["return_logits"] = megatron_lm_plugin.return_logits + megatron_lm_plugin.megatron_lm_default_args["tokenizer_type"] = "GPT2BPETokenizer" + megatron_lm_plugin.megatron_lm_default_args["model_type_name"] = model_type_name + megatron_lm_plugin.megatron_lm_default_args["num_layers"] = num_layers + megatron_lm_plugin.megatron_lm_default_args["hidden_size"] = hidden_size + megatron_lm_plugin.megatron_lm_default_args["num_attention_heads"] = num_attention_heads + megatron_lm_plugin.megatron_lm_default_args["max_position_embeddings"] = max_position_embeddings + megatron_lm_plugin.megatron_lm_default_args["pretraining_flag"] = pretraining_flag + megatron_lm_plugin.megatron_lm_default_args["orig_vocab_size"] = orig_vocab_size + megatron_lm_plugin.megatron_lm_default_args["model_return_dict"] = model.config.return_dict + + +@add_model_config_to_megatron_parser("t5") +def parse_t5_config(megatron_lm_plugin, model, batch_data): + model_type_name = "t5" + num_layers = model.config.num_layers + hidden_size = model.config.d_model + num_attention_heads = model.config.num_heads + max_position_embeddings = model.config.n_positions if hasattr(model.config, "n_positions") else 1024 + orig_vocab_size = model.config.vocab_size + pretraining_flag = True + if megatron_lm_plugin.encoder_seq_length is None: + if batch_data is not None: + megatron_lm_plugin.encoder_seq_length = batch_data["input_ids"].shape[1] + else: + megatron_lm_plugin.encoder_seq_length = max_position_embeddings + if megatron_lm_plugin.decoder_seq_length is None: + if batch_data is not None: + megatron_lm_plugin.decoder_seq_length = batch_data["labels"].shape[1] + else: + megatron_lm_plugin.decoder_seq_length = max_position_embeddings + megatron_lm_plugin.megatron_lm_default_args["encoder_seq_length"] = megatron_lm_plugin.encoder_seq_length + megatron_lm_plugin.megatron_lm_default_args["decoder_seq_length"] = megatron_lm_plugin.decoder_seq_length + megatron_lm_plugin.megatron_lm_default_args["model_type_name"] = model_type_name + megatron_lm_plugin.megatron_lm_default_args["num_layers"] = num_layers + megatron_lm_plugin.megatron_lm_default_args["hidden_size"] = hidden_size + megatron_lm_plugin.megatron_lm_default_args["num_attention_heads"] = num_attention_heads + megatron_lm_plugin.megatron_lm_default_args["max_position_embeddings"] = max_position_embeddings + megatron_lm_plugin.megatron_lm_default_args["pretraining_flag"] = pretraining_flag + megatron_lm_plugin.megatron_lm_default_args["orig_vocab_size"] = orig_vocab_size + megatron_lm_plugin.megatron_lm_default_args["model_return_dict"] = model.config.return_dict + + +@add_model_config_to_megatron_parser("llama") +def parse_llama_config(megatron_lm_plugin, model, batch_data): + model_type_name = "gpt" + num_layers = model.config.num_hidden_layers + pretraining_flag = True + hidden_size = model.config.hidden_size + num_attention_heads = model.config.num_attention_heads + orig_vocab_size = model.config.vocab_size + + max_position_embeddings = model.config.max_position_embeddings + seq_length = getattr(model.config, "max_sequence_length", None) + if megatron_lm_plugin.seq_length is None: + if seq_length is not None: + megatron_lm_plugin.seq_length = seq_length + elif megatron_lm_plugin.decoder_seq_length is not None: + megatron_lm_plugin.seq_length = megatron_lm_plugin.decoder_seq_length + elif batch_data is not None: + megatron_lm_plugin.seq_length = batch_data["input_ids"].shape[1] + else: + megatron_lm_plugin.seq_length = max_position_embeddings + + megatron_lm_plugin.megatron_lm_default_args["return_logits"] = megatron_lm_plugin.return_logits + megatron_lm_plugin.megatron_lm_default_args["tokenizer_type"] = "Llama2Tokenizer" + megatron_lm_plugin.megatron_lm_default_args["model_type_name"] = model_type_name + megatron_lm_plugin.megatron_lm_default_args["num_layers"] = num_layers + megatron_lm_plugin.megatron_lm_default_args["pretraining_flag"] = pretraining_flag + megatron_lm_plugin.megatron_lm_default_args["hidden_size"] = hidden_size + megatron_lm_plugin.megatron_lm_default_args["num_attention_heads"] = num_attention_heads + megatron_lm_plugin.megatron_lm_default_args["orig_vocab_size"] = orig_vocab_size + megatron_lm_plugin.megatron_lm_default_args["max_position_embeddings"] = max_position_embeddings + megatron_lm_plugin.megatron_lm_default_args["seq_length"] = megatron_lm_plugin.seq_length + megatron_lm_plugin.megatron_lm_default_args["model_return_dict"] = model.config.return_dict + + +@dataclass +class BnbQuantizationConfig: + """ + A plugin to enable BitsAndBytes 4bit and 8bit quantization + + Args: + load_in_8bit (`bool`, defaults to `False`): + Enable 8bit quantization. + llm_int8_threshold (`float`, defaults to `6.0`): + Value of the outliner threshold. Only relevant when `load_in_8bit=True`. + load_in_4bit (`bool`, defaults to `False`): + Enable 4bit quantization. + bnb_4bit_quant_type (`str`, defaults to `fp4`): + Set the quantization data type in the `bnb.nn.Linear4Bit` layers. Options are {'fp4','np4'}. + bnb_4bit_use_double_quant (`bool`, defaults to `False`): + Enable nested quantization where the quantization constants from the first quantization are quantized + again. + bnb_4bit_compute_dtype (`bool`, defaults to `fp16`): + This sets the computational type which might be different than the input time. For example, inputs might be + fp32, but computation can be set to bf16 for speedups. Options are {'fp32','fp16','bf16'}. + torch_dtype (`torch.dtype`, defaults to `None`): + This sets the dtype of the remaining non quantized layers. `bitsandbytes` library suggests to set the value + to `torch.float16` for 8 bit model and use the same dtype as the compute dtype for 4 bit model. + skip_modules (`List[str]`, defaults to `None`): + An explicit list of the modules that we don't quantize. The dtype of these modules will be `torch_dtype`. + keep_in_fp32_modules (`List`, defaults to `None`): + An explicit list of the modules that we don't quantize. We keep them in `torch.float32`. + """ + + load_in_8bit: bool = field(default=False, metadata={"help": "enable 8bit quantization."}) + + llm_int8_threshold: float = field( + default=6.0, + metadata={"help": "value of the outliner threshold. only relevant when load_in_8bit=True"}, + ) + + load_in_4bit: bool = field(default=False, metadata={"help": "enable 4bit quantization."}) + + bnb_4bit_quant_type: str = field( + default="fp4", + metadata={ + "help": "set the quantization data type in the `bnb.nn.Linear4Bit` layers. Options are {'fp4','nf4'}." + }, + ) + + bnb_4bit_use_double_quant: bool = field( + default=False, + metadata={ + "help": "enable nested quantization where the quantization constants from the first quantization are quantized again." + }, + ) + + bnb_4bit_compute_dtype: str = field( + default="fp16", + metadata={ + "help": "This sets the computational type which might be different than the input time. For example, inputs might be " + "fp32, but computation can be set to bf16 for speedups. Options are {'fp32','fp16','bf16'}." + }, + ) + + torch_dtype: torch.dtype = field( + default=None, + metadata={ + "help": "this sets the dtype of the remaining non quantized layers. `bitsandbytes` library suggests to set the value" + "to `torch.float16` for 8 bit model and use the same dtype as the compute dtype for 4 bit model " + }, + ) + + skip_modules: list[str] = field( + default=None, + metadata={ + "help": "an explicit list of the modules that we don't quantize. The dtype of these modules will be `torch_dtype`." + }, + ) + + keep_in_fp32_modules: list[str] = field( + default=None, + metadata={"help": "an explicit list of the modules that we don't quantize. We keep them in `torch.float32`."}, + ) + + def __post_init__(self): + """ + Safety checker that arguments are correct - also replaces some NoneType arguments with their default values. + """ + if not isinstance(self.load_in_8bit, bool): + raise ValueError("load_in_8bit must be a boolean") + + if not isinstance(self.load_in_4bit, bool): + raise ValueError("load_in_4bit must be a boolean") + + if self.load_in_4bit and self.load_in_8bit: + raise ValueError("load_in_4bit and load_in_8bit can't be both True") + + if not self.load_in_4bit and not self.load_in_8bit: + raise ValueError("load_in_4bit and load_in_8bit can't be both False") + + if not isinstance(self.llm_int8_threshold, (int, float)): + raise ValueError("llm_int8_threshold must be a float or an int") + + if not isinstance(self.bnb_4bit_quant_type, str): + raise ValueError("bnb_4bit_quant_type must be a string") + elif self.bnb_4bit_quant_type not in ["fp4", "nf4"]: + raise ValueError(f"bnb_4bit_quant_type must be in ['fp4','nf4'] but found {self.bnb_4bit_quant_type}") + + if not isinstance(self.bnb_4bit_use_double_quant, bool): + raise ValueError("bnb_4bit_use_double_quant must be a boolean") + + if isinstance(self.bnb_4bit_compute_dtype, str): + if self.bnb_4bit_compute_dtype == "fp32": + self.bnb_4bit_compute_dtype = torch.float32 + elif self.bnb_4bit_compute_dtype == "fp16": + self.bnb_4bit_compute_dtype = torch.float16 + elif self.bnb_4bit_compute_dtype == "bf16": + self.bnb_4bit_compute_dtype = torch.bfloat16 + else: + raise ValueError( + f"bnb_4bit_compute_dtype must be in ['fp32','fp16','bf16'] but found {self.bnb_4bit_compute_dtype}" + ) + elif not isinstance(self.bnb_4bit_compute_dtype, torch.dtype): + raise ValueError("bnb_4bit_compute_dtype must be a string or a torch.dtype") + + if self.skip_modules is not None and not isinstance(self.skip_modules, list): + raise ValueError("skip_modules must be a list of strings") + + if self.keep_in_fp32_modules is not None and not isinstance(self.keep_in_fp32_modules, list): + raise ValueError("keep_in_fp_32_modules must be a list of strings") + + if self.load_in_4bit: + self.target_dtype = CustomDtype.INT4 + + if self.load_in_8bit: + self.target_dtype = torch.int8 + + if self.load_in_4bit and self.llm_int8_threshold != 6.0: + warnings.warn("llm_int8_threshold can only be used for model loaded in 8bit") + + if isinstance(self.torch_dtype, str): + if self.torch_dtype == "fp32": + self.torch_dtype = torch.float32 + elif self.torch_dtype == "fp16": + self.torch_dtype = torch.float16 + elif self.torch_dtype == "bf16": + self.torch_dtype = torch.bfloat16 + else: + raise ValueError(f"torch_dtype must be in ['fp32','fp16','bf16'] but found {self.torch_dtype}") + if self.load_in_8bit and self.torch_dtype is None: + self.torch_dtype = torch.float16 + + if self.load_in_4bit and self.torch_dtype is None: + self.torch_dtype = self.bnb_4bit_compute_dtype + + if not isinstance(self.torch_dtype, torch.dtype): + raise ValueError("torch_dtype must be a torch.dtype") + + +def get_module_class_from_name(module, name): + """ + Gets a class from a module by its name. + + Args: + module (`torch.nn.Module`): The module to get the class from. + name (`str`): The name of the class. + """ + modules_children = list(module.children()) + if module.__class__.__name__ == name: + return module.__class__ + elif len(modules_children) == 0: + return + else: + for child_module in modules_children: + module_class = get_module_class_from_name(child_module, name) + if module_class is not None: + return module_class diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/deepspeed.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/deepspeed.py new file mode 100644 index 0000000000000000000000000000000000000000..22db891c63d9bd48691acd87a15a206c270017a9 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/deepspeed.py @@ -0,0 +1,385 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import base64 +import json +import os +from copy import deepcopy + +from torch import optim + +from ..optimizer import AcceleratedOptimizer +from ..scheduler import AcceleratedScheduler +from .dataclasses import DistributedType +from .imports import is_bnb_available +from .versions import compare_versions + + +def map_pytorch_optim_to_deepspeed(optimizer): + """ + Args: + optimizer: torch.optim.Optimizer + + Returns the DeepSeedCPUOptimizer (deepspeed.ops) version of the optimizer. + """ + + defaults = {k: v for k, v in optimizer.defaults.items() if k in ["lr", "weight_decay"]} + + # Select the DeepSpeedCPUOptimizer based on the original optimizer class. + # DeepSpeedCPUAdam is the default + from deepspeed.ops.adam import DeepSpeedCPUAdam + + optimizer_class = DeepSpeedCPUAdam + + # For DeepSpeedCPUAdam (adamw_mode) + if compare_versions("deepspeed", ">=", "0.3.1"): + defaults["adamw_mode"] = False + is_adaw = isinstance(optimizer, optim.AdamW) + + if is_bnb_available() and not is_adaw: + import bitsandbytes.optim as bnb_opt + + if isinstance(optimizer, (bnb_opt.AdamW, bnb_opt.AdamW32bit)): + try: + is_adaw = optimizer.optim_bits == 32 + except AttributeError: + is_adaw = optimizer.args.optim_bits == 32 + else: + is_adaw = False + + if is_adaw: + defaults["adamw_mode"] = True + + # For DeepSpeedCPUAdagrad + if compare_versions("deepspeed", ">=", "0.5.5"): + # Check if the optimizer is PyTorch's Adagrad. + is_ada = isinstance(optimizer, optim.Adagrad) + # If not, and bitsandbytes is available, + # # check if the optimizer is the 32-bit bitsandbytes Adagrad. + if is_bnb_available() and not is_ada: + import bitsandbytes.optim as bnb_opt + + if isinstance(optimizer, (bnb_opt.Adagrad, bnb_opt.Adagrad32bit)): + try: + is_ada = optimizer.optim_bits == 32 + except AttributeError: + is_ada = optimizer.args.optim_bits == 32 + if is_ada: + from deepspeed.ops.adagrad import DeepSpeedCPUAdagrad + + optimizer_class = DeepSpeedCPUAdagrad + + # For DeepSpeedCPULion + if is_bnb_available(min_version="0.38.0") and compare_versions("deepspeed", ">=", "0.11.0"): + from bitsandbytes.optim import Lion, Lion32bit + + if isinstance(optimizer, (Lion, Lion32bit)): + try: + is_bnb_32bits = optimizer.optim_bits == 32 + except AttributeError: + is_bnb_32bits = optimizer.args.optim_bits == 32 + if is_bnb_32bits: + from deepspeed.ops.lion import DeepSpeedCPULion + + optimizer_class = DeepSpeedCPULion + + return optimizer_class(optimizer.param_groups, **defaults) + + +def get_active_deepspeed_plugin(state): + """ + Returns the currently active DeepSpeedPlugin. + + Raises: + ValueError: If DeepSpeed was not enabled and this function is called. + """ + if state.distributed_type != DistributedType.DEEPSPEED: + raise ValueError( + "Couldn't retrieve the active `DeepSpeedPlugin` as none were enabled. " + "Please make sure that either `Accelerator` is configured for `deepspeed` " + "or make sure that the desired `DeepSpeedPlugin` has been enabled (`AcceleratorState().select_deepspeed_plugin(name)`) " + "before calling this function." + ) + if not isinstance(state.deepspeed_plugins, dict): + return state.deepspeed_plugins + return next(plugin for plugin in state.deepspeed_plugins.values() if plugin.selected) + + +class HfDeepSpeedConfig: + """ + This object contains a DeepSpeed configuration dictionary and can be quickly queried for things like zero stage. + + A `weakref` of this object is stored in the module's globals to be able to access the config from areas where + things like the Trainer object is not available (e.g. `from_pretrained` and `_get_resized_embeddings`). Therefore + it's important that this object remains alive while the program is still running. + + [`Trainer`] uses the `HfTrainerDeepSpeedConfig` subclass instead. That subclass has logic to sync the configuration + with values of [`TrainingArguments`] by replacing special placeholder values: `"auto"`. Without this special logic + the DeepSpeed configuration is not modified in any way. + + Args: + config_file_or_dict (`Union[str, Dict]`): path to DeepSpeed config file or dict. + + """ + + def __init__(self, config_file_or_dict): + if isinstance(config_file_or_dict, dict): + # Don't modify user's data should they want to reuse it (e.g. in tests), because once we + # modified it, it will not be accepted here again, since `auto` values would have been overridden + config = deepcopy(config_file_or_dict) + elif os.path.exists(config_file_or_dict): + with open(config_file_or_dict, encoding="utf-8") as f: + config = json.load(f) + else: + try: + try: + # First try parsing as JSON directly + config = json.loads(config_file_or_dict) + except json.JSONDecodeError: + # If that fails, try base64 decoding + config_decoded = base64.urlsafe_b64decode(config_file_or_dict).decode("utf-8") + config = json.loads(config_decoded) + except (UnicodeDecodeError, AttributeError, ValueError): + raise ValueError( + f"Expected a string path to an existing deepspeed config, or a dictionary, or a base64 encoded string. Received: {config_file_or_dict}" + ) + + self.config = config + + self.set_stage_and_offload() + + def set_stage_and_offload(self): + # zero stage - this is done as early as possible, before model is created, to allow + # ``is_deepspeed_zero3_enabled`` query and getting to the early deepspeed config object + # during ``zero.Init()`` which needs to know the dtype, and some other hparams. + self._stage = self.get_value("zero_optimization.stage", -1) + + # offload + self._offload = False + if self.is_zero2() or self.is_zero3(): + offload_devices_valid = set(["cpu", "nvme"]) + offload_devices = set( + [ + self.get_value("zero_optimization.offload_optimizer.device"), + self.get_value("zero_optimization.offload_param.device"), + ] + ) + if len(offload_devices & offload_devices_valid) > 0: + self._offload = True + + def find_config_node(self, ds_key_long): + config = self.config + + # find the config node of interest if it exists + nodes = ds_key_long.split(".") + ds_key = nodes.pop() + for node in nodes: + config = config.get(node) + if config is None: + return None, ds_key + + return config, ds_key + + def get_value(self, ds_key_long, default=None): + """ + Returns the set value or `default` if no value is set + """ + config, ds_key = self.find_config_node(ds_key_long) + if config is None: + return default + return config.get(ds_key, default) + + def del_config_sub_tree(self, ds_key_long, must_exist=False): + """ + Deletes a sub-section of the config file if it's found. + + Unless `must_exist` is `True` the section doesn't have to exist. + """ + config = self.config + + # find the config node of interest if it exists + nodes = ds_key_long.split(".") + for node in nodes: + parent_config = config + config = config.get(node) + if config is None: + if must_exist: + raise ValueError(f"Can't find {ds_key_long} entry in the config: {self.config}") + else: + return + + # if found remove it + if parent_config is not None: + parent_config.pop(node) + + def is_true(self, ds_key_long): + """ + Returns `True`/``False` only if the value is set, always `False` otherwise. So use this method to ask the very + specific question of whether the value is set to `True` (and it's not set to `False`` or isn't set). + + """ + value = self.get_value(ds_key_long) + return False if value is None else bool(value) + + def is_false(self, ds_key_long): + """ + Returns `True`/``False` only if the value is set, always `False` otherwise. So use this method to ask the very + specific question of whether the value is set to `False` (and it's not set to `True`` or isn't set). + """ + value = self.get_value(ds_key_long) + return False if value is None else not bool(value) + + def is_zero2(self): + return self._stage == 2 + + def is_zero3(self): + return self._stage == 3 + + def is_offload(self): + return self._offload + + +class DeepSpeedEngineWrapper: + """ + Internal wrapper for deepspeed.runtime.engine.DeepSpeedEngine. This is used to follow conventional training loop. + + Args: + engine (deepspeed.runtime.engine.DeepSpeedEngine): deepspeed engine to wrap + """ + + def __init__(self, engine): + self.engine = engine + + def backward(self, loss, sync_gradients=True, **kwargs): + # Set gradient accumulation boundary based on Accelerate's sync_gradients state + # This tells DeepSpeed whether this is the final micro-batch before gradient sync + self.engine.set_gradient_accumulation_boundary(is_boundary=sync_gradients) + + # runs backpropagation and handles mixed precision + self.engine.backward(loss, **kwargs) + + # Only perform step and related operations at gradient accumulation boundaries + if sync_gradients: + # Deepspeed's `engine.step` performs the following operations: + # - gradient accumulation check + # - gradient clipping + # - optimizer step + # - zero grad + # - checking overflow + # - lr_scheduler step (only if engine.lr_scheduler is not None) + self.engine.step() + # and this plugin overrides the above calls with no-ops when Accelerate runs under + # Deepspeed, but allows normal functionality for non-Deepspeed cases thus enabling a simple + # training loop that works transparently under many training regimes. + + def get_global_grad_norm(self): + """Get the global gradient norm from DeepSpeed engine.""" + grad_norm = self.engine.get_global_grad_norm() + # Convert to scalar if it's a tensor + if hasattr(grad_norm, "item"): + return grad_norm.item() + return grad_norm + + +class DeepSpeedOptimizerWrapper(AcceleratedOptimizer): + """ + Internal wrapper around a deepspeed optimizer. + + Args: + optimizer (`torch.optim.optimizer.Optimizer`): + The optimizer to wrap. + """ + + def __init__(self, optimizer): + super().__init__(optimizer, device_placement=False, scaler=None) + self.__has_overflow__ = hasattr(self.optimizer, "overflow") + + def zero_grad(self, set_to_none=None): + pass # `accelerator.backward(loss)` is doing that automatically. Therefore, its implementation is not needed + + def step(self): + pass # `accelerator.backward(loss)` is doing that automatically. Therefore, its implementation is not needed + + @property + def step_was_skipped(self): + """Whether or not the optimizer step was done, or skipped because of gradient overflow.""" + if self.__has_overflow__: + return self.optimizer.overflow + return False + + +class DeepSpeedSchedulerWrapper(AcceleratedScheduler): + """ + Internal wrapper around a deepspeed scheduler. + + Args: + scheduler (`torch.optim.lr_scheduler.LambdaLR`): + The scheduler to wrap. + optimizers (one or a list of `torch.optim.Optimizer`): + """ + + def __init__(self, scheduler, optimizers): + super().__init__(scheduler, optimizers) + + def step(self): + pass # `accelerator.backward(loss)` is doing that automatically. Therefore, its implementation is not needed + + +class DummyOptim: + """ + Dummy optimizer presents model parameters or param groups, this is primarily used to follow conventional training + loop when optimizer config is specified in the deepspeed config file. + + Args: + lr (float): + Learning rate. + params (iterable): iterable of parameters to optimize or dicts defining + parameter groups + weight_decay (float): + Weight decay. + **kwargs (additional keyword arguments, *optional*): + Other arguments. + """ + + def __init__(self, params, lr=0.001, weight_decay=0, **kwargs): + self.params = params + self.lr = lr + self.weight_decay = weight_decay + self.kwargs = kwargs + + +class DummyScheduler: + """ + Dummy scheduler presents model parameters or param groups, this is primarily used to follow conventional training + loop when scheduler config is specified in the deepspeed config file. + + Args: + optimizer (`torch.optim.optimizer.Optimizer`): + The optimizer to wrap. + total_num_steps (int, *optional*): + Total number of steps. + warmup_num_steps (int, *optional*): + Number of steps for warmup. + lr_scheduler_callable (callable, *optional*): + A callable function that creates an LR Scheduler. It accepts only one argument `optimizer`. + **kwargs (additional keyword arguments, *optional*): + Other arguments. + """ + + def __init__(self, optimizer, total_num_steps=None, warmup_num_steps=0, lr_scheduler_callable=None, **kwargs): + self.optimizer = optimizer + self.total_num_steps = total_num_steps + self.warmup_num_steps = warmup_num_steps + self.lr_scheduler_callable = lr_scheduler_callable + self.kwargs = kwargs diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/environment.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/environment.py new file mode 100644 index 0000000000000000000000000000000000000000..faa3be2d336ad8674fdbdfd3d5504645b25f2b79 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/environment.py @@ -0,0 +1,471 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import math +import os +import platform +import subprocess +import sys +from contextlib import contextmanager +from dataclasses import dataclass, field +from functools import lru_cache, wraps +from shutil import which +from typing import Optional, Union + +import torch +from packaging.version import parse + + +logger = logging.getLogger(__name__) + + +def convert_dict_to_env_variables(current_env: dict): + """ + Verifies that all keys and values in `current_env` do not contain illegal keys or values, and returns a list of + strings as the result. + + Example: + ```python + >>> from accelerate.utils.environment import verify_env + + >>> env = {"ACCELERATE_DEBUG_MODE": "1", "BAD_ENV_NAME": ">> valid_env_items = verify_env(env) + >>> print(valid_env_items) + ["ACCELERATE_DEBUG_MODE=1\n", "OTHER_ENV=2\n"] + ``` + """ + forbidden_chars = [";", "\n", "<", ">", " "] + valid_env_items = [] + for key, value in current_env.items(): + if all(char not in (key + value) for char in forbidden_chars) and len(key) >= 1 and len(value) >= 1: + valid_env_items.append(f"{key}={value}\n") + else: + logger.warning(f"WARNING: Skipping {key}={value} as it contains forbidden characters or missing values.") + return valid_env_items + + +def str_to_bool(value, to_bool: bool = False) -> Union[int, bool]: + """ + Converts a string representation of truth to `True` (1) or `False` (0). + + True values are `y`, `yes`, `t`, `true`, `on`, and `1`; False value are `n`, `no`, `f`, `false`, `off`, and `0`; + """ + value = value.lower() + if value in ("y", "yes", "t", "true", "on", "1"): + return 1 if not to_bool else True + elif value in ("n", "no", "f", "false", "off", "0"): + return 0 if not to_bool else False + else: + raise ValueError(f"invalid truth value {value}") + + +def get_int_from_env(env_keys, default): + """Returns the first positive env value found in the `env_keys` list or the default.""" + for e in env_keys: + val = int(os.environ.get(e, -1)) + if val >= 0: + return val + return default + + +def parse_flag_from_env(key, default=False): + """Returns truthy value for `key` from the env if available else the default.""" + value = os.environ.get(key, str(default)) + return str_to_bool(value) == 1 # As its name indicates `str_to_bool` actually returns an int... + + +def parse_choice_from_env(key, default="no"): + value = os.environ.get(key, str(default)) + return value + + +def are_libraries_initialized(*library_names: str) -> list[str]: + """ + Checks if any of `library_names` are imported in the environment. Will return any names that are. + """ + return [lib_name for lib_name in library_names if lib_name in sys.modules.keys()] + + +def get_current_device_type() -> tuple[str, str]: + """ + Determines the current device type and distributed type without initializing any device. + + This is particularly important when using fork-based multiprocessing, as device initialization + before forking can cause errors. + + The device detection order follows the same priority as state.py:_prepare_backend(): + MLU -> SDAA -> MUSA -> NPU -> HPU -> CUDA -> XPU + + Returns: + tuple[str, str]: A tuple of (device_type, distributed_type) + - device_type: The device string (e.g., "cuda", "npu", "xpu") + - distributed_type: The distributed type string (e.g., "MULTI_GPU", "MULTI_NPU") + + Example: + ```python + >>> device_type, distributed_type = get_current_device_type() + >>> print(device_type) # "cuda" + >>> print(distributed_type) # "MULTI_GPU" + ``` + """ + from .imports import ( + is_hpu_available, + is_mlu_available, + is_musa_available, + is_npu_available, + is_sdaa_available, + is_xpu_available, + ) + + if is_mlu_available(): + return "mlu", "MULTI_MLU" + elif is_sdaa_available(): + return "sdaa", "MULTI_SDAA" + elif is_musa_available(): + return "musa", "MULTI_MUSA" + elif is_npu_available(): + return "npu", "MULTI_NPU" + elif is_hpu_available(): + return "hpu", "MULTI_HPU" + elif torch.cuda.is_available(): + return "cuda", "MULTI_GPU" + elif is_xpu_available(): + return "xpu", "MULTI_XPU" + else: + # Default to CUDA even if not available (for CPU-only scenarios where CUDA code paths are still used) + return "cuda", "MULTI_GPU" + + +def _nvidia_smi(): + """ + Returns the right nvidia-smi command based on the system. + """ + if platform.system() == "Windows": + # If platform is Windows and nvidia-smi can't be found in path + # try from systemd drive with default installation path + command = which("nvidia-smi") + if command is None: + command = f"{os.environ['systemdrive']}\\Program Files\\NVIDIA Corporation\\NVSMI\\nvidia-smi.exe" + else: + command = "nvidia-smi" + return command + + +def get_gpu_info(): + """ + Gets GPU count and names using `nvidia-smi` instead of torch to not initialize CUDA. + + Largely based on the `gputil` library. + """ + # Returns as list of `n` GPUs and their names + output = subprocess.check_output( + [_nvidia_smi(), "--query-gpu=count,name", "--format=csv,noheader"], universal_newlines=True + ) + output = output.strip() + gpus = output.split(os.linesep) + # Get names from output + gpu_count = len(gpus) + gpu_names = [gpu.split(",")[1].strip() for gpu in gpus] + return gpu_names, gpu_count + + +def get_driver_version(): + """ + Returns the driver version + + In the case of multiple GPUs, will return the first. + """ + output = subprocess.check_output( + [_nvidia_smi(), "--query-gpu=driver_version", "--format=csv,noheader"], universal_newlines=True + ) + output = output.strip() + return output.split(os.linesep)[0] + + +def check_cuda_p2p_ib_support(): + """ + Checks if the devices being used have issues with P2P and IB communications, namely any consumer GPU hardware after + the 3090. + + Notably uses `nvidia-smi` instead of torch to not initialize CUDA. + """ + try: + device_names, device_count = get_gpu_info() + # As new consumer GPUs get released, add them to `unsupported_devices`` + unsupported_devices = {"RTX 40"} + if device_count > 1: + if any( + unsupported_device in device_name + for device_name in device_names + for unsupported_device in unsupported_devices + ): + # Check if they have the right driver version + acceptable_driver_version = "550.40.07" + current_driver_version = get_driver_version() + if parse(current_driver_version) < parse(acceptable_driver_version): + return False + return True + except Exception: + pass + return True + + +@lru_cache +def check_cuda_fp8_capability(): + """ + Checks if the current GPU available supports FP8. + + Notably might initialize `torch.cuda` to check. + """ + + try: + # try to get the compute capability from nvidia-smi + output = subprocess.check_output( + [_nvidia_smi(), "--query-gpu=compute_capability", "--format=csv,noheader"], universal_newlines=True + ) + output = output.strip() + # we take the first GPU's compute capability + compute_capability = tuple(map(int, output.split(os.linesep)[0].split("."))) + except Exception: + compute_capability = torch.cuda.get_device_capability() + + return compute_capability >= (8, 9) + + +@dataclass +class CPUInformation: + """ + Stores information about the CPU in a distributed environment. It contains the following attributes: + - rank: The rank of the current process. + - world_size: The total number of processes in the world. + - local_rank: The rank of the current process on the local node. + - local_world_size: The total number of processes on the local node. + """ + + rank: int = field(default=0, metadata={"help": "The rank of the current process."}) + world_size: int = field(default=1, metadata={"help": "The total number of processes in the world."}) + local_rank: int = field(default=0, metadata={"help": "The rank of the current process on the local node."}) + local_world_size: int = field(default=1, metadata={"help": "The total number of processes on the local node."}) + + +def get_cpu_distributed_information() -> CPUInformation: + """ + Returns various information about the environment in relation to CPU distributed training as a `CPUInformation` + dataclass. + """ + information = {} + information["rank"] = get_int_from_env(["RANK", "PMI_RANK", "OMPI_COMM_WORLD_RANK", "MV2_COMM_WORLD_RANK"], 0) + information["world_size"] = get_int_from_env( + ["WORLD_SIZE", "PMI_SIZE", "OMPI_COMM_WORLD_SIZE", "MV2_COMM_WORLD_SIZE"], 1 + ) + information["local_rank"] = get_int_from_env( + ["LOCAL_RANK", "MPI_LOCALRANKID", "OMPI_COMM_WORLD_LOCAL_RANK", "MV2_COMM_WORLD_LOCAL_RANK"], 0 + ) + information["local_world_size"] = get_int_from_env( + ["LOCAL_WORLD_SIZE", "MPI_LOCALNRANKS", "OMPI_COMM_WORLD_LOCAL_SIZE", "MV2_COMM_WORLD_LOCAL_SIZE"], + 1, + ) + return CPUInformation(**information) + + +def override_numa_affinity(local_process_index: int, verbose: Optional[bool] = None) -> None: + """ + Overrides whatever NUMA affinity is set for the current process. This is very taxing and requires recalculating the + affinity to set, ideally you should use `utils.environment.set_numa_affinity` instead. + + Args: + local_process_index (int): + The index of the current process on the current server. + verbose (bool, *optional*): + Whether to log out the assignment of each CPU. If `ACCELERATE_DEBUG_MODE` is enabled, will default to True. + """ + if verbose is None: + verbose = parse_flag_from_env("ACCELERATE_DEBUG_MODE", False) + if torch.cuda.is_available(): + from accelerate.utils import is_pynvml_available + + if not is_pynvml_available(): + raise ImportError( + "To set CPU affinity on CUDA GPUs the `nvidia-ml-py` package must be available. (`pip install nvidia-ml-py`)" + ) + import pynvml as nvml + + # The below code is based on https://github.com/NVIDIA/DeepLearningExamples/blob/master/TensorFlow2/LanguageModeling/BERT/gpu_affinity.py + nvml.nvmlInit() + num_elements = math.ceil(os.cpu_count() / 64) + handle = nvml.nvmlDeviceGetHandleByIndex(local_process_index) + affinity_string = "" + for j in nvml.nvmlDeviceGetCpuAffinity(handle, num_elements): + # assume nvml returns list of 64 bit ints + affinity_string = f"{j:064b}{affinity_string}" + affinity_list = [int(x) for x in affinity_string] + affinity_list.reverse() # so core 0 is the 0th element + affinity_to_set = [i for i, e in enumerate(affinity_list) if e != 0] + os.sched_setaffinity(0, affinity_to_set) + if verbose: + cpu_cores = os.sched_getaffinity(0) + logger.info(f"Assigning {len(cpu_cores)} cpu cores to process {local_process_index}: {cpu_cores}") + + +@lru_cache +def set_numa_affinity(local_process_index: int, verbose: Optional[bool] = None) -> None: + """ + Assigns the current process to a specific NUMA node. Ideally most efficient when having at least 2 cpus per node. + + This result is cached between calls. If you want to override it, please use + `accelerate.utils.environment.override_numa_afifnity`. + + Args: + local_process_index (int): + The index of the current process on the current server. + verbose (bool, *optional*): + Whether to print the new cpu cores assignment for each process. If `ACCELERATE_DEBUG_MODE` is enabled, will + default to True. + """ + override_numa_affinity(local_process_index=local_process_index, verbose=verbose) + + +@contextmanager +def clear_environment(): + """ + A context manager that will temporarily clear environment variables. + + When this context exits, the previous environment variables will be back. + + Example: + + ```python + >>> import os + >>> from accelerate.utils import clear_environment + + >>> os.environ["FOO"] = "bar" + >>> with clear_environment(): + ... print(os.environ) + ... os.environ["FOO"] = "new_bar" + ... print(os.environ["FOO"]) + {} + new_bar + + >>> print(os.environ["FOO"]) + bar + ``` + """ + _old_os_environ = os.environ.copy() + os.environ.clear() + + try: + yield + finally: + os.environ.clear() # clear any added keys, + os.environ.update(_old_os_environ) # then restore previous environment + + +@contextmanager +def patch_environment(**kwargs): + """ + A context manager that will add each keyword argument passed to `os.environ` and remove them when exiting. + + Will convert the values in `kwargs` to strings and upper-case all the keys. + + Example: + + ```python + >>> import os + >>> from accelerate.utils import patch_environment + + >>> with patch_environment(FOO="bar"): + ... print(os.environ["FOO"]) # prints "bar" + >>> print(os.environ["FOO"]) # raises KeyError + ``` + """ + existing_vars = {} + for key, value in kwargs.items(): + key = key.upper() + if key in os.environ: + existing_vars[key] = os.environ[key] + os.environ[key] = str(value) + + try: + yield + finally: + for key in kwargs: + key = key.upper() + if key in existing_vars: + # restore previous value + os.environ[key] = existing_vars[key] + else: + os.environ.pop(key, None) + + +def purge_accelerate_environment(func_or_cls): + """Decorator to clean up accelerate environment variables set by the decorated class or function. + + In some circumstances, calling certain classes or functions can result in accelerate env vars being set and not + being cleaned up afterwards. As an example, when calling: + + TrainingArguments(fp16=True, ...) + + The following env var will be set: + + ACCELERATE_MIXED_PRECISION=fp16 + + This can affect subsequent code, since the env var takes precedence over TrainingArguments(fp16=False). This is + especially relevant for unit testing, where we want to avoid the individual tests to have side effects on one + another. Decorate the unit test function or whole class with this decorator to ensure that after each test, the env + vars are cleaned up. This works for both unittest.TestCase and normal classes (pytest); it also works when + decorating the parent class. + + """ + prefix = "ACCELERATE_" + + @contextmanager + def env_var_context(): + # Store existing accelerate env vars + existing_vars = {k: v for k, v in os.environ.items() if k.startswith(prefix)} + try: + yield + finally: + # Restore original env vars or remove new ones + for key in [k for k in os.environ if k.startswith(prefix)]: + if key in existing_vars: + os.environ[key] = existing_vars[key] + else: + os.environ.pop(key, None) + + def wrap_function(func): + @wraps(func) + def wrapper(*args, **kwargs): + with env_var_context(): + return func(*args, **kwargs) + + wrapper._accelerate_is_purged_environment_wrapped = True + return wrapper + + if not isinstance(func_or_cls, type): + return wrap_function(func_or_cls) + + # Handle classes by wrapping test methods + def wrap_test_methods(test_class_instance): + for name in dir(test_class_instance): + if name.startswith("test"): + method = getattr(test_class_instance, name) + if callable(method) and not hasattr(method, "_accelerate_is_purged_environment_wrapped"): + setattr(test_class_instance, name, wrap_function(method)) + return test_class_instance + + # Handle inheritance + wrap_test_methods(func_or_cls) + func_or_cls.__init_subclass__ = classmethod(lambda cls, **kw: wrap_test_methods(cls)) + return func_or_cls diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/fsdp_utils.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/fsdp_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..b0475cb7d13fb5a6477a93455a9d025b6a582201 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/fsdp_utils.py @@ -0,0 +1,829 @@ +# Copyright 2023 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import copy +import functools +import os +import re +import shutil +import warnings +from collections import defaultdict +from collections.abc import Iterable +from contextlib import nullcontext +from pathlib import Path +from typing import Callable, Union + +import torch + +from ..logging import get_logger +from .constants import FSDP_MODEL_NAME, OPTIMIZER_NAME, SAFE_WEIGHTS_NAME, WEIGHTS_NAME +from .dataclasses import get_module_class_from_name +from .modeling import get_non_persistent_buffers, is_peft_model +from .other import get_module_children_bottom_up, is_compiled_module, save +from .versions import is_torch_version + + +logger = get_logger(__name__) + + +def enable_fsdp_ram_efficient_loading(): + """ + Enables RAM efficient loading of Hugging Face models for FSDP in the environment. + """ + # Sets values for `transformers.modeling_utils.is_fsdp_enabled` + if "ACCELERATE_USE_FSDP" not in os.environ: + os.environ["ACCELERATE_USE_FSDP"] = "True" + os.environ["FSDP_CPU_RAM_EFFICIENT_LOADING"] = "True" + + +def disable_fsdp_ram_efficient_loading(): + """ + Disables RAM efficient loading of Hugging Face models for FSDP in the environment. + """ + os.environ["FSDP_CPU_RAM_EFFICIENT_LOADING"] = "False" + + +def _get_model_state_dict(model, adapter_only=False, sd_options=None): + if adapter_only and is_peft_model(model): + from peft import get_peft_model_state_dict + + return get_peft_model_state_dict(model, adapter_name=model.active_adapter) + + # Invariant: `sd_options` is not None only for FSDP2 + if sd_options is not None: + from torch.distributed.checkpoint.state_dict import get_model_state_dict + + return get_model_state_dict(model, options=sd_options) + else: + return model.state_dict() + + +def _set_model_state_dict(model, state_dict, adapter_only=False, sd_options=None): + if adapter_only and is_peft_model(model): + from peft import set_peft_model_state_dict + + return set_peft_model_state_dict(model, state_dict, adapter_name=model.active_adapter) + + # Invariant: `sd_options` is not None only for FSDP2 + if sd_options is not None: + from torch.distributed.checkpoint.state_dict import set_model_state_dict + + return set_model_state_dict(model, state_dict, options=sd_options) + else: + return model.load_state_dict(state_dict) + + +def _prepare_sd_options(fsdp_plugin): + sd_options = None + + # we use this only for FSDP2, as it requires torch >= 2.6.0 and this api requires torch >= 2.2.0 + if fsdp_plugin.fsdp_version == 2: + from torch.distributed.checkpoint.state_dict import StateDictOptions + from torch.distributed.fsdp.fully_sharded_data_parallel import StateDictType + + sd_options = StateDictOptions( + full_state_dict=fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT, + cpu_offload=getattr(fsdp_plugin.state_dict_config, "offload_to_cpu", False), + broadcast_from_rank0=getattr(fsdp_plugin.state_dict_config, "rank0_only", False), + ) + + return sd_options + + +def save_fsdp_model(fsdp_plugin, accelerator, model, output_dir, model_index=0, adapter_only=False): + # Note: We import here to reduce import time from general modules, and isolate outside dependencies + import torch.distributed.checkpoint as dist_cp + from torch.distributed.checkpoint.default_planner import DefaultSavePlanner + from torch.distributed.fsdp.fully_sharded_data_parallel import FullyShardedDataParallel as FSDP + from torch.distributed.fsdp.fully_sharded_data_parallel import StateDictType + + os.makedirs(output_dir, exist_ok=True) + if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT: + # FSDP raises error when single GPU is used with `offload_to_cpu=True` for FULL_STATE_DICT + # so, only enable it when num_processes>1 + is_multi_process = accelerator.num_processes > 1 + fsdp_plugin.state_dict_config.offload_to_cpu = is_multi_process + fsdp_plugin.state_dict_config.rank0_only = is_multi_process + + ctx = ( + FSDP.state_dict_type( + model, fsdp_plugin.state_dict_type, fsdp_plugin.state_dict_config, fsdp_plugin.optim_state_dict_config + ) + if fsdp_plugin.fsdp_version == 1 + else nullcontext() + ) + sd_options = _prepare_sd_options(fsdp_plugin) + + with ctx: + state_dict = _get_model_state_dict(model, adapter_only=adapter_only, sd_options=sd_options) + if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT: + weights_name = f"{FSDP_MODEL_NAME}.bin" if model_index == 0 else f"{FSDP_MODEL_NAME}_{model_index}.bin" + output_model_file = os.path.join(output_dir, weights_name) + if accelerator.process_index == 0: + logger.info(f"Saving model to {output_model_file}") + torch.save(state_dict, output_model_file) + logger.info(f"Model saved to {output_model_file}") + # Invariant: `LOCAL_STATE_DICT` is never possible with `FSDP2` + elif fsdp_plugin.state_dict_type == StateDictType.LOCAL_STATE_DICT: + weights_name = ( + f"{FSDP_MODEL_NAME}_rank{accelerator.process_index}.bin" + if model_index == 0 + else f"{FSDP_MODEL_NAME}_{model_index}_rank{accelerator.process_index}.bin" + ) + output_model_file = os.path.join(output_dir, weights_name) + logger.info(f"Saving model to {output_model_file}") + torch.save(state_dict, output_model_file) + logger.info(f"Model saved to {output_model_file}") + elif fsdp_plugin.state_dict_type == StateDictType.SHARDED_STATE_DICT: + ckpt_dir = os.path.join(output_dir, f"{FSDP_MODEL_NAME}_{model_index}") + os.makedirs(ckpt_dir, exist_ok=True) + logger.info(f"Saving model to {ckpt_dir}") + state_dict = {"model": state_dict} + + dist_cp.save( + state_dict=state_dict, + storage_writer=dist_cp.FileSystemWriter(ckpt_dir), + planner=DefaultSavePlanner(), + ) + logger.info(f"Model saved to {ckpt_dir}") + + +def load_fsdp_model(fsdp_plugin, accelerator, model, input_dir, model_index=0, adapter_only=False): + # Note: We import here to reduce import time from general modules, and isolate outside dependencies + import torch.distributed.checkpoint as dist_cp + from torch.distributed.checkpoint.default_planner import DefaultLoadPlanner + from torch.distributed.fsdp.fully_sharded_data_parallel import FullyShardedDataParallel as FSDP + from torch.distributed.fsdp.fully_sharded_data_parallel import StateDictType + + accelerator.wait_for_everyone() + if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT: + # FSDP raises error when single GPU is used with `offload_to_cpu=True` for FULL_STATE_DICT + # so, only enable it when num_processes>1 + is_multi_process = accelerator.num_processes > 1 + fsdp_plugin.state_dict_config.offload_to_cpu = is_multi_process + fsdp_plugin.state_dict_config.rank0_only = is_multi_process + + ctx = ( + FSDP.state_dict_type( + model, fsdp_plugin.state_dict_type, fsdp_plugin.state_dict_config, fsdp_plugin.optim_state_dict_config + ) + if fsdp_plugin.fsdp_version == 1 + else nullcontext() + ) + sd_options = _prepare_sd_options(fsdp_plugin) + with ctx: + if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT: + if type(model) is not FSDP and accelerator.process_index != 0 and not accelerator.is_fsdp2: + if not fsdp_plugin.sync_module_states and fsdp_plugin.fsdp_version == 1: + raise ValueError( + "Set the `sync_module_states` flag to `True` so that model states are synced across processes when " + "initializing FSDP object" + ) + return + weights_name = f"{FSDP_MODEL_NAME}.bin" if model_index == 0 else f"{FSDP_MODEL_NAME}_{model_index}.bin" + input_model_file = os.path.join(input_dir, weights_name) + logger.info(f"Loading model from {input_model_file}") + # we want an empty state dict for FSDP2 as we use `broadcast_from_rank0` + load_model = not accelerator.is_fsdp2 or accelerator.is_main_process + if load_model: + state_dict = torch.load(input_model_file, weights_only=True) + else: + state_dict = {} + logger.info(f"Model loaded from {input_model_file}") + elif fsdp_plugin.state_dict_type == StateDictType.LOCAL_STATE_DICT: + weights_name = ( + f"{FSDP_MODEL_NAME}_rank{accelerator.process_index}.bin" + if model_index == 0 + else f"{FSDP_MODEL_NAME}_{model_index}_rank{accelerator.process_index}.bin" + ) + input_model_file = os.path.join(input_dir, weights_name) + logger.info(f"Loading model from {input_model_file}") + state_dict = torch.load(input_model_file, weights_only=True) + logger.info(f"Model loaded from {input_model_file}") + elif fsdp_plugin.state_dict_type == StateDictType.SHARDED_STATE_DICT: + ckpt_dir = ( + os.path.join(input_dir, f"{FSDP_MODEL_NAME}_{model_index}") + if f"{FSDP_MODEL_NAME}" not in input_dir + else input_dir + ) + logger.info(f"Loading model from {ckpt_dir}") + state_dict = {"model": _get_model_state_dict(model, adapter_only=adapter_only, sd_options=sd_options)} + dist_cp.load( + state_dict=state_dict, + storage_reader=dist_cp.FileSystemReader(ckpt_dir), + planner=DefaultLoadPlanner(), + ) + state_dict = state_dict["model"] + logger.info(f"Model loaded from {ckpt_dir}") + + load_result = _set_model_state_dict(model, state_dict, adapter_only=adapter_only, sd_options=sd_options) + return load_result + + +def save_fsdp_optimizer(fsdp_plugin, accelerator, optimizer, model, output_dir, optimizer_index=0): + # Note: We import here to reduce import time from general modules, and isolate outside dependencies + import torch.distributed.checkpoint as dist_cp + from torch.distributed.checkpoint.default_planner import DefaultSavePlanner + from torch.distributed.fsdp.fully_sharded_data_parallel import FullyShardedDataParallel as FSDP + from torch.distributed.fsdp.fully_sharded_data_parallel import StateDictType + + os.makedirs(output_dir, exist_ok=True) + + ctx = ( + FSDP.state_dict_type( + model, fsdp_plugin.state_dict_type, fsdp_plugin.state_dict_config, fsdp_plugin.optim_state_dict_config + ) + if fsdp_plugin.fsdp_version == 1 + else nullcontext() + ) + + sd_options = _prepare_sd_options(fsdp_plugin) + + with ctx: + if fsdp_plugin.fsdp_version == 2: + from torch.distributed.checkpoint.state_dict import get_optimizer_state_dict + + optim_state = get_optimizer_state_dict(model, optimizer, options=sd_options) + else: + optim_state = FSDP.optim_state_dict(model, optimizer) + + if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT: + if accelerator.process_index == 0: + optim_state_name = ( + f"{OPTIMIZER_NAME}.bin" if optimizer_index == 0 else f"{OPTIMIZER_NAME}_{optimizer_index}.bin" + ) + output_optimizer_file = os.path.join(output_dir, optim_state_name) + logger.info(f"Saving Optimizer state to {output_optimizer_file}") + torch.save(optim_state, output_optimizer_file) + logger.info(f"Optimizer state saved in {output_optimizer_file}") + else: + ckpt_dir = os.path.join(output_dir, f"{OPTIMIZER_NAME}_{optimizer_index}") + os.makedirs(ckpt_dir, exist_ok=True) + logger.info(f"Saving Optimizer state to {ckpt_dir}") + dist_cp.save( + state_dict={"optimizer": optim_state}, + storage_writer=dist_cp.FileSystemWriter(ckpt_dir), + planner=DefaultSavePlanner(), + ) + logger.info(f"Optimizer state saved in {ckpt_dir}") + + +def load_fsdp_optimizer(fsdp_plugin, accelerator, optimizer, model, input_dir, optimizer_index=0, adapter_only=False): + # Note: We import here to reduce import time from general modules, and isolate outside dependencies + import torch.distributed.checkpoint as dist_cp + from torch.distributed.fsdp.fully_sharded_data_parallel import FullyShardedDataParallel as FSDP + from torch.distributed.fsdp.fully_sharded_data_parallel import StateDictType + + accelerator.wait_for_everyone() + ctx = ( + FSDP.state_dict_type( + model, fsdp_plugin.state_dict_type, fsdp_plugin.state_dict_config, fsdp_plugin.optim_state_dict_config + ) + if fsdp_plugin.fsdp_version == 1 + else nullcontext() + ) + sd_options = _prepare_sd_options(fsdp_plugin) + with ctx: + if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT: + optim_state = None + if accelerator.process_index == 0 or not fsdp_plugin.optim_state_dict_config.rank0_only: + optimizer_name = ( + f"{OPTIMIZER_NAME}.bin" if optimizer_index == 0 else f"{OPTIMIZER_NAME}_{optimizer_index}.bin" + ) + input_optimizer_file = os.path.join(input_dir, optimizer_name) + logger.info(f"Loading Optimizer state from {input_optimizer_file}") + optim_state = torch.load(input_optimizer_file, weights_only=True) + logger.info(f"Optimizer state loaded from {input_optimizer_file}") + else: + ckpt_dir = ( + os.path.join(input_dir, f"{OPTIMIZER_NAME}_{optimizer_index}") + if f"{OPTIMIZER_NAME}" not in input_dir + else input_dir + ) + logger.info(f"Loading Optimizer from {ckpt_dir}") + optim_state = {"optimizer": optimizer.state_dict()} + dist_cp.load( + optim_state, + checkpoint_id=ckpt_dir, + storage_reader=dist_cp.FileSystemReader(ckpt_dir), + ) + optim_state = optim_state["optimizer"] + logger.info(f"Optimizer loaded from {ckpt_dir}") + + if fsdp_plugin.fsdp_version == 1: + flattened_osd = FSDP.optim_state_dict_to_load(model=model, optim=optimizer, optim_state_dict=optim_state) + optimizer.load_state_dict(flattened_osd) + else: + from torch.distributed.checkpoint.state_dict import set_optimizer_state_dict + + set_optimizer_state_dict(model, optimizer, optim_state, options=sd_options) + + +def _distributed_checkpoint_to_merged_weights(checkpoint_dir: str, save_path: str, safe_serialization: bool = True): + """ + Passthrough to `torch.distributed.checkpoint.format_utils.dcp_to_torch_save` + + Will save under `save_path` as either `model.safetensors` or `pytorch_model.bin`. + """ + # Note: We import here to reduce import time from general modules, and isolate outside dependencies + import torch.distributed.checkpoint as dist_cp + import torch.distributed.checkpoint.format_utils as dist_cp_format_utils + + state_dict = {} + save_path = Path(save_path) + save_path.mkdir(exist_ok=True) + dist_cp_format_utils._load_state_dict( + state_dict, + storage_reader=dist_cp.FileSystemReader(checkpoint_dir), + planner=dist_cp_format_utils._EmptyStateDictLoadPlanner(), + no_dist=True, + ) + save_path = save_path / SAFE_WEIGHTS_NAME if safe_serialization else save_path / WEIGHTS_NAME + + # To handle if state is a dict like {model: {...}} + if len(state_dict.keys()) == 1: + state_dict = state_dict[list(state_dict)[0]] + save(state_dict, save_path, safe_serialization=safe_serialization) + return save_path + + +def merge_fsdp_weights( + checkpoint_dir: str, output_path: str, safe_serialization: bool = True, remove_checkpoint_dir: bool = False +): + """ + Merge the weights from sharded FSDP model checkpoints into a single combined checkpoint. Should be used if + `SHARDED_STATE_DICT` was used for the model. Weights will be saved to `{output_path}/model.safetensors` if + `safe_serialization` else `pytorch_model.bin`. + + Note: this is a CPU-bound process. + + Args: + checkpoint_dir (`str`): + The directory containing the FSDP checkpoints (can be either the model or optimizer). + output_path (`str`): + The path to save the merged checkpoint. + safe_serialization (`bool`, *optional*, defaults to `True`): + Whether to save the merged weights with safetensors (recommended). + remove_checkpoint_dir (`bool`, *optional*, defaults to `False`): + Whether to remove the checkpoint directory after merging. + """ + checkpoint_dir = Path(checkpoint_dir) + from accelerate.state import PartialState + + if not is_torch_version(">=", "2.3.0"): + raise ValueError("`merge_fsdp_weights` requires PyTorch >= 2.3.0`") + + # Verify that the checkpoint directory exists + if not checkpoint_dir.exists(): + model_path_exists = (checkpoint_dir / "pytorch_model_fsdp_0").exists() + optimizer_path_exists = (checkpoint_dir / "optimizer_0").exists() + err = f"Tried to load from {checkpoint_dir} but couldn't find a valid metadata file." + if model_path_exists and optimizer_path_exists: + err += " However, potential model and optimizer checkpoint directories exist." + err += f"Please pass in either {checkpoint_dir}/pytorch_model_fsdp_0 or {checkpoint_dir}/optimizer_0" + err += "instead." + elif model_path_exists: + err += " However, a potential model checkpoint directory exists." + err += f"Please try passing in {checkpoint_dir}/pytorch_model_fsdp_0 instead." + elif optimizer_path_exists: + err += " However, a potential optimizer checkpoint directory exists." + err += f"Please try passing in {checkpoint_dir}/optimizer_0 instead." + raise ValueError(err) + + # To setup `save` to work + state = PartialState() + if state.is_main_process: + logger.info(f"Merging FSDP weights from {checkpoint_dir}") + save_path = _distributed_checkpoint_to_merged_weights(checkpoint_dir, output_path, safe_serialization) + logger.info(f"Successfully merged FSDP weights and saved to {save_path}") + if remove_checkpoint_dir: + logger.info(f"Removing old checkpoint directory {checkpoint_dir}") + shutil.rmtree(checkpoint_dir) + state.wait_for_everyone() + + +def ensure_weights_retied(param_init_fn, model: torch.nn.Module, device: torch.device): + _tied_names = getattr(model, "_tied_weights_keys", None) + if not _tied_names: + # if no tied names just passthrough + return param_init_fn + + # get map of parameter instances to params. + # - needed for replacement later + _tied_params = {} + for name in _tied_names: + name = name.split(".") + name, param_name = ".".join(name[:-1]), name[-1] + mod = model.get_submodule(name) + param = getattr(mod, param_name) + + _tied_params[id(param)] = None # placeholder for the param first + + # build param_init_fn for the case with tied params + def param_init_fn_tied_param(module: torch.nn.Module): + # track which params to tie + # - usually only 1, but for completeness consider > 1 + params_to_tie = defaultdict(list) + for n, param in module.named_parameters(recurse=False): + if id(param) in _tied_params: + params_to_tie[id(param)].append(n) + + # call the param init fn, which potentially re-allocates the + # parameters + module = param_init_fn(module) + + # search the parameters again and tie them up again + for id_key, _param_names in params_to_tie.items(): + for param_name in _param_names: + param = _tied_params[id_key] + if param is None: + # everything will be tied to the first time the + # param is observed + _tied_params[id_key] = getattr(module, param_name) + else: + setattr(module, param_name, param) # tie + + return module + + return param_init_fn_tied_param + + +def fsdp2_load_full_state_dict(accelerator, model: torch.nn.Module, full_sd: dict): + """ + Loads the full state dict (could be only on rank 0) into the sharded model. This is done by broadcasting the + parameters from rank 0 to all other ranks. This function modifies the model in-place. + + Args: + accelerator (`Accelerator`): The accelerator instance + model (`torch.nn.Module`): + The model to load the state dict into, expected to be on meta device or a VRAM spike can occur + full_sd (`dict`): The full state dict to load, can only be on rank 0 + """ + import torch.distributed as dist + from torch.distributed.tensor import DTensor, distribute_tensor + + # Model was previously copied to meta device + meta_sharded_sd = model.state_dict() + sharded_sd = {} + + # Rank 0 distributes the full state dict to other ranks + def _infer_parameter_dtype(model, param_name, empty_param): + try: + old_param = model.get_parameter_or_buffer(param_name) + except AttributeError: + # Need this for LORA, as there some params are not *parameters* of sorts + base_param_name, local_param_name = param_name.rsplit(".", 1) + submodule = model.get_submodule(base_param_name) + old_param = getattr(submodule, local_param_name) + + is_torch_e4m3fn_available = hasattr(torch, "float8_e4m3fn") + casting_dtype = None + is_param_float8_e4m3fn = is_torch_e4m3fn_available and empty_param.dtype == torch.float8_e4m3fn + + if empty_param.dtype.is_floating_point and not is_param_float8_e4m3fn: + casting_dtype = old_param.dtype + + return old_param is not None and old_param.is_contiguous(), casting_dtype + + def _cast_and_contiguous(tensor, to_contiguous, dtype): + if dtype is not None: + tensor = tensor.to(dtype=dtype) + if to_contiguous: + tensor = tensor.contiguous() + return tensor + + if accelerator.is_main_process: + for (param_name, full_param), sharded_param in zip(full_sd.items(), meta_sharded_sd.values()): + device_mesh = sharded_param.device_mesh + full_param = full_param.detach().to(device_mesh.device_type) + if isinstance(full_param, DTensor): + # dist.broadcast() only supports torch.Tensor. + # After prepare_tp(), model parameters may become DTensor. + # To broadcast such a parameter, convert it to a local tensor first. + full_param = full_param.to_local() + dist.broadcast(full_param, src=0, group=dist.group.WORLD) + sharded_tensor = distribute_tensor(full_param, device_mesh, sharded_param.placements) + to_contiguous, casting_dtype = _infer_parameter_dtype( + model, + param_name, + full_param, + ) + sharded_tensor = _cast_and_contiguous(sharded_tensor, to_contiguous, casting_dtype) + sharded_sd[param_name] = sharded_tensor + # We need this else to have a matching `broadcast` for all of the ranks, else we deadlock + else: + for param_name, sharded_param in meta_sharded_sd.items(): + device_mesh = sharded_param.device_mesh + full_tensor = torch.empty(sharded_param.size(), device=device_mesh.device_type, dtype=sharded_param.dtype) + dist.broadcast(full_tensor, src=0, group=dist.group.WORLD) + sharded_tensor = distribute_tensor(full_tensor, device_mesh, sharded_param.placements) + to_contiguous, casting_dtype = _infer_parameter_dtype( + model, + param_name, + full_tensor, + ) + sharded_tensor = _cast_and_contiguous(sharded_tensor, to_contiguous, casting_dtype) + sharded_sd[param_name] = sharded_tensor + + # we set `assign=True` because our params are on meta device + model.load_state_dict(sharded_sd, assign=True) + return model + + +def fsdp2_switch_optimizer_parameters(optimizer: torch.optim.Optimizer, mapping: dict): + """ + Switches the parameters of the optimizer to new ones (sharded parameters in usual case). This function modifies the + optimizer in-place. + + Args: + optimizer (`torch.optim.Optimizer`): Optimizer instance which contains the original model parameters + mapping (`dict`): Mapping from the original parameter (specified by `data_ptr`) to the sharded parameter + + Raises: + KeyError: + If a parameter in the optimizer couldn't be switched to its sharded version. This should never happen and + indicates a bug. If we kept the original params instead of raising, the training wouldn't be numerically + correct and weights wouldn't get updated. + """ + from torch.distributed.tensor import DTensor + + accessor_mapping = {} + + accessor_mapping[DTensor] = "_local_tensor" + try: + for param_group in optimizer.param_groups: + param_group["params"] = [mapping[p.data_ptr] for p in param_group["params"]] + except KeyError: + # This shouldn't ever happen, but we want to fail here else training wouldn't be numerically correct + # This basically means that we're missing a mapping from the original parameter to the sharded parameter + raise KeyError( + "A parameter in the optimizer couldn't be switched to its sharded version. This breaks the training. Please raise an issue on GitHub." + ) + + +def fsdp2_apply_ac(accelerator, model: torch.nn.Module): + """ + Applies the activation checkpointing to the model. + + Args: + accelerator (`Accelerator`): The accelerator instance + model (`torch.nn.Module`): The model to apply the activation checkpointing to + + Returns: + `torch.nn.Module`: The model with the activation checkpointing applied + """ + + from torch.distributed.algorithms._checkpoint.checkpoint_wrapper import ( + checkpoint_wrapper, + ) + + auto_wrap_policy_func = fsdp2_prepare_auto_wrap_policy(accelerator.state.fsdp_plugin, model) + + for layer_name, layer in get_module_children_bottom_up(model, return_fqns=True)[:-1]: + if len(layer_name.split(".")) > 1: + parent_name, child_name = layer_name.rsplit(".", 1) + else: + parent_name = None + child_name = layer_name + + parent_module = model.get_submodule(parent_name) if parent_name else model + if auto_wrap_policy_func(parent_module): + layer = checkpoint_wrapper(layer, preserve_rng_state=False) + parent_module.register_module(child_name, layer) + + return model + + +def fsdp2_prepare_model(accelerator, model: torch.nn.Module) -> torch.nn.Module: + """Prepares the model for FSDP2 in-place. Also returns the model to avoid misuse of the original model. + + Args: + accelerator (`Accelerator`): The accelerator instance + model (`torch.nn.Module`): The model to prepare + + Returns: + `torch.nn.Module`: Prepared model + """ + from torch.distributed.fsdp import FSDPModule, MixedPrecisionPolicy, fully_shard + + is_type_fsdp = isinstance(model, FSDPModule) or ( + is_compiled_module(model) and isinstance(model._orig_mod, FSDPModule) + ) + if is_type_fsdp: + return model + + fsdp2_plugin = accelerator.state.fsdp_plugin + + fsdp2_plugin.set_auto_wrap_policy(model) + + original_sd = model.state_dict() + mesh = getattr(accelerator, "torch_device_mesh", None) + + fsdp2_kwargs = { + "reshard_after_forward": fsdp2_plugin.reshard_after_forward, + "offload_policy": fsdp2_plugin.cpu_offload, + # `fully_shard` doesn't accept `None` in case of `MixedPrecisionPolicy` + "mp_policy": fsdp2_plugin.mixed_precision_policy or MixedPrecisionPolicy(), + "mesh": mesh[tuple(accelerator.parallelism_config.fsdp_dim_names)] if mesh is not None else None, + "ignored_params": get_parameters_from_modules(fsdp2_plugin.ignored_modules, model, accelerator.device), + } + + model_has_params4bit = False + for name, param in model.named_parameters(): + # this is a temporary fix whereby loading models with bnb params cannot be moved from + # GPU to a meta device due with FSDP2 because torch operations don't return the original class type + # bypassing the move to meta will still cause the VRAM spike, but at least it still will load + if param.__class__.__name__ == "Params4bit": + model_has_params4bit = True + break + + if fsdp2_plugin.cpu_ram_efficient_loading and not model_has_params4bit: + # Context: `fully_shard` moves the model to GPU if it was on CPU, however it can also be on `meta` and then it stays there even after `fully_shard` + # For this reason, we need to move the model to `meta` device, as then sharding happens on `meta` device + # If we kept the model on CPU (`cpu_ram_efficient_loading` has model be on CPU on all ranks, though non-main ranks only have `torch.empty`), `fully_shard` would move it to GPU + # Afterwards, when we call `fsdp2_load_full_state_dict`, us creating the state_dict would result into briefly having two copies of model state_dict on the GPU -> VRAM spike + + # We need to keep the original non-persistent buffers, as those MAY not be in the state_dict, resulting in them staying on meta device + # Also, these buffers aren't getting sharded by default + # We get the FQNs of all non-persistent buffers, to re-register them after + non_persistent_buffer_fqns = get_non_persistent_buffers(model, recurse=True, fqns=True) + original_non_persistent_buffers = copy.deepcopy( + {k: v for k, v in model.named_buffers() if k in non_persistent_buffer_fqns} + ) + # We move the model to meta device, as then sharding happens on meta device + model = model.to(torch.device("meta")) + # We need to re-tie the weights, not exactly sure why, but if we don't do this, reference to `lm_head/embed_tokens` stay hanging -> more VRAM usage + # We assume `transformers` models have a `tie_weights` method if they support it + if hasattr(model, "tie_weights"): + model.tie_weights() + + auto_wrap_policy_func = fsdp2_prepare_auto_wrap_policy(fsdp2_plugin, model) + if auto_wrap_policy_func is not None: + # We skip the model itself, as that one is always wrapped + for module in get_module_children_bottom_up(model)[:-1]: + if auto_wrap_policy_func(module) and not isinstance(module, FSDPModule): + fully_shard(module, **fsdp2_kwargs) + + if not isinstance(model, FSDPModule): + fully_shard(model, **fsdp2_kwargs) + + if fsdp2_plugin.cpu_ram_efficient_loading: + # If `cpu_ram_efficient_loading` is enabled, only rank 0 loads the weights + # Other ranks have an empty model on `meta` device, so we need to distribute the weights properly + fsdp2_load_full_state_dict(accelerator, model, original_sd) + + if fsdp2_plugin.cpu_ram_efficient_loading and not model_has_params4bit: + # We re-register the buffers, as they may not be in the state_dict + for fqn, buffer_tensor in original_non_persistent_buffers.items(): + buffer_tensor = buffer_tensor.to(accelerator.device) + + if "." in fqn: + parent_fqn, local_buffer_name = fqn.rsplit(".", 1) + parent_module = model.get_submodule(parent_fqn) + else: + local_buffer_name = fqn + parent_module = model + + parent_module.register_buffer(local_buffer_name, buffer_tensor, persistent=False) + + # We need to tie the weights again, as call to `load_full_state_dict` breaks the tie + # Needs to be called both here and above + # removing this call makes the have slightly different loss + # removing the call above leads to extra memory usage as explained in the comment above + if hasattr(model, "tie_weights"): + model.tie_weights() + + # There is no `dtype` attribution for nn.Module + # Set it to None if it doesn't exist and do the upcast always + model_dtype = getattr(model, "dtype", None) + if accelerator.mixed_precision != "no" and (model_dtype is None or model_dtype != torch.float32): + # We upcast the model according to `deepspeed`'s implementation + # More info about this can be found in `accelerator.py:prepare_model`s FSDP1 section + model = model.to(torch.float32) + if accelerator.is_main_process: + # TODO(siro1): Add a warning for each parameter that was upcasted + warnings.warn( + "FSDP upcast of low precision parameters to fp32 (since mixed_precision != 'no') may affect the precision of model checkpoints." + ) + return model + + +def fsdp2_prepare_auto_wrap_policy(fsdp2_plugin, model: torch.nn.Module) -> Callable[[torch.nn.Module], bool]: + """Prepares the auto wrap policy based on its type, done to mimic the behaviour of FSDP1 auto wrap policy. + + Args: + fsdp2_plugin (`FullyShardedDataParallelPlugin`): + Instance of `FullyShardedDataParallelPlugin` containing the configuration options + auto_wrap_policy_type (`str`): + Either `transformer` or `size` + model (`torch.nn.Module`): + The model to wrap + + Returns: + `Callable[[torch.nn.Module], bool]`: + The auto wrap policy function to be applied to the model + """ + from torch.distributed.fsdp.wrap import size_based_auto_wrap_policy, transformer_auto_wrap_policy + + fn = fsdp2_plugin.auto_wrap_policy + + if isinstance(fn, functools.partial): + fn = fn.func + + if fn is transformer_auto_wrap_policy: + no_split_modules = getattr(model, "_no_split_modules", None) + if no_split_modules is None: + no_split_modules = [] + transformer_cls_names_to_wrap = list(no_split_modules) + if fsdp2_plugin.transformer_cls_names_to_wrap is not None: + transformer_cls_names_to_wrap = fsdp2_plugin.transformer_cls_names_to_wrap + transformer_cls_to_wrap = set() + + for layer_class in transformer_cls_names_to_wrap: + transformer_cls = get_module_class_from_name(model, layer_class) + if transformer_cls is None: + raise ValueError(f"Could not find the transformer layer class {layer_class} in the model.") + transformer_cls_to_wrap.add(transformer_cls) + + def policy(module: torch.nn.Module) -> bool: + if fsdp2_plugin.transformer_cls_names_to_wrap is None: + return False + return isinstance(module, tuple(transformer_cls_to_wrap)) + + elif fn is size_based_auto_wrap_policy: + + def policy(module: torch.nn.Module) -> bool: + module_num_params = sum(p.numel() for p in module.parameters()) + return module_num_params > fsdp2_plugin.min_num_params + else: + return None + + return policy + + +def get_fsdp2_grad_scaler(**kwargs): + """ + Returns a `GradScaler` for FSDP2, as the current implementation of `get_grad_scaler` doesn't accept other args. We + need this as current `get_grad_scaler` accepts only `distributed_type` as arg, which doesn't differentiate between + FSDP1 and FSDP2 + """ + from torch.amp.grad_scaler import GradScaler + + return GradScaler(**kwargs) + + +def fsdp2_canonicalize_names(named_params: dict) -> dict: + """Removes parameter name modifiers in order to map them back to their original names. + + See huggingface/accelerate#3554 for more context. + + Args: + named_params (`dict`): The named parameters dictionary to canonicalize. + + Returns: + `dict`: The canonicalized named parameters dictionary + """ + named_params = {k.replace("._checkpoint_wrapped_module", ""): v for k, v in named_params.items()} + named_params = { + k.replace("_orig_mod.", "") if k.startswith("_orig_mod.") else k: v for k, v in named_params.items() + } + named_params = {k.replace("._orig_mod", ""): v for k, v in named_params.items()} + return named_params + + +def get_parameters_from_modules( + modules: Union[Iterable[torch.nn.Module], str], model, device +) -> set[torch.nn.Parameter]: + """Converts modules to parameters where modules can be a string or list of torch.nn.Module + + Args: + modules (`Union[Iterable[torch.nn.Module], str]`): List of modules + + Returns: + `set[torch.nn.Parameter]`: List of parameters + """ + if modules is None: + return set() + parameters = [] + # code taken from accelerate while preparing kwargs for FSDP + if isinstance(modules, str): + reg = re.compile(modules) + mapped_modules = [] + for name, module in model.named_modules(): + if reg.fullmatch(name): + module.to(device) + mapped_modules.append(module) + modules = mapped_modules + for module in modules: + parameters.extend(list(module.parameters())) + return set(parameters) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/imports.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/imports.py new file mode 100644 index 0000000000000000000000000000000000000000..68cef6b4a4cafd65de5e82de155a316683cee737 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/imports.py @@ -0,0 +1,564 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import importlib +import importlib.metadata +import os +import sys +import warnings +from functools import lru_cache, wraps + +import torch +from packaging import version +from packaging.version import parse + +from .environment import parse_flag_from_env, patch_environment, str_to_bool +from .versions import compare_versions, is_torch_version + + +# Try to run Torch native job in an environment with TorchXLA installed by setting this value to 0. +USE_TORCH_XLA = parse_flag_from_env("USE_TORCH_XLA", default=True) + +_torch_xla_available = False +if USE_TORCH_XLA: + try: + import torch_xla.core.xla_model as xm # noqa: F401 + import torch_xla.runtime + + _torch_xla_available = True + except ImportError: + pass + +# Keep it for is_tpu_available. It will be removed along with is_tpu_available. +_tpu_available = _torch_xla_available + +# Cache this result has it's a C FFI call which can be pretty time-consuming +_torch_distributed_available = torch.distributed.is_available() + + +def _is_package_available(pkg_name, metadata_name=None): + # Check we're not importing a "pkg_name" directory somewhere but the actual library by trying to grab the version + package_exists = importlib.util.find_spec(pkg_name) is not None + if package_exists: + try: + # Some libraries have different names in the metadata + _ = importlib.metadata.metadata(pkg_name if metadata_name is None else metadata_name) + return True + except importlib.metadata.PackageNotFoundError: + return False + + +def is_torch_distributed_available() -> bool: + return _torch_distributed_available + + +def is_xccl_available(): + if is_torch_version(">=", "2.7.0"): + return torch.distributed.distributed_c10d.is_xccl_available() + if is_ipex_available(): + return False + return False + + +def is_ccl_available(): + try: + pass + except ImportError: + print( + "Intel(R) oneCCL Bindings for PyTorch* is required to run DDP on Intel(R) XPUs, but it is not" + " detected. If you see \"ValueError: Invalid backend: 'ccl'\" error, please install Intel(R) oneCCL" + " Bindings for PyTorch*." + ) + return importlib.util.find_spec("oneccl_bindings_for_pytorch") is not None + + +def get_ccl_version(): + return importlib.metadata.version("oneccl_bind_pt") + + +def is_import_timer_available(): + return _is_package_available("import_timer") + + +def is_pynvml_available(): + return _is_package_available("pynvml") or _is_package_available("pynvml", "nvidia-ml-py") + + +def is_pytest_available(): + return _is_package_available("pytest") + + +def is_msamp_available(): + return _is_package_available("msamp", "ms-amp") + + +def is_schedulefree_available(): + return _is_package_available("schedulefree") + + +def is_transformer_engine_available(): + if is_hpu_available(): + return _is_package_available("intel_transformer_engine", "intel-transformer-engine") + else: + return _is_package_available("transformer_engine", "transformer-engine") + + +def is_transformer_engine_mxfp8_available(): + if _is_package_available("transformer_engine", "transformer-engine"): + import transformer_engine.pytorch as te + + return te.fp8.check_mxfp8_support()[0] + return False + + +def is_lomo_available(): + return _is_package_available("lomo_optim") + + +def is_cuda_available(): + """ + Checks if `cuda` is available via an `nvml-based` check which won't trigger the drivers and leave cuda + uninitialized. + """ + with patch_environment(PYTORCH_NVML_BASED_CUDA_CHECK="1"): + available = torch.cuda.is_available() + + return available + + +@lru_cache +def is_torch_xla_available(check_is_tpu=False, check_is_gpu=False): + """ + Check if `torch_xla` is available. To train a native pytorch job in an environment with torch xla installed, set + the USE_TORCH_XLA to false. + """ + assert not (check_is_tpu and check_is_gpu), "The check_is_tpu and check_is_gpu cannot both be true." + + if not _torch_xla_available: + return False + elif check_is_gpu: + return torch_xla.runtime.device_type() in ["GPU", "CUDA"] + elif check_is_tpu: + return torch_xla.runtime.device_type() == "TPU" + + return True + + +def is_torchao_available(): + package_exists = _is_package_available("torchao") + if package_exists: + torchao_version = version.parse(importlib.metadata.version("torchao")) + return compare_versions(torchao_version, ">=", "0.6.1") + return False + + +def is_deepspeed_available(): + return _is_package_available("deepspeed") + + +def is_pippy_available(): + return is_torch_version(">=", "2.4.0") + + +def is_bf16_available(ignore_tpu=False): + "Checks if bf16 is supported, optionally ignoring the TPU" + if is_torch_xla_available(check_is_tpu=True): + return not ignore_tpu + if is_cuda_available(): + return torch.cuda.is_bf16_supported() + if is_mlu_available(): + return torch.mlu.is_bf16_supported() + if is_xpu_available(): + return torch.xpu.is_bf16_supported() + if is_mps_available(): + return torch.backends.mps.is_macos_or_newer(14, 0) + return True + + +def is_fp16_available(): + "Checks if fp16 is supported" + if is_habana_gaudi1(): + return False + + return True + + +def is_fp8_available(): + "Checks if fp8 is supported" + return is_msamp_available() or is_transformer_engine_available() or is_torchao_available() + + +def is_4bit_bnb_available(): + package_exists = _is_package_available("bitsandbytes") + if package_exists: + bnb_version = version.parse(importlib.metadata.version("bitsandbytes")) + return compare_versions(bnb_version, ">=", "0.39.0") + return False + + +def is_8bit_bnb_available(): + package_exists = _is_package_available("bitsandbytes") + if package_exists: + bnb_version = version.parse(importlib.metadata.version("bitsandbytes")) + return compare_versions(bnb_version, ">=", "0.37.2") + return False + + +def is_bnb_available(min_version=None): + package_exists = _is_package_available("bitsandbytes") + if package_exists and min_version is not None: + bnb_version = version.parse(importlib.metadata.version("bitsandbytes")) + return compare_versions(bnb_version, ">=", min_version) + else: + return package_exists + + +def is_bitsandbytes_multi_backend_available(): + if not is_bnb_available(): + return False + import bitsandbytes as bnb + + return "multi_backend" in getattr(bnb, "features", set()) + + +def is_torchvision_available(): + return _is_package_available("torchvision") + + +def is_megatron_lm_available(): + if str_to_bool(os.environ.get("ACCELERATE_USE_MEGATRON_LM", "False")) == 1: + if importlib.util.find_spec("megatron") is not None: + try: + megatron_version = parse(importlib.metadata.version("megatron-core")) + if compare_versions(megatron_version, ">=", "0.8.0"): + return importlib.util.find_spec(".training", "megatron") + except Exception as e: + warnings.warn(f"Parse Megatron version failed. Exception:{e}") + return False + + +def is_transformers_available(): + return _is_package_available("transformers") + + +def is_datasets_available(): + return _is_package_available("datasets") + + +def is_peft_available(): + return _is_package_available("peft") + + +def is_timm_available(): + return _is_package_available("timm") + + +def is_triton_available(): + if is_xpu_available(): + return _is_package_available("triton", "pytorch-triton-xpu") + return _is_package_available("triton") + + +def is_aim_available(): + package_exists = _is_package_available("aim") + if package_exists: + aim_version = version.parse(importlib.metadata.version("aim")) + return compare_versions(aim_version, "<", "4.0.0") + return False + + +def is_tensorboard_available(): + return _is_package_available("tensorboard") or _is_package_available("tensorboardX") + + +def is_wandb_available(): + return _is_package_available("wandb") + + +def is_comet_ml_available(): + return _is_package_available("comet_ml") + + +def is_swanlab_available(): + return _is_package_available("swanlab") + + +def is_trackio_available(): + return sys.version_info >= (3, 10) and _is_package_available("trackio") + + +def is_boto3_available(): + return _is_package_available("boto3") + + +def is_rich_available(): + if _is_package_available("rich"): + return parse_flag_from_env("ACCELERATE_ENABLE_RICH", False) + return False + + +def is_sagemaker_available(): + return _is_package_available("sagemaker") + + +def is_tqdm_available(): + return _is_package_available("tqdm") + + +def is_clearml_available(): + return _is_package_available("clearml") + + +def is_pandas_available(): + return _is_package_available("pandas") + + +def is_matplotlib_available(): + return _is_package_available("matplotlib") + + +def is_mlflow_available(): + if _is_package_available("mlflow"): + return True + + if importlib.util.find_spec("mlflow") is not None: + try: + _ = importlib.metadata.metadata("mlflow-skinny") + return True + except importlib.metadata.PackageNotFoundError: + return False + return False + + +def is_mps_available(min_version="1.12"): + "Checks if MPS device is available. The minimum version required is 1.12." + # With torch 1.12, you can use torch.backends.mps + # With torch 2.0.0, you can use torch.mps + return is_torch_version(">=", min_version) and torch.backends.mps.is_available() and torch.backends.mps.is_built() + + +def is_ipex_available(): + "Checks if ipex is installed." + + def get_major_and_minor_from_version(full_version): + return str(version.parse(full_version).major) + "." + str(version.parse(full_version).minor) + + _torch_version = importlib.metadata.version("torch") + if importlib.util.find_spec("intel_extension_for_pytorch") is None: + return False + _ipex_version = "N/A" + try: + _ipex_version = importlib.metadata.version("intel_extension_for_pytorch") + except importlib.metadata.PackageNotFoundError: + return False + torch_major_and_minor = get_major_and_minor_from_version(_torch_version) + ipex_major_and_minor = get_major_and_minor_from_version(_ipex_version) + if torch_major_and_minor != ipex_major_and_minor: + warnings.warn( + f"Intel Extension for PyTorch {ipex_major_and_minor} needs to work with PyTorch {ipex_major_and_minor}.*," + f" but PyTorch {_torch_version} is found. Please switch to the matching version and run again." + ) + return False + return True + + +@lru_cache +def is_mlu_available(check_device=False): + """ + Checks if `mlu` is available via an `cndev-based` check which won't trigger the drivers and leave mlu + uninitialized. + """ + if importlib.util.find_spec("torch_mlu") is None: + return False + + import torch_mlu # noqa: F401 + + with patch_environment(PYTORCH_CNDEV_BASED_MLU_CHECK="1"): + available = torch.mlu.is_available() + + return available + + +@lru_cache +def is_musa_available(check_device=False): + "Checks if `torch_musa` is installed and potentially if a MUSA is in the environment" + if importlib.util.find_spec("torch_musa") is None: + return False + + import torch_musa # noqa: F401 + + if check_device: + try: + # Will raise a RuntimeError if no MUSA is found + _ = torch.musa.device_count() + return torch.musa.is_available() + except RuntimeError: + return False + return hasattr(torch, "musa") and torch.musa.is_available() + + +@lru_cache +def is_npu_available(check_device=False): + "Checks if `torch_npu` is installed and potentially if a NPU is in the environment" + if importlib.util.find_spec("torch_npu") is None: + return False + + # NOTE: importing torch_npu may raise error in some envs + # e.g. inside cpu-only container with torch_npu installed + try: + import torch_npu # noqa: F401 + except Exception: + return False + + if check_device: + try: + # Will raise a RuntimeError if no NPU is found + _ = torch.npu.device_count() + return torch.npu.is_available() + except RuntimeError: + return False + return hasattr(torch, "npu") and torch.npu.is_available() + + +@lru_cache +def is_sdaa_available(check_device=False): + "Checks if `torch_sdaa` is installed and potentially if a SDAA is in the environment" + if importlib.util.find_spec("torch_sdaa") is None: + return False + + import torch_sdaa # noqa: F401 + + if check_device: + try: + # Will raise a RuntimeError if no NPU is found + _ = torch.sdaa.device_count() + return torch.sdaa.is_available() + except RuntimeError: + return False + return hasattr(torch, "sdaa") and torch.sdaa.is_available() + + +@lru_cache +def is_hpu_available(init_hccl=False): + "Checks if `torch.hpu` is installed and potentially if a HPU is in the environment" + if ( + importlib.util.find_spec("habana_frameworks") is None + or importlib.util.find_spec("habana_frameworks.torch") is None + ): + return False + + import habana_frameworks.torch # noqa: F401 + + if init_hccl: + import habana_frameworks.torch.distributed.hccl as hccl # noqa: F401 + + return hasattr(torch, "hpu") and torch.hpu.is_available() + + +def is_habana_gaudi1(): + if is_hpu_available(): + import habana_frameworks.torch.utils.experimental as htexp # noqa: F401 + + if htexp._get_device_type() == htexp.synDeviceType.synDeviceGaudi: + return True + + return False + + +@lru_cache +def is_xpu_available(check_device=False): + """ + Checks if XPU acceleration is available either via `intel_extension_for_pytorch` or via stock PyTorch (>=2.4) and + potentially if a XPU is in the environment + """ + + if is_ipex_available(): + import intel_extension_for_pytorch # noqa: F401 + else: + if is_torch_version("<=", "2.3"): + return False + + if check_device: + try: + # Will raise a RuntimeError if no XPU is found + _ = torch.xpu.device_count() + return torch.xpu.is_available() + except RuntimeError: + return False + return hasattr(torch, "xpu") and torch.xpu.is_available() + + +def is_dvclive_available(): + return _is_package_available("dvclive") + + +def is_torchdata_available(): + return _is_package_available("torchdata") + + +# TODO: Remove this function once stateful_dataloader is a stable feature in torchdata. +def is_torchdata_stateful_dataloader_available(): + package_exists = _is_package_available("torchdata") + if package_exists: + torchdata_version = version.parse(importlib.metadata.version("torchdata")) + return compare_versions(torchdata_version, ">=", "0.8.0") + return False + + +def torchao_required(func): + """ + A decorator that ensures the decorated function is only called when torchao is available. + """ + + @wraps(func) + def wrapper(*args, **kwargs): + if not is_torchao_available(): + raise ImportError( + "`torchao` is not available, please install it before calling this function via `pip install torchao`." + ) + return func(*args, **kwargs) + + return wrapper + + +# TODO: Rework this into `utils.deepspeed` and migrate the "core" chunks into `accelerate.deepspeed` +def deepspeed_required(func): + """ + A decorator that ensures the decorated function is only called when deepspeed is enabled. + """ + + @wraps(func) + def wrapper(*args, **kwargs): + from accelerate.state import AcceleratorState + from accelerate.utils.dataclasses import DistributedType + + if AcceleratorState._shared_state != {} and AcceleratorState().distributed_type != DistributedType.DEEPSPEED: + raise ValueError( + "DeepSpeed is not enabled, please make sure that an `Accelerator` is configured for `deepspeed` " + "before calling this function." + ) + return func(*args, **kwargs) + + return wrapper + + +def is_weights_only_available(): + # Weights only with allowlist was added in 2.4.0 + # ref: https://github.com/pytorch/pytorch/pull/124331 + return is_torch_version(">=", "2.4.0") + + +def is_numpy_available(min_version="1.25.0"): + numpy_version = parse(importlib.metadata.version("numpy")) + return compare_versions(numpy_version, ">=", min_version) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/launch.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/launch.py new file mode 100644 index 0000000000000000000000000000000000000000..6182bd40d6f29086a0b01816569e147423c46192 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/launch.py @@ -0,0 +1,781 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import os +import subprocess +import sys +import warnings +from ast import literal_eval +from shutil import which +from typing import Any + +import torch + +from ..commands.config.config_args import SageMakerConfig +from ..utils import ( + DynamoBackend, + PrecisionType, + is_ccl_available, + is_fp8_available, + is_hpu_available, + is_ipex_available, + is_mlu_available, + is_musa_available, + is_npu_available, + is_sdaa_available, + is_torch_xla_available, + is_xpu_available, +) +from ..utils.constants import DEEPSPEED_MULTINODE_LAUNCHERS +from ..utils.other import get_free_port, is_port_in_use, merge_dicts +from ..utils.versions import compare_versions +from .dataclasses import DistributedType, SageMakerDistributedType + + +def _filter_args(args, parser, default_args=[]): + """ + Filters out all `accelerate` specific args + """ + new_args, _ = parser.parse_known_args(default_args) + for key, value in vars(args).items(): + if key in vars(new_args).keys(): + setattr(new_args, key, value) + return new_args + + +def _get_mpirun_args(): + """ + Determines the executable and argument names for mpirun, based on the type of install. The supported MPI programs + are: OpenMPI, Intel MPI, or MVAPICH. + + Returns: Program name and arg names for hostfile, num processes, and processes per node + """ + # Find the MPI program name + mpi_apps = [x for x in ["mpirun", "mpiexec"] if which(x)] + + if len(mpi_apps) == 0: + raise OSError("mpirun or mpiexec were not found. Ensure that Intel MPI, Open MPI, or MVAPICH are installed.") + + # Call the app with the --version flag to determine which MPI app is installed + mpi_app = mpi_apps[0] + mpirun_version = subprocess.check_output([mpi_app, "--version"]) + + if b"Open MPI" in mpirun_version: + return mpi_app, "--hostfile", "-n", "--npernode", "--bind-to" + else: + # Intel MPI and MVAPICH both use the same arg names + return mpi_app, "-f", "-n", "-ppn", "" + + +def setup_fp8_env(args: argparse.Namespace, current_env: dict[str, str]): + """ + Setup the FP8 environment variables. + """ + prefix = "ACCELERATE_" + for arg in vars(args): + if arg.startswith("fp8_"): + value = getattr(args, arg) + if value is not None: + if arg == "fp8_override_linear_precision": + current_env[prefix + "FP8_OVERRIDE_FPROP"] = str(value[0]) + current_env[prefix + "FP8_OVERRIDE_DGRAD"] = str(value[1]) + current_env[prefix + "FP8_OVERRIDE_WGRAD"] = str(value[2]) + else: + current_env[f"{prefix}{arg.upper()}"] = str(getattr(args, arg)) + return current_env + + +def prepare_simple_launcher_cmd_env(args: argparse.Namespace) -> tuple[list[str], dict[str, str]]: + """ + Prepares and returns the command list and an environment with the correct simple launcher environment variables. + """ + cmd = [] + if args.no_python and args.module: + raise ValueError("--module and --no_python cannot be used together") + + num_processes = getattr(args, "num_processes", None) + num_machines = args.num_machines + if args.mpirun_hostfile is not None: + mpi_app_name, hostfile_arg, num_proc_arg, proc_per_node_arg, bind_to_arg = _get_mpirun_args() + bind_to = getattr(args, "bind-to", "socket") + nproc_per_node = str(num_processes // num_machines) if num_processes and num_machines else "1" + cmd += [ + mpi_app_name, + hostfile_arg, + args.mpirun_hostfile, + proc_per_node_arg, + nproc_per_node, + ] + if num_processes: + cmd += [num_proc_arg, str(num_processes)] + if bind_to_arg: + cmd += [bind_to_arg, bind_to] + if not args.no_python: + cmd.append(sys.executable) + if args.module: + cmd.append("-m") + cmd.append(args.training_script) + cmd.extend(args.training_script_args) + + current_env = os.environ.copy() + current_env["ACCELERATE_USE_CPU"] = str(args.cpu or args.use_cpu) + if args.debug: + current_env["ACCELERATE_DEBUG_MODE"] = "true" + if args.gpu_ids != "all" and args.gpu_ids is not None: + if is_xpu_available(): + current_env["ZE_AFFINITY_MASK"] = args.gpu_ids + elif is_mlu_available(): + current_env["MLU_VISIBLE_DEVICES"] = args.gpu_ids + elif is_sdaa_available(): + current_env["SDAA_VISIBLE_DEVICES"] = args.gpu_ids + elif is_musa_available(): + current_env["MUSA_VISIBLE_DEVICES"] = args.gpu_ids + elif is_npu_available(): + current_env["ASCEND_RT_VISIBLE_DEVICES"] = args.gpu_ids + elif is_hpu_available(): + current_env["HABANA_VISIBLE_MODULES"] = args.gpu_ids + else: + current_env["CUDA_VISIBLE_DEVICES"] = args.gpu_ids + if num_machines > 1: + assert args.main_process_ip is not None, ( + "When using multiple machines, you need to specify the main process IP." + ) + assert args.main_process_port is not None, ( + "When using multiple machines, you need to specify the main process port." + ) + + ccl_worker_count = getattr(args, "mpirun_ccl", 0) if is_ccl_available() else 0 + if (num_processes is not None and num_processes > 1) or num_machines > 1: + current_env["MASTER_ADDR"] = args.main_process_ip if args.main_process_ip is not None else "127.0.0.1" + current_env["MASTER_PORT"] = str(args.main_process_port) if args.main_process_port is not None else "29500" + current_env["CCL_WORKER_COUNT"] = str(ccl_worker_count) + if current_env["ACCELERATE_USE_CPU"]: + current_env["KMP_AFFINITY"] = "granularity=fine,compact,1,0" + current_env["KMP_BLOCKTIME"] = str(1) + + try: + mixed_precision = PrecisionType(args.mixed_precision.lower()) + except ValueError: + raise ValueError( + f"Unknown mixed_precision mode: {args.mixed_precision.lower()}. Choose between {PrecisionType.list()}." + ) + + current_env["ACCELERATE_MIXED_PRECISION"] = str(mixed_precision) + if args.mixed_precision.lower() == "fp8": + if not is_fp8_available(): + raise RuntimeError( + "FP8 is not available on this machine. Please ensure that either Transformer Engine, MSAMP or torchao is installed." + ) + current_env = setup_fp8_env(args, current_env) + + try: + dynamo_backend = DynamoBackend(args.dynamo_backend.upper()) + except ValueError: + raise ValueError( + f"Unknown dynamo backend: {args.dynamo_backend.upper()}. Choose between {DynamoBackend.list()}." + ) + current_env["ACCELERATE_DYNAMO_BACKEND"] = dynamo_backend.value + current_env["ACCELERATE_DYNAMO_MODE"] = args.dynamo_mode + current_env["ACCELERATE_DYNAMO_USE_FULLGRAPH"] = str(args.dynamo_use_fullgraph) + current_env["ACCELERATE_DYNAMO_USE_DYNAMIC"] = str(args.dynamo_use_dynamic) + current_env["ACCELERATE_DYNAMO_USE_REGIONAL_COMPILATION"] = str(args.dynamo_use_regional_compilation) + + current_env["OMP_NUM_THREADS"] = str(args.num_cpu_threads_per_process) + if is_ipex_available(): + current_env["ACCELERATE_USE_IPEX"] = str(args.ipex).lower() + if args.enable_cpu_affinity: + current_env["ACCELERATE_CPU_AFFINITY"] = "1" + return cmd, current_env + + +def prepare_multi_gpu_env(args: argparse.Namespace) -> dict[str, str]: + """ + Prepares and returns an environment with the correct multi-GPU environment variables. + """ + # get free port and update configurations + if args.main_process_port == 0: + args.main_process_port = get_free_port() + + elif args.main_process_port is None: + args.main_process_port = 29500 + + num_processes = args.num_processes + num_machines = args.num_machines + main_process_ip = args.main_process_ip + main_process_port = args.main_process_port + if num_machines > 1: + args.nproc_per_node = str(num_processes // num_machines) + args.nnodes = str(num_machines) + args.node_rank = int(args.machine_rank) + if getattr(args, "same_network", False): + args.master_addr = str(main_process_ip) + args.master_port = str(main_process_port) + else: + args.rdzv_endpoint = f"{main_process_ip}:{main_process_port}" + else: + args.nproc_per_node = str(num_processes) + if main_process_port is not None: + args.master_port = str(main_process_port) + + # only need to check port availability in main process, in case we have to start multiple launchers on the same machine + # for some reasons like splitting log files. + need_port_check = num_machines <= 1 or int(args.machine_rank) == 0 + if need_port_check and is_port_in_use(main_process_port): + if num_machines <= 1: + args.standalone = True + warnings.warn( + f"Port `{main_process_port}` is already in use. " + "Accelerate will attempt to launch in a standalone-like mode by finding an open port automatically for this session. " + "If this current attempt fails, or for more control in future runs, please specify a different port " + "(e.g., `--main_process_port `) or use `--main_process_port 0` for automatic selection " + "in your launch command or Accelerate config file." + ) + else: + raise ConnectionError( + f"Tried to launch distributed communication on port `{main_process_port}`, but another process is utilizing it. " + "Please specify a different port (such as using the `--main_process_port` flag or specifying a different `main_process_port` in your config file)" + " and rerun your script. To automatically use the next open port (on a single node), you can set this to `0`." + ) + + if args.module and args.no_python: + raise ValueError("--module and --no_python cannot be used together") + elif args.module: + args.module = True + elif args.no_python: + args.no_python = True + + current_env = os.environ.copy() + if args.debug: + current_env["ACCELERATE_DEBUG_MODE"] = "true" + gpu_ids = getattr(args, "gpu_ids", "all") + if gpu_ids != "all" and args.gpu_ids is not None: + if is_xpu_available(): + current_env["ZE_AFFINITY_MASK"] = gpu_ids + elif is_mlu_available(): + current_env["MLU_VISIBLE_DEVICES"] = gpu_ids + elif is_sdaa_available(): + current_env["SDAA_VISIBLE_DEVICES"] = gpu_ids + elif is_musa_available(): + current_env["MUSA_VISIBLE_DEVICES"] = gpu_ids + elif is_npu_available(): + current_env["ASCEND_RT_VISIBLE_DEVICES"] = gpu_ids + elif is_hpu_available(): + current_env["HABANA_VISIBLE_MODULES"] = gpu_ids + else: + current_env["CUDA_VISIBLE_DEVICES"] = gpu_ids + mixed_precision = args.mixed_precision.lower() + try: + mixed_precision = PrecisionType(mixed_precision) + except ValueError: + raise ValueError(f"Unknown mixed_precision mode: {mixed_precision}. Choose between {PrecisionType.list()}.") + + current_env["ACCELERATE_MIXED_PRECISION"] = str(mixed_precision) + if args.mixed_precision.lower() == "fp8": + if not is_fp8_available(): + raise RuntimeError( + "FP8 is not available on this machine. Please ensure that either Transformer Engine, MSAMP or torchao is installed." + ) + current_env = setup_fp8_env(args, current_env) + + try: + dynamo_backend = DynamoBackend(args.dynamo_backend.upper()) + except ValueError: + raise ValueError( + f"Unknown dynamo backend: {args.dynamo_backend.upper()}. Choose between {DynamoBackend.list()}." + ) + current_env["ACCELERATE_DYNAMO_BACKEND"] = dynamo_backend.value + current_env["ACCELERATE_DYNAMO_MODE"] = args.dynamo_mode + current_env["ACCELERATE_DYNAMO_USE_FULLGRAPH"] = str(args.dynamo_use_fullgraph) + current_env["ACCELERATE_DYNAMO_USE_DYNAMIC"] = str(args.dynamo_use_dynamic) + current_env["ACCELERATE_DYNAMO_USE_REGIONAL_COMPILATION"] = str(args.dynamo_use_regional_compilation) + + if args.use_fsdp: + current_env["ACCELERATE_USE_FSDP"] = "true" + if args.fsdp_cpu_ram_efficient_loading and not args.fsdp_sync_module_states: + raise ValueError("When using `--fsdp_cpu_ram_efficient_loading` set `--fsdp_sync_module_states` to `True`") + + current_env["FSDP_VERSION"] = str(args.fsdp_version) if hasattr(args, "fsdp_version") else "1" + + # For backwards compatibility, we support this in launched scripts, + # however, we do not ask users for this in `accelerate config` CLI + current_env["FSDP_SHARDING_STRATEGY"] = str(args.fsdp_sharding_strategy) + + current_env["FSDP_RESHARD_AFTER_FORWARD"] = str(args.fsdp_reshard_after_forward).lower() + current_env["FSDP_OFFLOAD_PARAMS"] = str(args.fsdp_offload_params).lower() + current_env["FSDP_MIN_NUM_PARAMS"] = str(args.fsdp_min_num_params) + if args.fsdp_auto_wrap_policy is not None: + current_env["FSDP_AUTO_WRAP_POLICY"] = str(args.fsdp_auto_wrap_policy) + if args.fsdp_transformer_layer_cls_to_wrap is not None: + current_env["FSDP_TRANSFORMER_CLS_TO_WRAP"] = str(args.fsdp_transformer_layer_cls_to_wrap) + if args.fsdp_backward_prefetch is not None: + current_env["FSDP_BACKWARD_PREFETCH"] = str(args.fsdp_backward_prefetch) + if args.fsdp_state_dict_type is not None: + current_env["FSDP_STATE_DICT_TYPE"] = str(args.fsdp_state_dict_type) + current_env["FSDP_FORWARD_PREFETCH"] = str(args.fsdp_forward_prefetch).lower() + current_env["FSDP_USE_ORIG_PARAMS"] = str(args.fsdp_use_orig_params).lower() + current_env["FSDP_CPU_RAM_EFFICIENT_LOADING"] = str(args.fsdp_cpu_ram_efficient_loading).lower() + current_env["FSDP_SYNC_MODULE_STATES"] = str(args.fsdp_sync_module_states).lower() + current_env["FSDP_ACTIVATION_CHECKPOINTING"] = str(args.fsdp_activation_checkpointing).lower() + if getattr(args, "fsdp_ignored_modules", None) is not None: + current_env["FSDP_IGNORED_MODULES"] = str(args.fsdp_ignored_modules) + + if args.use_megatron_lm: + prefix = "MEGATRON_LM_" + current_env["ACCELERATE_USE_MEGATRON_LM"] = "true" + current_env[prefix + "TP_DEGREE"] = str(args.megatron_lm_tp_degree) + current_env[prefix + "PP_DEGREE"] = str(args.megatron_lm_pp_degree) + current_env[prefix + "GRADIENT_CLIPPING"] = str(args.megatron_lm_gradient_clipping) + if args.megatron_lm_num_micro_batches is not None: + current_env[prefix + "NUM_MICRO_BATCHES"] = str(args.megatron_lm_num_micro_batches) + if args.megatron_lm_sequence_parallelism is not None: + current_env[prefix + "SEQUENCE_PARALLELISM"] = str(args.megatron_lm_sequence_parallelism) + if args.megatron_lm_recompute_activations is not None: + current_env[prefix + "RECOMPUTE_ACTIVATIONS"] = str(args.megatron_lm_recompute_activations) + if args.megatron_lm_use_distributed_optimizer is not None: + current_env[prefix + "USE_DISTRIBUTED_OPTIMIZER"] = str(args.megatron_lm_use_distributed_optimizer) + + current_env["OMP_NUM_THREADS"] = str(args.num_cpu_threads_per_process) + if args.enable_cpu_affinity: + current_env["ACCELERATE_CPU_AFFINITY"] = "1" + + if args.use_parallelism_config: + current_env = prepare_extend_env_parallelism_config(args, current_env) + + return current_env + + +def prepare_extend_env_parallelism_config( + args: argparse.Namespace, current_env: dict +) -> tuple[list[str], dict[str, str]]: + """ + Extends `current_env` with context parallelism env vars if any have been set + """ + + prefix = "PARALLELISM_CONFIG_" + + current_env["ACCELERATE_USE_PARALLELISM_CONFIG"] = "true" + current_env[prefix + "DP_REPLICATE_SIZE"] = str(args.parallelism_config_dp_replicate_size) + current_env[prefix + "DP_SHARD_SIZE"] = str(args.parallelism_config_dp_shard_size) + current_env[prefix + "TP_SIZE"] = str(args.parallelism_config_tp_size) + current_env[prefix + "CP_SIZE"] = str(args.parallelism_config_cp_size) + current_env[prefix + "CP_BACKEND"] = str(args.parallelism_config_cp_backend) + current_env[prefix + "SP_SIZE"] = str(args.parallelism_config_sp_size) + current_env[prefix + "SP_BACKEND"] = str(args.parallelism_config_sp_backend) + if args.parallelism_config_cp_size > 1: + current_env[prefix + "CP_COMM_STRATEGY"] = str(args.parallelism_config_cp_comm_strategy) + if args.parallelism_config_sp_size > 1: + current_env[prefix + "SP_SEQ_LENGTH"] = str(args.parallelism_config_sp_seq_length) + current_env[prefix + "SP_SEQ_LENGTH_IS_VARIABLE"] = str(args.parallelism_config_sp_seq_length_is_variable) + current_env[prefix + "SP_ATTN_IMPLEMENTATION"] = str(args.parallelism_config_sp_attn_implementation) + + return current_env + + +def prepare_deepspeed_cmd_env(args: argparse.Namespace) -> tuple[list[str], dict[str, str]]: + """ + Prepares and returns the command list and an environment with the correct DeepSpeed environment variables. + """ + # get free port and update configurations + if args.main_process_port == 0: + args.main_process_port = get_free_port() + + elif args.main_process_port is None: + args.main_process_port = 29500 + + num_processes = args.num_processes + num_machines = args.num_machines + main_process_ip = args.main_process_ip + main_process_port = args.main_process_port + cmd = None + + # make sure launcher is not None + if args.deepspeed_multinode_launcher is None: + # set to default pdsh + args.deepspeed_multinode_launcher = DEEPSPEED_MULTINODE_LAUNCHERS[0] + + if num_machines > 1 and args.deepspeed_multinode_launcher != DEEPSPEED_MULTINODE_LAUNCHERS[1]: + cmd = ["deepspeed"] + cmd.extend(["--hostfile", str(args.deepspeed_hostfile)]) + if args.deepspeed_multinode_launcher == "nossh": + if compare_versions("deepspeed", "<", "0.14.5"): + raise ValueError("nossh launcher requires DeepSpeed >= 0.14.5") + cmd.extend(["--node_rank", str(args.machine_rank), "--no_ssh"]) + else: + cmd.extend(["--no_local_rank", "--launcher", str(args.deepspeed_multinode_launcher)]) + if args.deepspeed_exclusion_filter is not None: + cmd.extend( + [ + "--exclude", + str(args.deepspeed_exclusion_filter), + ] + ) + elif args.deepspeed_inclusion_filter is not None: + cmd.extend( + [ + "--include", + str(args.deepspeed_inclusion_filter), + ] + ) + else: + cmd.extend(["--num_gpus", str(args.num_processes // args.num_machines)]) + if main_process_ip: + cmd.extend(["--master_addr", str(main_process_ip)]) + cmd.extend(["--master_port", str(main_process_port)]) + if args.module and args.no_python: + raise ValueError("--module and --no_python cannot be used together") + elif args.module: + cmd.append("--module") + elif args.no_python: + cmd.append("--no_python") + cmd.append(args.training_script) + cmd.extend(args.training_script_args) + elif num_machines > 1 and args.deepspeed_multinode_launcher == DEEPSPEED_MULTINODE_LAUNCHERS[1]: + args.nproc_per_node = str(num_processes // num_machines) + args.nnodes = str(num_machines) + args.node_rank = int(args.machine_rank) + if getattr(args, "same_network", False): + args.master_addr = str(main_process_ip) + args.master_port = str(main_process_port) + else: + args.rdzv_endpoint = f"{main_process_ip}:{main_process_port}" + else: + args.nproc_per_node = str(num_processes) + if main_process_port is not None: + args.master_port = str(main_process_port) + + # only need to check port availability in main process, in case we have to start multiple launchers on the same machine + # for some reasons like splitting log files. + need_port_check = num_machines <= 1 or int(args.machine_rank) == 0 + if need_port_check and is_port_in_use(main_process_port): + if num_machines <= 1: + args.standalone = True + warnings.warn( + f"Port `{main_process_port}` is already in use. " + "Accelerate will attempt to launch in a standalone-like mode by finding an open port automatically for this session. " + "If this current attempt fails, or for more control in future runs, please specify a different port " + "(e.g., `--main_process_port `) or use `--main_process_port 0` for automatic selection " + "in your launch command or Accelerate config file." + ) + else: + raise ConnectionError( + f"Tried to launch distributed communication on port `{main_process_port}`, but another process is utilizing it. " + "Please specify a different port (such as using the `--main_process_port` flag or specifying a different `main_process_port` in your config file)" + " and rerun your script. To automatically use the next open port (on a single node), you can set this to `0`." + ) + + if args.module and args.no_python: + raise ValueError("--module and --no_python cannot be used together") + elif args.module: + args.module = True + elif args.no_python: + args.no_python = True + + current_env = os.environ.copy() + if args.debug: + current_env["ACCELERATE_DEBUG_MODE"] = "true" + gpu_ids = getattr(args, "gpu_ids", "all") + if gpu_ids != "all" and args.gpu_ids is not None: + if is_xpu_available(): + current_env["ZE_AFFINITY_MASK"] = gpu_ids + elif is_mlu_available(): + current_env["MLU_VISIBLE_DEVICES"] = gpu_ids + elif is_sdaa_available(): + current_env["SDAA_VISIBLE_DEVICES"] = gpu_ids + elif is_musa_available(): + current_env["MUSA_VISIBLE_DEVICES"] = gpu_ids + elif is_npu_available(): + current_env["ASCEND_RT_VISIBLE_DEVICES"] = gpu_ids + elif is_hpu_available(): + current_env["HABANA_VISIBLE_MODULES"] = gpu_ids + else: + current_env["CUDA_VISIBLE_DEVICES"] = gpu_ids + try: + mixed_precision = PrecisionType(args.mixed_precision.lower()) + except ValueError: + raise ValueError( + f"Unknown mixed_precision mode: {args.mixed_precision.lower()}. Choose between {PrecisionType.list()}." + ) + + current_env["PYTHONPATH"] = env_var_path_add("PYTHONPATH", os.path.abspath(".")) + current_env["ACCELERATE_MIXED_PRECISION"] = str(mixed_precision) + if args.mixed_precision.lower() == "fp8": + if not is_fp8_available(): + raise RuntimeError( + "FP8 is not available on this machine. Please ensure that either Transformer Engine, MSAMP or torchao is installed." + ) + current_env = setup_fp8_env(args, current_env) + current_env["ACCELERATE_CONFIG_DS_FIELDS"] = str(args.deepspeed_fields_from_accelerate_config).lower() + current_env["ACCELERATE_USE_DEEPSPEED"] = "true" + if args.zero_stage is not None: + current_env["ACCELERATE_DEEPSPEED_ZERO_STAGE"] = str(args.zero_stage) + if args.gradient_accumulation_steps is not None: + current_env["ACCELERATE_GRADIENT_ACCUMULATION_STEPS"] = str(args.gradient_accumulation_steps) + if args.gradient_clipping is not None: + current_env["ACCELERATE_GRADIENT_CLIPPING"] = str(args.gradient_clipping).lower() + if args.offload_optimizer_device is not None: + current_env["ACCELERATE_DEEPSPEED_OFFLOAD_OPTIMIZER_DEVICE"] = str(args.offload_optimizer_device).lower() + if args.offload_param_device is not None: + current_env["ACCELERATE_DEEPSPEED_OFFLOAD_PARAM_DEVICE"] = str(args.offload_param_device).lower() + if args.zero3_init_flag is not None: + current_env["ACCELERATE_DEEPSPEED_ZERO3_INIT"] = str(args.zero3_init_flag).lower() + if args.zero3_save_16bit_model is not None: + current_env["ACCELERATE_DEEPSPEED_ZERO3_SAVE_16BIT_MODEL"] = str(args.zero3_save_16bit_model).lower() + if args.deepspeed_config_file is not None: + current_env["ACCELERATE_DEEPSPEED_CONFIG_FILE"] = str(args.deepspeed_config_file) + if args.enable_cpu_affinity: + current_env["ACCELERATE_CPU_AFFINITY"] = "1" + if args.deepspeed_moe_layer_cls_names is not None: + current_env["ACCELERATE_DEEPSPEED_MOE_LAYER_CLS_NAMES"] = str(args.deepspeed_moe_layer_cls_names) + + if args.use_parallelism_config: + current_env = prepare_extend_env_parallelism_config(args, current_env) + + return cmd, current_env + + +def prepare_tpu( + args: argparse.Namespace, current_env: dict[str, str], pod: bool = False +) -> tuple[argparse.Namespace, dict[str, str]]: + """ + Prepares and returns an environment with the correct TPU environment variables. + """ + if args.mixed_precision == "bf16" and is_torch_xla_available(check_is_tpu=True): + if args.downcast_bf16: + current_env["XLA_DOWNCAST_BF16"] = "1" + else: + current_env["XLA_USE_BF16"] = "1" + if args.debug: + current_env["ACCELERATE_DEBUG_MODE"] = "true" + if pod: + # Take explicit args and set them up for XLA + args.vm = args.tpu_vm + args.tpu = args.tpu_name + return args, current_env + + +def _convert_nargs_to_dict(nargs: list[str]) -> dict[str, str]: + if len(nargs) < 0: + return {} + # helper function to infer type for argsparser + + def _infer_type(s): + try: + s = float(s) + + if s // 1 == s: + return int(s) + return s + except ValueError: + return s + + parser = argparse.ArgumentParser() + _, unknown = parser.parse_known_args(nargs) + for index, argument in enumerate(unknown): + if argument.startswith(("-", "--")): + action = None + if index + 1 < len(unknown): # checks if next index would be in list + if unknown[index + 1].startswith(("-", "--")): # checks if next element is an key + # raise an error if element is store_true or store_false + raise ValueError( + "SageMaker doesn’t support argparse actions for `store_true` or `store_false`. Please define explicit types" + ) + else: # raise an error if last element is store_true or store_false + raise ValueError( + "SageMaker doesn’t support argparse actions for `store_true` or `store_false`. Please define explicit types" + ) + # adds argument to parser based on action_store true + if action is None: + parser.add_argument(argument, type=_infer_type) + else: + parser.add_argument(argument, action=action) + + return { + key: (literal_eval(value) if value in ("True", "False") else value) + for key, value in parser.parse_args(nargs).__dict__.items() + } + + +def prepare_sagemager_args_inputs( + sagemaker_config: SageMakerConfig, args: argparse.Namespace +) -> tuple[argparse.Namespace, dict[str, Any]]: + # configure environment + print("Configuring Amazon SageMaker environment") + os.environ["AWS_DEFAULT_REGION"] = sagemaker_config.region + + # configure credentials + if sagemaker_config.profile is not None: + os.environ["AWS_PROFILE"] = sagemaker_config.profile + elif args.aws_access_key_id is not None and args.aws_secret_access_key is not None: + os.environ["AWS_ACCESS_KEY_ID"] = args.aws_access_key_id + os.environ["AWS_SECRET_ACCESS_KEY"] = args.aws_secret_access_key + else: + raise OSError("You need to provide an aws_access_key_id and aws_secret_access_key when not using aws_profile") + + # extract needed arguments + source_dir = os.path.dirname(args.training_script) + if not source_dir: # checks if string is empty + source_dir = "." + entry_point = os.path.basename(args.training_script) + if not entry_point.endswith(".py"): + raise ValueError(f'Your training script should be a python script and not "{entry_point}"') + + print("Converting Arguments to Hyperparameters") + hyperparameters = _convert_nargs_to_dict(args.training_script_args) + + try: + mixed_precision = PrecisionType(args.mixed_precision.lower()) + except ValueError: + raise ValueError( + f"Unknown mixed_precision mode: {args.mixed_precision.lower()}. Choose between {PrecisionType.list()}." + ) + + try: + dynamo_backend = DynamoBackend(args.dynamo_backend.upper()) + except ValueError: + raise ValueError( + f"Unknown dynamo backend: {args.dynamo_backend.upper()}. Choose between {DynamoBackend.list()}." + ) + + # Environment variables to be set for use during training job + environment = { + "ACCELERATE_USE_SAGEMAKER": "true", + "ACCELERATE_MIXED_PRECISION": str(mixed_precision), + "ACCELERATE_DYNAMO_BACKEND": dynamo_backend.value, + "ACCELERATE_DYNAMO_MODE": args.dynamo_mode, + "ACCELERATE_DYNAMO_USE_FULLGRAPH": str(args.dynamo_use_fullgraph), + "ACCELERATE_DYNAMO_USE_DYNAMIC": str(args.dynamo_use_dynamic), + "ACCELERATE_DYNAMO_USE_REGIONAL_COMPILATION": str(args.dynamo_use_regional_compilation), + "ACCELERATE_SAGEMAKER_DISTRIBUTED_TYPE": sagemaker_config.distributed_type.value, + } + if args.mixed_precision.lower() == "fp8": + if not is_fp8_available(): + raise RuntimeError( + "FP8 is not available on this machine. Please ensure that either Transformer Engine, MSAMP or torchao is installed." + ) + environment = setup_fp8_env(args, environment) + # configure distribution set up + distribution = None + if sagemaker_config.distributed_type == SageMakerDistributedType.DATA_PARALLEL: + distribution = {"smdistributed": {"dataparallel": {"enabled": True}}} + + # configure sagemaker inputs + sagemaker_inputs = None + if sagemaker_config.sagemaker_inputs_file is not None: + print(f"Loading SageMaker Inputs from {sagemaker_config.sagemaker_inputs_file} file") + sagemaker_inputs = {} + with open(sagemaker_config.sagemaker_inputs_file) as file: + for i, line in enumerate(file): + if i == 0: + continue + l = line.split("\t") + sagemaker_inputs[l[0]] = l[1].strip() + print(f"Loaded SageMaker Inputs: {sagemaker_inputs}") + + # configure sagemaker metrics + sagemaker_metrics = None + if sagemaker_config.sagemaker_metrics_file is not None: + print(f"Loading SageMaker Metrics from {sagemaker_config.sagemaker_metrics_file} file") + sagemaker_metrics = [] + with open(sagemaker_config.sagemaker_metrics_file) as file: + for i, line in enumerate(file): + if i == 0: + continue + l = line.split("\t") + metric_dict = { + "Name": l[0], + "Regex": l[1].strip(), + } + sagemaker_metrics.append(metric_dict) + print(f"Loaded SageMaker Metrics: {sagemaker_metrics}") + + # configure session + print("Creating Estimator") + args = { + "image_uri": sagemaker_config.image_uri, + "entry_point": entry_point, + "source_dir": source_dir, + "role": sagemaker_config.iam_role_name, + "transformers_version": sagemaker_config.transformers_version, + "pytorch_version": sagemaker_config.pytorch_version, + "py_version": sagemaker_config.py_version, + "base_job_name": sagemaker_config.base_job_name, + "instance_count": sagemaker_config.num_machines, + "instance_type": sagemaker_config.ec2_instance_type, + "debugger_hook_config": False, + "distribution": distribution, + "hyperparameters": hyperparameters, + "environment": environment, + "metric_definitions": sagemaker_metrics, + } + + if sagemaker_config.additional_args is not None: + args = merge_dicts(sagemaker_config.additional_args, args) + return args, sagemaker_inputs + + +def env_var_path_add(env_var_name, path_to_add): + """ + Extends a path-based environment variable's value with a new path and returns the updated value. It's up to the + caller to set it in os.environ. + """ + paths = [p for p in os.environ.get(env_var_name, "").split(":") if len(p) > 0] + paths.append(str(path_to_add)) + return ":".join(paths) + + +class PrepareForLaunch: + """ + Prepare a function that will launched in a distributed setup. + + Args: + launcher (`Callable`): + The function to launch. + distributed_type ([`~state.DistributedType`]): + The distributed type to prepare for. + debug (`bool`, *optional*, defaults to `False`): + Whether or not this is a debug launch. + """ + + def __init__(self, launcher, distributed_type="NO", debug=False): + self.launcher = launcher + self.distributed_type = DistributedType(distributed_type) + self.debug = debug + + def __call__(self, index, *args): + if self.debug: + world_size = int(os.environ.get("WORLD_SIZE")) + rdv_file = os.environ.get("ACCELERATE_DEBUG_RDV_FILE") + torch.distributed.init_process_group( + "gloo", + rank=index, + store=torch.distributed.FileStore(rdv_file, world_size), + world_size=world_size, + ) + elif self.distributed_type in ( + DistributedType.MULTI_GPU, + DistributedType.MULTI_MLU, + DistributedType.MULTI_MUSA, + DistributedType.MULTI_NPU, + DistributedType.MULTI_XPU, + DistributedType.MULTI_CPU, + ): + # Prepare the environment for torch.distributed + os.environ["LOCAL_RANK"] = str(index) + nproc = int(os.environ.get("NPROC", 1)) + node_rank = int(os.environ.get("NODE_RANK", 0)) + os.environ["RANK"] = str(nproc * node_rank + index) + + os.environ["FORK_LAUNCHED"] = str(1) + self.launcher(*args) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/megatron_lm.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/megatron_lm.py new file mode 100644 index 0000000000000000000000000000000000000000..e3754098801102d67b98cebae5bf18b2fd6129d2 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/megatron_lm.py @@ -0,0 +1,1424 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import math +import os +from abc import ABC +from functools import partial + +import torch +import torch.nn.functional as F +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss +from torch.nn.parallel.distributed import DistributedDataParallel as torchDDP + +from ..optimizer import AcceleratedOptimizer +from ..scheduler import AcceleratedScheduler +from .imports import is_megatron_lm_available +from .operations import recursively_apply, send_to_device + + +if is_megatron_lm_available(): + from megatron.core import mpu, tensor_parallel + from megatron.core.distributed import DistributedDataParallel as LocalDDP + from megatron.core.distributed import finalize_model_grads + from megatron.core.enums import ModelType + from megatron.core.num_microbatches_calculator import get_num_microbatches + from megatron.core.optimizer import get_megatron_optimizer + from megatron.core.parallel_state import get_tensor_model_parallel_group, get_tensor_model_parallel_src_rank + from megatron.core.pipeline_parallel import get_forward_backward_func + from megatron.core.utils import get_model_config + from megatron.inference.text_generation.communication import broadcast_int_list, broadcast_tensor + from megatron.inference.text_generation.generation import ( + beam_search_and_return_on_first_stage, + generate_tokens_probs_and_return_on_first_stage, + ) + from megatron.legacy.data.dataset_utils import build_train_valid_test_datasets + from megatron.legacy.model import BertModel, Float16Module, GPTModel, T5Model + from megatron.legacy.model.classification import Classification + from megatron.training import ( + get_args, + get_tensorboard_writer, + get_tokenizer, + print_rank_last, + ) + from megatron.training.arguments import ( + _add_data_args, + _add_validation_args, + core_transformer_config_from_args, + parse_args, + validate_args, + ) + from megatron.training.checkpointing import load_args_from_checkpoint, load_checkpoint, save_checkpoint + from megatron.training.global_vars import set_global_variables + from megatron.training.initialize import ( + _compile_dependencies, + _init_autoresume, + _initialize_distributed, + _set_random_seed, + set_jit_fusion_options, + write_args_to_tensorboard, + ) + from megatron.training.tokenizer.tokenizer import _vocab_size_with_padding + from megatron.training.training import ( + build_train_valid_test_data_iterators, + get_optimizer_param_scheduler, + num_floating_point_operations, + setup_model_and_optimizer, + train_step, + training_log, + ) + from megatron.training.utils import ( + average_losses_across_data_parallel_group, + calc_params_l2_norm, + get_ltor_masks_and_position_ids, + unwrap_model, + ) + + +# model utilities +def model_provider_func(pre_process=True, post_process=True, add_encoder=True, add_decoder=True): + """Build the model.""" + args = get_args() + mode = "pre-training" if args.pretraining_flag else "fine-tuning" + if args.rank == 0: + print(f"Building {args.model_type_name} model in the {mode} mode.") + print( + "The Megatron LM model weights are initialized at random in `accelerator.prepare`. " + "Please use `accelerator.load_checkpoint` to load a pre-trained checkpoint matching the distributed setup." + ) + config = core_transformer_config_from_args(args) + if args.model_type_name == "bert": + if args.pretraining_flag: + num_tokentypes = 2 if args.bert_binary_head else 0 + model = BertModel( + config=config, + num_tokentypes=num_tokentypes, + add_binary_head=args.bert_binary_head, + parallel_output=True, + pre_process=pre_process, + post_process=post_process, + ) + else: + model = Classification( + config=config, + num_classes=args.num_labels, + num_tokentypes=2, + pre_process=pre_process, + post_process=post_process, + ) + elif args.model_type_name == "gpt": + model = GPTModel( + config=config, + num_tokentypes=0, + parallel_output=True, + pre_process=pre_process, + post_process=post_process, + ) + elif args.model_type_name == "t5": + model = T5Model( + config=config, + num_tokentypes=0, + parallel_output=True, + pre_process=pre_process, + post_process=post_process, + add_encoder=add_encoder, + add_decoder=add_decoder, + ) + else: + raise ValueError(f"Unsupported model type: {args.model_type_name}") + return model + + +def prepare_model_optimizer_scheduler(accelerator): + accelerator.print("Preparing model optimizer scheduler") + args = get_args() + if accelerator.state.megatron_lm_plugin.custom_prepare_model_function is not None: + if accelerator.state.megatron_lm_plugin.custom_model_provider_function is None: + raise ValueError( + "You must provide a `custom_model_provider_function` when using a `custom_prepare_model_function`." + ) + custom_model_provider_func = accelerator.state.megatron_lm_plugin.custom_model_provider_function + model = accelerator.state.megatron_lm_plugin.custom_prepare_model_function(custom_model_provider_func) + optimizer = prepare_optimizer(accelerator, model) + scheduler = prepare_scheduler(accelerator, optimizer, scheduler=None) + else: + model_type = ModelType.encoder_or_decoder + if args.model_type_name == "t5": + model_type = ModelType.encoder_and_decoder + model_provider_func_ = model_provider_func + if accelerator.state.megatron_lm_plugin.custom_model_provider_function is not None: + model_provider_func_ = accelerator.state.megatron_lm_plugin.custom_model_provider_function + (model, optimizer, scheduler) = setup_model_and_optimizer( + model_provider_func_, + model_type, + no_wd_decay_cond=args.no_wd_decay_cond, + scale_lr_cond=args.scale_lr_cond, + lr_mult=args.lr_mult, + ) + args.model_len = len(model) + return model, optimizer, scheduler + + +# dataloader utilities +class MegatronLMDummyDataLoader: + """ + Dummy dataloader presents model parameters or param groups, this is primarily used to follow conventional training + + Args: + **dataset_kwargs: Megatron data arguments. + """ + + def __init__(self, **dataset_kwargs): + parser = argparse.ArgumentParser() + parser = _add_data_args(parser) + parser = _add_validation_args(parser) + data_args = parser.parse_known_args() + self.dataset_args = vars(data_args[0]) + self.dataset_args.update(dataset_kwargs) + self.dataset_args["megatron_dataset_flag"] = True + + def set_megatron_data_args(self): + args = get_args() + for key, value in self.dataset_args.items(): + old_value = getattr(args, key, "") + if old_value != value: + print( + f"WARNING: MegatronLMDummyDataLoader overriding arguments for {key}:{old_value} with {key}:{value}" + ) + setattr(args, key, value) + + def get_train_valid_test_datasets_provider(self, accelerator): + def train_valid_test_datasets_provider(train_val_test_num_samples): + """Build train, valid, and test datasets.""" + args = get_args() + dataset_args = { + "data_prefix": args.data_path if isinstance(args.data_path, (list, tuple)) else [args.data_path], + "splits_string": args.split, + "train_valid_test_num_samples": train_val_test_num_samples, + "seed": args.seed, + } + if args.model_type_name == "bert": + dataset_args.update( + { + "max_seq_length": args.seq_length, + "binary_head": args.bert_binary_head, + } + ) + elif args.model_type_name == "gpt": + dataset_args.update( + { + "max_seq_length": args.seq_length, + } + ) + elif args.model_type_name == "t5": + dataset_args.update( + { + "max_seq_length": args.encoder_seq_length, + "max_seq_length_dec": args.decoder_seq_length, + "dataset_type": "t5", + } + ) + else: + raise ValueError(f"Unsupported model type: {args.model_type_name}") + train_ds, valid_ds, test_ds = build_train_valid_test_datasets(**dataset_args) + return train_ds, valid_ds, test_ds + + if accelerator.state.megatron_lm_plugin.custom_megatron_datasets_provider_function is not None: + return accelerator.state.megatron_lm_plugin.custom_megatron_datasets_provider_function + try: + args = get_args() + # Use '--no-use-pep517 -e' to pip install nvidia's megatron from source + if args.model_type_name == "bert": + from pretrain_bert import train_valid_test_datasets_provider + + train_valid_test_datasets_provider.is_distributed = True + return train_valid_test_datasets_provider + elif args.model_type_name == "gpt": + from pretrain_gpt import train_valid_test_datasets_provider + + train_valid_test_datasets_provider.is_distributed = True + return train_valid_test_datasets_provider + elif args.model_type_name == "t5": + from pretrain_t5 import train_valid_test_datasets_provider + + train_valid_test_datasets_provider.is_distributed = True + return train_valid_test_datasets_provider + except ImportError: + pass + return train_valid_test_datasets_provider + + def build_train_valid_test_data_iterators(self, accelerator): + args = get_args() + + train_valid_test_dataset_provider = self.get_train_valid_test_datasets_provider(accelerator) + if args.virtual_pipeline_model_parallel_size is not None: + train_data_iterator = [] + valid_data_iterator = [] + test_data_iterator = [] + for i in range(getattr(args, "model_len", 0)): + mpu.set_virtual_pipeline_model_parallel_rank(i) + iterators = build_train_valid_test_data_iterators(train_valid_test_dataset_provider) + train_data_iterator.append(iterators[0]) + valid_data_iterator.append(iterators[1]) + test_data_iterator.append(iterators[2]) + else: + train_data_iterator, valid_data_iterator, test_data_iterator = build_train_valid_test_data_iterators( + train_valid_test_dataset_provider + ) + + return train_data_iterator, valid_data_iterator, test_data_iterator + + +def _handle_megatron_data_iterator(accelerator, data_iterator): + class DummyMegatronDataloader: + def __iter__(self): + return self + + def __next__(self): + return {} + + is_data_iterator_empty = data_iterator is None + is_src_data_iterator_empty = torch.tensor(is_data_iterator_empty, dtype=torch.bool, device=accelerator.device) + torch.distributed.broadcast( + is_src_data_iterator_empty, get_tensor_model_parallel_src_rank(), group=get_tensor_model_parallel_group() + ) + if not is_src_data_iterator_empty and is_data_iterator_empty: + return DummyMegatronDataloader() + return data_iterator + + +def prepare_data_loader(accelerator, dataloader): + accelerator.print("Preparing dataloader") + args = get_args() + if not args.megatron_dataset_flag: + from ..data_loader import _PYTORCH_DATALOADER_KWARGS, prepare_data_loader + + micro_batch_size = args.micro_batch_size * args.num_micro_batches + kwargs = {k: getattr(dataloader, k, _PYTORCH_DATALOADER_KWARGS[k]) for k in _PYTORCH_DATALOADER_KWARGS} + if kwargs["batch_size"] is None: + if isinstance(kwargs["sampler"], torch.utils.data.BatchSampler): + kwargs["sampler"].batch_size = micro_batch_size + else: + del kwargs["sampler"] + del kwargs["shuffle"] + del kwargs["batch_size"] + kwargs["batch_sampler"].batch_size = micro_batch_size + else: + del kwargs["batch_sampler"] + kwargs["batch_size"] = micro_batch_size + + dataloader = torch.utils.data.DataLoader(dataloader.dataset, **kwargs) + # split_batches: + # Megatron only needs to fetch different data between different dp groups, + # and does not need to split the data within the dp group. + return prepare_data_loader( + dataloader, + accelerator.device, + num_processes=mpu.get_data_parallel_world_size(), + process_index=mpu.get_data_parallel_rank(), + split_batches=False, + put_on_device=True, + rng_types=accelerator.rng_types.copy(), + dispatch_batches=accelerator.dispatch_batches, + ) + else: + if args.consumed_samples is not None: + ( + args.consumed_train_samples, + args.consumed_valid_samples, + args.consumed_test_samples, + ) = args.consumed_samples + else: + args.consumed_train_samples, args.consumed_valid_samples, args.consumed_test_samples = 0, 0, 0 + args.micro_batch_size = args.micro_batch_size * args.num_micro_batches + # In order to be compatible with data in transform format, + # it needs to increase the size of mbs first, + # and then split the large batch data into some mbs. + ( + train_data_iterator, + valid_data_iterator, + test_data_iterator, + ) = dataloader.build_train_valid_test_data_iterators(accelerator) + args.micro_batch_size = args.micro_batch_size // args.num_micro_batches + + train_data_iterator = _handle_megatron_data_iterator( + accelerator=accelerator, data_iterator=train_data_iterator + ) + valid_data_iterator = _handle_megatron_data_iterator( + accelerator=accelerator, data_iterator=valid_data_iterator + ) + test_data_iterator = _handle_megatron_data_iterator(accelerator=accelerator, data_iterator=test_data_iterator) + + return train_data_iterator, valid_data_iterator, test_data_iterator + + +# optimizer utilities +class MegatronLMOptimizerWrapper(AcceleratedOptimizer): + def __init__(self, optimizer): + super().__init__(optimizer, device_placement=False, scaler=None) + + def zero_grad(self, set_to_none=None): + pass # `model(**batch)` is doing that automatically. Therefore, its implementation is not needed + + def step(self): + pass # `model(**batch)` is doing that automatically. Therefore, its implementation is not needed + + @property + def step_was_skipped(self): + """Whether or not the optimizer step was done, or skipped because of gradient overflow.""" + return self.optimizer.skipped_iter + + +def prepare_optimizer(accelerator, model): + accelerator.print("Preparing optimizer") + args = get_args() + return get_megatron_optimizer(model, args.no_wd_decay_cond, args.scale_lr_cond, args.lr_mult) + + +# scheduler utilities +class MegatronLMDummyScheduler: + """ + Dummy scheduler presents model parameters or param groups, this is primarily used to follow conventional training + loop when scheduler config is specified in the deepspeed config file. + + Args: + optimizer (`torch.optim.optimizer.Optimizer`): + The optimizer to wrap. + total_num_steps (int): + Total number of steps. + warmup_num_steps (int): + Number of steps for warmup. + **kwargs (additional keyword arguments, *optional*): + Other arguments. + """ + + def __init__(self, optimizer, total_num_steps=None, warmup_num_steps=0, **kwargs): + self.optimizer = optimizer + self.total_num_steps = total_num_steps + self.warmup_num_steps = warmup_num_steps + self.kwargs = kwargs + + +class MegatronLMSchedulerWrapper(AcceleratedScheduler): + def __init__(self, scheduler, optimizers): + super().__init__(scheduler, optimizers) + + def step(self, *args, **kwargs): + return # `model(**batch)` is doing that automatically. Therefore, its implementation is not needed + + +def prepare_scheduler(accelerator, optimizer, scheduler): + accelerator.print("Preparing scheduler") + scheduler = get_optimizer_param_scheduler(optimizer) + return scheduler + + +class AbstractTrainStep(ABC): + """Abstract class for batching, forward pass and loss handler.""" + + def __init__(self, name): + super().__init__() + self.name = name + + def get_batch_func(self, accelerator, megatron_dataset_flag): + pass + + def get_forward_step_func(self): + pass + + def get_loss_func(self, accelerator): + pass + + +class BertTrainStep(AbstractTrainStep): + """ + Bert train step class. + + Args: + args (`argparse.Namespace`): Megatron-LM arguments. + """ + + def __init__(self, accelerator, args): + super().__init__("BertTrainStep") + self.get_batch = self.get_batch_func(accelerator, args.megatron_dataset_flag) + self.loss_func = self.get_loss_func(accelerator, args.pretraining_flag, args.num_labels) + self.forward_step = self.get_forward_step_func(args.pretraining_flag, args.bert_binary_head) + if not args.model_return_dict: + self.model_output_class = None + else: + from transformers.modeling_outputs import SequenceClassifierOutput + + self.model_output_class = SequenceClassifierOutput + + def get_batch_func(self, accelerator, megatron_dataset_flag): + def get_batch_megatron(data_iterator): + """Build the batch.""" + + # Items and their type. + keys = ["text", "types", "labels", "is_random", "loss_mask", "padding_mask"] + datatype = torch.int64 + + # Broadcast data. + if data_iterator is not None: + data = next(data_iterator) + else: + data = None + data_b = tensor_parallel.broadcast_data(keys, data, datatype) + + # Unpack. + tokens = data_b["text"].long() + types = data_b["types"].long() + sentence_order = data_b["is_random"].long() + loss_mask = data_b["loss_mask"].float() + lm_labels = data_b["labels"].long() + padding_mask = data_b["padding_mask"].long() + + return tokens, types, sentence_order, loss_mask, lm_labels, padding_mask + + def get_batch_transformer(data_iterator): + """Build the batch.""" + data = next(data_iterator) + data = send_to_device(data, torch.cuda.current_device()) + + # Unpack. + tokens = data["input_ids"].long() + padding_mask = data["attention_mask"].long() + if "token_type_ids" in data: + types = data["token_type_ids"].long() + else: + types = None + if "labels" in data: + lm_labels = data["labels"].long() + loss_mask = (data["labels"] != -100).to(torch.float) + else: + lm_labels = None + loss_mask = None + if "next_sentence_label" in data: + sentence_order = data["next_sentence_label"].long() + else: + sentence_order = None + + return tokens, types, sentence_order, loss_mask, lm_labels, padding_mask + + if accelerator.state.megatron_lm_plugin.custom_get_batch_function is not None: + return accelerator.state.megatron_lm_plugin.custom_get_batch_function + if megatron_dataset_flag: + try: + # Use '--no-use-pep517 -e' to pip install nvidia's megatron from source + from pretrain_bert import get_batch + + return get_batch + except ImportError: + pass + return get_batch_megatron + else: + return get_batch_transformer + + def get_loss_func(self, accelerator, pretraining_flag, num_labels): + def loss_func_pretrain(loss_mask, sentence_order, output_tensor): + lm_loss_, sop_logits = output_tensor + + lm_loss_ = lm_loss_.float() + loss_mask = loss_mask.float() + lm_loss = torch.sum(lm_loss_.view(-1) * loss_mask.reshape(-1)) / loss_mask.sum() + + if sop_logits is not None: + sop_loss = F.cross_entropy(sop_logits.view(-1, 2).float(), sentence_order.view(-1), ignore_index=-1) + sop_loss = sop_loss.float() + loss = lm_loss + sop_loss + averaged_losses = average_losses_across_data_parallel_group([lm_loss, sop_loss]) + return loss, {"lm loss": averaged_losses[0], "sop loss": averaged_losses[1]} + + else: + loss = lm_loss + averaged_losses = average_losses_across_data_parallel_group([lm_loss]) + return loss, {"lm loss": averaged_losses[0]} + + def loss_func_finetune(labels, logits): + if num_labels == 1: + # We are doing regression + loss_fct = MSELoss() + loss = loss_fct(logits.view(-1), labels.view(-1)) + elif self.num_labels > 1 and (labels.dtype in (torch.long, torch.int)): + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, num_labels), labels.view(-1)) + else: + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + averaged_losses = average_losses_across_data_parallel_group([loss]) + return loss, {"loss": averaged_losses[0]} + + if accelerator.state.megatron_lm_plugin.custom_loss_function is not None: + return accelerator.state.megatron_lm_plugin.custom_loss_function + if pretraining_flag: + return loss_func_pretrain + else: + return loss_func_finetune + + def get_forward_step_func(self, pretraining_flag, bert_binary_head): + def forward_step(data_iterator, model): + """Forward step.""" + tokens, types, sentence_order, loss_mask, labels, padding_mask = self.get_batch(data_iterator) + if not bert_binary_head: + types = None + # Forward pass through the model. + if pretraining_flag: + output_tensor = model(tokens, padding_mask, tokentype_ids=types, lm_labels=labels) + return output_tensor, partial(self.loss_func, loss_mask, sentence_order) + else: + logits = model(tokens, padding_mask, tokentype_ids=types) + return logits, partial(self.loss_func, labels) + + return forward_step + + +class GPTTrainStep(AbstractTrainStep): + """ + GPT train step class. + + Args: + args (`argparse.Namespace`): Megatron-LM arguments. + """ + + def __init__(self, accelerator, args): + super().__init__("GPTTrainStep") + self.get_batch = self.get_batch_func(accelerator, args.megatron_dataset_flag) + self.loss_func = self.get_loss_func(accelerator) + self.forward_step = self.get_forward_step_func() + self.eod_token = args.padded_vocab_size - 1 + if args.vocab_file is not None: + tokenizer = get_tokenizer() + self.eod_token = tokenizer.eod + self.reset_position_ids = args.reset_position_ids + self.reset_attention_mask = args.reset_attention_mask + self.eod_mask_loss = args.eod_mask_loss + if not args.model_return_dict: + self.model_output_class = None + else: + from transformers.modeling_outputs import CausalLMOutputWithCrossAttentions + + self.model_output_class = CausalLMOutputWithCrossAttentions + + def get_batch_func(self, accelerator, megatron_dataset_flag): + def get_batch_megatron(data_iterator): + """Generate a batch""" + # Items and their type. + keys = ["text"] + datatype = torch.int64 + + # Broadcast data. + if data_iterator is not None: + data = next(data_iterator) + else: + data = None + data_b = tensor_parallel.broadcast_data(keys, data, datatype) + + # Unpack. + tokens_ = data_b["text"].long() + labels = tokens_[:, 1:].contiguous() + tokens = tokens_[:, :-1].contiguous() + + # Get the masks and position ids. + attention_mask, loss_mask, position_ids = get_ltor_masks_and_position_ids( + tokens, self.eod_token, self.reset_position_ids, self.reset_attention_mask, self.eod_mask_loss + ) + + return tokens, labels, loss_mask, attention_mask, position_ids + + def get_batch_transformer(data_iterator): + data = next(data_iterator) + data = {"input_ids": data["input_ids"]} + data = send_to_device(data, torch.cuda.current_device()) + + tokens_ = data["input_ids"].long() + padding = torch.zeros((tokens_.shape[0], 1), dtype=tokens_.dtype, device=tokens_.device) + self.eod_token + tokens_ = torch.concat([tokens_, padding], dim=1) + labels = tokens_[:, 1:].contiguous() + tokens = tokens_[:, :-1].contiguous() + # Get the masks and position ids. + attention_mask, loss_mask, position_ids = get_ltor_masks_and_position_ids( + tokens, self.eod_token, self.reset_position_ids, self.reset_attention_mask, True + ) + return tokens, labels, loss_mask, attention_mask, position_ids + + if accelerator.state.megatron_lm_plugin.custom_get_batch_function is not None: + return accelerator.state.megatron_lm_plugin.custom_get_batch_function + if megatron_dataset_flag: + try: + # Use '--no-use-pep517 -e' to pip install nvidia's megatron from source + from pretrain_gpt import get_batch + + return get_batch + except ImportError: + pass + return get_batch_megatron + else: + return get_batch_transformer + + def get_loss_func(self, accelerator): + args = get_args() + + def loss_func(loss_mask, output_tensor): + if args.return_logits: + losses, logits = output_tensor + else: + losses = output_tensor + losses = losses.float() + loss_mask = loss_mask.view(-1).float() + if args.context_parallel_size > 1: + loss = torch.cat([torch.sum(losses.view(-1) * loss_mask).view(1), loss_mask.sum().view(1)]) + torch.distributed.all_reduce(loss, group=mpu.get_context_parallel_group()) + loss = loss[0] / loss[1] + else: + loss = torch.sum(losses.view(-1) * loss_mask) / loss_mask.sum() + + # Check individual rank losses are not NaN prior to DP all-reduce. + if args.check_for_nan_in_loss_and_grad: + global_rank = torch.distributed.get_rank() + assert not loss.isnan(), ( + f"Rank {global_rank}: found NaN in local forward loss calculation. " + f"Device: {torch.cuda.current_device()}, node: {os.uname()[1]}" + ) + + # Reduce loss for logging. + averaged_loss = average_losses_across_data_parallel_group([loss]) + + output_dict = {"lm loss": averaged_loss[0]} + if args.return_logits: + output_dict.update({"logits": logits}) + return loss, output_dict + + if accelerator.state.megatron_lm_plugin.custom_loss_function is not None: + return accelerator.state.megatron_lm_plugin.custom_loss_function + return loss_func + + def get_forward_step_func(self): + def forward_step(data_iterator, model): + """Forward step.""" + # Get the batch. + tokens, labels, loss_mask, attention_mask, position_ids = self.get_batch(data_iterator) + output_tensor = model(tokens, position_ids, attention_mask, labels=labels) + + return output_tensor, partial(self.loss_func, loss_mask) + + return forward_step + + +class T5TrainStep(AbstractTrainStep): + """ + T5 train step class. + + Args: + args (`argparse.Namespace`): Megatron-LM arguments. + """ + + def __init__(self, accelerator, args): + super().__init__("T5TrainStep") + self.get_batch = self.get_batch_func(accelerator, args.megatron_dataset_flag) + self.loss_func = self.get_loss_func(accelerator) + self.forward_step = self.get_forward_step_func() + if not args.model_return_dict: + self.model_output_class = None + else: + from transformers.modeling_outputs import Seq2SeqLMOutput + + self.model_output_class = Seq2SeqLMOutput + + @staticmethod + def attn_mask_postprocess(attention_mask): + # We create a 3D attention mask from a 2D tensor mask. + # [b, 1, s] + attention_mask_b1s = attention_mask.unsqueeze(1) + # [b, s, 1] + attention_mask_bs1 = attention_mask.unsqueeze(2) + # [b, s, s] + attention_mask_bss = attention_mask_b1s * attention_mask_bs1 + # Convert attention mask to binary: + extended_attention_mask = attention_mask_bss < 0.5 + return extended_attention_mask + + @staticmethod + def get_decoder_mask(seq_length, device): + attention_mask = torch.tril(torch.ones((1, seq_length, seq_length), device=device)) + attention_mask = attention_mask < 0.5 + return attention_mask + + @staticmethod + def get_enc_dec_mask(attention_mask, dec_seq_length, device): + batch_size, _ = attention_mask.shape + # We create a 3D attention mask from a 2D tensor mask. + # [b, 1, s] + attention_mask_b1s = attention_mask.unsqueeze(1) + # [b, s, 1] + attention_mask_bs1 = torch.ones((batch_size, dec_seq_length, 1), device=device) + attention_mask_bss = attention_mask_bs1 * attention_mask_b1s + extended_attention_mask = attention_mask_bss < 0.5 + return extended_attention_mask + + def get_batch_func(self, accelerator, megatron_dataset_flag): + def get_batch_megatron(data_iterator): + """Build the batch.""" + + keys = ["text_enc", "text_dec", "labels", "loss_mask", "enc_mask", "dec_mask", "enc_dec_mask"] + datatype = torch.int64 + + # Broadcast data. + if data_iterator is not None: + data = next(data_iterator) + else: + data = None + data_b = tensor_parallel.broadcast_data(keys, data, datatype) + + # Unpack. + tokens_enc = data_b["text_enc"].long() + tokens_dec = data_b["text_dec"].long() + labels = data_b["labels"].long() + loss_mask = data_b["loss_mask"].float() + + enc_mask = data_b["enc_mask"] < 0.5 + dec_mask = data_b["dec_mask"] < 0.5 + enc_dec_mask = data_b["enc_dec_mask"] < 0.5 + + return tokens_enc, tokens_dec, loss_mask, labels, enc_mask, dec_mask, enc_dec_mask + + def get_batch_transformer(data_iterator): + """Build the batch.""" + data = next(data_iterator) + data = send_to_device(data, torch.cuda.current_device()) + + tokens_enc = data["input_ids"].long() + labels = data["labels"].long() + loss_mask = (labels != -100).to(torch.float) + if "decoder_input_ids" in data: + tokens_dec = data["decoder_input_ids"].long() + else: + tokens_dec = labels.new_zeros(labels.shape, device=labels.device, dtype=torch.long) + tokens_dec[..., 1:] = labels[..., :-1].clone() + tokens_dec[..., 0] = 0 + tokens_dec.masked_fill_(tokens_dec == -100, 0) + enc_mask = T5TrainStep.attn_mask_postprocess(data["attention_mask"].long()) + dec_mask = T5TrainStep.get_decoder_mask(tokens_dec.shape[1], tokens_dec.device) + enc_dec_mask = T5TrainStep.get_enc_dec_mask( + data["attention_mask"].long(), tokens_dec.shape[1], tokens_dec.device + ) + + return tokens_enc, tokens_dec, loss_mask, labels, enc_mask, dec_mask, enc_dec_mask + + if accelerator.state.megatron_lm_plugin.custom_get_batch_function is not None: + return accelerator.state.megatron_lm_plugin.custom_get_batch_function + if megatron_dataset_flag: + try: + # Use '--no-use-pep517 -e' to pip install nvidia's megatron from source + from pretrain_t5 import get_batch + + return get_batch + except ImportError: + pass + return get_batch_megatron + else: + return get_batch_transformer + + def get_loss_func(self, accelerator): + def loss_func(loss_mask, output_tensor): + lm_loss_ = output_tensor.float() + lm_loss = torch.sum(lm_loss_.view(-1) * loss_mask.reshape(-1)) / loss_mask.sum() + + loss = lm_loss + averaged_losses = average_losses_across_data_parallel_group([lm_loss]) + + return loss, {"lm loss": averaged_losses[0]} + + if accelerator.state.megatron_lm_plugin.custom_loss_function is not None: + return accelerator.state.megatron_lm_plugin.custom_loss_function + return loss_func + + def get_forward_step_func(self): + def forward_step(data_iterator, model): + """Forward step.""" + # Get the batch. + tokens_enc, tokens_dec, loss_mask, lm_labels, enc_mask, dec_mask, enc_dec_mask = self.get_batch( + data_iterator + ) + # Forward model lm_labels + output_tensor = model( + tokens_enc, tokens_dec, enc_mask, dec_mask, enc_dec_mask, tokentype_ids=None, lm_labels=lm_labels + ) + + return output_tensor, partial(self.loss_func, loss_mask) + + return forward_step + + +def finish_mpu_init(): + # torch.distributed initialization + args = get_args() + # Pytorch distributed. + _initialize_distributed() + + # Random seeds for reproducibility. + if args.rank == 0: + print(f"> setting random seeds to {args.seed} ...") + _set_random_seed(args.seed, args.data_parallel_random_init) + + +# initialize megatron setup +def initialize(accelerator, extra_args_provider=None, args_defaults={}): + accelerator.print("Initializing Megatron-LM") + assert torch.cuda.is_available(), "Megatron requires CUDA." + + # Parse arguments + args = parse_args(extra_args_provider, ignore_unknown_args=True) + + # Set defaults + for key, value in args_defaults.items(): + if getattr(args, key, None) is not None: + if args.rank == 0: + print( + f"WARNING: overriding default arguments for {key}:{getattr(args, key)} with {key}:{value}", + flush=True, + ) + setattr(args, key, value) + + if args.use_checkpoint_args or args_defaults.get("use_checkpoint_args", False): + assert args.load is not None, "--use-checkpoints-args requires --load argument" + load_args_from_checkpoint(args) + + validate_args(args) + + # set global args, build tokenizer, and set adlr-autoresume, + # tensorboard-writer, and timers. + set_global_variables(args) + + # Megatron's MPU is the master. Complete initialization right away. + finish_mpu_init() + + # Autoresume. + _init_autoresume() + + # Compile dependencies. + _compile_dependencies() + + # Set pytorch JIT layer fusion options and warmup JIT functions. + set_jit_fusion_options() + args = get_args() + if getattr(args, "padded_vocab_size", None) is None: + args.padded_vocab_size = _vocab_size_with_padding(args.orig_vocab_size, args) + if args.model_type_name == "bert" and args.pretraining_flag and args.num_labels == 2: + args.bert_binary_head = True + else: + args.bert_binary_head = False + args.iteration = 0 + + +class MegatronEngine(torch.nn.Module): + """ + Megatron-LM model wrapper + + Args: + accelerator (:class:`~accelerate.Accelerator`): The accelerator object to use. + model: Megatron-LM model + optimizer: Megatron-LM optimizer + lr_scheduler: Megatron-LM lr scheduler + """ + + def __init__(self, accelerator, model, optimizer, scheduler): + super().__init__() + self.module = model + self.base_model = model[0] + self.optimizer = optimizer + self.scheduler = scheduler + args = get_args() + if accelerator.state.megatron_lm_plugin.custom_train_step_class is not None: + self.train_step_handler = accelerator.state.megatron_lm_plugin.custom_train_step_class( + args, **accelerator.state.megatron_lm_plugin.custom_train_step_kwargs + ) + elif args.model_type_name == "bert": + self.train_step_handler = BertTrainStep(accelerator, args) + elif args.model_type_name == "gpt": + self.train_step_handler = GPTTrainStep(accelerator, args) + elif args.model_type_name == "t5": + self.train_step_handler = T5TrainStep(accelerator, args) + else: + raise ValueError(f"Unsupported model type: {args.model_type_name}") + self.optimizer.skipped_iter = False + + # Tracking loss. + self.total_loss_dict = {} + self.eval_total_loss_dict = {} + self.iteration = 0 + self.report_memory_flag = True + self.num_floating_point_operations_so_far = 0 + self.module_config = None + if args.tensorboard_dir is not None: + write_args_to_tensorboard() + + def get_module_config(self): + args = get_args() + config = get_model_config(self.module[0]) + # Setup some training config params + config.grad_scale_func = self.optimizer.scale_loss + if isinstance(self.module[0], LocalDDP) and args.overlap_grad_reduce: + assert config.no_sync_func is None, ( + "When overlap_grad_reduce is True, config.no_sync_func must be None; " + "a custom no_sync_func is not supported when overlapping grad-reduce" + ) + config.no_sync_func = [model_chunk.no_sync for model_chunk in self.module] + if len(self.module) == 1: + config.no_sync_func = config.no_sync_func[0] + if args.delay_grad_reduce: + config.grad_sync_func = [model_chunk.start_grad_sync for model_chunk in self.module] + if len(self.module) == 1: + config.grad_sync_func = config.grad_sync_func[0] + if args.overlap_param_gather and args.delay_param_gather: + config.param_sync_func = [ + lambda x: self.optimizer.finish_param_sync(model_index, x) for model_index in range(len(self.module)) + ] + if len(self.module) == 1: + config.param_sync_func = config.param_sync_func[0] + config.finalize_model_grads_func = finalize_model_grads + return config + + def train(self): + for model_module in self.module: + model_module.train() + + if self.module_config is None: + self.module_config = self.get_module_config() + + self.log_eval_results() + + def eval(self): + for model_module in self.module: + model_module.eval() + + if self.module_config is None: + self.module_config = self.get_module_config() + + def get_batch_data_iterator(self, batch_data): + args = get_args() + data_chunks = [] + if len(batch_data) > 0: + if args.num_micro_batches > 1: + for i in range(0, args.num_micro_batches): + data_chunks.append( + { + k: v[i * args.micro_batch_size : (i + 1) * args.micro_batch_size] + for k, v in batch_data.items() + } + ) + else: + data_chunks = [batch_data] + + if len(self.module) > 1: + batch_data_iterator = ( + [iter(data_chunks) for _ in range(len(self.module))] + if len(batch_data) > 0 + else [None] * len(self.module) + ) + else: + batch_data_iterator = iter(data_chunks) if len(batch_data) > 0 else None + return batch_data_iterator + + def train_step(self, **batch_data): + """ + Training step for Megatron-LM + + Args: + batch_data (:obj:`dict`): The batch data to train on. + """ + + batch_data_iterator = self.get_batch_data_iterator(batch_data) + + loss_reduced, skipped_iter, grad_norm, num_zeros_in_grad = train_step( + forward_step_func=self.train_step_handler.forward_step, + data_iterator=batch_data_iterator, + model=self.module, + optimizer=self.optimizer, + opt_param_scheduler=self.scheduler, + config=self.module_config, + ) + + self.optimizer.skipped_iter = skipped_iter == 1 + + return loss_reduced, skipped_iter, grad_norm, num_zeros_in_grad + + def eval_step(self, **batch_data): + """ + Evaluation step for Megatron-LM + + Args: + batch_data (:obj:`dict`): The batch data to evaluate on. + """ + + args = get_args() + batch_data_iterator = self.get_batch_data_iterator(batch_data) + forward_backward_func = get_forward_backward_func() + loss_dicts = forward_backward_func( + forward_step_func=self.train_step_handler.forward_step, + data_iterator=batch_data_iterator, + model=self.module, + num_microbatches=get_num_microbatches(), + seq_length=args.seq_length, + micro_batch_size=args.micro_batch_size, + forward_only=True, + ) + # Empty unused memory + if args.empty_unused_memory_level >= 1: + torch.cuda.empty_cache() + + args.consumed_valid_samples += ( + mpu.get_data_parallel_world_size() * args.micro_batch_size * get_num_microbatches() + ) + + if mpu.is_pipeline_last_stage(ignore_virtual=True): + # Average loss across microbatches. + loss_reduced = {} + for key in loss_dicts[0]: + losses_reduced_for_key = [x[key] for x in loss_dicts] + if len(losses_reduced_for_key[0].shape) == 0: + loss_reduced[key] = sum(losses_reduced_for_key) / len(losses_reduced_for_key) + else: + loss_reduced[key] = torch.concat(losses_reduced_for_key) + return loss_reduced + return {} + + def forward(self, **batch_data): + # During training, we use train_step() + # model(**batch_data) performs following operations by delegating it to `self.train_step`: + # 1. Prepare **batch_data for Tendor, Pipeline and Model Parallelism + # 2. Set grad to zero. + # 3. forward pass and backward pass using Pipeline Parallelism + # 4. Empty unused memory. + # 5. Reduce gradients. + # 6. Update parameters. + # 7. Gather params when using Distributed Optimizer (Data Parallelism). + # 8. Update learning rate if scheduler is specified. + # 9. Empty unused memory. + # 10. Average loss across microbatches and across DP ranks. + # + # During evaluation, we use eval_step() + args = get_args() + if self.module[0].training: + loss_dict, skipped_iter, grad_norm, num_zeros_in_grad = self.train_step(**batch_data) + self.iteration += 1 + batch_size = mpu.get_data_parallel_world_size() * args.micro_batch_size * get_num_microbatches() + args.consumed_train_samples += batch_size + self.num_floating_point_operations_so_far += num_floating_point_operations(args, batch_size) + if args.tensorboard_dir is not None: + # Logging. + loss_scale = self.optimizer.get_loss_scale().item() + params_norm = None + if args.log_params_norm: + params_norm = calc_params_l2_norm(self.model) + self.report_memory_flag = training_log( + loss_dict, + self.total_loss_dict, + self.optimizer.param_groups[0]["lr"], + self.iteration, + loss_scale, + self.report_memory_flag, + skipped_iter, + grad_norm, + params_norm, + num_zeros_in_grad, + ) + else: + loss_dict = self.eval_step(**batch_data) + if args.tensorboard_dir is not None: + for key in loss_dict: + self.eval_total_loss_dict[key] = ( + self.eval_total_loss_dict.get(key, torch.cuda.FloatTensor([0.0])) + loss_dict[key] + ) + self.eval_total_loss_dict[key + "_num_iters"] = self.eval_total_loss_dict.get( + key + "_num_iters", torch.cuda.FloatTensor([0.0]) + ) + torch.cuda.FloatTensor([1.0]) + + loss = torch.tensor(0.0, device=torch.cuda.current_device()) + for key in loss_dict: + if len(loss_dict[key].shape) == 0: + loss += loss_dict[key] + + logits = None + if "logits" in loss_dict: + logits = loss_dict["logits"] + if self.train_step_handler.model_output_class is not None: + return self.train_step_handler.model_output_class(loss=loss, logits=logits) + return loss + + def log_eval_results(self): + args = get_args() + if args.tensorboard_dir is None or self.iteration == 0: + return + args = get_args() + writer = get_tensorboard_writer() + string = f"validation loss at iteration {self.iteration} | " + for key in self.eval_total_loss_dict: + if key.endswith("_num_iters"): + continue + value = self.eval_total_loss_dict[key] / self.eval_total_loss_dict[key + "_num_iters"] + string += f"{key} value: {value} | " + ppl = math.exp(min(20, value.item())) + if args.pretraining_flag: + string += f"{key} PPL: {ppl} | " + if writer: + writer.add_scalar(f"{key} validation", value.item(), self.iteration) + if args.pretraining_flag: + writer.add_scalar(f"{key} validation ppl", ppl, self.iteration) + + length = len(string) + 1 + print_rank_last("-" * length) + print_rank_last(string) + print_rank_last("-" * length) + self.eval_total_loss_dict = {} + + def save_checkpoint(self, output_dir): + self.log_eval_results() + args = get_args() + args.save = output_dir + torch.distributed.barrier() + save_checkpoint( + self.iteration, + self.module, + self.optimizer, + self.scheduler, + num_floating_point_operations_so_far=self.num_floating_point_operations_so_far, + ) + torch.distributed.barrier() + + def load_checkpoint(self, input_dir): + args = get_args() + args.load = input_dir + args.consumed_train_samples = 0 + args.consumed_valid_samples = 0 + torch.distributed.barrier() + iteration, num_floating_point_operations_so_far = load_checkpoint(self.module, self.optimizer, self.scheduler) + torch.distributed.barrier() + self.iteration = iteration + self.num_floating_point_operations_so_far = num_floating_point_operations_so_far + if args.fp16 and self.iteration == 0: + self.optimizer.reload_model_params() + + def megatron_generate( + self, + inputs, + attention_mask=None, + max_length=None, + max_new_tokens=None, + num_beams=None, + temperature=None, + top_k=None, + top_p=None, + length_penalty=None, + **kwargs, + ): + """ + Generate method for GPT2 model. This method is used for inference. Supports both greedy and beam search along + with sampling. Refer the Megatron-LM repo for more details + + Args: + inputs (torch.Tensor): input ids + attention_mask (torch.Tensor, optional): attention mask. Defaults to None. + max_length (int, optional): max length of the generated sequence. Defaults to None. + Either this or max_new_tokens should be provided. + max_new_tokens (int, optional): max number of tokens to be generated. Defaults to None. + Either this or max_length should be provided. + num_beams (int, optional): number of beams to use for beam search. Defaults to None. + temperature (float, optional): temperature for sampling. Defaults to 1.0. + top_k (int, optional): top k tokens to consider for sampling. Defaults to 0.0. + top_p (float, optional): tokens in top p probability are considered for sampling. Defaults to 0.0. + length_penalty (float, optional): length penalty for beam search. Defaults to None. + kwargs: additional key-value arguments + """ + + # checking if required arguments are passed + args = get_args() + if args.model_type_name != "gpt": + raise NotImplementedError("Generate method is not implemented for this model") + + if args.data_parallel_size > 1: + raise ValueError("Generate method requires data parallelism to be 1") + + if args.sequence_parallel: + raise ValueError("Generate method requires sequence parallelism to be False") + + if args.recompute_granularity is not None: + raise ValueError("Checkpoint activations cannot be set for inference") + + if args.vocab_file is None: + raise ValueError("Vocab file is required for inference") + + # Prepare inputs + if max_length is None and max_new_tokens is None: + raise ValueError("`max_length` or `max_new_tokens` are required for inference") + + if temperature is None: + temperature = 1.0 + elif not (0.0 < temperature <= 100.0): + raise ValueError("temperature must be a positive number less than or equal to 100.0") + + if top_k is None: + top_k = 0 + elif not (0 <= top_k <= 1000): + raise ValueError("top_k must be a positive number less than or equal to 1000") + + if top_p is None: + top_p = 0.0 + elif top_p > 0.0 and top_k > 0.0: + raise ValueError("top_p and top_k sampling cannot be set together") + else: + if not (0.0 <= top_p <= 1.0): + raise ValueError("top_p must be less than or equal to 1.0") + + top_p_decay = kwargs.get("top_p_decay", 0.0) + if not (0.0 <= top_p_decay <= 1.0): + raise ValueError("top_p_decay must be less than or equal to 1.0") + + top_p_bound = kwargs.get("top_p_bound", 0.0) + if not (0.0 <= top_p_bound <= 1.0): + raise ValueError("top_p_bound must be less than or equal to 1.0") + + add_BOS = kwargs.get("add_BOS", False) + if not (isinstance(add_BOS, bool)): + raise ValueError("add_BOS must be a boolean") + + beam_width = num_beams + if beam_width is not None: + if not isinstance(beam_width, int): + raise ValueError("beam_width must be an integer") + if beam_width < 1: + raise ValueError("beam_width must be greater than 0") + if inputs.shape[0] > 1: + return "When doing beam_search, batch size must be 1" + + tokenizer = get_tokenizer() + + stop_token = kwargs.get("stop_token", tokenizer.eod) + if stop_token is not None: + if not isinstance(stop_token, int): + raise ValueError("stop_token must be an integer") + + if length_penalty is None: + length_penalty = 1.0 + + sizes_list = None + prompts_tokens_tensor = None + prompts_length_tensor = None + if torch.distributed.get_rank() == 0: + # Get the prompts length. + if attention_mask is None: + prompts_length_tensor = torch.cuda.LongTensor([inputs.shape[1]] * inputs.shape[0]) + else: + prompts_length_tensor = attention_mask.sum(axis=-1).cuda() + + if max_new_tokens is None: + max_new_tokens = max_length - inputs.shape[1] + if max_new_tokens <= 0: + raise ValueError("max_new_tokens must be greater than 0") + + if add_BOS: + max_length = max_new_tokens + inputs.shape[1] + 1 + # making sure that `max_length` is a multiple of 4 to leverage fused kernels + max_length = 4 * math.ceil(max_length / 4) + max_new_tokens = max_length - (inputs.shape[1] + 1) + padding = torch.cuda.LongTensor([[tokenizer.eod] * max_new_tokens] * inputs.shape[0]) + prompts_tokens_tensor = torch.concat( + [torch.unsqueeze(padding[:, 0], axis=-1), inputs.cuda(), padding], axis=-1 + ) + else: + # making sure that `max_length` is a multiple of 4 to leverage fused kernels + max_length = max_new_tokens + inputs.shape[1] + max_length = 4 * math.ceil(max_length / 4) + max_new_tokens = max_length - inputs.shape[1] + padding = torch.cuda.LongTensor([[tokenizer.eod] * max_new_tokens] * inputs.shape[0]) + prompts_tokens_tensor = torch.concat([inputs.cuda(), padding], axis=-1) + + # We need the sizes of these tensors for the broadcast + sizes_list = [ + prompts_tokens_tensor.size(0), # Batch size + prompts_tokens_tensor.size(1), + ] # Sequence length + + # First, broadcast the sizes. + sizes_tensor = broadcast_int_list(2, int_list=sizes_list, rank=0) + + # Now that we have the sizes, we can broadcast the tokens + # and length tensors. + sizes = sizes_tensor.tolist() + context_tokens_tensor = broadcast_tensor(sizes, torch.int64, tensor=prompts_tokens_tensor, rank=0) + context_length_tensor = broadcast_tensor(sizes[0], torch.int64, tensor=prompts_length_tensor, rank=0) + + # Run the inference + random_seed = kwargs.get("random_seed", 0) + torch.random.manual_seed(random_seed) + unwrapped_model = unwrap_model(self.base_model, (torchDDP, LocalDDP, Float16Module)) + if beam_width is not None: + tokens, _ = beam_search_and_return_on_first_stage( + unwrapped_model, + context_tokens_tensor, + context_length_tensor, + beam_width, + stop_token=stop_token, + num_return_gen=1, + length_penalty=length_penalty, + ) + else: + tokens, _, _ = generate_tokens_probs_and_return_on_first_stage( + unwrapped_model, + context_tokens_tensor, + context_length_tensor, + return_output_log_probs=False, + top_k=top_k, + top_p=top_p, + top_p_decay=top_p_decay, + top_p_bound=top_p_bound, + temperature=temperature, + use_eod_token_for_early_termination=True, + ) + return tokens + + +# other utilities +def avg_losses_across_data_parallel_group(losses): + """ + Average losses across data parallel group. + + Args: + losses (List[Tensor]): List of losses to average across data parallel group. + """ + + return average_losses_across_data_parallel_group(losses) + + +def gather_across_data_parallel_groups(tensor): + """ + Recursively gather tensor in a nested list/tuple/dictionary of tensors from data parallel ranks. + + Args: + tensor (nested list/tuple/dictionary of `torch.Tensor`): + The data to gather across data parallel ranks. + + """ + + def _gpu_gather_one(tensor): + if tensor.ndim == 0: + tensor = tensor.clone()[None] + output_tensors = [ + torch.empty_like(tensor) + for _ in range(torch.distributed.get_world_size(group=mpu.get_data_parallel_group())) + ] + torch.distributed.all_gather(output_tensors, tensor, group=mpu.get_data_parallel_group()) + return torch.cat(output_tensors, dim=0) + + return recursively_apply(_gpu_gather_one, tensor, error_on_other_type=True) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/memory.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/memory.py new file mode 100644 index 0000000000000000000000000000000000000000..51b71107e5b1c7209e17948cde889f7d82f56b41 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/memory.py @@ -0,0 +1,210 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +A collection of utilities for ensuring that training can always occur. Heavily influenced by the +[toma](https://github.com/BlackHC/toma) library. +""" + +import functools +import gc +import importlib +import inspect +import warnings +from typing import Optional + +import torch +from packaging import version + +from .imports import ( + is_cuda_available, + is_hpu_available, + is_ipex_available, + is_mlu_available, + is_mps_available, + is_musa_available, + is_npu_available, + is_sdaa_available, + is_xpu_available, +) +from .versions import compare_versions + + +def clear_device_cache(garbage_collection=False): + """ + Clears the device cache by calling `torch.{backend}.empty_cache`. Can also run `gc.collect()`, but do note that + this is a *considerable* slowdown and should be used sparingly. + """ + if garbage_collection: + gc.collect() + + if is_xpu_available(): + torch.xpu.empty_cache() + elif is_mlu_available(): + torch.mlu.empty_cache() + elif is_sdaa_available(): + torch.sdaa.empty_cache() + elif is_musa_available(): + torch.musa.empty_cache() + elif is_npu_available(): + torch.npu.empty_cache() + elif is_mps_available(min_version="2.0"): + torch.mps.empty_cache() + elif is_cuda_available(): + torch.cuda.empty_cache() + elif is_hpu_available(): + # torch.hpu.empty_cache() # not available on hpu as it reserves all device memory for the current process + pass + + +def release_memory(*objects): + """ + Releases memory from `objects` by setting them to `None` and calls `gc.collect()` and `torch.cuda.empty_cache()`. + Returned objects should be reassigned to the same variables. + + Args: + objects (`Iterable`): + An iterable of objects + Returns: + A list of `None` objects to replace `objects` + + Example: + + ```python + >>> import torch + >>> from accelerate.utils import release_memory + + >>> a = torch.ones(1000, 1000).cuda() + >>> b = torch.ones(1000, 1000).cuda() + >>> a, b = release_memory(a, b) + ``` + """ + if not isinstance(objects, list): + objects = list(objects) + for i in range(len(objects)): + objects[i] = None + clear_device_cache(garbage_collection=True) + return objects + + +def should_reduce_batch_size(exception: Exception) -> bool: + """ + Checks if `exception` relates to CUDA out-of-memory, XPU out-of-memory, CUDNN not supported, or CPU out-of-memory + + Args: + exception (`Exception`): + An exception + """ + _statements = [ + " out of memory.", # OOM for CUDA, HIP, XPU + "cuDNN error: CUDNN_STATUS_NOT_SUPPORTED.", # CUDNN SNAFU + "DefaultCPUAllocator: can't allocate memory", # CPU OOM + "FATAL ERROR :: MODULE:PT_DEVMEM Allocation failed", # HPU OOM + ] + if isinstance(exception, RuntimeError) and len(exception.args) == 1: + return any(err in exception.args[0] for err in _statements) + return False + + +def find_executable_batch_size( + function: Optional[callable] = None, + starting_batch_size: int = 128, + reduce_batch_size_fn: Optional[callable] = None, +): + """ + A basic decorator that will try to execute `function`. If it fails from exceptions related to out-of-memory or + CUDNN, the batch size is multiplied by 0.9 and passed to `function` + + `function` must take in a `batch_size` parameter as its first argument. + + Args: + function (`callable`, *optional*): + A function to wrap + starting_batch_size (`int`, *optional*): + The batch size to try and fit into memory + + Example: + + ```python + >>> from accelerate.utils import find_executable_batch_size + + + >>> @find_executable_batch_size(starting_batch_size=128) + ... def train(batch_size, model, optimizer): + ... ... + + + >>> train(model, optimizer) + ``` + """ + if function is None: + return functools.partial(find_executable_batch_size, starting_batch_size=starting_batch_size) + + batch_size = starting_batch_size + if reduce_batch_size_fn is None: + + def reduce_batch_size_fn(): + nonlocal batch_size + batch_size = int(batch_size * 0.9) + return batch_size + + def decorator(*args, **kwargs): + nonlocal batch_size + clear_device_cache(garbage_collection=True) + params = list(inspect.signature(function).parameters.keys()) + # Guard against user error + if len(params) < (len(args) + 1): + arg_str = ", ".join([f"{arg}={value}" for arg, value in zip(params[1:], args[1:])]) + raise TypeError( + f"Batch size was passed into `{function.__name__}` as the first argument when called." + f"Remove this as the decorator already does so: `{function.__name__}({arg_str})`" + ) + while True: + if batch_size == 0: + raise RuntimeError("No executable batch size found, reached zero.") + try: + return function(batch_size, *args, **kwargs) + except Exception as e: + if should_reduce_batch_size(e): + clear_device_cache(garbage_collection=True) + batch_size = reduce_batch_size_fn() + else: + raise + + return decorator + + +def get_xpu_available_memory(device_index: int): + if version.parse(torch.__version__).release >= version.parse("2.6").release: + # torch.xpu.mem_get_info API is available starting from PyTorch 2.6 + # It further requires PyTorch built with the SYCL runtime which supports API + # to query available device memory. If not available, exception will be + # raised. Version of SYCL runtime used to build PyTorch is being reported + # with print(torch.version.xpu) and corresponds to the version of Intel DPC++ + # SYCL compiler. First version to support required feature is 20250001. + try: + return torch.xpu.mem_get_info(device_index)[0] + except Exception: + pass + elif is_ipex_available(): + ipex_version = version.parse(importlib.metadata.version("intel_extension_for_pytorch")) + if compare_versions(ipex_version, ">=", "2.5"): + from intel_extension_for_pytorch.xpu import mem_get_info + + return mem_get_info(device_index)[0] + + warnings.warn( + "The XPU `mem_get_info` API is available in IPEX version >=2.5 or PyTorch >=2.6. The current returned available memory is incorrect. Please consider upgrading your IPEX or PyTorch version." + ) + return torch.xpu.max_memory_allocated(device_index) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/modeling.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/modeling.py new file mode 100644 index 0000000000000000000000000000000000000000..830249ffb1041b6cb29b6e7bdda1d7e47f28bc99 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/modeling.py @@ -0,0 +1,2186 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import contextlib +import gc +import inspect +import json +import logging +import os +import re +import shutil +import tempfile +import warnings +from collections import OrderedDict, defaultdict +from typing import Optional, Union + +import torch +from torch import distributed as dist +from torch import nn + +from ..state import AcceleratorState +from .constants import SAFE_WEIGHTS_NAME, WEIGHTS_NAME +from .dataclasses import AutocastKwargs, CustomDtype, DistributedType +from .imports import ( + is_hpu_available, + is_mlu_available, + is_mps_available, + is_musa_available, + is_npu_available, + is_peft_available, + is_sdaa_available, + is_torch_xla_available, + is_xpu_available, +) +from .memory import clear_device_cache, get_xpu_available_memory +from .offload import load_offloaded_weight, offload_weight, save_offload_index +from .tqdm import is_tqdm_available, tqdm +from .versions import is_torch_version + + +if is_npu_available(check_device=False): + import torch_npu # noqa: F401 + +if is_mlu_available(check_device=False): + import torch_mlu # noqa: F401 + +if is_sdaa_available(check_device=False): + import torch_sdaa # noqa: F401 + +if is_musa_available(check_device=False): + import torch_musa # noqa: F401 + +from safetensors import safe_open +from safetensors.torch import load_file as safe_load_file + + +WEIGHTS_INDEX_NAME = "pytorch_model.bin.index.json" + +logger = logging.getLogger(__name__) + + +def is_peft_model(model): + from .other import extract_model_from_parallel + + if is_peft_available(): + from peft import PeftModel + + return is_peft_available() and isinstance(extract_model_from_parallel(model), PeftModel) + + +def check_device_same(first_device, second_device): + """ + Utility method to check if two `torch` devices are similar. When dealing with CUDA devices, torch throws `False` + for `torch.device("cuda") == torch.device("cuda:0")` whereas they should be the same + + Args: + first_device (`torch.device`): + First device to check + second_device (`torch.device`): + Second device to check + """ + if first_device.type != second_device.type: + return False + + if first_device.type != "cpu" and first_device.index is None: + # In case the first_device is a cuda device and have + # the index attribute set to `None`, default it to `0` + first_device = torch.device(first_device.type, index=0) + + if second_device.type != "cpu" and second_device.index is None: + # In case the second_device is a cuda device and have + # the index attribute set to `None`, default it to `0` + second_device = torch.device(second_device.type, index=0) + + return first_device == second_device + + +def convert_file_size_to_int(size: Union[int, str]): + """ + Converts a size expressed as a string with digits an unit (like `"5MB"`) to an integer (in bytes). + + Args: + size (`int` or `str`): The size to convert. Will be directly returned if an `int`. + + Example: + + ```py + >>> convert_file_size_to_int("1MiB") + 1048576 + ``` + """ + mem_size = -1 + err_msg = ( + f"`size` {size} is not in a valid format. Use an integer for bytes, or a string with an unit (like '5.0GB')." + ) + try: + if isinstance(size, int): + mem_size = size + elif size.upper().endswith("GIB"): + mem_size = int(float(size[:-3]) * (2**30)) + elif size.upper().endswith("MIB"): + mem_size = int(float(size[:-3]) * (2**20)) + elif size.upper().endswith("KIB"): + mem_size = int(float(size[:-3]) * (2**10)) + elif size.upper().endswith("GB"): + int_size = int(float(size[:-2]) * (10**9)) + mem_size = int_size // 8 if size.endswith("b") else int_size + elif size.upper().endswith("MB"): + int_size = int(float(size[:-2]) * (10**6)) + mem_size = int_size // 8 if size.endswith("b") else int_size + elif size.upper().endswith("KB"): + int_size = int(float(size[:-2]) * (10**3)) + mem_size = int_size // 8 if size.endswith("b") else int_size + except ValueError: + raise ValueError(err_msg) + + if mem_size < 0: + raise ValueError(err_msg) + return mem_size + + +def dtype_byte_size(dtype: torch.dtype): + """ + Returns the size (in bytes) occupied by one parameter of type `dtype`. + + Example: + + ```py + >>> dtype_byte_size(torch.float32) + 4 + ``` + """ + if dtype == torch.bool: + return 1 / 8 + elif dtype == CustomDtype.INT2: + return 1 / 4 + elif dtype == CustomDtype.INT4: + return 1 / 2 + elif dtype == CustomDtype.FP8: + return 1 + elif is_torch_version(">=", "2.1.0") and dtype in [torch.float8_e4m3fn, torch.float8_e5m2]: + return 1 + bit_search = re.search(r"[^\d](\d+)$", str(dtype)) + if bit_search is None: + raise ValueError(f"`dtype` is not a valid dtype: {dtype}.") + bit_size = int(bit_search.groups()[0]) + return bit_size // 8 + + +def id_tensor_storage(tensor: torch.Tensor) -> tuple[torch.device, int, int]: + """ + Unique identifier to a tensor storage. Multiple different tensors can share the same underlying storage. For + example, "meta" tensors all share the same storage, and thus their identifier will all be equal. This identifier is + guaranteed to be unique and constant for this tensor's storage during its lifetime. Two tensor storages with + non-overlapping lifetimes may have the same id. + """ + _SIZE = { + torch.int64: 8, + torch.float32: 4, + torch.int32: 4, + torch.bfloat16: 2, + torch.float16: 2, + torch.int16: 2, + torch.uint8: 1, + torch.int8: 1, + torch.bool: 1, + torch.float64: 8, + } + try: + storage_ptr = tensor.untyped_storage().data_ptr() + storage_size = tensor.untyped_storage().nbytes() + except Exception: + try: + # Fallback for torch==1.10 + storage_ptr = tensor.storage().data_ptr() + storage_size = tensor.storage().size() * _SIZE[tensor.dtype] + except NotImplementedError: + # Fallback for meta storage + storage_ptr = 0 + # On torch >=2.0 this is the tensor size + storage_size = tensor.nelement() * _SIZE[tensor.dtype] + + return tensor.device, storage_ptr, storage_size + + +def set_module_tensor_to_device( + module: nn.Module, + tensor_name: str, + device: Union[int, str, torch.device], + value: Optional[torch.Tensor] = None, + dtype: Optional[Union[str, torch.dtype]] = None, + fp16_statistics: Optional[torch.HalfTensor] = None, + tied_params_map: Optional[dict[int, dict[torch.device, torch.Tensor]]] = None, + non_blocking: bool = False, + clear_cache: bool = True, +): + """ + A helper function to set a given tensor (parameter of buffer) of a module on a specific device (note that doing + `param.to(device)` creates a new tensor not linked to the parameter, which is why we need this function). + + Args: + module (`torch.nn.Module`): + The module in which the tensor we want to move lives. + tensor_name (`str`): + The full name of the parameter/buffer. + device (`int`, `str` or `torch.device`): + The device on which to set the tensor. + value (`torch.Tensor`, *optional*): + The value of the tensor (useful when going from the meta device to any other device). + dtype (`torch.dtype`, *optional*): + If passed along the value of the parameter will be cast to this `dtype`. Otherwise, `value` will be cast to + the dtype of the existing parameter in the model. + fp16_statistics (`torch.HalfTensor`, *optional*): + The list of fp16 statistics to set on the module, used for 8 bit model serialization. + tied_params_map (Dict[int, Dict[torch.device, torch.Tensor]], *optional*, defaults to `None`): + A map of current data pointers to dictionaries of devices to already dispatched tied weights. For a given + execution device, this parameter is useful to reuse the first available pointer of a shared weight on the + device for all others, instead of duplicating memory. + non_blocking (`bool`, *optional*, defaults to `False`): + If `True`, the device transfer will be asynchronous with respect to the host, if possible. + clear_cache (`bool`, *optional*, defaults to `True`): + Whether or not to clear the device cache after setting the tensor on the device. + """ + # Recurse if needed + if "." in tensor_name: + splits = tensor_name.split(".") + for split in splits[:-1]: + new_module = getattr(module, split) + if new_module is None: + raise ValueError(f"{module} has no attribute {split}.") + module = new_module + tensor_name = splits[-1] + + if tensor_name not in module._parameters and tensor_name not in module._buffers: + raise ValueError(f"{module} does not have a parameter or a buffer named {tensor_name}.") + is_buffer = tensor_name in module._buffers + old_value = getattr(module, tensor_name) + + # Treat the case where old_value (or a custom `value`, typically offloaded to RAM/disk) belongs to a tied group, and one of the weight + # in the tied group has already been dispatched to the device, by avoiding reallocating memory on the device and just copying the pointer. + if ( + value is not None + and tied_params_map is not None + and value.data_ptr() in tied_params_map + and device in tied_params_map[value.data_ptr()] + ): + module._parameters[tensor_name] = tied_params_map[value.data_ptr()][device] + return + elif ( + tied_params_map is not None + and old_value.data_ptr() in tied_params_map + and device in tied_params_map[old_value.data_ptr()] + ): + module._parameters[tensor_name] = tied_params_map[old_value.data_ptr()][device] + return + + if old_value.device == torch.device("meta") and device not in ["meta", torch.device("meta")] and value is None: + raise ValueError(f"{tensor_name} is on the meta device, we need a `value` to put in on {device}.") + + param = module._parameters[tensor_name] if tensor_name in module._parameters else None + param_cls = type(param) + + if value is not None: + # We can expect mismatches when using bnb 4bit since Params4bit will reshape and pack the weights. + # In other cases, we want to make sure we're not loading checkpoints that do not match the config. + if old_value.shape != value.shape and param_cls.__name__ != "Params4bit": + raise ValueError( + f'Trying to set a tensor of shape {value.shape} in "{tensor_name}" (which has shape {old_value.shape}), this looks incorrect.' + ) + + if dtype is None: + # For compatibility with PyTorch load_state_dict which converts state dict dtype to existing dtype in model + value = value.to(old_value.dtype, non_blocking=non_blocking) + elif not str(value.dtype).startswith(("torch.uint", "torch.int", "torch.bool")): + value = value.to(dtype, non_blocking=non_blocking) + + device_quantization = None + with torch.no_grad(): + # leave it on cpu first before moving them to cuda + # # fix the case where the device is meta, we don't want to put it on cpu because there is no data =0 + if ( + param is not None + and param.device.type not in ("cuda", "xpu") + and torch.device(device).type in ("cuda", "xpu") + and param_cls.__name__ in ["Int8Params", "FP4Params", "Params4bit"] + ): + device_quantization = device + device = "cpu" + # `torch.Tensor.to()` is not supported by `torch_npu` (see this [issue](https://github.com/Ascend/pytorch/issues/16)). + if isinstance(device, int): + if is_npu_available(): + device = f"npu:{device}" + elif is_mlu_available(): + device = f"mlu:{device}" + elif is_sdaa_available(): + device = f"sdaa:{device}" + elif is_musa_available(): + device = f"musa:{device}" + elif is_hpu_available(): + device = "hpu" + if "xpu" in str(device) and not is_xpu_available(): + raise ValueError(f'{device} is not available, you should use device="cpu" instead') + if value is None: + new_value = old_value.to(device, non_blocking=non_blocking) + if dtype is not None and device in ["meta", torch.device("meta")]: + if not str(old_value.dtype).startswith(("torch.uint", "torch.int", "torch.bool")): + new_value = new_value.to(dtype, non_blocking=non_blocking) + + if not is_buffer: + module._parameters[tensor_name] = param_cls(new_value, requires_grad=old_value.requires_grad) + elif isinstance(value, torch.Tensor): + new_value = value.to(device, non_blocking=non_blocking) + else: + new_value = torch.tensor(value, device=device) + if device_quantization is not None: + device = device_quantization + if is_buffer: + module._buffers[tensor_name] = new_value + elif value is not None or not check_device_same(torch.device(device), module._parameters[tensor_name].device): + param_cls = type(module._parameters[tensor_name]) + kwargs = module._parameters[tensor_name].__dict__ + if param_cls.__name__ in ["Int8Params", "FP4Params", "Params4bit"]: + if param_cls.__name__ == "Int8Params" and new_value.dtype == torch.float32: + # downcast to fp16 if any - needed for 8bit serialization + new_value = new_value.to(torch.float16, non_blocking=non_blocking) + # quantize module that are going to stay on the cpu so that we offload quantized weights + if device == "cpu" and param_cls.__name__ == "Int8Params": + new_value = param_cls(new_value, requires_grad=old_value.requires_grad, **kwargs).to(0).to("cpu") + new_value.CB = new_value.CB.to("cpu") + new_value.SCB = new_value.SCB.to("cpu") + else: + new_value = param_cls(new_value, requires_grad=old_value.requires_grad, **kwargs).to( + device, non_blocking=non_blocking + ) + elif param_cls.__name__ in ["QTensor", "QBitsTensor"]: + new_value = torch.nn.Parameter(new_value, requires_grad=old_value.requires_grad).to( + device, non_blocking=non_blocking + ) + elif param_cls.__name__ in ["AffineQuantizedTensor"]: + new_value = new_value.to(device, non_blocking=non_blocking) + else: + new_value = param_cls(new_value, requires_grad=old_value.requires_grad).to( + device, non_blocking=non_blocking + ) + + module._parameters[tensor_name] = new_value + if fp16_statistics is not None: + module._parameters[tensor_name].SCB = fp16_statistics.to(device, non_blocking=non_blocking) + del fp16_statistics + # as we put the weight to meta, it doesn't have SCB attr anymore. make sure that it is not a meta weight + if ( + module.__class__.__name__ == "Linear8bitLt" + and getattr(module.weight, "SCB", None) is None + and str(module.weight.device) != "meta" + ): + # quantize only if necessary + device_index = torch.device(device).index if torch.device(device).type == "cuda" else None + if not getattr(module.weight, "SCB", None) and device_index is not None: + if module.bias is not None and module.bias.device.type != "meta": + # if a bias exists, we need to wait until the bias is set on the correct device + module = module.cuda(device_index) + elif module.bias is None: + # if no bias exists, we can quantize right away + module = module.cuda(device_index) + elif ( + module.__class__.__name__ == "Linear4bit" + and getattr(module.weight, "quant_state", None) is None + and str(module.weight.device) != "meta" + ): + # quantize only if necessary + device_index = torch.device(device).index if torch.device(device).type == "cuda" else None + if not getattr(module.weight, "quant_state", None) and device_index is not None: + module.weight = module.weight.cuda(device_index) + + # clean pre and post forward hook + if clear_cache and device not in ("cpu", "meta"): + clear_device_cache() + + # When handling tied weights, we update tied_params_map to keep track of the tied weights that have already been allocated on the device in + # order to avoid duplicating memory, see above. + if ( + tied_params_map is not None + and old_value.data_ptr() in tied_params_map + and device not in tied_params_map[old_value.data_ptr()] + ): + tied_params_map[old_value.data_ptr()][device] = new_value + elif ( + value is not None + and tied_params_map is not None + and value.data_ptr() in tied_params_map + and device not in tied_params_map[value.data_ptr()] + ): + tied_params_map[value.data_ptr()][device] = new_value + + +def named_module_tensors( + module: nn.Module, include_buffers: bool = True, recurse: bool = False, remove_non_persistent: bool = False +): + """ + A helper function that gathers all the tensors (parameters + buffers) of a given module. If `include_buffers=True` + it's the same as doing `module.named_parameters(recurse=recurse) + module.named_buffers(recurse=recurse)`. + + Args: + module (`torch.nn.Module`): + The module we want the tensors on. + include_buffer (`bool`, *optional*, defaults to `True`): + Whether or not to include the buffers in the result. + recurse (`bool`, *optional`, defaults to `False`): + Whether or not to go look in every submodule or just return the direct parameters and buffers. + remove_non_persistent (`bool`, *optional*, defaults to `False`): + Whether or not to remove the non persistent buffer from the buffers. Useful only when include_buffers = + True + """ + yield from module.named_parameters(recurse=recurse) + + if include_buffers: + non_persistent_buffers = set() + if remove_non_persistent: + non_persistent_buffers = get_non_persistent_buffers(module, recurse=recurse) + for named_buffer in module.named_buffers(recurse=recurse): + name, _ = named_buffer + if name not in non_persistent_buffers: + yield named_buffer + + +def get_non_persistent_buffers(module: nn.Module, recurse: bool = False, fqns: bool = False): + """ + Gather all non persistent buffers of a given modules into a set + + Args: + module (`nn.Module`): + The module we want the non persistent buffers on. + recurse (`bool`, *optional*, defaults to `False`): + Whether or not to go look in every submodule or just return the direct non persistent buffers. + fqns (`bool`, *optional*, defaults to `False`): + Whether or not to return the fully-qualified names of the non persistent buffers. + """ + + non_persistent_buffers_set = module._non_persistent_buffers_set + if recurse: + for n, m in module.named_modules(): + if fqns: + non_persistent_buffers_set |= {n + "." + b for b in m._non_persistent_buffers_set} + else: + non_persistent_buffers_set |= m._non_persistent_buffers_set + + return non_persistent_buffers_set + + +def check_tied_parameters_in_config(model: nn.Module): + """ + Check if there is any indication in the given model that some weights should be tied. + + Args: + model (`torch.nn.Module`): The model to inspect + + Returns: + bool: True if the model needs to have tied weights + """ + + # based on model.tie_weights() method + has_tied_word_embedding = False + has_tied_encoder_decoder = False + has_tied_module = False + + if "PreTrainedModel" in [c.__name__ for c in inspect.getmro(model.__class__)]: + has_tied_word_embedding = False + model_decoder_config = None + if hasattr(model, "config"): + model_decoder_config = ( + model.config.get_text_config(decoder=True) + if hasattr(model.config, "get_text_config") + else model.config + ) + has_tied_word_embedding = ( + model_decoder_config is not None + and getattr(model_decoder_config, "tie_word_embeddings", False) + and model.get_output_embeddings() + ) + + has_tied_encoder_decoder = ( + hasattr(model, "config") + and getattr(model.config, "is_encoder_decoder", False) + and getattr(model.config, "tie_encoder_decoder", False) + ) + has_tied_module = any(hasattr(module, "_tie_weights") for module in model.modules()) + return any([has_tied_word_embedding, has_tied_encoder_decoder, has_tied_module]) + + +def _get_param_device(param, device_map): + if param in device_map: + return device_map[param] + parent_param = ".".join(param.split(".")[:-1]) + if parent_param == param: + raise ValueError(f"The `device_map` does not contain the module {param}.") + else: + return _get_param_device(parent_param, device_map) + + +def check_tied_parameters_on_same_device(tied_params, device_map): + """ + Check if tied parameters are on the same device + + Args: + tied_params (`List[List[str]]`): + A list of lists of parameter names being all tied together. + + device_map (`Dict[str, Union[int, str, torch.device]]`): + A map that specifies where each submodule should go. + + """ + for tie_param in tied_params: + tie_param_devices = {} + for param in tie_param: + tie_param_devices[param] = _get_param_device(param, device_map) + if len(set(tie_param_devices.values())) > 1: + logger.warning( + f"Tied parameters are on different devices: {tie_param_devices}. " + "Please modify your custom device map or set `device_map='auto'`. " + ) + + +def find_tied_parameters(model: torch.nn.Module, **kwargs) -> list[list[str]]: + """ + Find the tied parameters in a given model. + + + + The signature accepts keyword arguments, but they are for the recursive part of this function and you should ignore + them. + + + + Args: + model (`torch.nn.Module`): The model to inspect. + + Returns: + List[List[str]]: A list of lists of parameter names being all tied together. + + Example: + + ```py + >>> from collections import OrderedDict + >>> import torch.nn as nn + + >>> model = nn.Sequential(OrderedDict([("linear1", nn.Linear(4, 4)), ("linear2", nn.Linear(4, 4))])) + >>> model.linear2.weight = model.linear1.weight + >>> find_tied_parameters(model) + [['linear1.weight', 'linear2.weight']] + ``` + """ + + # get ALL model parameters and their names + all_named_parameters = {name: param for name, param in model.named_parameters(remove_duplicate=False)} + + # get ONLY unique named parameters, + # if parameter is tied and have multiple names, it will be included only once + no_duplicate_named_parameters = {name: param for name, param in model.named_parameters(remove_duplicate=True)} + + # the difference of the two sets will give us the tied parameters + tied_param_names = set(all_named_parameters.keys()) - set(no_duplicate_named_parameters.keys()) + + # 'tied_param_names' contains the names of parameters that are tied in the model, but we do not know + # which names refer to the same parameter. To identify this, we need to group them together. + tied_param_groups = {} + for tied_param_name in tied_param_names: + tied_param = all_named_parameters[tied_param_name] + for param_name, param in no_duplicate_named_parameters.items(): + # compare if parameters are the same, if so, group their names together + if param is tied_param: + if param_name not in tied_param_groups: + tied_param_groups[param_name] = [] + tied_param_groups[param_name].append(tied_param_name) + + return [sorted([weight] + list(set(tied))) for weight, tied in tied_param_groups.items()] + + +def retie_parameters(model, tied_params): + """ + Reties tied parameters in a given model if the link was broken (for instance when adding hooks). + + Args: + model (`torch.nn.Module`): + The model in which to retie parameters. + tied_params (`List[List[str]]`): + A mapping parameter name to tied parameter name as obtained by `find_tied_parameters`. + """ + for tied_group in tied_params: + param_to_tie = None + # two loops : the first one to set param_to_tie , the second one to change the values of tied_group + for param_name in tied_group: + module = model + splits = param_name.split(".") + for split in splits[:-1]: + module = getattr(module, split) + param = getattr(module, splits[-1]) + if param_to_tie is None and param.device != torch.device("meta"): + param_to_tie = param + break + if param_to_tie is not None: + for param_name in tied_group: + module = model + splits = param_name.split(".") + for split in splits[:-1]: + module = getattr(module, split) + setattr(module, splits[-1], param_to_tie) + + +def _get_proper_dtype(dtype: Union[str, torch.device]) -> torch.dtype: + """ + Just does torch.dtype(dtype) if necessary. + """ + if isinstance(dtype, str): + # We accept "torch.float16" or just "float16" + dtype = dtype.replace("torch.", "") + dtype = getattr(torch, dtype) + return dtype + + +def compute_module_sizes( + model: nn.Module, + dtype: Optional[Union[str, torch.device]] = None, + special_dtypes: Optional[dict[str, Union[str, torch.device]]] = None, + buffers_only: bool = False, +): + """ + Compute the size of each submodule of a given model. + """ + if dtype is not None: + dtype = _get_proper_dtype(dtype) + dtype_size = dtype_byte_size(dtype) + if special_dtypes is not None: + special_dtypes = {key: _get_proper_dtype(dtyp) for key, dtyp in special_dtypes.items()} + special_dtypes_size = {key: dtype_byte_size(dtyp) for key, dtyp in special_dtypes.items()} + module_sizes = defaultdict(int) + + module_list = [] + + if not buffers_only: + module_list = named_module_tensors(model, recurse=True) + else: + module_list = model.named_buffers(recurse=True) + + for name, tensor in module_list: + if special_dtypes is not None and name in special_dtypes: + size = tensor.numel() * special_dtypes_size[name] + elif dtype is None: + size = tensor.numel() * dtype_byte_size(tensor.dtype) + elif str(tensor.dtype).startswith(("torch.uint", "torch.int", "torch.bool")): + # According to the code in set_module_tensor_to_device, these types won't be converted + # so use their original size here + size = tensor.numel() * dtype_byte_size(tensor.dtype) + else: + size = tensor.numel() * min(dtype_size, dtype_byte_size(tensor.dtype)) + name_parts = name.split(".") + for idx in range(len(name_parts) + 1): + module_sizes[".".join(name_parts[:idx])] += size + + return module_sizes + + +def compute_module_total_buffer_size( + model: nn.Module, + dtype: Optional[Union[str, torch.device]] = None, + special_dtypes: Optional[dict[str, Union[str, torch.device]]] = None, +): + """ + Compute the total size of buffers in each submodule of a given model. + """ + module_sizes = compute_module_sizes(model, dtype=dtype, special_dtypes=special_dtypes, buffers_only=True) + return module_sizes.get("", 0) + + +def get_max_layer_size( + modules: list[tuple[str, torch.nn.Module]], module_sizes: dict[str, int], no_split_module_classes: list[str] +): + """ + Utility function that will scan a list of named modules and return the maximum size used by one full layer. The + definition of a layer being: + - a module with no direct children (just parameters and buffers) + - a module whose class name is in the list `no_split_module_classes` + + Args: + modules (`List[Tuple[str, torch.nn.Module]]`): + The list of named modules where we want to determine the maximum layer size. + module_sizes (`Dict[str, int]`): + A dictionary mapping each layer name to its size (as generated by `compute_module_sizes`). + no_split_module_classes (`List[str]`): + A list of class names for layers we don't want to be split. + + Returns: + `Tuple[int, List[str]]`: The maximum size of a layer with the list of layer names realizing that maximum size. + """ + max_size = 0 + layer_names = [] + modules_to_treat = modules.copy() + while len(modules_to_treat) > 0: + module_name, module = modules_to_treat.pop(0) + modules_children = list(module.named_children()) if isinstance(module, torch.nn.Module) else [] + if len(modules_children) == 0 or module.__class__.__name__ in no_split_module_classes: + # No splitting this one so we compare to the max_size + size = module_sizes[module_name] + if size > max_size: + max_size = size + layer_names = [module_name] + elif size == max_size: + layer_names.append(module_name) + else: + modules_to_treat = [(f"{module_name}.{n}", v) for n, v in modules_children] + modules_to_treat + return max_size, layer_names + + +def get_max_memory(max_memory: Optional[dict[Union[int, str], Union[int, str]]] = None): + """ + Get the maximum memory available if nothing is passed, converts string to int otherwise. + """ + import psutil + + if max_memory is None: + max_memory = {} + # Make sure CUDA is initialized on each GPU to have the right memory info. + if is_npu_available(): + for i in range(torch.npu.device_count()): + try: + _ = torch.tensor(0, device=torch.device("npu", i)) + max_memory[i] = torch.npu.mem_get_info(i)[0] + except Exception: + logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.") + continue + elif is_mlu_available(): + for i in range(torch.mlu.device_count()): + try: + _ = torch.tensor(0, device=torch.device("mlu", i)) + max_memory[i] = torch.mlu.mem_get_info(i)[0] + except Exception: + logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.") + continue + elif is_sdaa_available(): + for i in range(torch.sdaa.device_count()): + try: + _ = torch.tensor(0, device=torch.device("sdaa", i)) + max_memory[i] = torch.sdaa.mem_get_info(i)[0] + except Exception: + logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.") + continue + elif is_musa_available(): + for i in range(torch.musa.device_count()): + try: + _ = torch.tensor(0, device=torch.device("musa", i)) + max_memory[i] = torch.musa.mem_get_info(i)[0] + except Exception: + logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.") + continue + elif is_xpu_available(): + for i in range(torch.xpu.device_count()): + try: + _ = torch.tensor(0, device=torch.device("xpu", i)) + max_memory[i] = get_xpu_available_memory(i) + except Exception: + logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.") + continue + elif is_hpu_available(): + for i in range(torch.hpu.device_count()): + try: + _ = torch.tensor(0, device=torch.device("hpu", i)) + max_memory[i] = torch.hpu.mem_get_info(i)[0] + except Exception: + logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.") + continue + else: + for i in range(torch.cuda.device_count()): + try: + _ = torch.tensor([0], device=i) + max_memory[i] = torch.cuda.mem_get_info(i)[0] + except Exception: + logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.") + continue + # allocate everything in the mps device as the RAM is shared + if is_mps_available(): + max_memory["mps"] = psutil.virtual_memory().available + else: + max_memory["cpu"] = psutil.virtual_memory().available + return max_memory + + for key in max_memory: + if isinstance(max_memory[key], str): + max_memory[key] = convert_file_size_to_int(max_memory[key]) + + # Need to sort the device by type to make sure that we allocate the gpu first. + # As gpu/npu/xpu are represented by int, we need to sort them first. + gpu_devices = [k for k in max_memory.keys() if isinstance(k, int)] + gpu_devices.sort() + # check if gpu/npu/xpu devices are available and if not, throw a warning + if is_npu_available(): + num_devices = torch.npu.device_count() + elif is_mlu_available(): + num_devices = torch.mlu.device_count() + elif is_sdaa_available(): + num_devices = torch.sdaa.device_count() + elif is_musa_available(): + num_devices = torch.musa.device_count() + elif is_xpu_available(): + num_devices = torch.xpu.device_count() + elif is_hpu_available(): + num_devices = torch.hpu.device_count() + else: + num_devices = torch.cuda.device_count() + for device in gpu_devices: + if device >= num_devices or device < 0: + logger.warning(f"Device {device} is not available, available devices are {list(range(num_devices))}") + # Add the other devices in the preset order if they are available + all_devices = gpu_devices + [k for k in ["mps", "cpu", "disk"] if k in max_memory.keys()] + # Raise an error if a device is not recognized + for k in max_memory.keys(): + if k not in all_devices: + raise ValueError( + f"Device {k} is not recognized, available devices are integers(for GPU/XPU), 'mps', 'cpu' and 'disk'" + ) + max_memory = {k: max_memory[k] for k in all_devices} + + return max_memory + + +def clean_device_map(device_map: dict[str, Union[int, str, torch.device]], module_name: str = ""): + """ + Cleans a device_map by grouping all submodules that go on the same device together. + """ + # Get the value of the current module and if there is only one split across several keys, regroup it. + prefix = "" if module_name == "" else f"{module_name}." + values = [v for k, v in device_map.items() if k.startswith(prefix)] + if len(set(values)) == 1 and len(values) > 1: + for k in [k for k in device_map if k.startswith(prefix)]: + del device_map[k] + device_map[module_name] = values[0] + + # Recurse over the children + children_modules = [k for k in device_map.keys() if k.startswith(prefix) and len(k) > len(module_name)] + idx = len(module_name.split(".")) + 1 if len(module_name) > 0 else 1 + children_modules = set(".".join(k.split(".")[:idx]) for k in children_modules) + for child in children_modules: + clean_device_map(device_map, module_name=child) + + return device_map + + +def load_offloaded_weights(model, index, offload_folder): + """ + Loads the weights from the offload folder into the model. + + Args: + model (`torch.nn.Module`): + The model to load the weights into. + index (`dict`): + A dictionary containing the parameter name and its metadata for each parameter that was offloaded from the + model. + offload_folder (`str`): + The folder where the offloaded weights are stored. + """ + if index is None or len(index) == 0: + # Nothing to do + return + for param_name, metadata in index.items(): + if "SCB" in param_name: + continue + fp16_statistics = None + if "weight" in param_name and param_name.replace("weight", "SCB") in index.keys(): + weight_name = param_name.replace("weight", "SCB") + fp16_statistics = load_offloaded_weight( + os.path.join(offload_folder, f"{weight_name}.dat"), index[weight_name] + ) + tensor_file = os.path.join(offload_folder, f"{param_name}.dat") + weight = load_offloaded_weight(tensor_file, metadata) + set_module_tensor_to_device(model, param_name, "cpu", value=weight, fp16_statistics=fp16_statistics) + + +def get_module_leaves(module_sizes): + module_children = {} + for module in module_sizes: + if module == "" or "." not in module: + continue + parent = module.rsplit(".", 1)[0] + module_children[parent] = module_children.get(parent, 0) + 1 + leaves = [module for module in module_sizes if module_children.get(module, 0) == 0 and module != ""] + return leaves + + +def get_balanced_memory( + model: nn.Module, + max_memory: Optional[dict[Union[int, str], Union[int, str]]] = None, + no_split_module_classes: Optional[list[str]] = None, + dtype: Optional[Union[str, torch.dtype]] = None, + special_dtypes: Optional[dict[str, Union[str, torch.device]]] = None, + low_zero: bool = False, +): + """ + Compute a `max_memory` dictionary for [`infer_auto_device_map`] that will balance the use of each available GPU. + + + + All computation is done analyzing sizes and dtypes of the model parameters. As a result, the model can be on the + meta device (as it would if initialized within the `init_empty_weights` context manager). + + + + Args: + model (`torch.nn.Module`): + The model to analyze. + max_memory (`Dict`, *optional*): + A dictionary device identifier to maximum memory. Will default to the maximum memory available if unset. + Example: `max_memory={0: "1GB"}`. + no_split_module_classes (`List[str]`, *optional*): + A list of layer class names that should never be split across device (for instance any layer that has a + residual connection). + dtype (`str` or `torch.dtype`, *optional*): + If provided, the weights will be converted to that type when loaded. + special_dtypes (`Dict[str, Union[str, torch.device]]`, *optional*): + If provided, special dtypes to consider for some specific weights (will override dtype used as default for + all weights). + low_zero (`bool`, *optional*): + Minimizes the number of weights on GPU 0, which is convenient when it's used for other operations (like the + Transformers generate function). + """ + # Get default / clean up max_memory + user_not_set_max_memory = max_memory is None + max_memory = get_max_memory(max_memory) + + if is_npu_available(): + expected_device_type = "npu" + elif is_mlu_available(): + expected_device_type = "mlu" + elif is_sdaa_available(): + expected_device_type = "sdaa" + elif is_musa_available(): + expected_device_type = "musa" + elif is_xpu_available(): + expected_device_type = "xpu" + elif is_hpu_available(): + expected_device_type = "hpu" + elif is_mps_available(): + expected_device_type = "mps" + else: + expected_device_type = "cuda" + num_devices = len([d for d in max_memory if torch.device(d).type == expected_device_type and max_memory[d] > 0]) + + if num_devices == 0: + return max_memory + + if num_devices == 1: + # We cannot do low_zero on just one GPU, but we will still reserve some memory for the buffer + low_zero = False + # If user just asked us to handle memory usage, we should avoid OOM + if user_not_set_max_memory: + for key in max_memory.keys(): + if isinstance(key, int): + max_memory[key] *= 0.9 # 90% is a good compromise + logger.info( + f"We will use 90% of the memory on device {key} for storing the model, and 10% for the buffer to avoid OOM. " + "You can set `max_memory` in to a higher value to use more memory (at your own risk)." + ) + break # only one device + + module_sizes = compute_module_sizes(model, dtype=dtype, special_dtypes=special_dtypes) + per_gpu = module_sizes[""] // (num_devices - 1 if low_zero else num_devices) + + # We can't just set the memory to model_size // num_devices as it will end being too small: each GPU will get + # slightly less layers and some layers will end up offload at the end. So this function computes a buffer size to + # add which is the biggest of: + # - the size of no split block (if applicable) + # - the mean of the layer sizes + if no_split_module_classes is None: + no_split_module_classes = [] + elif not isinstance(no_split_module_classes, (list, tuple)): + no_split_module_classes = [no_split_module_classes] + + # Identify the size of the no_split_block modules + if len(no_split_module_classes) > 0: + no_split_children = {} + for name, size in module_sizes.items(): + if name == "": + continue + submodule = model + for submodule_name in name.split("."): + submodule = getattr(submodule, submodule_name) + class_name = submodule.__class__.__name__ + if class_name in no_split_module_classes and class_name not in no_split_children: + no_split_children[class_name] = size + + if set(no_split_children.keys()) == set(no_split_module_classes): + break + buffer = max(no_split_children.values()) if len(no_split_children) > 0 else 0 + else: + buffer = 0 + + # Compute mean of final modules. In the first dict of module sizes, leaves are the parameters + leaves = get_module_leaves(module_sizes) + leaves_set = set(leaves) # Convert to set for O(1) membership testing + module_sizes = {n: v for n, v in module_sizes.items() if n not in leaves_set} + # Once removed, leaves are the final modules. + leaves = get_module_leaves(module_sizes) + mean_leaves = int(sum([module_sizes[n] for n in leaves]) / max(len(leaves), 1)) + buffer = int(1.25 * max(buffer, mean_leaves)) + per_gpu += buffer + + # Sorted list of GPUs id (we may have some gpu ids not included in the our max_memory list - let's ignore them) + gpus_idx_list = list( + sorted( + device_id for device_id, device_mem in max_memory.items() if isinstance(device_id, int) and device_mem > 0 + ) + ) + # The last device is left with max_memory just in case the buffer is not enough. + for idx in gpus_idx_list[:-1]: + max_memory[idx] = min(max_memory[0] if low_zero and idx == 0 else per_gpu, max_memory[idx]) + + if low_zero: + min_zero = max(0, module_sizes[""] - sum([max_memory[i] for i in range(1, num_devices)])) + max_memory[0] = min(min_zero, max_memory[0]) + + return max_memory + + +def calculate_maximum_sizes(model: torch.nn.Module): + "Computes the total size of the model and its largest layer" + sizes = compute_module_sizes(model) + # `transformers` models store this information for us + no_split_modules = getattr(model, "_no_split_modules", None) + if no_split_modules is None: + no_split_modules = [] + + modules_to_treat = ( + list(model.named_parameters(recurse=False)) + + list(model.named_children()) + + list(model.named_buffers(recurse=False)) + ) + largest_layer = get_max_layer_size(modules_to_treat, sizes, no_split_modules) + total_size = sizes[""] + return total_size, largest_layer + + +def _init_infer_auto_device_map( + model: nn.Module, + max_memory: Optional[dict[Union[int, str], Union[int, str]]] = None, + no_split_module_classes: Optional[list[str]] = None, + dtype: Optional[Union[str, torch.dtype]] = None, + special_dtypes: Optional[dict[str, Union[str, torch.device]]] = None, +) -> tuple[ + list[Union[int, str]], + dict[Union[int, str], Union[int, str]], + list[Union[int, str]], + list[int], + dict[str, int], + list[list[str]], + list[str], + list[tuple[str, nn.Module]], +]: + """ + Initialize variables required for computing the device map for model allocation. + """ + max_memory = get_max_memory(max_memory) + if no_split_module_classes is None: + no_split_module_classes = [] + elif not isinstance(no_split_module_classes, (list, tuple)): + no_split_module_classes = [no_split_module_classes] + + devices = list(max_memory.keys()) + if "disk" not in devices: + devices.append("disk") + gpus = [device for device in devices if device not in ["cpu", "disk"]] + + # Devices that need to keep space for a potential offloaded layer. + if "mps" in gpus: + main_devices = ["mps"] + elif len(gpus) > 0: + main_devices = [gpus[0], "cpu"] + else: + main_devices = ["cpu"] + + module_sizes = compute_module_sizes(model, dtype=dtype, special_dtypes=special_dtypes) + tied_parameters = find_tied_parameters(model) + if check_tied_parameters_in_config(model) and len(tied_parameters) == 0: + logger.warning( + "The model weights are not tied. Please use the `tie_weights` method before using the `infer_auto_device` function." + ) + + # Direct submodules and parameters + modules_to_treat = ( + list(model.named_parameters(recurse=False)) + + list(model.named_children()) + + list(model.named_buffers(recurse=False)) + ) + + return ( + devices, + max_memory, + main_devices, + gpus, + module_sizes, + tied_parameters, + no_split_module_classes, + modules_to_treat, + ) + + +def get_module_size_with_ties( + tied_params, + module_size, + module_sizes, + modules_to_treat, +) -> tuple[int, list[str], list[nn.Module]]: + """ + Calculate the total size of a module, including its tied parameters. + + Args: + tied_params (`List[str]`): The list of tied parameters. + module_size (`int`): The size of the module without tied parameters. + module_sizes (`Dict[str, int]`): A dictionary mapping each layer name to its size. + modules_to_treat (`List[Tuple[str, nn.Module]]`): The list of named modules to treat. + + Returns: + `Tuple[int, List[str], List[nn.Module]]`: The total size of the module, the names of the tied modules, and the + tied modules. + """ + if len(tied_params) < 1: + return module_size, [], [] + tied_module_names = [] + tied_modules = [] + + for tied_param in tied_params: + tied_module_index = [i for i, (n, _) in enumerate(modules_to_treat) if tied_param.startswith(n + ".")][0] + tied_module_names.append(modules_to_treat[tied_module_index][0]) + tied_modules.append(modules_to_treat[tied_module_index][1]) + + module_size_with_ties = module_size + for tied_param, tied_module_name in zip(tied_params, tied_module_names): + module_size_with_ties += module_sizes[tied_module_name] - module_sizes[tied_param] + + return module_size_with_ties, tied_module_names, tied_modules + + +def fallback_allocate( + modules: list[tuple[str, nn.Module]], + module_sizes: dict[str, int], + size_limit: Union[int, str], + no_split_module_classes: Optional[list[str]] = None, + tied_parameters: Optional[list[list[str]]] = None, +) -> tuple[Optional[str], Optional[nn.Module], list[tuple[str, nn.Module]]]: + """ + Find a module that fits in the size limit using BFS and return it with its name and the remaining modules. + + Args: + modules (`List[Tuple[str, nn.Module]]`): + The list of named modules to search in. + module_sizes (`Dict[str, int]`): + A dictionary mapping each layer name to its size (as generated by `compute_module_sizes`). + size_limit (`Union[int, str]`): + The maximum size a module can have. + no_split_module_classes (`Optional[List[str]]`, *optional*): + A list of class names for layers we don't want to be split. + tied_parameters (`Optional[List[List[str]]`, *optional*): + A list of lists of parameter names being all tied together. + + Returns: + `Tuple[Optional[str], Optional[nn.Module], List[Tuple[str, nn.Module]]]`: A tuple containing: + - The name of the module that fits within the size limit. + - The module itself. + - The list of remaining modules after the found module is removed. + """ + try: + size_limit = convert_file_size_to_int(size_limit) + except ValueError: + return None, None, modules + + if no_split_module_classes is None: + no_split_module_classes = [] + + if tied_parameters is None: + tied_parameters = [] + + modules_to_search = modules.copy() + module_found = False + + while modules_to_search: + name, module = modules_to_search.pop(0) + + tied_param_groups = [ + tied_group + for tied_group in tied_parameters + if any(name + "." in k + "." for k in tied_group) and not all(name + "." in k + "." for k in tied_group) + ] + + tied_params = sum( + [[p for p in tied_group if name + "." not in p + "."] for tied_group in tied_param_groups], [] + ) + + module_size_with_ties, _, _ = get_module_size_with_ties( + tied_params, module_sizes[name], module_sizes, modules_to_search + ) + + # If the module fits in the size limit, we found it. + if module_size_with_ties <= size_limit: + module_found = True + break + + # The module is too big, we need to split it if possible. + modules_children = ( + [] + if isinstance(module, nn.Parameter) or isinstance(module, torch.Tensor) + else list(module.named_children()) + ) + + # Split fails, move to the next module + if len(modules_children) == 0 or module.__class__.__name__ in no_split_module_classes: + continue + + # split is possible, add the children to the list of modules to search + modules_children = list(module.named_parameters(recurse=False)) + modules_children + modules_to_search = [(f"{name}.{n}", v) for n, v in modules_children] + modules_to_search + + if not module_found: + return None, None, modules + + # Prepare the module list for removal of the found module + current_names = [n for n, _ in modules] + dot_idx = [i for i, c in enumerate(name) if c == "."] + + for dot_index in dot_idx: + parent_name = name[:dot_index] + if parent_name in current_names: + parent_module_idx = current_names.index(parent_name) + _, parent_module = modules[parent_module_idx] + module_children = list(parent_module.named_parameters(recurse=False)) + list( + parent_module.named_children() + ) + modules = ( + modules[:parent_module_idx] + + [(f"{parent_name}.{n}", v) for n, v in module_children] + + modules[parent_module_idx + 1 :] + ) + current_names = [n for n, _ in modules] + + # Now the target module should be directly in the list + target_idx = current_names.index(name) + name, module = modules.pop(target_idx) + + return name, module, modules + + +def infer_auto_device_map( + model: nn.Module, + max_memory: Optional[dict[Union[int, str], Union[int, str]]] = None, + no_split_module_classes: Optional[list[str]] = None, + dtype: Optional[Union[str, torch.dtype]] = None, + special_dtypes: Optional[dict[str, Union[str, torch.dtype]]] = None, + verbose: bool = False, + clean_result: bool = True, + offload_buffers: bool = False, + fallback_allocation: bool = False, +): + """ + Compute a device map for a given model giving priority to GPUs, then offload on CPU and finally offload to disk, + such that: + - we don't exceed the memory available of any of the GPU. + - if offload to the CPU is needed, there is always room left on GPU 0 to put back the layer offloaded on CPU that + has the largest size. + - if offload to the CPU is needed,we don't exceed the RAM available on the CPU. + - if offload to the disk is needed, there is always room left on the CPU to put back the layer offloaded on disk + that has the largest size. + + + + All computation is done analyzing sizes and dtypes of the model parameters. As a result, the model can be on the + meta device (as it would if initialized within the `init_empty_weights` context manager). + + + + Args: + model (`torch.nn.Module`): + The model to analyze. + max_memory (`Dict`, *optional*): + A dictionary device identifier to maximum memory. Will default to the maximum memory available if unset. + Example: `max_memory={0: "1GB"}`. + no_split_module_classes (`List[str]`, *optional*): + A list of layer class names that should never be split across device (for instance any layer that has a + residual connection). + dtype (`str` or `torch.dtype`, *optional*): + If provided, the weights will be converted to that type when loaded. + special_dtypes (`Dict[str, Union[str, torch.device]]`, *optional*): + If provided, special dtypes to consider for some specific weights (will override dtype used as default for + all weights). + verbose (`bool`, *optional*, defaults to `False`): + Whether or not to provide debugging statements as the function builds the device_map. + clean_result (`bool`, *optional*, defaults to `True`): + Clean the resulting device_map by grouping all submodules that go on the same device together. + offload_buffers (`bool`, *optional*, defaults to `False`): + In the layers that are offloaded on the CPU or the hard drive, whether or not to offload the buffers as + well as the parameters. + fallback_allocation (`bool`, *optional*, defaults to `False`): + When regular allocation fails, try to allocate a module that fits in the size limit using BFS. + """ + + # Initialize the variables + ( + devices, + max_memory, + main_devices, + gpus, + module_sizes, + tied_parameters, + no_split_module_classes, + modules_to_treat, + ) = _init_infer_auto_device_map(model, max_memory, no_split_module_classes, dtype, special_dtypes) + + device_map = OrderedDict() + current_device = 0 + device_memory_used = {device: 0 for device in devices} + device_buffer_sizes = {} + device_minimum_assignment_memory = {} + + # Initialize maximum largest layer, to know which space to keep in memory + max_layer_size, max_layer_names = get_max_layer_size(modules_to_treat, module_sizes, no_split_module_classes) + + # Ready ? This is going to be a bit messy. + while len(modules_to_treat) > 0: + name, module = modules_to_treat.pop(0) + if verbose: + print(f"\nTreating module {name}.") + # Max size in the remaining layers may have changed since we took one, so we maybe update it. + max_layer_names = [n for n in max_layer_names if n != name and not n.startswith(name + ".")] + if len(max_layer_names) == 0: + max_layer_size, max_layer_names = get_max_layer_size( + [(n, m) for n, m in modules_to_treat if isinstance(m, torch.nn.Module)], + module_sizes, + no_split_module_classes, + ) + # Assess size needed + module_size = module_sizes[name] + + # We keep relevant tied parameters only: one of the tied parameters in the group is inside the current module + # and the other is not. + # Note: If we are currently processing the name `compute.weight`, an other parameter named + # e.g. `compute.weight_submodule.parameter` + # needs to be considered outside the current module, hence the check with additional dots. + tied_param_groups = [ + tied_group + for tied_group in tied_parameters + if any(name + "." in k + "." for k in tied_group) and not all(name + "." in k + "." for k in tied_group) + ] + + if verbose and len(tied_param_groups) > 0: + print(f" Found the relevant tied param groups {tied_param_groups}") + + # Then we keep track of all the parameters that are tied to the current module, but not in the current module + tied_params = sum( + [[p for p in tied_group if name + "." not in p + "."] for tied_group in tied_param_groups], [] + ) + + if verbose and len(tied_params) > 0: + print(f" So those parameters need to be taken into account {tied_params}") + + device = devices[current_device] + current_max_size = max_memory[device] if device != "disk" else None + current_memory_reserved = 0 + # Reduce max size available by the largest layer. + if devices[current_device] in main_devices: + current_max_size = current_max_size - max_layer_size + current_memory_reserved = max_layer_size + + module_size_with_ties, tied_module_names, tied_modules = get_module_size_with_ties( + tied_params, module_size, module_sizes, modules_to_treat + ) + + # The module and its tied modules fit on the current device. + if current_max_size is None or device_memory_used[device] + module_size_with_ties <= current_max_size: + if verbose: + output = f"Putting {name}" + + if tied_module_names: + output += f" and {tied_module_names}" + else: + output += f" (size={module_size})" + + if current_max_size is not None: + output += f" (available={current_max_size - device_memory_used[device]})" + + output += f" on {device}." + print(output) + + device_memory_used[device] += module_size_with_ties + + # Assign the primary module to the device. + device_map[name] = device + + # Assign tied modules if any. + for tied_module_name in tied_module_names: + if tied_module_name in [m[0] for m in modules_to_treat]: + # Find the index of the tied module in the list + tied_module_index = next(i for i, (n, _) in enumerate(modules_to_treat) if n == tied_module_name) + # Remove the tied module from the list to prevent reprocessing + modules_to_treat.pop(tied_module_index) + + # Assign the tied module to the device + device_map[tied_module_name] = device + + # Buffer Handling + if not offload_buffers and isinstance(module, nn.Module): + # Compute the total buffer size for the module + current_buffer_size = compute_module_total_buffer_size( + module, dtype=dtype, special_dtypes=special_dtypes + ) + # Update the buffer size on the device + device_buffer_sizes[device] = device_buffer_sizes.get(device, 0) + current_buffer_size + + continue + + # The current module itself fits, so we try to split the tied modules. + if len(tied_params) > 0 and device_memory_used[device] + module_size <= current_max_size: + # can we split one of the tied modules to make it smaller or do we need to go on the next device? + if verbose: + print( + f"Not enough space on {devices[current_device]} to put {name} and {tied_module_names} (space " + f"available {current_max_size - device_memory_used[device]}, needed size {module_size_with_ties})." + ) + split_happened = False + for tied_module_name, tied_module in zip(tied_module_names, tied_modules): + tied_module_children = list(tied_module.named_children()) + if len(tied_module_children) == 0 or tied_module.__class__.__name__ in no_split_module_classes: + # can't break this one. + continue + + if verbose: + print(f"Splitting {tied_module_name}.") + tied_module_children = list(tied_module.named_parameters(recurse=False)) + tied_module_children + tied_module_children = [(f"{tied_module_name}.{n}", v) for n, v in tied_module_children] + tied_module_index = [i for i, (n, _) in enumerate(modules_to_treat) if n == tied_module_name][0] + + modules_to_treat = ( + [(name, module)] + + modules_to_treat[:tied_module_index] + + tied_module_children + + modules_to_treat[tied_module_index + 1 :] + ) + # Update the max layer size. + max_layer_size, max_layer_names = get_max_layer_size( + [(n, m) for n, m in modules_to_treat if isinstance(m, torch.nn.Module)], + module_sizes, + no_split_module_classes, + ) + split_happened = True + break + + if split_happened: + continue + + # If the tied module is not split, we go to the next device + if verbose: + print("None of the tied module can be split, going to the next device.") + + # The current module itself doesn't fit, so we have to split it or go to the next device. + if device_memory_used[device] + module_size >= current_max_size: + # Split or not split? + modules_children = ( + [] + if isinstance(module, nn.Parameter) or isinstance(module, torch.Tensor) + else list(module.named_children()) + ) + if verbose: + print( + f"Not enough space on {devices[current_device]} to put {name} (space available " + f"{current_max_size - device_memory_used[device]}, module size {module_size})." + ) + if len(modules_children) == 0 or module.__class__.__name__ in no_split_module_classes: + # -> no split, we go to the next device + if verbose: + print("This module cannot be split, going to the next device.") + + else: + # -> split, we replace the module studied by its children + parameters + if verbose: + print(f"Splitting {name}.") + modules_children = list(module.named_parameters(recurse=False)) + modules_children + modules_to_treat = [(f"{name}.{n}", v) for n, v in modules_children] + modules_to_treat + # Update the max layer size. + max_layer_size, max_layer_names = get_max_layer_size( + [(n, m) for n, m in modules_to_treat if isinstance(m, torch.nn.Module)], + module_sizes, + no_split_module_classes, + ) + continue + + # If no module is assigned to the current device, we attempt to allocate a fallback module + # if fallback_allocation is enabled. + if device_memory_used[device] == 0 and fallback_allocation and device != "disk": + # We try to allocate a module that fits in the size limit using BFS. + # Recompute the current max size as we need to consider the current module as well. + current_max_size = max_memory[device] - max(max_layer_size, module_size_with_ties) + + fallback_module_name, fallback_module, remaining_modules = fallback_allocate( + modules_to_treat, + module_sizes, + current_max_size - device_memory_used[device], + no_split_module_classes, + tied_parameters, + ) + # use the next iteration to put the fallback module on the next device to avoid code duplication + if fallback_module is not None: + modules_to_treat = [(fallback_module_name, fallback_module)] + [(name, module)] + remaining_modules + continue + + if device_memory_used[device] == 0: + device_minimum_assignment_memory[device] = module_size_with_ties + current_memory_reserved + + # Neither the current module nor any tied modules can be split, so we move to the next device. + device_memory_used[device] = device_memory_used[device] + current_memory_reserved + current_device += 1 + modules_to_treat = [(name, module)] + modules_to_treat + + device_memory_used = {device: mem for device, mem in device_memory_used.items() if mem > 0} + + if clean_result: + device_map = clean_device_map(device_map) + + non_gpu_buffer_size = device_buffer_sizes.get("cpu", 0) + device_buffer_sizes.get("disk", 0) + if non_gpu_buffer_size > 0 and not offload_buffers: + is_buffer_fit_any_gpu = False + for gpu_device, gpu_max_memory in max_memory.items(): + if gpu_device == "cpu" or gpu_device == "disk": + continue + + if not is_buffer_fit_any_gpu: + gpu_memory_used = device_memory_used.get(gpu_device, 0) + + if gpu_max_memory >= non_gpu_buffer_size + gpu_memory_used: + is_buffer_fit_any_gpu = True + + if len(gpus) > 0 and not is_buffer_fit_any_gpu: + warnings.warn( + f"Current model requires {non_gpu_buffer_size} bytes of buffer for offloaded layers, which seems does " + f"not fit any GPU's remaining memory. If you are experiencing a OOM later, please consider using " + f"offload_buffers=True." + ) + + if device_minimum_assignment_memory: + devices_info = "\n".join( + f" - {device}: {mem} bytes required" for device, mem in device_minimum_assignment_memory.items() + ) + logger.info( + f"Based on the current allocation process, no modules could be assigned to the following devices due to " + f"insufficient memory:\n" + f"{devices_info}\n" + f"These minimum requirements are specific to this allocation attempt and may vary. Consider increasing " + f"the available memory for these devices to at least the specified minimum, or adjusting the model config." + ) + return device_map + + +def check_device_map(model: nn.Module, device_map: dict[str, Union[int, str, torch.device]]): + """ + Checks a device map covers everything in a given model. + + Args: + model (`torch.nn.Module`): The model to check the device map against. + device_map (`Dict[str, Union[int, str, torch.device]]`): The device map to check. + """ + all_module_names = dict(model.named_modules()) + invalid_keys = [k for k in device_map if k != "" and k not in all_module_names] + + if invalid_keys: + warnings.warn( + f"The following device_map keys do not match any submodules in the model: {invalid_keys}", UserWarning + ) + + all_model_tensors = [name for name, _ in model.state_dict().items()] + for module_name in device_map.keys(): + if module_name == "": + all_model_tensors.clear() + break + else: + all_model_tensors = [ + name + for name in all_model_tensors + if not name == module_name and not name.startswith(module_name + ".") + ] + if len(all_model_tensors) > 0: + non_covered_params = ", ".join(all_model_tensors) + raise ValueError( + f"The device_map provided does not give any device for the following parameters: {non_covered_params}" + ) + + +def load_state_dict(checkpoint_file, device_map=None): + """ + Load a checkpoint from a given file. If the checkpoint is in the safetensors format and a device map is passed, the + weights can be fast-loaded directly on the GPU. + + Args: + checkpoint_file (`str`): The path to the checkpoint to load. + device_map (`Dict[str, Union[int, str, torch.device]]`, *optional*): + A map that specifies where each submodule should go. It doesn't need to be refined to each parameter/buffer + name, once a given module name is inside, every submodule of it will be sent to the same device. + """ + if checkpoint_file.endswith(".safetensors"): + with safe_open(checkpoint_file, framework="pt") as f: + metadata = f.metadata() + weight_names = f.keys() + + if metadata is None: + logger.warning( + f"The safetensors archive passed at {checkpoint_file} does not contain metadata. " + "Make sure to save your model with the `save_pretrained` method. Defaulting to 'pt' metadata." + ) + metadata = {"format": "pt"} + + if metadata.get("format") not in ["pt", "tf", "flax"]: + raise OSError( + f"The safetensors archive passed at {checkpoint_file} does not contain the valid metadata. Make sure " + "you save your model with the `save_pretrained` method." + ) + elif metadata["format"] != "pt": + raise ValueError(f"The checkpoint passed was saved with {metadata['format']}, we need a the pt format.") + if device_map is None: + return safe_load_file(checkpoint_file) + else: + # if we only have one device we can load everything directly + if len(set(device_map.values())) == 1: + device = list(device_map.values())[0] + target_device = device + if isinstance(device, int): + if is_npu_available(): + target_device = f"npu:{device}" + elif is_hpu_available(): + target_device = "hpu" + + return safe_load_file(checkpoint_file, device=target_device) + + devices = list(set(device_map.values()) - {"disk"}) + # cpu device should always exist as fallback option + if "cpu" not in devices: + devices.append("cpu") + + # For each device, get the weights that go there + device_weights = {device: [] for device in devices} + for module_name, device in device_map.items(): + if device in devices: + device_weights[device].extend( + [k for k in weight_names if k == module_name or k.startswith(module_name + ".")] + ) + + # all weights that haven't defined a device should be loaded on CPU + device_weights["cpu"].extend([k for k in weight_names if k not in sum(device_weights.values(), [])]) + tensors = {} + if is_tqdm_available(): + progress_bar = tqdm( + main_process_only=False, + total=sum([len(device_weights[device]) for device in devices]), + unit="w", + smoothing=0, + leave=False, + ) + else: + progress_bar = None + for device in devices: + target_device = device + if isinstance(device, int): + if is_npu_available(): + target_device = f"npu:{device}" + elif is_hpu_available(): + target_device = "hpu" + + with safe_open(checkpoint_file, framework="pt", device=target_device) as f: + for key in device_weights[device]: + if progress_bar is not None: + progress_bar.set_postfix(dev=device, refresh=False) + progress_bar.set_description(key) + tensors[key] = f.get_tensor(key) + if progress_bar is not None: + progress_bar.update() + if progress_bar is not None: + progress_bar.close() + + return tensors + else: + return torch.load(checkpoint_file, map_location=torch.device("cpu"), weights_only=True) + + +def get_state_dict_offloaded_model(model: nn.Module): + """ + Returns the state dictionary for an offloaded model via iterative onloading + + Args: + model (`torch.nn.Module`): + The offloaded model we want to save + """ + + state_dict = {} + placeholders = set() + for name, module in model.named_modules(): + if name == "": + continue + + try: + with align_module_device(module, "cpu"): + module_state_dict = module.state_dict() + except MemoryError: + raise MemoryError("Offloaded module must fit in CPU memory to call save_model!") from None + + for key in module_state_dict: + # ignore placeholder parameters that are still on the meta device + if module_state_dict[key].device == torch.device("meta"): + placeholders.add(name + f".{key}") + continue + params = module_state_dict[key] + state_dict[name + f".{key}"] = params.to("cpu") # move buffers to cpu + for key in placeholders.copy(): + if key in state_dict: + placeholders.remove(key) + if placeholders: + logger.warning(f"The following tensors were not saved because they were still on meta device: {placeholders}") + + return state_dict + + +def get_state_dict_from_offload( + module: nn.Module, + module_name: str, + state_dict: dict[str, Union[str, torch.tensor]], + device_to_put_offload: Union[int, str, torch.device] = "cpu", +): + """ + Retrieve the state dictionary (with parameters) from an offloaded module and load into a specified device (defaults + to cpu). + + Args: + module: (`torch.nn.Module`): + The module we want to retrieve a state dictionary from + module_name: (`str`): + The name of the module of interest + state_dict (`Dict[str, Union[int, str, torch.device]]`): + Dictionary of {module names: parameters} + device_to_put_offload (`Union[int, str, torch.device]`): + Device to load offloaded parameters into, defaults to the cpu. + """ + + root = module_name[: module_name.rfind(".")] # module name without .weight or .bias + + # do not move parameters if the module is not offloaded + if not has_offloaded_params(module): + device_to_put_offload = None + + # assign the device to which the offloaded parameters will be sent + with align_module_device(module, device_to_put_offload): + for m_key, params in module.state_dict().items(): + if (root + f".{m_key}") in state_dict: + state_dict[root + f".{m_key}"] = params + + return state_dict + + +def load_checkpoint_in_model( + model: nn.Module, + checkpoint: Union[str, os.PathLike], + device_map: Optional[dict[str, Union[int, str, torch.device]]] = None, + offload_folder: Optional[Union[str, os.PathLike]] = None, + dtype: Optional[Union[str, torch.dtype]] = None, + offload_state_dict: bool = False, + offload_buffers: bool = False, + keep_in_fp32_modules: Optional[list[str]] = None, + offload_8bit_bnb: bool = False, + strict: bool = False, + full_state_dict: bool = True, + broadcast_from_rank0: bool = False, +): + """ + Loads a (potentially sharded) checkpoint inside a model, potentially sending weights to a given device as they are + loaded. + + + + Once loaded across devices, you still need to call [`dispatch_model`] on your model to make it able to run. To + group the checkpoint loading and dispatch in one single call, use [`load_checkpoint_and_dispatch`]. + + + + Args: + model (`torch.nn.Module`): + The model in which we want to load a checkpoint. + checkpoint (`str` or `os.PathLike`): + The folder checkpoint to load. It can be: + - a path to a file containing a whole model state dict + - a path to a `.json` file containing the index to a sharded checkpoint + - a path to a folder containing a unique `.index.json` file and the shards of a checkpoint. + - a path to a folder containing a unique pytorch_model.bin or a model.safetensors file. + device_map (`Dict[str, Union[int, str, torch.device]]`, *optional*): + A map that specifies where each submodule should go. It doesn't need to be refined to each parameter/buffer + name, once a given module name is inside, every submodule of it will be sent to the same device. + offload_folder (`str` or `os.PathLike`, *optional*): + If the `device_map` contains any value `"disk"`, the folder where we will offload weights. + dtype (`str` or `torch.dtype`, *optional*): + If provided, the weights will be converted to that type when loaded. + offload_state_dict (`bool`, *optional*, defaults to `False`): + If `True`, will temporarily offload the CPU state dict on the hard drive to avoid getting out of CPU RAM if + the weight of the CPU state dict + the biggest shard does not fit. + offload_buffers (`bool`, *optional*, defaults to `False`): + Whether or not to include the buffers in the weights offloaded to disk. + keep_in_fp32_modules(`List[str]`, *optional*): + A list of the modules that we keep in `torch.float32` dtype. + offload_8bit_bnb (`bool`, *optional*): + Whether or not to enable offload of 8-bit modules on cpu/disk. + strict (`bool`, *optional*, defaults to `False`): + Whether to strictly enforce that the keys in the checkpoint state_dict match the keys of the model's + state_dict. + full_state_dict (`bool`, *optional*, defaults to `True`): if this is set to `True`, all the tensors in the + loaded state_dict will be gathered. No ShardedTensor and DTensor will be in the loaded state_dict. + broadcast_from_rank0 (`False`, *optional*, defaults to `False`): when the option is `True`, a distributed + `ProcessGroup` must be initialized. rank0 should receive a full state_dict and will broadcast the tensors + in the state_dict one by one to other ranks. Other ranks will receive the tensors and shard (if applicable) + according to the local shards in the model. + + """ + if offload_8bit_bnb: + from .bnb import quantize_and_offload_8bit + + tied_params = find_tied_parameters(model) + + if check_tied_parameters_in_config(model) and len(tied_params) == 0: + logger.warning( + "The model weights are not tied. Please use the `tie_weights` method before using the `infer_auto_device` function." + ) + if device_map is not None: + check_tied_parameters_on_same_device(tied_params, device_map) + + if offload_folder is None and device_map is not None and "disk" in device_map.values(): + raise ValueError( + "At least one of the model submodule will be offloaded to disk, please pass along an `offload_folder`." + ) + elif offload_folder is not None and device_map is not None and "disk" in device_map.values(): + os.makedirs(offload_folder, exist_ok=True) + + if isinstance(dtype, str): + # We accept "torch.float16" or just "float16" + dtype = dtype.replace("torch.", "") + dtype = getattr(torch, dtype) + + checkpoint_files = None + index_filename = None + if os.path.isfile(checkpoint): + if str(checkpoint).endswith(".json"): + index_filename = checkpoint + else: + checkpoint_files = [checkpoint] + elif os.path.isdir(checkpoint): + # check if the whole state dict is present + potential_state_bin = [f for f in os.listdir(checkpoint) if f == WEIGHTS_NAME] + potential_state_safetensor = [f for f in os.listdir(checkpoint) if f == SAFE_WEIGHTS_NAME] + if len(potential_state_bin) == 1: + checkpoint_files = [os.path.join(checkpoint, potential_state_bin[0])] + elif len(potential_state_safetensor) == 1: + checkpoint_files = [os.path.join(checkpoint, potential_state_safetensor[0])] + else: + # otherwise check for sharded checkpoints + potential_index = [f for f in os.listdir(checkpoint) if f.endswith(".index.json")] + if len(potential_index) == 0: + raise ValueError( + f"{checkpoint} is not a folder containing a `.index.json` file or a {WEIGHTS_NAME} or a {SAFE_WEIGHTS_NAME} file" + ) + elif len(potential_index) == 1: + index_filename = os.path.join(checkpoint, potential_index[0]) + else: + raise ValueError( + f"{checkpoint} containing more than one `.index.json` file, delete the irrelevant ones." + ) + else: + raise ValueError( + "`checkpoint` should be the path to a file containing a whole state dict, or the index of a sharded " + f"checkpoint, or a folder containing a sharded checkpoint or the whole state dict, but got {checkpoint}." + ) + + if index_filename is not None: + checkpoint_folder = os.path.split(index_filename)[0] + with open(index_filename) as f: + index = json.loads(f.read()) + + if "weight_map" in index: + index = index["weight_map"] + checkpoint_files = sorted(list(set(index.values()))) + checkpoint_files = [os.path.join(checkpoint_folder, f) for f in checkpoint_files] + + # Logic for missing/unexepected keys goes here. + + offload_index = {} + if offload_state_dict: + state_dict_folder = tempfile.mkdtemp() + state_dict_index = {} + + unexpected_keys = set() + model_keys = set(model.state_dict().keys()) + buffer_names = [name for name, _ in model.named_buffers()] + model_devices = {t.device for t in model.state_dict().values() if isinstance(t, torch.Tensor)} + model_physical_devices = model_devices - {torch.device("meta")} + for checkpoint_file in checkpoint_files: + if device_map is None: + # exception for multi-device loading was made for the meta device in torch v2.7.0 + # https://github.com/pytorch/pytorch/blob/v2.6.0/torch/distributed/checkpoint/state_dict.py#L557-L563 + # https://github.com/pytorch/pytorch/blob/v2.7.0-rc2/torch/distributed/checkpoint/state_dict.py#L575-L587 + if is_torch_version(">=", "2.2.0") and ( + (is_torch_version(">=", "2.7.0") and len(model_physical_devices) <= 1) or len(model_devices) <= 1 + ): + from torch.distributed.checkpoint.state_dict import StateDictOptions, set_model_state_dict + + broadcast_from_rank0 &= is_torch_version(">=", "2.4.0") + loaded_checkpoint = ( + load_state_dict(checkpoint_file, device_map=device_map) + if not broadcast_from_rank0 or dist.get_rank() == 0 + else {} + ) + set_model_state_dict( + model, + loaded_checkpoint, + options=StateDictOptions( + full_state_dict=full_state_dict, + strict=strict, + **({"broadcast_from_rank0": broadcast_from_rank0} if is_torch_version(">=", "2.4.0") else {}), + ), + ) + else: + loaded_checkpoint = load_state_dict(checkpoint_file, device_map=device_map) + model.load_state_dict(loaded_checkpoint, strict=strict) + + unexpected_keys.update(set(loaded_checkpoint.keys()) - model_keys) + else: + loaded_checkpoint = load_state_dict(checkpoint_file, device_map=device_map) + + for param_name, param in loaded_checkpoint.items(): + # skip SCB parameter (for 8-bit serialization) + if "SCB" in param_name: + continue + + if param_name not in model_keys: + unexpected_keys.add(param_name) + if not strict: + continue # Skip loading this parameter. + + module_name = param_name + + while len(module_name) > 0 and module_name not in device_map: + module_name = ".".join(module_name.split(".")[:-1]) + if module_name == "" and "" not in device_map: + # TODO: group all errors and raise at the end. + raise ValueError(f"{param_name} doesn't have any device set.") + param_device = device_map[module_name] + new_dtype = dtype + if dtype is not None and torch.is_floating_point(param): + if keep_in_fp32_modules is not None and dtype == torch.float16: + proceed = False + for key in keep_in_fp32_modules: + if ((key in param_name) and (key + "." in param_name)) or key == param_name: + proceed = True + break + if proceed: + new_dtype = torch.float32 + + if "weight" in param_name and param_name.replace("weight", "SCB") in loaded_checkpoint.keys(): + if param.dtype == torch.int8: + fp16_statistics = loaded_checkpoint[param_name.replace("weight", "SCB")] + else: + fp16_statistics = None + + if param_device == "disk": + if offload_buffers or param_name not in buffer_names: + if new_dtype is None: + new_dtype = param.dtype + if offload_8bit_bnb: + quantize_and_offload_8bit( + model, param, param_name, new_dtype, offload_folder, offload_index, fp16_statistics + ) + continue + else: + set_module_tensor_to_device(model, param_name, "meta", dtype=new_dtype) + offload_weight(param, param_name, offload_folder, index=offload_index) + elif param_device == "cpu" and offload_state_dict: + if new_dtype is None: + new_dtype = param.dtype + if offload_8bit_bnb: + quantize_and_offload_8bit( + model, param, param_name, new_dtype, state_dict_folder, state_dict_index, fp16_statistics + ) + else: + set_module_tensor_to_device(model, param_name, "meta", dtype=new_dtype) + offload_weight(param, param_name, state_dict_folder, index=state_dict_index) + else: + set_module_tensor_to_device( + model, + param_name, + param_device, + value=param, + dtype=new_dtype, + fp16_statistics=fp16_statistics, + ) + + # Force Python to clean up. + del loaded_checkpoint + gc.collect() + + if not strict and len(unexpected_keys) > 0: + logger.warning( + f"Some weights of the model checkpoint at {checkpoint} were not used when" + f" initializing {model.__class__.__name__}: {unexpected_keys}. This may or may not be an issue - make sure that the checkpoint does not have unnecessary parameters, or that the model definition correctly corresponds to the checkpoint." + ) + + save_offload_index(offload_index, offload_folder) + + # Load back offloaded state dict on CPU + if offload_state_dict: + load_offloaded_weights(model, state_dict_index, state_dict_folder) + shutil.rmtree(state_dict_folder) + + retie_parameters(model, tied_params) + + +def get_mixed_precision_context_manager(native_amp: bool = False, autocast_kwargs: AutocastKwargs = None): + """ + Return a context manager for autocasting mixed precision + + Args: + native_amp (`bool`, *optional*, defaults to False): + Whether mixed precision is actually enabled. + cache_enabled (`bool`, *optional*, defaults to True): + Whether the weight cache inside autocast should be enabled. + """ + state = AcceleratorState() + if autocast_kwargs is None: + autocast_kwargs = {} + else: + autocast_kwargs = autocast_kwargs.to_kwargs() + if native_amp: + device_type = ( + "cuda" + if (state.distributed_type == DistributedType.XLA and is_torch_xla_available(check_is_gpu=True)) + else state.device.type + ) + if state.mixed_precision == "fp16": + return torch.autocast(device_type=device_type, dtype=torch.float16, **autocast_kwargs) + elif state.mixed_precision in ["bf16", "fp8"] and state.distributed_type in [ + DistributedType.NO, + DistributedType.MULTI_CPU, + DistributedType.MULTI_GPU, + DistributedType.MULTI_MLU, + DistributedType.MULTI_SDAA, + DistributedType.MULTI_MUSA, + DistributedType.MULTI_NPU, + DistributedType.MULTI_XPU, + DistributedType.MULTI_HPU, + DistributedType.FSDP, + DistributedType.XLA, + ]: + return torch.autocast(device_type=device_type, dtype=torch.bfloat16, **autocast_kwargs) + else: + return torch.autocast(device_type=device_type, **autocast_kwargs) + else: + return contextlib.nullcontext() + + +def get_grad_scaler(distributed_type: DistributedType = None, **kwargs): + """ + A generic helper which will initialize the correct `GradScaler` implementation based on the environment and return + it. + + Args: + distributed_type (`DistributedType`, *optional*, defaults to None): + The type of distributed environment. + kwargs: + Additional arguments for the utilized `GradScaler` constructor. + """ + if distributed_type == DistributedType.FSDP: + from torch.distributed.fsdp.sharded_grad_scaler import ShardedGradScaler + + return ShardedGradScaler(**kwargs) + if is_torch_xla_available(check_is_gpu=True): + import torch_xla.amp as xamp + + return xamp.GradScaler(**kwargs) + elif is_mlu_available(): + return torch.mlu.amp.GradScaler(**kwargs) + elif is_sdaa_available(): + return torch.sdaa.amp.GradScaler(**kwargs) + elif is_musa_available(): + return torch.musa.amp.GradScaler(**kwargs) + elif is_npu_available(): + return torch.npu.amp.GradScaler(**kwargs) + elif is_hpu_available(): + return torch.amp.GradScaler("hpu", **kwargs) + elif is_xpu_available(): + return torch.amp.GradScaler("xpu", **kwargs) + elif is_mps_available(): + if not is_torch_version(">=", "2.8.0"): + raise ValueError("Grad Scaler with MPS device requires a Pytorch >= 2.8.0") + return torch.amp.GradScaler("mps", **kwargs) + else: + if is_torch_version(">=", "2.3"): + return torch.amp.GradScaler("cuda", **kwargs) + else: + return torch.cuda.amp.GradScaler(**kwargs) + + +def has_offloaded_params(module: torch.nn.Module) -> bool: + """ + Checks if a module has offloaded parameters by checking if the given module has a AlignDevicesHook attached with + offloading enabled + + Args: + module (`torch.nn.Module`): The module to check for an offload hook. + + Returns: + bool: `True` if the module has an offload hook and offloading is enabled, `False` otherwise. + """ + from ..hooks import AlignDevicesHook # avoid circular import + + return hasattr(module, "_hf_hook") and isinstance(module._hf_hook, AlignDevicesHook) and module._hf_hook.offload + + +@contextlib.contextmanager +def align_module_device(module: torch.nn.Module, execution_device: Optional[torch.device] = None): + """ + Context manager that moves a module's parameters to the specified execution device. + + Args: + module (`torch.nn.Module`): + Module with parameters to align. + execution_device (`torch.device`, *optional*): + If provided, overrides the module's execution device within the context. Otherwise, use hook execution + device or pass + """ + if has_offloaded_params(module): + if execution_device is not None: + original_device = module._hf_hook.execution_device + module._hf_hook.execution_device = execution_device + + try: + module._hf_hook.pre_forward(module) + yield + finally: + module._hf_hook.post_forward(module, None) + if execution_device is not None: + module._hf_hook.execution_device = original_device + + elif execution_device is not None: + devices = {name: param.device for name, param in module.named_parameters(recurse=False)} + try: + for name in devices: + set_module_tensor_to_device(module, name, execution_device) + yield + finally: + for name, device in devices.items(): + set_module_tensor_to_device(module, name, device) + + else: + yield diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/offload.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/offload.py new file mode 100644 index 0000000000000000000000000000000000000000..da8cfaf3ebf7f2965f408e2b952103ac26868647 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/offload.py @@ -0,0 +1,213 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +from collections.abc import Mapping +from typing import Optional, Union + +import numpy as np +import torch +from safetensors import safe_open + + +def offload_weight(weight, weight_name, offload_folder, index=None): + dtype = None + # Check the string instead of the dtype to be compatible with versions of PyTorch that don't have bfloat16. + if str(weight.dtype) == "torch.bfloat16": + # Need to reinterpret the underlined data as int16 since NumPy does not handle bfloat16s. + weight = weight.view(torch.int16) + dtype = "bfloat16" + array = weight.cpu().numpy() + tensor_file = os.path.join(offload_folder, f"{weight_name}.dat") + if index is not None: + if dtype is None: + dtype = str(array.dtype) + index[weight_name] = {"dtype": dtype, "shape": list(array.shape)} + if array.ndim == 0: + array = array[None] + file_array = np.memmap(tensor_file, dtype=array.dtype, mode="w+", shape=array.shape) + file_array[:] = array[:] + file_array.flush() + return index + + +def load_offloaded_weight(weight_file, weight_info): + shape = tuple(weight_info["shape"]) + if shape == (): + # NumPy memory-mapped arrays can't have 0 dims so it was saved as 1d tensor + shape = (1,) + + dtype = weight_info["dtype"] + if dtype == "bfloat16": + # NumPy does not support bfloat16 so this was saved as a int16 + dtype = "int16" + + weight = np.memmap(weight_file, dtype=dtype, shape=shape, mode="r") + + if len(weight_info["shape"]) == 0: + weight = weight[0] + weight = torch.tensor(weight) + if weight_info["dtype"] == "bfloat16": + weight = weight.view(torch.bfloat16) + + return weight + + +def save_offload_index(index, offload_folder): + if index is None or len(index) == 0: + # Nothing to save + return + + offload_index_file = os.path.join(offload_folder, "index.json") + if os.path.isfile(offload_index_file): + with open(offload_index_file, encoding="utf-8") as f: + current_index = json.load(f) + else: + current_index = {} + current_index.update(index) + + with open(offload_index_file, "w", encoding="utf-8") as f: + json.dump(current_index, f, indent=2) + + +def offload_state_dict(save_dir: Union[str, os.PathLike], state_dict: dict[str, torch.Tensor]): + """ + Offload a state dict in a given folder. + + Args: + save_dir (`str` or `os.PathLike`): + The directory in which to offload the state dict. + state_dict (`Dict[str, torch.Tensor]`): + The dictionary of tensors to offload. + """ + os.makedirs(save_dir, exist_ok=True) + index = {} + for name, parameter in state_dict.items(): + index = offload_weight(parameter, name, save_dir, index=index) + + # Update index + save_offload_index(index, save_dir) + + +class PrefixedDataset(Mapping): + """ + Will access keys in a given dataset by adding a prefix. + + Args: + dataset (`Mapping`): Any map with string keys. + prefix (`str`): A prefix to add when trying to access any element in the underlying dataset. + """ + + def __init__(self, dataset: Mapping, prefix: str): + self.dataset = dataset + self.prefix = prefix + + def __getitem__(self, key): + return self.dataset[f"{self.prefix}{key}"] + + def __iter__(self): + return iter([key for key in self.dataset if key.startswith(self.prefix)]) + + def __len__(self): + return len(self.dataset) + + +class OffloadedWeightsLoader(Mapping): + """ + A collection that loads weights stored in a given state dict or memory-mapped on disk. + + Args: + state_dict (`Dict[str, torch.Tensor]`, *optional*): + A dictionary parameter name to tensor. + save_folder (`str` or `os.PathLike`, *optional*): + The directory in which the weights are stored (by `offload_state_dict` for instance). + index (`Dict`, *optional*): + A dictionary from weight name to their information (`dtype`/ `shape` or safetensors filename). Will default + to the index saved in `save_folder`. + """ + + def __init__( + self, + state_dict: Optional[dict[str, torch.Tensor]] = None, + save_folder: Optional[Union[str, os.PathLike]] = None, + index: Optional[Mapping] = None, + device=None, + ): + if state_dict is None and save_folder is None and index is None: + raise ValueError("Need either a `state_dict`, a `save_folder` or an `index` containing offloaded weights.") + + self.state_dict = {} if state_dict is None else state_dict + self.save_folder = save_folder + if index is None and save_folder is not None: + with open(os.path.join(save_folder, "index.json")) as f: + index = json.load(f) + self.index = {} if index is None else index + self.all_keys = list(self.state_dict.keys()) + self.all_keys.extend([key for key in self.index if key not in self.all_keys]) + self.device = device + + def __getitem__(self, key: str): + # State dict gets priority + if key in self.state_dict: + return self.state_dict[key] + weight_info = self.index[key] + if weight_info.get("safetensors_file") is not None: + device = "cpu" if self.device is None else self.device + tensor = None + try: + with safe_open(weight_info["safetensors_file"], framework="pt", device=device) as f: + tensor = f.get_tensor(weight_info.get("weight_name", key)) + except TypeError: + # if failed to get_tensor on the device, such as bf16 on mps, try to load it on CPU first + with safe_open(weight_info["safetensors_file"], framework="pt", device="cpu") as f: + tensor = f.get_tensor(weight_info.get("weight_name", key)) + + if "dtype" in weight_info: + tensor = tensor.to(getattr(torch, weight_info["dtype"])) + + if tensor.device != torch.device(device): + tensor = tensor.to(device) + return tensor + + weight_file = os.path.join(self.save_folder, f"{key}.dat") + return load_offloaded_weight(weight_file, weight_info) + + def __iter__(self): + return iter(self.all_keys) + + def __len__(self): + return len(self.all_keys) + + +def extract_submodules_state_dict(state_dict: dict[str, torch.Tensor], submodule_names: list[str]): + """ + Extract the sub state-dict corresponding to a list of given submodules. + + Args: + state_dict (`Dict[str, torch.Tensor]`): The state dict to extract from. + submodule_names (`List[str]`): The list of submodule names we want to extract. + """ + result = {} + for module_name in submodule_names: + # We want to catch module_name parameter (module_name.xxx) or potentially module_name, but not any of the + # submodules that could being like module_name (transformers.h.1 and transformers.h.10 for instance) + result.update( + { + key: param + for key, param in state_dict.items() + if key == module_name or key.startswith(module_name + ".") + } + ) + return result diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/operations.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/operations.py new file mode 100644 index 0000000000000000000000000000000000000000..2357fdf03ba533714bf517e67269b3be36a78e39 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/operations.py @@ -0,0 +1,867 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +A set of basic tensor ops compatible with tpu, gpu, and multigpu +""" + +import pickle +import warnings +from collections.abc import Mapping +from contextlib import contextmanager, nullcontext +from functools import update_wrapper, wraps +from typing import Any + +import torch + +from ..state import AcceleratorState, PartialState +from .constants import TORCH_DISTRIBUTED_OPERATION_TYPES +from .dataclasses import DistributedType, TensorInformation +from .imports import ( + is_npu_available, + is_torch_distributed_available, + is_torch_xla_available, +) +from .versions import is_torch_version + + +if is_torch_xla_available(): + import torch_xla.core.xla_model as xm + +if is_torch_distributed_available(): + from torch.distributed import ReduceOp + + +def is_torch_tensor(tensor): + return isinstance(tensor, torch.Tensor) + + +def is_torch_xpu_tensor(tensor): + return isinstance( + tensor, + torch.xpu.FloatTensor, + torch.xpu.ByteTensor, + torch.xpu.IntTensor, + torch.xpu.LongTensor, + torch.xpu.HalfTensor, + torch.xpu.DoubleTensor, + torch.xpu.BFloat16Tensor, + ) + + +def is_tensor_information(tensor_info): + return isinstance(tensor_info, TensorInformation) + + +def is_namedtuple(data): + """ + Checks if `data` is a `namedtuple` or not. Can have false positives, but only if a user is trying to mimic a + `namedtuple` perfectly. + """ + return isinstance(data, tuple) and hasattr(data, "_asdict") and hasattr(data, "_fields") + + +def honor_type(obj, generator): + """ + Cast a generator to the same type as obj (list, tuple, or namedtuple) + """ + # Some objects may not be able to instantiate from a generator directly + if is_namedtuple(obj): + return type(obj)(*list(generator)) + else: + return type(obj)(generator) + + +def recursively_apply(func, data, *args, test_type=is_torch_tensor, error_on_other_type=False, **kwargs): + """ + Recursively apply a function on a data structure that is a nested list/tuple/dictionary of a given base type. + + Args: + func (`callable`): + The function to recursively apply. + data (nested list/tuple/dictionary of `main_type`): + The data on which to apply `func` + *args: + Positional arguments that will be passed to `func` when applied on the unpacked data. + main_type (`type`, *optional*, defaults to `torch.Tensor`): + The base type of the objects to which apply `func`. + error_on_other_type (`bool`, *optional*, defaults to `False`): + Whether to return an error or not if after unpacking `data`, we get on an object that is not of type + `main_type`. If `False`, the function will leave objects of types different than `main_type` unchanged. + **kwargs (additional keyword arguments, *optional*): + Keyword arguments that will be passed to `func` when applied on the unpacked data. + + Returns: + The same data structure as `data` with `func` applied to every object of type `main_type`. + """ + if isinstance(data, (tuple, list)): + return honor_type( + data, + ( + recursively_apply( + func, o, *args, test_type=test_type, error_on_other_type=error_on_other_type, **kwargs + ) + for o in data + ), + ) + elif isinstance(data, Mapping): + return type(data)( + { + k: recursively_apply( + func, v, *args, test_type=test_type, error_on_other_type=error_on_other_type, **kwargs + ) + for k, v in data.items() + } + ) + elif test_type(data): + return func(data, *args, **kwargs) + elif error_on_other_type: + raise TypeError( + f"Unsupported types ({type(data)}) passed to `{func.__name__}`. Only nested list/tuple/dicts of " + f"objects that are valid for `{test_type.__name__}` should be passed." + ) + return data + + +def send_to_device(tensor, device, non_blocking=False, skip_keys=None): + """ + Recursively sends the elements in a nested list/tuple/dictionary of tensors to a given device. + + Args: + tensor (nested list/tuple/dictionary of `torch.Tensor`): + The data to send to a given device. + device (`torch.device`): + The device to send the data to. + + Returns: + The same data structure as `tensor` with all tensors sent to the proper device. + """ + if is_torch_tensor(tensor) or hasattr(tensor, "to"): + # `torch.Tensor.to("npu")` could not find context when called for the first time (see this [issue](https://gitee.com/ascend/pytorch/issues/I8KECW?from=project-issue)). + if device == "npu": + device = "npu:0" + try: + return tensor.to(device, non_blocking=non_blocking) + except TypeError: # .to() doesn't accept non_blocking as kwarg + return tensor.to(device) + except AssertionError as error: + # `torch.Tensor.to()` is not supported by `torch_npu` (see this [issue](https://github.com/Ascend/pytorch/issues/16)). + # This call is inside the try-block since is_npu_available is not supported by torch.compile. + if is_npu_available(): + if isinstance(device, int): + device = f"npu:{device}" + else: + raise error + try: + return tensor.to(device, non_blocking=non_blocking) + except TypeError: # .to() doesn't accept non_blocking as kwarg + return tensor.to(device) + elif isinstance(tensor, (tuple, list)): + return honor_type( + tensor, (send_to_device(t, device, non_blocking=non_blocking, skip_keys=skip_keys) for t in tensor) + ) + elif isinstance(tensor, Mapping): + if isinstance(skip_keys, str): + skip_keys = [skip_keys] + elif skip_keys is None: + skip_keys = [] + return type(tensor)( + { + k: t if k in skip_keys else send_to_device(t, device, non_blocking=non_blocking, skip_keys=skip_keys) + for k, t in tensor.items() + } + ) + else: + return tensor + + +def get_data_structure(data): + """ + Recursively gathers the information needed to rebuild a nested list/tuple/dictionary of tensors. + + Args: + data (nested list/tuple/dictionary of `torch.Tensor`): + The data to send to analyze. + + Returns: + The same data structure as `data` with [`~utils.TensorInformation`] instead of tensors. + """ + + def _get_data_structure(tensor): + return TensorInformation(shape=tensor.shape, dtype=tensor.dtype) + + return recursively_apply(_get_data_structure, data) + + +def get_shape(data): + """ + Recursively gathers the shape of a nested list/tuple/dictionary of tensors as a list. + + Args: + data (nested list/tuple/dictionary of `torch.Tensor`): + The data to send to analyze. + + Returns: + The same data structure as `data` with lists of tensor shapes instead of tensors. + """ + + def _get_shape(tensor): + return list(tensor.shape) + + return recursively_apply(_get_shape, data) + + +def initialize_tensors(data_structure): + """ + Recursively initializes tensors from a nested list/tuple/dictionary of [`~utils.TensorInformation`]. + + Returns: + The same data structure as `data` with tensors instead of [`~utils.TensorInformation`]. + """ + + def _initialize_tensor(tensor_info): + return torch.empty(*tensor_info.shape, dtype=tensor_info.dtype) + + return recursively_apply(_initialize_tensor, data_structure, test_type=is_tensor_information) + + +def find_batch_size(data): + """ + Recursively finds the batch size in a nested list/tuple/dictionary of lists of tensors. + + Args: + data (nested list/tuple/dictionary of `torch.Tensor`): The data from which to find the batch size. + + Returns: + `int`: The batch size. + """ + if isinstance(data, (tuple, list, Mapping)) and (len(data) == 0): + raise ValueError(f"Cannot find the batch size from empty {type(data)}.") + + if isinstance(data, (tuple, list)): + return find_batch_size(data[0]) + elif isinstance(data, Mapping): + for k in data.keys(): + return find_batch_size(data[k]) + elif not isinstance(data, torch.Tensor): + raise TypeError(f"Can only find the batch size of tensors but got {type(data)}.") + return data.shape[0] + + +def ignorant_find_batch_size(data): + """ + Same as [`utils.operations.find_batch_size`] except will ignore if `ValueError` and `TypeErrors` are raised + + Args: + data (nested list/tuple/dictionary of `torch.Tensor`): The data from which to find the batch size. + + Returns: + `int`: The batch size. + """ + try: + return find_batch_size(data) + except (ValueError, TypeError): + pass + return None + + +def listify(data): + """ + Recursively finds tensors in a nested list/tuple/dictionary and converts them to a list of numbers. + + Args: + data (nested list/tuple/dictionary of `torch.Tensor`): The data from which to convert to regular numbers. + + Returns: + The same data structure as `data` with lists of numbers instead of `torch.Tensor`. + """ + + def _convert_to_list(tensor): + tensor = tensor.detach().cpu() + if tensor.dtype == torch.bfloat16: + # As of Numpy 1.21.4, NumPy does not support bfloat16 (see + # https://github.com/numpy/numpy/blob/a47ecdea856986cd60eabbd53265c2ca5916ad5d/doc/source/user/basics.types.rst ). + # Until Numpy adds bfloat16, we must convert float32. + tensor = tensor.to(torch.float32) + return tensor.tolist() + + return recursively_apply(_convert_to_list, data) + + +def _tpu_gather(tensor): + def _tpu_gather_one(tensor): + if tensor.ndim == 0: + tensor = tensor.clone()[None] + + # Can only gather contiguous tensors + if not tensor.is_contiguous(): + tensor = tensor.contiguous() + return xm.all_gather(tensor) + + res = recursively_apply(_tpu_gather_one, tensor, error_on_other_type=True) + xm.mark_step() + return res + + +def _gpu_gather(tensor): + state = PartialState() + gather_op = torch.distributed.all_gather_into_tensor + + # NOTE: need manually synchronize to workaourd a INT64 collectives bug in oneCCL before torch 2.9.0 + if state.device.type == "xpu" and is_torch_version("<=", "2.8"): + torch.xpu.synchronize() + + def _gpu_gather_one(tensor): + if tensor.ndim == 0: + tensor = tensor.clone()[None] + + # Can only gather contiguous tensors + if not tensor.is_contiguous(): + tensor = tensor.contiguous() + + if state.backend is not None and state.backend != "gloo": + # We use `empty` as `all_gather_into_tensor` slightly + # differs from `all_gather` for better efficiency, + # and we rely on the number of items in the tensor + # rather than its direct shape + output_tensors = torch.empty( + state.num_processes * tensor.numel(), + dtype=tensor.dtype, + device=state.device, + ) + gather_op(output_tensors, tensor) + return output_tensors.view(-1, *tensor.size()[1:]) + else: + # a backend of `None` is always CPU + # also gloo does not support `all_gather_into_tensor`, + # which will result in a larger memory overhead for the op + output_tensors = [torch.empty_like(tensor) for _ in range(state.num_processes)] + torch.distributed.all_gather(output_tensors, tensor) + return torch.cat(output_tensors, dim=0) + + return recursively_apply(_gpu_gather_one, tensor, error_on_other_type=True) + + +class DistributedOperationException(Exception): + """ + An exception class for distributed operations. Raised if the operation cannot be performed due to the shape of the + tensors. + """ + + pass + + +def verify_operation(function): + """ + Verifies that `tensor` is the same shape across all processes. Only ran if `PartialState().debug` is `True`. + """ + + @wraps(function) + def wrapper(*args, **kwargs): + if PartialState().distributed_type == DistributedType.NO or not PartialState().debug: + return function(*args, **kwargs) + operation = f"{function.__module__}.{function.__name__}" + if "tensor" in kwargs: + tensor = kwargs["tensor"] + else: + tensor = args[0] + if PartialState().device.type != find_device(tensor).type: + raise DistributedOperationException( + f"One or more of the tensors passed to {operation} were not on the {tensor.device.type} while the `Accelerator` is configured for {PartialState().device.type}. " + f"Please move it to the {PartialState().device.type} before calling {operation}." + ) + shapes = get_shape(tensor) + output = gather_object([shapes]) + if output[0] is not None: + are_same = output.count(output[0]) == len(output) + if not are_same: + process_shape_str = "\n - ".join([f"Process {i}: {shape}" for i, shape in enumerate(output)]) + raise DistributedOperationException( + f"Cannot apply desired operation due to shape mismatches. " + "All shapes across devices must be valid." + f"\n\nOperation: `{operation}`\nInput shapes:\n - {process_shape_str}" + ) + return function(*args, **kwargs) + + return wrapper + + +def chained_operation(function): + """ + Checks that `verify_operation` failed and if so reports a more helpful error chaining the existing + `DistributedOperationException`. + """ + + @wraps(function) + def wrapper(*args, **kwargs): + try: + return function(*args, **kwargs) + except DistributedOperationException as e: + operation = f"{function.__module__}.{function.__name__}" + raise DistributedOperationException( + f"Error found while calling `{operation}`. Please see the earlier error for more details." + ) from e + + return wrapper + + +@verify_operation +def gather(tensor): + """ + Recursively gather tensor in a nested list/tuple/dictionary of tensors from all devices. + + Args: + tensor (nested list/tuple/dictionary of `torch.Tensor`): + The data to gather. + + Returns: + The same data structure as `tensor` with all tensors sent to the proper device. + """ + if PartialState().distributed_type == DistributedType.XLA: + return _tpu_gather(tensor) + elif PartialState().distributed_type in TORCH_DISTRIBUTED_OPERATION_TYPES: + return _gpu_gather(tensor) + else: + return tensor + + +def _gpu_gather_object(object: Any): + output_objects = [None for _ in range(PartialState().num_processes)] + torch.distributed.all_gather_object(output_objects, object) + # all_gather_object returns a list of lists, so we need to flatten it + return [x for y in output_objects for x in y] + + +def gather_object(object: Any): + """ + Recursively gather object in a nested list/tuple/dictionary of objects from all devices. + + Args: + object (nested list/tuple/dictionary of picklable object): + The data to gather. + + Returns: + The same data structure as `object` with all the objects sent to every device. + """ + if PartialState().distributed_type == DistributedType.XLA: + raise NotImplementedError("gather objects in TPU is not supported") + elif PartialState().distributed_type in TORCH_DISTRIBUTED_OPERATION_TYPES: + return _gpu_gather_object(object) + else: + return object + + +def _gpu_broadcast(data, src=0): + def _gpu_broadcast_one(tensor, src=0): + torch.distributed.broadcast(tensor, src=src) + return tensor + + return recursively_apply(_gpu_broadcast_one, data, error_on_other_type=True, src=src) + + +def _tpu_broadcast(tensor, src=0, name="broadcast tensor"): + if isinstance(tensor, (list, tuple)): + return honor_type(tensor, (_tpu_broadcast(t, name=f"{name}_{i}") for i, t in enumerate(tensor))) + elif isinstance(tensor, Mapping): + return type(tensor)({k: _tpu_broadcast(v, name=f"{name}_{k}") for k, v in tensor.items()}) + return xm.mesh_reduce(name, tensor, lambda x: x[src]) + + +TENSOR_TYPE_TO_INT = { + torch.float: 1, + torch.double: 2, + torch.half: 3, + torch.bfloat16: 4, + torch.uint8: 5, + torch.int8: 6, + torch.int16: 7, + torch.int32: 8, + torch.int64: 9, + torch.bool: 10, +} + +TENSOR_INT_TO_DTYPE = {v: k for k, v in TENSOR_TYPE_TO_INT.items()} + + +def gather_tensor_shape(tensor): + """ + Grabs the shape of `tensor` only available on one process and returns a tensor of its shape + """ + # Allocate 80 bytes to store the shape + max_tensor_dimension = 2**20 + state = PartialState() + base_tensor = torch.empty(max_tensor_dimension, dtype=torch.int, device=state.device) + + # Since PyTorch can't just send a tensor to another GPU without + # knowing its size, we store the size of the tensor with data + # in an allocation + if tensor is not None: + shape = tensor.shape + tensor_dtype = TENSOR_TYPE_TO_INT[tensor.dtype] + base_tensor[: len(shape) + 1] = torch.tensor(list(shape) + [tensor_dtype], dtype=int) + # Perform a reduction to copy the size data onto all GPUs + base_tensor = reduce(base_tensor, reduction="sum") + base_tensor = base_tensor[base_tensor.nonzero()] + # The last non-zero data contains the coded dtype the source tensor is + dtype = int(base_tensor[-1:][0]) + base_tensor = base_tensor[:-1] + return base_tensor, dtype + + +def copy_tensor_to_devices(tensor=None) -> torch.Tensor: + """ + Copies a tensor that only exists on a single device and broadcasts it to other devices. Differs from `broadcast` as + each worker doesn't need to know its shape when used (and tensor can be `None`) + + Args: + tensor (`torch.tensor`): + The tensor that should be sent to all devices. Must only have it be defined on a single device, the rest + should be `None`. + """ + state = PartialState() + shape, dtype = gather_tensor_shape(tensor) + if tensor is None: + tensor = torch.zeros(shape, dtype=TENSOR_INT_TO_DTYPE[dtype]).to(state.device) + return reduce(tensor, reduction="sum") + + +@verify_operation +def broadcast(tensor, from_process: int = 0): + """ + Recursively broadcast tensor in a nested list/tuple/dictionary of tensors to all devices. + + Args: + tensor (nested list/tuple/dictionary of `torch.Tensor`): + The data to gather. + from_process (`int`, *optional*, defaults to 0): + The process from which to send the data + + Returns: + The same data structure as `tensor` with all tensors broadcasted to the proper device. + """ + if PartialState().distributed_type == DistributedType.XLA: + return _tpu_broadcast(tensor, src=from_process, name="accelerate.utils.broadcast") + elif PartialState().distributed_type in TORCH_DISTRIBUTED_OPERATION_TYPES: + return _gpu_broadcast(tensor, src=from_process) + else: + return tensor + + +def broadcast_object_list(object_list, from_process: int = 0): + """ + Broadcast a list of picklable objects from one process to the others. + + Args: + object_list (list of picklable objects): + The list of objects to broadcast. This list will be modified inplace. + from_process (`int`, *optional*, defaults to 0): + The process from which to send the data. + + Returns: + The same list containing the objects from process 0. + """ + if PartialState().distributed_type == DistributedType.XLA: + for i, obj in enumerate(object_list): + object_list[i] = xm.mesh_reduce("accelerate.utils.broadcast_object_list", obj, lambda x: x[from_process]) + elif PartialState().distributed_type in TORCH_DISTRIBUTED_OPERATION_TYPES: + torch.distributed.broadcast_object_list(object_list, src=from_process) + return object_list + + +def slice_tensors(data, tensor_slice, process_index=None, num_processes=None): + """ + Recursively takes a slice in a nested list/tuple/dictionary of tensors. + + Args: + data (nested list/tuple/dictionary of `torch.Tensor`): + The data to slice. + tensor_slice (`slice`): + The slice to take. + + Returns: + The same data structure as `data` with all the tensors slices. + """ + + def _slice_tensor(tensor, tensor_slice): + return tensor[tensor_slice] + + return recursively_apply(_slice_tensor, data, tensor_slice) + + +def concatenate(data, dim=0): + """ + Recursively concatenate the tensors in a nested list/tuple/dictionary of lists of tensors with the same shape. + + Args: + data (nested list/tuple/dictionary of lists of tensors `torch.Tensor`): + The data to concatenate. + dim (`int`, *optional*, defaults to 0): + The dimension on which to concatenate. + + Returns: + The same data structure as `data` with all the tensors concatenated. + """ + if isinstance(data[0], (tuple, list)): + return honor_type(data[0], (concatenate([d[i] for d in data], dim=dim) for i in range(len(data[0])))) + elif isinstance(data[0], Mapping): + return type(data[0])({k: concatenate([d[k] for d in data], dim=dim) for k in data[0].keys()}) + elif not isinstance(data[0], torch.Tensor): + raise TypeError(f"Can only concatenate tensors but got {type(data[0])}") + return torch.cat(data, dim=dim) + + +class CannotPadNestedTensorWarning(UserWarning): + pass + + +@chained_operation +def pad_across_processes(tensor, dim=0, pad_index=0, pad_first=False): + """ + Recursively pad the tensors in a nested list/tuple/dictionary of tensors from all devices to the same size so they + can safely be gathered. + + Args: + tensor (nested list/tuple/dictionary of `torch.Tensor`): + The data to gather. + dim (`int`, *optional*, defaults to 0): + The dimension on which to pad. + pad_index (`int`, *optional*, defaults to 0): + The value with which to pad. + pad_first (`bool`, *optional*, defaults to `False`): + Whether to pad at the beginning or the end. + """ + + def _pad_across_processes(tensor, dim=0, pad_index=0, pad_first=False): + if getattr(tensor, "is_nested", False): + warnings.warn( + "Cannot pad nested tensors without more information. Leaving unprocessed.", + CannotPadNestedTensorWarning, + ) + return tensor + if dim >= len(tensor.shape) or dim < -len(tensor.shape): + return tensor + # Convert negative dimensions to non-negative + if dim < 0: + dim += len(tensor.shape) + + # Gather all sizes + size = torch.tensor(tensor.shape, device=tensor.device)[None] + sizes = gather(size).cpu() + # Then pad to the maximum size + max_size = max(s[dim] for s in sizes) + if max_size == tensor.shape[dim]: + return tensor + + old_size = tensor.shape + new_size = list(old_size) + new_size[dim] = max_size + new_tensor = tensor.new_zeros(tuple(new_size)) + pad_index + if pad_first: + indices = tuple( + slice(max_size - old_size[dim], max_size) if i == dim else slice(None) for i in range(len(new_size)) + ) + else: + indices = tuple(slice(0, old_size[dim]) if i == dim else slice(None) for i in range(len(new_size))) + new_tensor[indices] = tensor + return new_tensor + + return recursively_apply( + _pad_across_processes, tensor, error_on_other_type=True, dim=dim, pad_index=pad_index, pad_first=pad_first + ) + + +def pad_input_tensors(tensor, batch_size, num_processes, dim=0): + """ + Takes a `tensor` of arbitrary size and pads it so that it can work given `num_processes` needed dimensions. + + New tensors are just the last input repeated. + + E.g.: + Tensor: ([3,4,4]) Num processes: 4 Expected result shape: ([4,4,4]) + + """ + + def _pad_input_tensors(tensor, batch_size, num_processes, dim=0): + remainder = batch_size // num_processes + last_inputs = batch_size - (remainder * num_processes) + if batch_size // num_processes == 0: + to_pad = num_processes - batch_size + else: + to_pad = num_processes - (batch_size // num_processes) + # In the rare case that `to_pad` is negative, + # we need to pad the last inputs - the found `to_pad` + if last_inputs > to_pad & to_pad < 1: + to_pad = last_inputs - to_pad + old_size = tensor.shape + new_size = list(old_size) + new_size[0] = batch_size + to_pad + new_tensor = tensor.new_zeros(tuple(new_size)) + indices = tuple(slice(0, old_size[dim]) if i == dim else slice(None) for i in range(len(new_size))) + new_tensor[indices] = tensor + return new_tensor + + return recursively_apply( + _pad_input_tensors, + tensor, + error_on_other_type=True, + batch_size=batch_size, + num_processes=num_processes, + dim=dim, + ) + + +@verify_operation +def reduce(tensor, reduction="mean", scale=1.0): + """ + Recursively reduce the tensors in a nested list/tuple/dictionary of lists of tensors across all processes by the + mean of a given operation. + + Args: + tensor (nested list/tuple/dictionary of `torch.Tensor`): + The data to reduce. + reduction (`str`, *optional*, defaults to `"mean"`): + A reduction method. Can be of "mean", "sum", or "none" + scale (`float`, *optional*): + A default scaling value to be applied after the reduce, only valid on XLA. + + Returns: + The same data structure as `data` with all the tensors reduced. + """ + + def _reduce_across_processes(tensor, reduction="mean", scale=1.0): + state = PartialState() + cloned_tensor = tensor.clone() + if state.distributed_type == DistributedType.NO: + return cloned_tensor + if state.distributed_type == DistributedType.XLA: + # Some processes may have different HLO graphs than other + # processes, for example in the breakpoint API + # accelerator.set_trigger(). Use mark_step to make HLOs + # the same on all processes. + xm.mark_step() + xm.all_reduce(xm.REDUCE_SUM, [cloned_tensor], scale) + xm.mark_step() + elif state.distributed_type.value in TORCH_DISTRIBUTED_OPERATION_TYPES: + torch.distributed.all_reduce(cloned_tensor, ReduceOp.SUM) + if reduction == "mean": + cloned_tensor /= state.num_processes + return cloned_tensor + + return recursively_apply( + _reduce_across_processes, tensor, error_on_other_type=True, reduction=reduction, scale=scale + ) + + +def convert_to_fp32(tensor): + """ + Recursively converts the elements nested list/tuple/dictionary of tensors in FP16/BF16 precision to FP32. + + Args: + tensor (nested list/tuple/dictionary of `torch.Tensor`): + The data to convert from FP16/BF16 to FP32. + + Returns: + The same data structure as `tensor` with all tensors that were in FP16/BF16 precision converted to FP32. + """ + + def _convert_to_fp32(tensor): + return tensor.float() + + def _is_fp16_bf16_tensor(tensor): + return (is_torch_tensor(tensor) or hasattr(tensor, "dtype")) and tensor.dtype in ( + torch.float16, + torch.bfloat16, + ) + + return recursively_apply(_convert_to_fp32, tensor, test_type=_is_fp16_bf16_tensor) + + +class ConvertOutputsToFp32: + """ + Decorator to apply to a function outputting tensors (like a model forward pass) that ensures the outputs in FP16 + precision will be convert back to FP32. + + Args: + model_forward (`Callable`): + The function which outputs we want to treat. + + Returns: + The same function as `model_forward` but with converted outputs. + """ + + def __init__(self, model_forward): + self.model_forward = model_forward + update_wrapper(self, model_forward) + + def __call__(self, *args, **kwargs): + return convert_to_fp32(self.model_forward(*args, **kwargs)) + + def __getstate__(self): + raise pickle.PicklingError( + "Cannot pickle a prepared model with automatic mixed precision, please unwrap the model with `Accelerator.unwrap_model(model)` before pickling it." + ) + + +def convert_outputs_to_fp32(model_forward): + model_forward = ConvertOutputsToFp32(model_forward) + + def forward(*args, **kwargs): + return model_forward(*args, **kwargs) + + # To act like a decorator so that it can be popped when doing `extract_model_from_parallel` + forward.__wrapped__ = model_forward + + return forward + + +def find_device(data): + """ + Finds the device on which a nested dict/list/tuple of tensors lies (assuming they are all on the same device). + + Args: + (nested list/tuple/dictionary of `torch.Tensor`): The data we want to know the device of. + """ + if isinstance(data, Mapping): + for obj in data.values(): + device = find_device(obj) + if device is not None: + return device + elif isinstance(data, (tuple, list)): + for obj in data: + device = find_device(obj) + if device is not None: + return device + elif isinstance(data, torch.Tensor): + return data.device + + +@contextmanager +def GatheredParameters(params, modifier_rank=None, fwd_module=None, enabled=True): + """ + Wrapper around `deepspeed.runtime.zero.GatheredParameters`, but if Zero-3 is not enabled, will be a no-op context + manager. + """ + # We need to use the `AcceleratorState` here since it has access to the deepspeed plugin + if AcceleratorState().distributed_type != DistributedType.DEEPSPEED or ( + AcceleratorState().deepspeed_plugin is not None + and not AcceleratorState().deepspeed_plugin.is_zero3_init_enabled() + ): + gather_param_context = nullcontext() + else: + import deepspeed + + gather_param_context = deepspeed.zero.GatheredParameters( + params, modifier_rank=modifier_rank, fwd_module=fwd_module, enabled=enabled + ) + with gather_param_context: + yield diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/other.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/other.py new file mode 100644 index 0000000000000000000000000000000000000000..69bed25cb66b31e32cbc984e8779af875b0cfde1 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/other.py @@ -0,0 +1,561 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import collections +import platform +import re +import socket +from codecs import encode +from collections import OrderedDict +from functools import partial, reduce +from types import MethodType +from typing import Optional + +import numpy as np +import torch +from packaging.version import Version +from safetensors.torch import save_file as safe_save_file + +from ..commands.config.default import write_basic_config # noqa: F401 +from ..logging import get_logger +from ..state import PartialState +from .constants import FSDP_PYTORCH_VERSION +from .dataclasses import DistributedType +from .imports import ( + is_deepspeed_available, + is_numpy_available, + is_torch_distributed_available, + is_torch_xla_available, + is_weights_only_available, +) +from .modeling import id_tensor_storage +from .transformer_engine import convert_model +from .versions import is_torch_version + + +logger = get_logger(__name__) + + +if is_torch_xla_available(): + import torch_xla.core.xla_model as xm + + +def is_compiled_module(module: torch.nn.Module) -> bool: + """ + Check whether the module was compiled with torch.compile() + """ + if not hasattr(torch, "_dynamo"): + return False + + return isinstance(module, torch._dynamo.eval_frame.OptimizedModule) + + +def has_compiled_regions(module: torch.nn.Module) -> bool: + """ + Check whether the module has submodules that were compiled with `torch.compile()`. + """ + if not hasattr(torch, "_dynamo"): + return False + + if module._modules: + for submodule in module.modules(): + if isinstance(submodule, torch._dynamo.eval_frame.OptimizedModule): + return True + + return False + + +def is_repeated_blocks(module: torch.nn.Module) -> bool: + """ + Check whether the module is a repeated block, i.e. `torch.nn.ModuleList` with all children of the same class. This + is useful to determine whether we should apply regional compilation to the module. + """ + + return isinstance(module, torch.nn.ModuleList) and all(isinstance(m, module[0].__class__) for m in module) + + +def has_repeated_blocks(module: torch.nn.Module) -> bool: + """ + Check whether the module has repeated blocks, i.e. `torch.nn.ModuleList` with all children of the same class, at + any level of the module hierarchy. This is useful to determine whether we should apply regional compilation to the + module. + """ + if module._modules: + for submodule in module.modules(): + if is_repeated_blocks(submodule): + return True + + return False + + +def compile_regions(module: torch.nn.Module, **compile_kwargs) -> torch.nn.Module: + """ + Performs regional compilation where we target repeated blocks of the same class and compile them sequentially to + hit the compiler's cache. For example, in `GPT2LMHeadModel`, the repeated block/class is `GPT2Block`, and can be + accessed as `model.transformer.h[0]`. The rest of the model (e.g. model.lm_head) is compiled separately. + + This allows us to speed up the compilation overhead / cold start of models like LLMs and Transformers in general. + See https://pytorch.org/tutorials/recipes/regional_compilation.html for more details. + + Args: + module (`torch.nn.Module`): + The model to compile. + **compile_kwargs: + Additional keyword arguments to pass to `torch.compile()`. + + Returns: + `torch.nn.Module`: A new instance of the model with some compiled regions. + + Example: + ```python + >>> from accelerate.utils import compile_regions + >>> from transformers import AutoModelForCausalLM + + >>> model = AutoModelForCausalLM.from_pretrained("gpt2") + >>> compiled_model = compile_regions(model, mode="reduce-overhead") + >>> compiled_model.transformer.h[0] + OptimizedModule( + (_orig_mod): GPT2Block( + (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) + (attn): GPT2Attention( + (c_attn): Conv1D(nf=2304, nx=768) + (c_proj): Conv1D(nf=768, nx=768) + (attn_dropout): Dropout(p=0.1, inplace=False) + (resid_dropout): Dropout(p=0.1, inplace=False) + ) + (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) + (mlp): GPT2MLP( + (c_fc): Conv1D(nf=3072, nx=768) + (c_proj): Conv1D(nf=768, nx=3072) + (act): NewGELUActivation() + (dropout): Dropout(p=0.1, inplace=False) + ) + ) + ) + ``` + """ + + def _compile_regions(module: torch.nn.Module, **compile_kwargs) -> torch.nn.Module: + if is_repeated_blocks(module): + new_module = torch.nn.ModuleList() + for submodule in module: + new_module.append(torch.compile(submodule, **compile_kwargs)) + elif has_repeated_blocks(module): + new_module = module.__class__.__new__(module.__class__) + new_module.__dict__.update(module.__dict__) + new_module._modules = {} + for name, submodule in module.named_children(): + new_module.add_module(name, _compile_regions(submodule, **compile_kwargs)) + else: + new_module = torch.compile(module, **compile_kwargs) + + return new_module + + new_module = _compile_regions(module, **compile_kwargs) + + if "_orig_mod" not in new_module.__dict__: + # Keeps a reference to the original module to decompile/unwrap it later + new_module.__dict__["_orig_mod"] = module + + return new_module + + +def compile_regions_deepspeed(module: torch.nn.Module, **compile_kwargs): + """ + Performs regional compilation the same way as `compile_regions`, but specifically for `DeepSpeedEngine.module`. + Since the model is wrapped in a `DeepSpeedEngine` and has many added hooks, offloaded parameters, etc that + `torch.compile(...)` interferes with, version of trgional compilation uses the inplace `module.compile()` method + instead. + + Args: + module (`torch.nn.Module`): + The model to compile. + **compile_kwargs: + Additional keyword arguments to pass to `module.compile()`. + """ + + if is_repeated_blocks(module): + for submodule in module: + submodule.compile(**compile_kwargs) + elif has_repeated_blocks(module): + for child in module.children(): + compile_regions_deepspeed(child, **compile_kwargs) + else: # leaf node + module.compile(**compile_kwargs) + + +def model_has_dtensor(model: torch.nn.Module) -> bool: + """ + Check if the model has DTensor parameters. + + Args: + model (`torch.nn.Module`): + The model to check. + + Returns: + `bool`: Whether the model has DTensor parameters. + """ + if is_torch_version(">=", "2.5.0"): + from torch.distributed.tensor import DTensor + else: + # from torch 2.0.0 (oldest supported accelerate torch version), DTensor is in torch.distributed._tensor + from torch.distributed._tensor import DTensor + + return any(isinstance(p, DTensor) for p in model.parameters()) + + +def extract_model_from_parallel( + model, keep_fp32_wrapper: bool = True, keep_torch_compile: bool = True, recursive: bool = False +): + """ + Extract a model from its distributed containers. + + Args: + model (`torch.nn.Module`): + The model to extract. + keep_fp32_wrapper (`bool`, *optional*): + Whether to remove mixed precision hooks from the model. + keep_torch_compile (`bool`, *optional*): + Whether to unwrap compiled model. + recursive (`bool`, *optional*, defaults to `False`): + Whether to recursively extract all cases of `module.module` from `model` as well as unwrap child sublayers + recursively, not just the top-level distributed containers. + + Returns: + `torch.nn.Module`: The extracted model. + """ + options = (torch.nn.parallel.DistributedDataParallel, torch.nn.DataParallel) + + is_compiled = is_compiled_module(model) + has_compiled = has_compiled_regions(model) + + if is_compiled: + compiled_model = model + model = model._orig_mod + elif has_compiled: + compiled_model = model + model = model.__dict__["_orig_mod"] + + if is_deepspeed_available(): + from deepspeed import DeepSpeedEngine + + options += (DeepSpeedEngine,) + + if is_torch_version(">=", FSDP_PYTORCH_VERSION) and is_torch_distributed_available(): + from torch.distributed.fsdp.fully_sharded_data_parallel import FullyShardedDataParallel as FSDP + + options += (FSDP,) + + while isinstance(model, options): + model = model.module + + if recursive: + # This is needed in cases such as using FSDPv2 on XLA + def _recursive_unwrap(module): + # Wrapped modules are standardly wrapped as `module`, similar to the cases earlier + # with DDP, DataParallel, DeepSpeed, and FSDP + if hasattr(module, "module"): + unwrapped_module = _recursive_unwrap(module.module) + else: + unwrapped_module = module + # Next unwrap child sublayers recursively + for name, child in unwrapped_module.named_children(): + setattr(unwrapped_module, name, _recursive_unwrap(child)) + return unwrapped_module + + # Start with top-level + model = _recursive_unwrap(model) + + if not keep_fp32_wrapper: + forward = model.forward + original_forward = model.__dict__.pop("_original_forward", None) + if original_forward is not None: + while hasattr(forward, "__wrapped__"): + forward = forward.__wrapped__ + if forward == original_forward: + break + model.forward = MethodType(forward, model) + if getattr(model, "_converted_to_transformer_engine", False): + convert_model(model, to_transformer_engine=False) + + if keep_torch_compile: + if is_compiled: + compiled_model._orig_mod = model + model = compiled_model + elif has_compiled: + compiled_model.__dict__["_orig_mod"] = model + model = compiled_model + + return model + + +def wait_for_everyone(): + """ + Introduces a blocking point in the script, making sure all processes have reached this point before continuing. + + + + Make sure all processes will reach this instruction otherwise one of your processes will hang forever. + + + """ + PartialState().wait_for_everyone() + + +def clean_state_dict_for_safetensors(state_dict: dict): + """ + Cleans the state dictionary from a model and removes tensor aliasing if present. + + Args: + state_dict (`dict`): + The state dictionary from a model + """ + ptrs = collections.defaultdict(list) + # When bnb serialization is used, weights in state dict can be strings + for name, tensor in state_dict.items(): + if not isinstance(tensor, str): + ptrs[id_tensor_storage(tensor)].append(name) + + # These are all pointers of tensors with shared memory + shared_ptrs = {ptr: names for ptr, names in ptrs.items() if len(names) > 1} + warn_names = set() + for names in shared_ptrs.values(): + # When not all duplicates have been cleaned, we still remove those keys but put a clear warning. + # If the link between tensors was done at runtime then `from_pretrained` will not get + # the key back leading to random tensor. A proper warning will be shown + # during reload (if applicable), but since the file is not necessarily compatible with + # the config, better show a proper warning. + found_names = [name for name in names if name in state_dict] + warn_names.update(found_names[1:]) + for name in found_names[1:]: + del state_dict[name] + if len(warn_names) > 0: + logger.warning( + f"Removed shared tensor {warn_names} while saving. This should be OK, but check by verifying that you don't receive any warning while reloading", + ) + state_dict = {k: v.contiguous() if isinstance(v, torch.Tensor) else v for k, v in state_dict.items()} + return state_dict + + +def save(obj, f, save_on_each_node: bool = False, safe_serialization: bool = False): + """ + Save the data to disk. Use in place of `torch.save()`. + + Args: + obj: + The data to save + f: + The file (or file-like object) to use to save the data + save_on_each_node (`bool`, *optional*, defaults to `False`): + Whether to only save on the global main process + safe_serialization (`bool`, *optional*, defaults to `False`): + Whether to save `obj` using `safetensors` or the traditional PyTorch way (that uses `pickle`). + """ + # When TorchXLA is enabled, it's necessary to transfer all data to the CPU before saving. + # Another issue arises with `id_tensor_storage`, which treats all XLA tensors as identical. + # If tensors remain on XLA, calling `clean_state_dict_for_safetensors` will result in only + # one XLA tensor remaining. + if PartialState().distributed_type == DistributedType.XLA: + obj = xm._maybe_convert_to_cpu(obj) + # Check if it's a model and remove duplicates + if safe_serialization: + save_func = partial(safe_save_file, metadata={"format": "pt"}) + if isinstance(obj, OrderedDict): + obj = clean_state_dict_for_safetensors(obj) + else: + save_func = torch.save + + if PartialState().is_main_process and not save_on_each_node: + save_func(obj, f) + elif PartialState().is_local_main_process and save_on_each_node: + save_func(obj, f) + + +# The following are considered "safe" globals to reconstruct various types of objects when using `weights_only=True` +# These should be added and then removed after loading in the file +np_core = np._core if is_numpy_available("2.0.0") else np.core +TORCH_SAFE_GLOBALS = [ + # numpy arrays are just numbers, not objects, so we can reconstruct them safely + np_core.multiarray._reconstruct, + np.ndarray, + # The following are needed for the RNG states + encode, + np.dtype, +] + +if is_numpy_available("1.25.0"): + TORCH_SAFE_GLOBALS.append(np.dtypes.UInt32DType) + + +def load(f, map_location=None, **kwargs): + """ + Compatible drop-in replacement of `torch.load()` which allows for `weights_only` to be used if `torch` version is + 2.4.0 or higher. Otherwise will ignore the kwarg. + + Will also add (and then remove) an exception for numpy arrays + + Args: + f: + The file (or file-like object) to use to load the data + map_location: + a function, `torch.device`, string or a dict specifying how to remap storage locations + **kwargs: + Additional keyword arguments to pass to `torch.load()`. + """ + try: + if is_weights_only_available(): + old_safe_globals = torch.serialization.get_safe_globals() + if "weights_only" not in kwargs: + kwargs["weights_only"] = True + torch.serialization.add_safe_globals(TORCH_SAFE_GLOBALS) + else: + kwargs.pop("weights_only", None) + loaded_obj = torch.load(f, map_location=map_location, **kwargs) + finally: + if is_weights_only_available(): + torch.serialization.clear_safe_globals() + if old_safe_globals: + torch.serialization.add_safe_globals(old_safe_globals) + return loaded_obj + + +def get_pretty_name(obj): + """ + Gets a pretty name from `obj`. + """ + if not hasattr(obj, "__qualname__") and not hasattr(obj, "__name__"): + obj = getattr(obj, "__class__", obj) + if hasattr(obj, "__qualname__"): + return obj.__qualname__ + if hasattr(obj, "__name__"): + return obj.__name__ + return str(obj) + + +def merge_dicts(source, destination): + """ + Recursively merges two dictionaries. + + Args: + source (`dict`): The dictionary to merge into `destination`. + destination (`dict`): The dictionary to merge `source` into. + """ + for key, value in source.items(): + if isinstance(value, dict): + node = destination.setdefault(key, {}) + merge_dicts(value, node) + else: + destination[key] = value + + return destination + + +def is_port_in_use(port: Optional[int] = None) -> bool: + """ + Checks if a port is in use on `localhost`. Useful for checking if multiple `accelerate launch` commands have been + run and need to see if the port is already in use. + """ + if port is None: + port = 29500 + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + return s.connect_ex(("localhost", port)) == 0 + + +def get_free_port() -> int: + """ + Gets a free port on `localhost`. Useful for automatic port selection when port 0 is specified in distributed + training scenarios. + + Returns: + int: An available port number + """ + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind(("", 0)) # bind to port 0 for OS to assign a free port + return s.getsockname()[1] + + +def convert_bytes(size): + "Converts `size` from bytes to the largest possible unit" + for x in ["bytes", "KB", "MB", "GB", "TB"]: + if size < 1024.0: + return f"{round(size, 2)} {x}" + size /= 1024.0 + + return f"{round(size, 2)} PB" + + +def check_os_kernel(): + """Warns if the kernel version is below the recommended minimum on Linux.""" + # see issue #1929 + info = platform.uname() + system = info.system + if system != "Linux": + return + + _, version, *_ = re.split(r"(\d+\.\d+\.\d+)", info.release) + min_version = "5.5.0" + if Version(version) < Version(min_version): + msg = ( + f"Detected kernel version {version}, which is below the recommended minimum of {min_version}; this can " + "cause the process to hang. It is recommended to upgrade the kernel to the minimum version or higher." + ) + logger.warning(msg, main_process_only=True) + + +def recursive_getattr(obj, attr: str): + """ + Recursive `getattr`. + + Args: + obj: + A class instance holding the attribute. + attr (`str`): + The attribute that is to be retrieved, e.g. 'attribute1.attribute2'. + """ + + def _getattr(obj, attr): + return getattr(obj, attr) + + return reduce(_getattr, [obj] + attr.split(".")) + + +def get_module_children_bottom_up(model: torch.nn.Module, return_fqns: bool = False) -> list[torch.nn.Module]: + """Traverse the model in bottom-up order and return the children modules in that order. + + Args: + model (`torch.nn.Module`): the model to get the children of + + Returns: + `list[torch.nn.Module]`: a list of children modules of `model` in bottom-up order. The last element is the + `model` itself. + """ + top = model if not return_fqns else ("", model) + stack = [top] + ordered_modules = [] + while stack: + current_module = stack.pop() + if return_fqns: + current_module_name, current_module = current_module + for name, attr in current_module.named_children(): + if isinstance(attr, torch.nn.Module): + if return_fqns: + child_name = current_module_name + "." + name if current_module_name else name + stack.append((child_name, attr)) + else: + stack.append(attr) + if return_fqns: + ordered_modules.append((current_module_name, current_module)) + else: + ordered_modules.append(current_module) + return ordered_modules[::-1] diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/random.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/random.py new file mode 100644 index 0000000000000000000000000000000000000000..9dceb598cacc1c1d17b198e0a7c19789ab3b9f39 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/random.py @@ -0,0 +1,156 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import random +from typing import Optional, Union + +import numpy as np +import torch + +from ..state import AcceleratorState +from .constants import CUDA_DISTRIBUTED_TYPES +from .dataclasses import DistributedType, RNGType +from .imports import ( + is_hpu_available, + is_mlu_available, + is_musa_available, + is_npu_available, + is_sdaa_available, + is_torch_xla_available, + is_xpu_available, +) + + +if is_torch_xla_available(): + import torch_xla.core.xla_model as xm + + +def set_seed(seed: int, device_specific: bool = False, deterministic: bool = False): + """ + Helper function for reproducible behavior to set the seed in `random`, `numpy`, `torch`. + + Args: + seed (`int`): + The seed to set. + device_specific (`bool`, *optional*, defaults to `False`): + Whether to differ the seed on each device slightly with `self.process_index`. + deterministic (`bool`, *optional*, defaults to `False`): + Whether to use deterministic algorithms where available. Can slow down training. + """ + if device_specific: + seed += AcceleratorState().process_index + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + if is_xpu_available(): + torch.xpu.manual_seed_all(seed) + elif is_npu_available(): + torch.npu.manual_seed_all(seed) + elif is_mlu_available(): + torch.mlu.manual_seed_all(seed) + elif is_sdaa_available(): + torch.sdaa.manual_seed_all(seed) + elif is_musa_available(): + torch.musa.manual_seed_all(seed) + elif is_hpu_available(): + torch.hpu.manual_seed_all(seed) + else: + torch.cuda.manual_seed_all(seed) + # ^^ safe to call this function even if cuda is not available + if is_torch_xla_available(): + xm.set_rng_state(seed) + + if deterministic: + torch.use_deterministic_algorithms(True) + + +def synchronize_rng_state(rng_type: Optional[RNGType] = None, generator: Optional[torch.Generator] = None): + # Get the proper rng state + if rng_type == RNGType.TORCH: + rng_state = torch.get_rng_state() + elif rng_type == RNGType.CUDA: + rng_state = torch.cuda.get_rng_state() + elif rng_type == RNGType.XLA: + assert is_torch_xla_available(), "Can't synchronize XLA seeds as torch_xla is unavailable." + rng_state = torch.tensor(xm.get_rng_state()) + elif rng_type == RNGType.NPU: + assert is_npu_available(), "Can't synchronize NPU seeds on an environment without NPUs." + rng_state = torch.npu.get_rng_state() + elif rng_type == RNGType.MLU: + assert is_mlu_available(), "Can't synchronize MLU seeds on an environment without MLUs." + rng_state = torch.mlu.get_rng_state() + elif rng_type == RNGType.SDAA: + assert is_sdaa_available(), "Can't synchronize SDAA seeds on an environment without SDAAs." + rng_state = torch.sdaa.get_rng_state() + elif rng_type == RNGType.MUSA: + assert is_musa_available(), "Can't synchronize MUSA seeds on an environment without MUSAs." + rng_state = torch.musa.get_rng_state() + elif rng_type == RNGType.XPU: + assert is_xpu_available(), "Can't synchronize XPU seeds on an environment without XPUs." + rng_state = torch.xpu.get_rng_state() + elif rng_type == RNGType.HPU: + assert is_hpu_available(), "Can't synchronize HPU seeds on an environment without HPUs." + rng_state = torch.hpu.get_rng_state() + elif rng_type == RNGType.GENERATOR: + assert generator is not None, "Need a generator to synchronize its seed." + rng_state = generator.get_state() + + # Broadcast the rng state from device 0 to other devices + state = AcceleratorState() + if state.distributed_type == DistributedType.XLA: + rng_state = rng_state.to(xm.xla_device()) + xm.collective_broadcast([rng_state]) + xm.mark_step() + rng_state = rng_state.cpu() + elif ( + state.distributed_type in CUDA_DISTRIBUTED_TYPES + or state.distributed_type == DistributedType.MULTI_MLU + or state.distributed_type == DistributedType.MULTI_SDAA + or state.distributed_type == DistributedType.MULTI_MUSA + or state.distributed_type == DistributedType.MULTI_NPU + or state.distributed_type == DistributedType.MULTI_XPU + or state.distributed_type == DistributedType.MULTI_HPU + ): + rng_state = rng_state.to(state.device) + torch.distributed.broadcast(rng_state, 0) + rng_state = rng_state.cpu() + elif state.distributed_type == DistributedType.MULTI_CPU: + torch.distributed.broadcast(rng_state, 0) + + # Set the broadcast rng state + if rng_type == RNGType.TORCH: + torch.set_rng_state(rng_state) + elif rng_type == RNGType.CUDA: + torch.cuda.set_rng_state(rng_state) + elif rng_type == RNGType.NPU: + torch.npu.set_rng_state(rng_state) + elif rng_type == RNGType.MLU: + torch.mlu.set_rng_state(rng_state) + elif rng_type == RNGType.SDAA: + torch.sdaa.set_rng_state(rng_state) + elif rng_type == RNGType.MUSA: + torch.musa.set_rng_state(rng_state) + elif rng_type == RNGType.XPU: + torch.xpu.set_rng_state(rng_state) + elif rng_state == RNGType.HPU: + torch.hpu.set_rng_state(rng_state) + elif rng_type == RNGType.XLA: + xm.set_rng_state(rng_state.item()) + elif rng_type == RNGType.GENERATOR: + generator.set_state(rng_state) + + +def synchronize_rng_states(rng_types: list[Union[str, RNGType]], generator: Optional[torch.Generator] = None): + for rng_type in rng_types: + synchronize_rng_state(RNGType(rng_type), generator=generator) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/rich.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/rich.py new file mode 100644 index 0000000000000000000000000000000000000000..2d48661b7fcef92ef1168b74cc275c6d3ccc67a1 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/rich.py @@ -0,0 +1,24 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from .imports import is_rich_available + + +if is_rich_available(): + from rich.traceback import install + + install(show_locals=False) + +else: + raise ModuleNotFoundError("To use the rich extension, install rich with `pip install rich`") diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/torch_xla.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/torch_xla.py new file mode 100644 index 0000000000000000000000000000000000000000..140133926c2f88d39c70f5a9f46a08f88bed36da --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/torch_xla.py @@ -0,0 +1,51 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import importlib.metadata +import subprocess +import sys + + +def install_xla(upgrade: bool = False): + """ + Helper function to install appropriate xla wheels based on the `torch` version in Google Colaboratory. + + Args: + upgrade (`bool`, *optional*, defaults to `False`): + Whether to upgrade `torch` and install the latest `torch_xla` wheels. + + Example: + + ```python + >>> from accelerate.utils import install_xla + + >>> install_xla(upgrade=True) + ``` + """ + in_colab = False + if "IPython" in sys.modules: + in_colab = "google.colab" in str(sys.modules["IPython"].get_ipython()) + + if in_colab: + if upgrade: + torch_install_cmd = ["pip", "install", "-U", "torch"] + subprocess.run(torch_install_cmd, check=True) + # get the current version of torch + torch_version = importlib.metadata.version("torch") + torch_version_trunc = torch_version[: torch_version.rindex(".")] + xla_wheel = f"https://storage.googleapis.com/tpu-pytorch/wheels/colab/torch_xla-{torch_version_trunc}-cp37-cp37m-linux_x86_64.whl" + xla_install_cmd = ["pip", "install", xla_wheel] + subprocess.run(xla_install_cmd, check=True) + else: + raise RuntimeError("`install_xla` utility works only on google colab.") diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/tqdm.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/tqdm.py new file mode 100644 index 0000000000000000000000000000000000000000..2d4873c1573eb2ee7392162f440a76d4f07cd8ce --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/tqdm.py @@ -0,0 +1,43 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from .imports import is_tqdm_available + + +if is_tqdm_available(): + from tqdm.auto import tqdm as _tqdm + +from ..state import PartialState + + +def tqdm(*args, main_process_only: bool = True, **kwargs): + """ + Wrapper around `tqdm.tqdm` that optionally displays only on the main process. + + Args: + main_process_only (`bool`, *optional*): + Whether to display the progress bar only on the main process + """ + if not is_tqdm_available(): + raise ImportError("Accelerate's `tqdm` module requires `tqdm` to be installed. Please run `pip install tqdm`.") + if len(args) > 0 and isinstance(args[0], bool): + raise ValueError( + "Passing `True` or `False` as the first argument to Accelerate's `tqdm` wrapper is unsupported. " + "Please use the `main_process_only` keyword argument instead." + ) + disable = kwargs.pop("disable", False) + if main_process_only and not disable: + disable = PartialState().local_process_index != 0 + return _tqdm(*args, **kwargs, disable=disable) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/transformer_engine.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/transformer_engine.py new file mode 100644 index 0000000000000000000000000000000000000000..6a950d131ddcb1575a2cccd7937ed25bf762663e --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/transformer_engine.py @@ -0,0 +1,186 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from types import MethodType + +import torch.nn as nn + +from .imports import is_hpu_available, is_transformer_engine_available +from .operations import GatheredParameters + + +# Do not import `transformer_engine` at package level to avoid potential issues + + +def convert_model(model, to_transformer_engine=True, _convert_linear=True, _convert_ln=True): + """ + Recursively converts the linear and layernorm layers of a model to their `transformers_engine` counterpart. + """ + if not is_transformer_engine_available(): + raise ImportError("Using `convert_model` requires transformer_engine to be installed.") + + if is_hpu_available(): + import intel_transformer_engine as te + + if not hasattr(te, "LayerNorm"): + # HPU does not have a LayerNorm implementation in TE + te.LayerNorm = nn.LayerNorm + else: + import transformer_engine.pytorch as te + + for name, module in model.named_children(): + if isinstance(module, nn.Linear) and to_transformer_engine and _convert_linear: + has_bias = module.bias is not None + params_to_gather = [module.weight] + if has_bias: + params_to_gather.append(module.bias) + + with GatheredParameters(params_to_gather, modifier_rank=0): + if any(p % 16 != 0 for p in module.weight.shape): + return + te_module = te.Linear( + module.in_features, module.out_features, bias=has_bias, params_dtype=module.weight.dtype + ) + te_module.weight.copy_(module.weight) + if has_bias: + te_module.bias.copy_(module.bias) + + setattr(model, name, te_module) + # Note: @xrsrke (Phuc) found that te.LayerNorm doesn't have any real memory savings or speedups over nn.LayerNorm + elif isinstance(module, nn.LayerNorm) and to_transformer_engine and _convert_ln: + with GatheredParameters([module.weight, module.bias], modifier_rank=0): + has_bias = module.bias is not None + te_module = te.LayerNorm(module.normalized_shape[0], eps=module.eps, params_dtype=module.weight.dtype) + te_module.weight.copy_(module.weight) + if has_bias: + te_module.bias.copy_(module.bias) + + setattr(model, name, te_module) + elif isinstance(module, te.Linear) and not to_transformer_engine and _convert_linear: + has_bias = module.bias is not None + new_module = nn.Linear( + module.in_features, module.out_features, bias=has_bias, params_dtype=module.weight.dtype + ) + new_module.weight.copy_(module.weight) + if has_bias: + new_module.bias.copy_(module.bias) + + setattr(model, name, new_module) + elif isinstance(module, te.LayerNorm) and not to_transformer_engine and _convert_ln: + new_module = nn.LayerNorm(module.normalized_shape[0], eps=module.eps, params_dtype=module.weight.dtype) + new_module.weight.copy_(module.weight) + new_module.bias.copy_(module.bias) + + setattr(model, name, new_module) + else: + convert_model( + module, + to_transformer_engine=to_transformer_engine, + _convert_linear=_convert_linear, + _convert_ln=_convert_ln, + ) + + +def has_transformer_engine_layers(model): + """ + Returns whether a given model has some `transformer_engine` layer or not. + """ + if not is_transformer_engine_available(): + raise ImportError("Using `has_transformer_engine_layers` requires transformer_engine to be installed.") + + if is_hpu_available(): + import intel_transformer_engine as te + + module_cls_to_check = te.Linear + else: + import transformer_engine.pytorch as te + + module_cls_to_check = (te.LayerNorm, te.Linear, te.TransformerLayer) + + for m in model.modules(): + if isinstance(m, module_cls_to_check): + return True + + return False + + +def contextual_fp8_autocast(model_forward, fp8_recipe, use_during_eval=False): + """ + Wrapper for a model's forward method to apply FP8 autocast. Is context aware, meaning that by default it will + disable FP8 autocast during eval mode, which is generally better for more accurate metrics. + """ + if not is_transformer_engine_available(): + raise ImportError("Using `contextual_fp8_autocast` requires transformer_engine to be installed.") + + if is_hpu_available(): + from intel_transformer_engine import fp8_autocast + else: + from transformer_engine.pytorch import fp8_autocast + + def forward(self, *args, **kwargs): + enabled = use_during_eval or self.training + with fp8_autocast(enabled=enabled, fp8_recipe=fp8_recipe): + return model_forward(*args, **kwargs) + + # To act like a decorator so that it can be popped when doing `extract_model_from_parallel` + forward.__wrapped__ = model_forward + + return forward + + +def apply_fp8_autowrap(model, fp8_recipe_handler): + """ + Applies FP8 context manager to the model's forward method + """ + if not is_transformer_engine_available(): + raise ImportError("Using `apply_fp8_autowrap` requires transformer_engine to be installed.") + + if is_hpu_available(): + import intel_transformer_engine.recipe as te_recipe + + is_fp8_block_scaling_available = False + message = "MXFP8 block scaling is not available on HPU." + + else: + import transformer_engine.common.recipe as te_recipe + import transformer_engine.pytorch as te + + is_fp8_block_scaling_available, message = te.fp8.check_mxfp8_support() + + kwargs = fp8_recipe_handler.to_kwargs() if fp8_recipe_handler is not None else {} + if "fp8_format" in kwargs: + kwargs["fp8_format"] = getattr(te_recipe.Format, kwargs["fp8_format"]) + use_during_eval = kwargs.pop("use_autocast_during_eval", False) + use_mxfp8_block_scaling = kwargs.pop("use_mxfp8_block_scaling", False) + + if use_mxfp8_block_scaling and not is_fp8_block_scaling_available: + raise ValueError(f"MXFP8 block scaling is not available: {message}") + + if use_mxfp8_block_scaling: + if "amax_compute_algo" in kwargs: + raise ValueError("`amax_compute_algo` is not supported for MXFP8 block scaling.") + if "amax_history_len" in kwargs: + raise ValueError("`amax_history_len` is not supported for MXFP8 block scaling.") + fp8_recipe = te_recipe.MXFP8BlockScaling(**kwargs) + else: + fp8_recipe = te_recipe.DelayedScaling(**kwargs) + + new_forward = contextual_fp8_autocast(model.forward, fp8_recipe, use_during_eval) + + if hasattr(model.forward, "__func__"): + model.forward = MethodType(new_forward, model) + else: + model.forward = new_forward + + return model diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/versions.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/versions.py new file mode 100644 index 0000000000000000000000000000000000000000..985c918f0e057bacc70c372f6906071bb73db577 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/versions.py @@ -0,0 +1,56 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import importlib.metadata +from typing import Union + +from packaging.version import Version, parse + +from .constants import STR_OPERATION_TO_FUNC + + +torch_version = parse(importlib.metadata.version("torch")) + + +def compare_versions(library_or_version: Union[str, Version], operation: str, requirement_version: str): + """ + Compares a library version to some requirement using a given operation. + + Args: + library_or_version (`str` or `packaging.version.Version`): + A library name or a version to check. + operation (`str`): + A string representation of an operator, such as `">"` or `"<="`. + requirement_version (`str`): + The version to compare the library version against + """ + if operation not in STR_OPERATION_TO_FUNC.keys(): + raise ValueError(f"`operation` must be one of {list(STR_OPERATION_TO_FUNC.keys())}, received {operation}") + operation = STR_OPERATION_TO_FUNC[operation] + if isinstance(library_or_version, str): + library_or_version = parse(importlib.metadata.version(library_or_version)) + return operation(library_or_version, parse(requirement_version)) + + +def is_torch_version(operation: str, version: str): + """ + Compares the current PyTorch version to a given reference with an operation. + + Args: + operation (`str`): + A string representation of an operator, such as `">"` or `"<="` + version (`str`): + A string version of PyTorch + """ + return compare_versions(torch_version, operation, version) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98c2564c8966644aa958350a4afc2a19f19f86ba Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/main.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f3a27e7b870169958255e3f0641a6d8801e98555 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/main.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/cuda_pathfinder-1.4.0.dist-info/licenses/LICENSE b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/cuda_pathfinder-1.4.0.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..f433b1a53f5b830a205fd2df78e2b34974656c7b --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/cuda_pathfinder-1.4.0.dist-info/licenses/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a154b6c3f66b9747ea4b20827b879c599a9699ea Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__version__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__version__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d96937a1ab7e1de0569e0c45cc5bf71d0e3dce69 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__version__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a85f9de40d76319b2272a028ab1a911b40da6965 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align_getter.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align_getter.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..013b432dc99f031790e596676bf6037d4163dc06 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align_getter.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_base.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_base.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06b3b57ea1a8e40bc3c3e2090530e464e957e061 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_base.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_column.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_column.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ecec2689e08698adcc07f90a2060c5727ef3fd7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_column.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_common.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_common.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..711210fa2a636e917be5bb7668818b7cf406f35c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_common.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_container.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_container.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b23ab100108d7e629094a668e21bab3abfa1f506 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_container.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_converter.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_converter.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3230c8f52e3fb9426d5748a43caf1ff7d71f2363 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_converter.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_dataproperty.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_dataproperty.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..42244310abeba55262d7346b74be7d1acde53478 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_dataproperty.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_extractor.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_extractor.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e91d2ed17fb58600ff68f6b33dcbe237af3b3411 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_extractor.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_formatter.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_formatter.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb28999c1e4edd828dc75c6b94bba42bedfeffe6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_formatter.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_function.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_function.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cb79ad7fe3685cfb2b21795a3a5d132d6acb66c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_function.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_interface.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_interface.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f200b38789938bfb52db2bee7e8771c1e915444e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_interface.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_line_break.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_line_break.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81224d415abe824b4ba780575fa3478efe35c1e1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_line_break.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_preprocessor.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_preprocessor.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c7de264a800ef8b6edd9531b239323ff93d7bb66 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_preprocessor.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/typing.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/typing.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f06d96a8f1d354412a78ee849947dc4d61587224 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/typing.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..af2ff6d54dfd57bdea24e51fc39722ae07b14491 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__init__.py @@ -0,0 +1,7 @@ +from ._logger import logger, set_logger # type: ignore + + +__all__ = ( + "logger", + "set_logger", +) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d52afc2e77d2426ea921edc3547761bd7fc6ca3 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_logger.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_logger.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb0d9572fec69988484026c89e89f561a079560e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_logger.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_null_logger.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_null_logger.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94cfc04edde1d715bf18f2dc4bdf8a1502e00e43 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_null_logger.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_logger.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_logger.py new file mode 100644 index 0000000000000000000000000000000000000000..4a828f2bcf3d9ecbcfd6c0aaeaf9227e4edd4f17 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_logger.py @@ -0,0 +1,22 @@ +""" +.. codeauthor:: Tsuyoshi Hombashi +""" + +from ._null_logger import NullLogger + + +MODULE_NAME = "dataproperty" + +try: + from loguru import logger # type: ignore + + logger.disable(MODULE_NAME) +except ImportError: + logger = NullLogger() + + +def set_logger(is_enable: bool, propagation_depth: int = 1) -> None: + if is_enable: + logger.enable(MODULE_NAME) + else: + logger.disable(MODULE_NAME) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_null_logger.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_null_logger.py new file mode 100644 index 0000000000000000000000000000000000000000..ad0f293ce2a288057ea07297e21504c7669edfd0 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_null_logger.py @@ -0,0 +1,41 @@ +class NullLogger: + level_name = None + + def remove(self, handler_id=None): # pragma: no cover + pass + + def add(self, sink, **kwargs): # pragma: no cover + pass + + def disable(self, name): # pragma: no cover + pass + + def enable(self, name): # pragma: no cover + pass + + def critical(self, __message, *args, **kwargs): # pragma: no cover + pass + + def debug(self, __message, *args, **kwargs): # pragma: no cover + pass + + def error(self, __message, *args, **kwargs): # pragma: no cover + pass + + def exception(self, __message, *args, **kwargs): # pragma: no cover + pass + + def info(self, __message, *args, **kwargs): # pragma: no cover + pass + + def log(self, __level, __message, *args, **kwargs): # pragma: no cover + pass + + def success(self, __message, *args, **kwargs): # pragma: no cover + pass + + def trace(self, __message, *args, **kwargs): # pragma: no cover + pass + + def warning(self, __message, *args, **kwargs): # pragma: no cover + pass diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90ff33cd3da492341e937479b9a0e3e123ad28ec Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__main__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__main__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bbd8753299bd6b25c9855f044f91fbd988ba5509 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__main__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_check.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_check.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e06075dbd1a4ae6c343b18a37c86b173ee8ba0f3 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_check.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_classdef.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_classdef.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..678ed43d82fe16a3551d06f9464eba0dcbbe73d6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_classdef.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_dataclasses.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_dataclasses.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e871e04d69e52728a90ee81e105bf896047c2c2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_dataclasses.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_diff.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_diff.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4907221962617d54634d8da90dc6f4c12ea35ca Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_diff.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_extendpickle.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_extendpickle.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a698de7ab74d5b7829a3583c69c7c5184a4733b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_extendpickle.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_file.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_file.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23cc0a4d1a6e671559bfe282232564ae836c0183 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_file.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functions.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f0181607e3f40b988aecfa42e688f880d39a01a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functions.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functors.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functors.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dca06df76f489f36485b5c037f4a1e6cf17986f9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functors.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_module.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_module.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..786730dca9789517498274f365f3813c435e2bbc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_module.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_nested.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_nested.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13f60f69eacfefc50a753fd08bb71c53a8a04302 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_nested.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_objects.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_objects.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b99ea2861438a2787ef5f8a42a16cbce85b202c8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_objects.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_properties.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_properties.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc826d81e2d1ae2e80fcc10264676d52d4e318be Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_properties.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_pycapsule.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_pycapsule.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c16322692715b62fff4acaf89013f85dcab8db3a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_pycapsule.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_recursive.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_recursive.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..879b9a31c81f44d4ebe091e56ae83f34a55eed25 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_recursive.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_registered.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_registered.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a14f7741a3525217954a6ec4d2650931253fd683 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_registered.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_restricted.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_restricted.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae461b4e4e51d4374104c2ab17f7f5fcbdc4150d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_restricted.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_selected.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_selected.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..265041dc77c06a6691efba262228e2175f4ad8c6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_selected.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_temp.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_temp.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c287433aa1776d15c9ad1f420c7562fcfb85c039 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_temp.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_weakref.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_weakref.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf0766e92f1af89015c9f96317d502e3cf5eaccd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_weakref.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluation_suite/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluation_suite/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a306d8068a6d66b60fbcc5420bf0cbb334c36305 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluation_suite/__init__.py @@ -0,0 +1,128 @@ +import importlib +import inspect +from dataclasses import dataclass +from pathlib import Path +from typing import Callable, Dict, Optional, Union + +from datasets import Dataset, DownloadConfig, DownloadMode, load_dataset +from datasets.utils.version import Version + +from ..evaluator import evaluator +from ..loading import evaluation_module_factory +from ..utils.logging import get_logger + + +logger = get_logger(__name__) + + +@dataclass +class SubTask: + task_type: str + data: Optional[Union[str, Dataset]] = None + subset: Optional[str] = None + split: Optional[str] = None + data_preprocessor: Optional[Callable] = None + args_for_task: Optional[dict] = None + + def __post_init__(self): + if type(self.task_type) is not str: + raise ValueError(f"'task_type' must be type 'str', got {type(self.task_type)}") + if type(self.data) not in [Dataset, str]: + raise ValueError( + f"'data' must be an already-instantiated Dataset object or type 'str', got {type(self.data)}" + ) + if self.subset and type(self.subset) is not str: + raise ValueError(f"'subset' must be type 'str', got {type(self.subset)}") + if self.split and type(self.split) is not str: + raise ValueError(f"'split' must be type 'str', got {type(self.split)}") + if self.data_preprocessor and not callable(self.data_preprocessor): + raise ValueError(f"'data_preprocessor' must be a Callable', got {self.data_preprocessor}") + if self.args_for_task and type(self.args_for_task) is not dict: + raise ValueError(f"'args_for_task' must be type 'dict', got {type(self.args_for_task)}") + + +def import_main_class(module_path): + """Import a module at module_path and return the EvaluationSuite class""" + module = importlib.import_module(module_path) + + module_main_cls = None + for name, obj in module.__dict__.items(): + if isinstance(obj, type) and obj.__name__ == "Suite": + if inspect.isabstract(obj): + continue + module_main_cls = obj + break + + return module_main_cls + + +class EvaluationSuite: + """ + This class instantiates an evaluation suite made up of multiple tasks, where each task consists of a dataset and + an associated metric, and runs evaluation on a model or pipeline. Evaluation suites can be a Python script found + either locally or uploaded as a Space on the Hugging Face Hub. + Usage: + ```python + from evaluate import EvaluationSuite + suite = EvaluationSuite.load("evaluate/evaluation-suite-ci") + results = suite.run("lvwerra/distilbert-imdb") + ``` + """ + + def __init__(self, name): + self.name = name + + @staticmethod + def load( + path: str, + download_mode: Optional[DownloadMode] = None, + revision: Optional[Union[str, Version]] = None, + download_config: Optional[DownloadConfig] = None, + ): + download_mode = DownloadMode(download_mode or DownloadMode.REUSE_DATASET_IF_EXISTS) + evaluation_module = evaluation_module_factory( + path, module_type=None, revision=revision, download_config=download_config, download_mode=download_mode + ) + name = Path(path).stem + evaluation_cls = import_main_class(evaluation_module.module_path) + evaluation_instance = evaluation_cls(name) + + return evaluation_instance + + def __repr__(self): + self.tasks = [str(task) for task in self.suite] + return f'EvaluationSuite name: "{self.name}", ' f"Tasks: {self.tasks})" + + def assert_suite_nonempty(self): + if not self.suite: + raise ValueError( + "No evaluation tasks found. The EvaluationSuite must include at least one SubTask definition." + ) + + def run( + self, model_or_pipeline: Union[str, "Pipeline", Callable, "PreTrainedModel", "TFPreTrainedModel"] # noqa: F821 + ) -> Dict[str, float]: + + self.assert_suite_nonempty() + + results_all = [] + for task in self.suite: + + task_name = task.data + + if task.data_preprocessor: # task requires extra preprocessing + ds = load_dataset(task.data, name=task.subset, split=task.split) + task.data = ds.map(task.data_preprocessor) + + task_evaluator = evaluator(task.task_type) + args_for_task = task.args_for_task + args_for_task["model_or_pipeline"] = model_or_pipeline + args_for_task["data"] = task.data + args_for_task["subset"] = task.subset + args_for_task["split"] = task.split + results = task_evaluator.compute(**args_for_task) + + results["task_name"] = task_name + "/" + task.subset if task.subset else task_name + results["data_preprocessor"] = str(task.data_preprocessor) if task.data_preprocessor is not None else None + results_all.append(results) + return results_all diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fac692eeb80def645bce9901324902ac9e1899f5 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/__init__.py @@ -0,0 +1,39 @@ +# Copyright 2020 The HuggingFace Datasets Authors and the TensorFlow Datasets Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# flake8: noqa +# Lint as: python3 +"""Util import.""" + +__all__ = [ + "disable_progress_bar", + "enable_progress_bar", + "is_progress_bar_enabled", + "infer_gradio_input_types", + "json_to_string_type", + "parse_readme", + "parse_gradio_data", + "parse_test_cases", + "launch_gradio_widget", +] + +from .gradio import ( + infer_gradio_input_types, + json_to_string_type, + launch_gradio_widget, + parse_gradio_data, + parse_readme, + parse_test_cases, +) +from .logging import disable_progress_bar, enable_progress_bar, is_progress_bar_enabled diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/file_utils.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/file_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..4c278905f9bf9a61810b6ba256dae331ce6d8a8c --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/file_utils.py @@ -0,0 +1,605 @@ +""" +Utilities for working with the local dataset cache. +This file is adapted from the AllenNLP library at https://github.com/allenai/allennlp +Copyright by the AllenNLP authors. +""" + +import copy +import io +import json +import os +import posixpath +import re +import shutil +import sys +import tempfile +import time +import urllib +from contextlib import closing, contextmanager +from functools import partial +from hashlib import sha256 +from pathlib import Path +from typing import List, Optional, Type, TypeVar, Union +from urllib.parse import urlparse + +import requests +from datasets import DownloadConfig +from datasets.utils.extract import ExtractManager +from datasets.utils.filelock import FileLock + +from .. import __version__, config +from . import logging + + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + +INCOMPLETE_SUFFIX = ".incomplete" + +T = TypeVar("T", str, Path) + + +def init_hf_modules(hf_modules_cache: Optional[Union[Path, str]] = None) -> str: + """ + Add hf_modules_cache to the python path. + By default hf_modules_cache='~/.cache/huggingface/modules'. + It can also be set with the environment variable HF_MODULES_CACHE. + This is used to add modules such as `datasets_modules` + """ + hf_modules_cache = hf_modules_cache if hf_modules_cache is not None else config.HF_MODULES_CACHE + hf_modules_cache = str(hf_modules_cache) + if hf_modules_cache not in sys.path: + sys.path.append(hf_modules_cache) + + os.makedirs(hf_modules_cache, exist_ok=True) + if not os.path.exists(os.path.join(hf_modules_cache, "__init__.py")): + with open(os.path.join(hf_modules_cache, "__init__.py"), "w"): + pass + return hf_modules_cache + + +def is_remote_url(url_or_filename: str) -> bool: + parsed = urlparse(url_or_filename) + return parsed.scheme in ("http", "https", "s3", "gs", "hdfs", "ftp") + + +def is_local_path(url_or_filename: str) -> bool: + # On unix the scheme of a local path is empty (for both absolute and relative), + # while on windows the scheme is the drive name (ex: "c") for absolute paths. + # for details on the windows behavior, see https://bugs.python.org/issue42215 + return urlparse(url_or_filename).scheme == "" or os.path.ismount(urlparse(url_or_filename).scheme + ":/") + + +def is_relative_path(url_or_filename: str) -> bool: + return urlparse(url_or_filename).scheme == "" and not os.path.isabs(url_or_filename) + + +def relative_to_absolute_path(path: T) -> T: + """Convert relative path to absolute path.""" + abs_path_str = os.path.abspath(os.path.expanduser(os.path.expandvars(str(path)))) + return Path(abs_path_str) if isinstance(path, Path) else abs_path_str + + +def hf_bucket_url(identifier: str, filename: str, use_cdn=False, dataset=True) -> str: + if dataset: + endpoint = config.CLOUDFRONT_DATASETS_DISTRIB_PREFIX if use_cdn else config.S3_DATASETS_BUCKET_PREFIX + else: + endpoint = config.CLOUDFRONT_METRICS_DISTRIB_PREFIX if use_cdn else config.S3_METRICS_BUCKET_PREFIX + return "/".join((endpoint, identifier, filename)) + + +def head_hf_s3( + identifier: str, filename: str, use_cdn=False, dataset=True, max_retries=0 +) -> Union[requests.Response, Exception]: + return http_head( + hf_bucket_url(identifier=identifier, filename=filename, use_cdn=use_cdn, dataset=dataset), + max_retries=max_retries, + ) + + +def hf_hub_url(path: str, name: str, revision: Optional[str] = None) -> str: + revision = revision or config.HUB_DEFAULT_VERSION + return config.HUB_EVALUATE_URL.format(path=path, name=name, revision=revision) + + +def url_or_path_join(base_name: str, *pathnames: str) -> str: + if is_remote_url(base_name): + return posixpath.join(base_name, *(str(pathname).replace(os.sep, "/").lstrip("/") for pathname in pathnames)) + else: + return Path(base_name, *pathnames).as_posix() + + +def url_or_path_parent(url_or_path: str) -> str: + if is_remote_url(url_or_path): + return url_or_path[: url_or_path.rindex("/")] + else: + return os.path.dirname(url_or_path) + + +def hash_url_to_filename(url, etag=None): + """ + Convert `url` into a hashed filename in a repeatable way. + If `etag` is specified, append its hash to the url's, delimited + by a period. + If the url ends with .h5 (Keras HDF5 weights) adds '.h5' to the name + so that TF 2.0 can identify it as a HDF5 file + (see https://github.com/tensorflow/tensorflow/blob/00fad90125b18b80fe054de1055770cfb8fe4ba3/tensorflow/python/keras/engine/network.py#L1380) + """ + url_bytes = url.encode("utf-8") + url_hash = sha256(url_bytes) + filename = url_hash.hexdigest() + + if etag: + etag_bytes = etag.encode("utf-8") + etag_hash = sha256(etag_bytes) + filename += "." + etag_hash.hexdigest() + + if url.endswith(".py"): + filename += ".py" + + return filename + + +def cached_path( + url_or_filename, + download_config=None, + **download_kwargs, +) -> str: + """ + Given something that might be a URL (or might be a local path), + determine which. If it's a URL, download the file and cache it, and + return the path to the cached file. If it's already a local path, + make sure the file exists and then return the path. + + Return: + Local path (string) + + Raises: + FileNotFoundError: in case of non-recoverable file + (non-existent or no cache on disk) + ConnectionError: in case of unreachable url + and no cache on disk + ValueError: if it couldn't parse the url or filename correctly + requests.exceptions.ConnectionError: in case of internet connection issue + """ + if download_config is None: + download_config = DownloadConfig(**download_kwargs) + + cache_dir = download_config.cache_dir or config.DOWNLOADED_EVALUATE_PATH + if isinstance(cache_dir, Path): + cache_dir = str(cache_dir) + if isinstance(url_or_filename, Path): + url_or_filename = str(url_or_filename) + + if is_remote_url(url_or_filename): + # URL, so get it from the cache (downloading if necessary) + output_path = get_from_cache( + url_or_filename, + cache_dir=cache_dir, + force_download=download_config.force_download, + proxies=download_config.proxies, + resume_download=download_config.resume_download, + user_agent=download_config.user_agent, + local_files_only=download_config.local_files_only, + use_etag=download_config.use_etag, + max_retries=download_config.max_retries, + token=download_config.token, + download_desc=download_config.download_desc, + ) + elif os.path.exists(url_or_filename): + # File, and it exists. + output_path = url_or_filename + elif is_local_path(url_or_filename): + # File, but it doesn't exist. + raise FileNotFoundError(f"Local file {url_or_filename} doesn't exist") + else: + # Something unknown + raise ValueError(f"unable to parse {url_or_filename} as a URL or as a local path") + + if output_path is None: + return output_path + + if download_config.extract_compressed_file: + output_path = ExtractManager(cache_dir=download_config.cache_dir).extract( + output_path, force_extract=download_config.force_extract + ) + + return output_path + + +def get_datasets_user_agent(user_agent: Optional[Union[str, dict]] = None) -> str: + ua = f"datasets/{__version__}; python/{config.PY_VERSION}" + ua += f"; pyarrow/{config.PYARROW_VERSION}" + if config.TORCH_AVAILABLE: + ua += f"; torch/{config.TORCH_VERSION}" + if config.TF_AVAILABLE: + ua += f"; tensorflow/{config.TF_VERSION}" + if config.JAX_AVAILABLE: + ua += f"; jax/{config.JAX_VERSION}" + if isinstance(user_agent, dict): + ua += f"; {'; '.join(f'{k}/{v}' for k, v in user_agent.items())}" + elif isinstance(user_agent, str): + ua += "; " + user_agent + return ua + + +def get_authentication_headers_for_url(url: str, token: Optional[Union[str, bool]] = None) -> dict: + """Handle the HF authentication""" + headers = {} + if url.startswith(config.HF_ENDPOINT): + from huggingface_hub.utils import build_hf_headers + + headers = build_hf_headers(token=token, library_name="evaluate", library_version=__version__) + + return headers + + +class OfflineModeIsEnabled(ConnectionError): + pass + + +def _raise_if_offline_mode_is_enabled(msg: Optional[str] = None): + """Raise an OfflineModeIsEnabled error (subclass of ConnectionError) if HF_EVALUATE_OFFLINE is True.""" + if config.HF_EVALUATE_OFFLINE: + raise OfflineModeIsEnabled( + "Offline mode is enabled." if msg is None else "Offline mode is enabled. " + str(msg) + ) + + +def _retry( + func, + func_args: Optional[tuple] = None, + func_kwargs: Optional[dict] = None, + exceptions: Type[requests.exceptions.RequestException] = requests.exceptions.RequestException, + status_codes: Optional[List[int]] = None, + max_retries: int = 0, + base_wait_time: float = 0.5, + max_wait_time: float = 2, +): + func_args = func_args or () + func_kwargs = func_kwargs or {} + retry = 0 + while True: + try: + return func(*func_args, **func_kwargs) + except exceptions as err: + if retry >= max_retries or (status_codes and err.response.status_code not in status_codes): + raise err + else: + sleep_time = min(max_wait_time, base_wait_time * 2**retry) # Exponential backoff + logger.info(f"{func} timed out, retrying in {sleep_time}s... [{retry/max_retries}]") + time.sleep(sleep_time) + retry += 1 + + +def _request_with_retry( + method: str, + url: str, + max_retries: int = 0, + base_wait_time: float = 0.5, + max_wait_time: float = 2, + timeout: float = 10.0, + **params, +) -> requests.Response: + """Wrapper around requests to retry in case it fails with a ConnectTimeout, with exponential backoff. + + Note that if the environment variable HF_EVALUATE_OFFLINE is set to 1, then a OfflineModeIsEnabled error is raised. + + Args: + method (str): HTTP method, such as 'GET' or 'HEAD'. + url (str): The URL of the resource to fetch. + max_retries (int): Maximum number of retries, defaults to 0 (no retries). + base_wait_time (float): Duration (in seconds) to wait before retrying the first time. Wait time between + retries then grows exponentially, capped by max_wait_time. + max_wait_time (float): Maximum amount of time between two retries, in seconds. + **params: Params to pass to :obj:`requests.request`. + """ + _raise_if_offline_mode_is_enabled(f"Tried to reach {url}") + tries, success = 0, False + while not success: + tries += 1 + try: + response = requests.request(method=method.upper(), url=url, timeout=timeout, **params) + success = True + except (requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError) as err: + if tries > max_retries: + raise err + else: + logger.info(f"{method} request to {url} timed out, retrying... [{tries/max_retries}]") + sleep_time = min(max_wait_time, base_wait_time * 2 ** (tries - 1)) # Exponential backoff + time.sleep(sleep_time) + return response + + +def ftp_head(url, timeout=10.0): + _raise_if_offline_mode_is_enabled(f"Tried to reach {url}") + try: + with closing(urllib.request.urlopen(url, timeout=timeout)) as r: + r.read(1) + except Exception: + return False + return True + + +def ftp_get(url, temp_file, timeout=10.0): + _raise_if_offline_mode_is_enabled(f"Tried to reach {url}") + try: + logger.info(f"Getting through FTP {url} into {temp_file.name}") + with closing(urllib.request.urlopen(url, timeout=timeout)) as r: + shutil.copyfileobj(r, temp_file) + except urllib.error.URLError as e: + raise ConnectionError(e) from None + + +def http_get( + url, temp_file, proxies=None, resume_size=0, headers=None, cookies=None, timeout=100.0, max_retries=0, desc=None +): + headers = copy.deepcopy(headers) or {} + headers["user-agent"] = get_datasets_user_agent(user_agent=headers.get("user-agent")) + if resume_size > 0: + headers["Range"] = f"bytes={resume_size:d}-" + response = _request_with_retry( + method="GET", + url=url, + stream=True, + proxies=proxies, + headers=headers, + cookies=cookies, + max_retries=max_retries, + timeout=timeout, + ) + if response.status_code == 416: # Range not satisfiable + return + content_length = response.headers.get("Content-Length") + total = resume_size + int(content_length) if content_length is not None else None + with logging.tqdm( + unit="B", + unit_scale=True, + total=total, + initial=resume_size, + desc=desc or "Downloading", + disable=not logging.is_progress_bar_enabled(), + ) as progress: + for chunk in response.iter_content(chunk_size=1024): + progress.update(len(chunk)) + temp_file.write(chunk) + + +def http_head( + url, proxies=None, headers=None, cookies=None, allow_redirects=True, timeout=10.0, max_retries=0 +) -> requests.Response: + headers = copy.deepcopy(headers) or {} + headers["user-agent"] = get_datasets_user_agent(user_agent=headers.get("user-agent")) + response = _request_with_retry( + method="HEAD", + url=url, + proxies=proxies, + headers=headers, + cookies=cookies, + allow_redirects=allow_redirects, + timeout=timeout, + max_retries=max_retries, + ) + return response + + +def request_etag(url: str, token: Optional[Union[str, bool]] = None) -> Optional[str]: + headers = get_authentication_headers_for_url(url, token=token) + response = http_head(url, headers=headers, max_retries=3) + response.raise_for_status() + etag = response.headers.get("ETag") if response.ok else None + return etag + + +def get_from_cache( + url, + cache_dir=None, + force_download=False, + proxies=None, + etag_timeout=100, + resume_download=False, + user_agent=None, + local_files_only=False, + use_etag=True, + max_retries=0, + token=None, + download_desc=None, +) -> str: + """ + Given a URL, look for the corresponding file in the local cache. + If it's not there, download it. Then return the path to the cached file. + + Return: + Local path (string) + + Raises: + FileNotFoundError: in case of non-recoverable file + (non-existent or no cache on disk) + ConnectionError: in case of unreachable url + and no cache on disk + """ + if cache_dir is None: + cache_dir = config.HF_EVALUATE_CACHE + if isinstance(cache_dir, Path): + cache_dir = str(cache_dir) + + os.makedirs(cache_dir, exist_ok=True) + + connected = False + response = None + cookies = None + etag = None + head_error = None + + # Try a first time to file the file on the local file system without eTag (None) + # if we don't ask for 'force_download' then we spare a request + filename = hash_url_to_filename(url, etag=None) + cache_path = os.path.join(cache_dir, filename) + + if os.path.exists(cache_path) and not force_download and not use_etag: + return cache_path + + # Prepare headers for authentication + headers = get_authentication_headers_for_url(url, token=token) + if user_agent is not None: + headers["user-agent"] = user_agent + + # We don't have the file locally or we need an eTag + if not local_files_only: + if url.startswith("ftp://"): + connected = ftp_head(url) + try: + response = http_head( + url, + allow_redirects=True, + proxies=proxies, + timeout=etag_timeout, + max_retries=max_retries, + headers=headers, + ) + if response.status_code == 200: # ok + etag = response.headers.get("ETag") if use_etag else None + for k, v in response.cookies.items(): + # In some edge cases, we need to get a confirmation token + if k.startswith("download_warning") and "drive.google.com" in url: + url += "&confirm=" + v + cookies = response.cookies + connected = True + # Fix Google Drive URL to avoid Virus scan warning + if "drive.google.com" in url and "confirm=" not in url: + url += "&confirm=t" + # In some edge cases, head request returns 400 but the connection is actually ok + elif ( + (response.status_code == 400 and "firebasestorage.googleapis.com" in url) + or (response.status_code == 405 and "drive.google.com" in url) + or ( + response.status_code == 403 + and ( + re.match(r"^https?://github.com/.*?/.*?/releases/download/.*?/.*?$", url) + or re.match(r"^https://.*?s3.*?amazonaws.com/.*?$", response.url) + ) + ) + or (response.status_code == 403 and "ndownloader.figstatic.com" in url) + ): + connected = True + logger.info(f"Couldn't get ETag version for url {url}") + elif response.status_code == 401 and config.HF_ENDPOINT in url and token is None: + raise ConnectionError( + f"Unauthorized for URL {url}. Please use the parameter ``token=True`` after logging in with ``huggingface-cli login``" + ) + except (OSError, requests.exceptions.Timeout) as e: + # not connected + head_error = e + pass + + # connected == False = we don't have a connection, or url doesn't exist, or is otherwise inaccessible. + # try to get the last downloaded one + if not connected: + if os.path.exists(cache_path) and not force_download: + return cache_path + if local_files_only: + raise FileNotFoundError( + f"Cannot find the requested files in the cached path at {cache_path} and outgoing traffic has been" + " disabled. To enable file online look-ups, set 'local_files_only' to False." + ) + elif response is not None and response.status_code == 404: + raise FileNotFoundError(f"Couldn't find file at {url}") + _raise_if_offline_mode_is_enabled(f"Tried to reach {url}") + if head_error is not None: + raise ConnectionError(f"Couldn't reach {url} ({repr(head_error)})") + elif response is not None: + raise ConnectionError(f"Couldn't reach {url} (error {response.status_code})") + else: + raise ConnectionError(f"Couldn't reach {url}") + + # Try a second time + filename = hash_url_to_filename(url, etag) + cache_path = os.path.join(cache_dir, filename) + + if os.path.exists(cache_path) and not force_download: + return cache_path + + # From now on, connected is True. + # Prevent parallel downloads of the same file with a lock. + lock_path = cache_path + ".lock" + with FileLock(lock_path): + + if resume_download: + incomplete_path = cache_path + ".incomplete" + + @contextmanager + def _resumable_file_manager(): + with open(incomplete_path, "a+b") as f: + yield f + + temp_file_manager = _resumable_file_manager + if os.path.exists(incomplete_path): + resume_size = os.stat(incomplete_path).st_size + else: + resume_size = 0 + else: + temp_file_manager = partial(tempfile.NamedTemporaryFile, dir=cache_dir, delete=False) + resume_size = 0 + + # Download to temporary file, then copy to cache dir once finished. + # Otherwise you get corrupt cache entries if the download gets interrupted. + with temp_file_manager() as temp_file: + logger.info(f"{url} not found in cache or force_download set to True, downloading to {temp_file.name}") + + # GET file object + if url.startswith("ftp://"): + ftp_get(url, temp_file) + else: + http_get( + url, + temp_file, + proxies=proxies, + resume_size=resume_size, + headers=headers, + cookies=cookies, + max_retries=max_retries, + desc=download_desc, + ) + + logger.info(f"storing {url} in cache at {cache_path}") + shutil.move(temp_file.name, cache_path) + + logger.info(f"creating metadata file for {cache_path}") + meta = {"url": url, "etag": etag} + meta_path = cache_path + ".json" + with open(meta_path, "w", encoding="utf-8") as meta_file: + json.dump(meta, meta_file) + + return cache_path + + +def add_start_docstrings(*docstr): + def docstring_decorator(fn): + fn.__doc__ = "".join(docstr) + "\n\n" + (fn.__doc__ if fn.__doc__ is not None else "") + return fn + + return docstring_decorator + + +def add_end_docstrings(*docstr): + def docstring_decorator(fn): + fn.__doc__ = (fn.__doc__ if fn.__doc__ is not None else "") + "\n\n" + "".join(docstr) + return fn + + return docstring_decorator + + +def estimate_dataset_size(paths): + return sum(path.stat().st_size for path in paths) + + +def readline(f: io.RawIOBase): + # From: https://github.com/python/cpython/blob/d27e2f4d118e7a9909b6a3e5da06c5ff95806a85/Lib/_pyio.py#L525 + res = bytearray() + while True: + b = f.read(1) + if not b: + break + res += b + if res.endswith(b"\n"): + break + return bytes(res) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/gradio.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/gradio.py new file mode 100644 index 0000000000000000000000000000000000000000..3b73d9c67e711caad66edaf0f66808fff296aabd --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/gradio.py @@ -0,0 +1,131 @@ +import json +import os +import re +import sys +from pathlib import Path + +import numpy as np +from datasets import Value + +from .logging import get_logger + + +logger = get_logger(__name__) + +REGEX_YAML_BLOCK = re.compile(r"---[\n\r]+([\S\s]*?)[\n\r]+---[\n\r]") + + +def infer_gradio_input_types(feature_types): + """ + Maps metric feature types to input types for gradio Dataframes: + - float/int -> numbers + - string -> strings + - any other -> json + Note that json is not a native gradio type but will be treated as string that + is then parsed as a json. + """ + input_types = [] + for feature_type in feature_types: + input_type = "json" + if isinstance(feature_type, Value): + if feature_type.dtype.startswith("int") or feature_type.dtype.startswith("float"): + input_type = "number" + elif feature_type.dtype == "string": + input_type = "str" + input_types.append(input_type) + return input_types + + +def json_to_string_type(input_types): + """Maps json input type to str.""" + return ["str" if i == "json" else i for i in input_types] + + +def parse_readme(filepath): + """Parses a repositories README and removes""" + if not os.path.exists(filepath): + return "No README.md found." + with open(filepath, "r") as f: + text = f.read() + match = REGEX_YAML_BLOCK.search(text) + if match: + text = text[match.end() :] + return text + + +def parse_gradio_data(data, input_types): + """Parses data from gradio Dataframe for use in metric.""" + metric_inputs = {} + data.replace("", np.nan, inplace=True) + data.dropna(inplace=True) + for feature_name, input_type in zip(data, input_types): + if input_type == "json": + metric_inputs[feature_name] = [json.loads(d) for d in data[feature_name].to_list()] + elif input_type == "str": + metric_inputs[feature_name] = [d.strip('"') for d in data[feature_name].to_list()] + else: + metric_inputs[feature_name] = data[feature_name] + return metric_inputs + + +def parse_test_cases(test_cases, feature_names, input_types): + """ + Parses test cases to be used in gradio Dataframe. Note that an apostrophe is added + to strings to follow the format in json. + """ + if len(test_cases) == 0: + return None + examples = [] + for test_case in test_cases: + parsed_cases = [] + for feat, input_type in zip(feature_names, input_types): + if input_type == "json": + parsed_cases.append([str(element) for element in test_case[feat]]) + elif input_type == "str": + parsed_cases.append(['"' + element + '"' for element in test_case[feat]]) + else: + parsed_cases.append(test_case[feat]) + examples.append([list(i) for i in zip(*parsed_cases)]) + return examples + + +def launch_gradio_widget(metric): + """Launches `metric` widget with Gradio.""" + + try: + import gradio as gr + except ImportError as error: + logger.error("To create a metric widget with Gradio make sure gradio is installed.") + raise error + + local_path = Path(sys.path[0]) + # if there are several input types, use first as default. + if isinstance(metric.features, list): + (feature_names, feature_types) = zip(*metric.features[0].items()) + else: + (feature_names, feature_types) = zip(*metric.features.items()) + gradio_input_types = infer_gradio_input_types(feature_types) + + def compute(data): + return metric.compute(**parse_gradio_data(data, gradio_input_types)) + + iface = gr.Interface( + fn=compute, + inputs=gr.inputs.Dataframe( + headers=feature_names, + col_count=len(feature_names), + row_count=1, + datatype=json_to_string_type(gradio_input_types), + ), + outputs=gr.outputs.Textbox(label=metric.name), + description=( + metric.info.description + "\nIf this is a text-based metric, make sure to wrap you input in double quotes." + " Alternatively you can use a JSON-formatted list as input." + ), + title=f"Metric: {metric.name}", + article=parse_readme(local_path / "README.md"), + # TODO: load test cases and use them to populate examples + # examples=[parse_test_cases(test_cases, feature_names, gradio_input_types)] + ) + + iface.launch() diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/logging.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/logging.py new file mode 100644 index 0000000000000000000000000000000000000000..d29b7f4845f292f13dc40a4b3df123c704b8d807 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/logging.py @@ -0,0 +1,233 @@ +# Copyright 2020 Optuna, Hugging Face +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Logging utilities. """ + +import logging +import os +from logging import CRITICAL # NOQA +from logging import DEBUG # NOQA +from logging import ERROR # NOQA +from logging import FATAL # NOQA +from logging import INFO # NOQA +from logging import NOTSET # NOQA +from logging import WARN # NOQA +from logging import WARNING # NOQA +from typing import Optional + +from tqdm import auto as tqdm_lib + + +log_levels = { + "debug": logging.DEBUG, + "info": logging.INFO, + "warning": logging.WARNING, + "error": logging.ERROR, + "critical": logging.CRITICAL, +} + +_default_log_level = logging.WARNING + + +def _get_default_logging_level(): + """ + If EVALUATE_VERBOSITY env var is set to one of the valid choices return that as the new default level. + If it is not - fall back to ``_default_log_level`` + """ + env_level_str = os.getenv("EVALUATE_VERBOSITY", None) + if env_level_str: + if env_level_str in log_levels: + return log_levels[env_level_str] + else: + logging.getLogger().warning( + f"Unknown option EVALUATE_VERBOSITY={env_level_str}, " + f"has to be one of: { ', '.join(log_levels.keys()) }" + ) + return _default_log_level + + +def _get_library_name() -> str: + return __name__.split(".")[0] + + +def _get_library_root_logger() -> logging.Logger: + return logging.getLogger(_get_library_name()) + + +def _configure_library_root_logger() -> None: + # Apply our default configuration to the library root logger. + library_root_logger = _get_library_root_logger() + library_root_logger.setLevel(_get_default_logging_level()) + + +def _reset_library_root_logger() -> None: + library_root_logger = _get_library_root_logger() + library_root_logger.setLevel(logging.NOTSET) + + +def get_logger(name: Optional[str] = None) -> logging.Logger: + """Return a logger with the specified name.""" + if name is None: + name = _get_library_name() + return logging.getLogger(name) + + +def get_verbosity() -> int: + """Return the current level for the Hugging Face Evaluate library's root logger. + Returns: + Logging level, e.g., `evaluate.logging.DEBUG` and `evaluate.logging.INFO`. + + + + Hugging Face Evaluate library has following logging levels: + - `evaluate.logging.CRITICAL`, `evaluate.logging.FATAL` + - `evaluate.logging.ERROR` + - `evaluate.logging.WARNING`, `evaluate.logging.WARN` + - `evaluate.logging.INFO` + - `evaluate.logging.DEBUG` + + + """ + return _get_library_root_logger().getEffectiveLevel() + + +def set_verbosity(verbosity: int) -> None: + """Set the level for the Hugging Face Evaluate library's root logger. + Args: + verbosity: + Logging level, e.g., `evaluate.logging.DEBUG` and `evaluate.logging.INFO`. + """ + _get_library_root_logger().setLevel(verbosity) + + +def set_verbosity_info(): + """Set the level for the Hugging Face Evaluate library's root logger to `INFO`. + + This will display most of the logging information and tqdm bars. + + Shortcut to `evaluate.logging.set_verbosity(evaluate.logging.INFO)`. + """ + return set_verbosity(INFO) + + +def set_verbosity_warning(): + """Set the level for the Hugging Face Evaluate library's root logger to `WARNING`. + + This will display only the warning and errors logging information and tqdm bars. + + Shortcut to `evaluate.logging.set_verbosity(evaluate.logging.WARNING)`. + """ + return set_verbosity(WARNING) + + +def set_verbosity_debug(): + """Set the level for the Hugging Face Evaluate library's root logger to `DEBUG`. + + This will display all the logging information and tqdm bars. + + Shortcut to `evaluate.logging.set_verbosity(evaluate.logging.DEBUG)`. + """ + return set_verbosity(DEBUG) + + +def set_verbosity_error(): + """Set the level for the Hugging Face Evaluate library's root logger to `ERROR`. + + This will display only the errors logging information and tqdm bars. + + Shortcut to `evaluate.logging.set_verbosity(evaluate.logging.ERROR)`. + """ + return set_verbosity(ERROR) + + +def disable_propagation() -> None: + """Disable propagation of the library log outputs. + Note that log propagation is disabled by default. + """ + _get_library_root_logger().propagate = False + + +def enable_propagation() -> None: + """Enable propagation of the library log outputs. + Please disable the Hugging Face Evaluate library's default handler to prevent double logging if the root logger has + been configured. + """ + _get_library_root_logger().propagate = True + + +# Configure the library root logger at the module level (singleton-like) +_configure_library_root_logger() + + +class EmptyTqdm: + """Dummy tqdm which doesn't do anything.""" + + def __init__(self, *args, **kwargs): # pylint: disable=unused-argument + self._iterator = args[0] if args else None + + def __iter__(self): + return iter(self._iterator) + + def __getattr__(self, _): + """Return empty function.""" + + def empty_fn(*args, **kwargs): # pylint: disable=unused-argument + return + + return empty_fn + + def __enter__(self): + return self + + def __exit__(self, type_, value, traceback): + return + + +_tqdm_active = True + + +class _tqdm_cls: + def __call__(self, *args, **kwargs): + if _tqdm_active: + return tqdm_lib.tqdm(*args, **kwargs) + else: + return EmptyTqdm(*args, **kwargs) + + def set_lock(self, *args, **kwargs): + self._lock = None + if _tqdm_active: + return tqdm_lib.tqdm.set_lock(*args, **kwargs) + + def get_lock(self): + if _tqdm_active: + return tqdm_lib.tqdm.get_lock() + + +tqdm = _tqdm_cls() + + +def is_progress_bar_enabled() -> bool: + """Return a boolean indicating whether tqdm progress bars are enabled.""" + return bool(_tqdm_active) + + +def enable_progress_bar(): + """Enable tqdm progress bar.""" + global _tqdm_active + _tqdm_active = True + + +def disable_progress_bar(): + """Enable tqdm progress bar.""" + global _tqdm_active + _tqdm_active = False diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/licenses/LICENSE b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/licenses/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/sboms/hf_xet.cyclonedx.json b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/sboms/hf_xet.cyclonedx.json new file mode 100644 index 0000000000000000000000000000000000000000..0d428a16fade54a583c7ee17489a129e7828e423 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/sboms/hf_xet.cyclonedx.json @@ -0,0 +1,12019 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "serialNumber": "urn:uuid:8142c7e6-0d78-4fdc-8071-fe9a0e46fe4a", + "metadata": { + "timestamp": "2026-02-27T17:17:38.240074353Z", + "tools": [ + { + "vendor": "CycloneDX", + "name": "cargo-cyclonedx", + "version": "0.5.7" + } + ], + "component": { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/hf_xet#1.3.2", + "name": "hf_xet", + "version": "1.3.2", + "scope": "required", + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/hf_xet@1.3.2?download_url=file://.", + "components": [ + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/hf_xet#1.3.2 bin-target-0", + "name": "hf_xet", + "version": "1.3.2", + "purl": "pkg:cargo/hf_xet@1.3.2?download_url=file://.#src/lib.rs" + } + ] + }, + "properties": [ + { + "name": "cdx:rustc:sbom:target:all_targets", + "value": "true" + } + ] + }, + "components": [ + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/cas_client#0.14.5", + "name": "cas_client", + "version": "0.14.5", + "scope": "required", + "purl": "pkg:cargo/cas_client@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/cas_client" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/cas_object#0.1.0", + "name": "cas_object", + "version": "0.1.0", + "scope": "required", + "purl": "pkg:cargo/cas_object@0.1.0?download_url=file:///home/runner/work/xet-core/xet-core/cas_object" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/cas_types#0.1.0", + "name": "cas_types", + "version": "0.1.0", + "scope": "required", + "purl": "pkg:cargo/cas_types@0.1.0?download_url=file:///home/runner/work/xet-core/xet-core/cas_types" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/data#0.14.5", + "name": "data", + "version": "0.14.5", + "scope": "required", + "purl": "pkg:cargo/data@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/data" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/deduplication#0.14.5", + "name": "deduplication", + "version": "0.14.5", + "scope": "required", + "purl": "pkg:cargo/deduplication@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/deduplication" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/error_printer#0.14.5", + "name": "error_printer", + "version": "0.14.5", + "scope": "required", + "purl": "pkg:cargo/error_printer@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/error_printer" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/file_reconstruction#0.14.5", + "name": "file_reconstruction", + "version": "0.14.5", + "scope": "required", + "purl": "pkg:cargo/file_reconstruction@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/file_reconstruction" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/file_utils#0.14.2", + "name": "file_utils", + "version": "0.14.2", + "scope": "required", + "purl": "pkg:cargo/file_utils@0.14.2?download_url=file:///home/runner/work/xet-core/xet-core/file_utils" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/hub_client#0.1.0", + "name": "hub_client", + "version": "0.1.0", + "scope": "required", + "purl": "pkg:cargo/hub_client@0.1.0?download_url=file:///home/runner/work/xet-core/xet-core/hub_client" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/mdb_shard#0.14.5", + "name": "mdb_shard", + "version": "0.14.5", + "scope": "required", + "purl": "pkg:cargo/mdb_shard@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/mdb_shard" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5", + "name": "merklehash", + "version": "0.14.5", + "scope": "required", + "purl": "pkg:cargo/merklehash@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/merklehash" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/progress_tracking#0.1.0", + "name": "progress_tracking", + "version": "0.1.0", + "scope": "required", + "purl": "pkg:cargo/progress_tracking@0.1.0?download_url=file:///home/runner/work/xet-core/xet-core/progress_tracking" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5", + "name": "utils", + "version": "0.14.5", + "scope": "required", + "purl": "pkg:cargo/utils@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/utils" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/xet_config#0.14.5", + "name": "xet_config", + "version": "0.14.5", + "scope": "required", + "purl": "pkg:cargo/xet_config@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/xet_config" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/xet_logging#0.14.5", + "name": "xet_logging", + "version": "0.14.5", + "scope": "required", + "purl": "pkg:cargo/xet_logging@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/xet_logging" + }, + { + "type": "library", + "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#0.1.0", + "name": "xet_runtime", + "version": "0.1.0", + "scope": "required", + "purl": "pkg:cargo/xet_runtime@0.1.0?download_url=file:///home/runner/work/xet-core/xet-core/xet_runtime" + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#aho-corasick@1.1.4", + "author": "Andrew Gallant ", + "name": "aho-corasick", + "version": "1.1.4", + "description": "Fast multiple substring searching.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/aho-corasick@1.1.4", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/BurntSushi/aho-corasick" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/aho-corasick" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstream@0.6.21", + "name": "anstream", + "version": "0.6.21", + "description": "IO stream adapters for writing colored text that will gracefully degrade according to your terminal's capabilities.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/anstream@0.6.21", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-cli/anstyle.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle-parse@0.2.7", + "name": "anstyle-parse", + "version": "0.2.7", + "description": "Parse ANSI Style Escapes", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/anstyle-parse@0.2.7", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-cli/anstyle.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle-query@1.1.5", + "name": "anstyle-query", + "version": "1.1.5", + "description": "Look up colored console capabilities", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/anstyle-query@1.1.5", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-cli/anstyle.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle@1.0.13", + "name": "anstyle", + "version": "1.0.13", + "description": "ANSI text styling", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/anstyle@1.0.13", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-cli/anstyle.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.101", + "author": "David Tolnay ", + "name": "anyhow", + "version": "1.0.101", + "description": "Flexible concrete Error type built on std::error::Error", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/anyhow@1.0.101", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/anyhow" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/anyhow" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#approx@0.5.1", + "author": "Brendan Zabarauskas ", + "name": "approx", + "version": "0.5.1", + "description": "Approximate floating point equality comparisons and assertions.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" + } + ], + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/approx@0.5.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/approx" + }, + { + "type": "website", + "url": "https://github.com/brendanzab/approx" + }, + { + "type": "vcs", + "url": "https://github.com/brendanzab/approx" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#arrayref@0.3.9", + "author": "David Roundy ", + "name": "arrayref", + "version": "0.3.9", + "description": "Macros to take array references of slices", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + } + ], + "licenses": [ + { + "expression": "BSD-2-Clause" + } + ], + "purl": "pkg:cargo/arrayref@0.3.9", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/arrayref" + }, + { + "type": "vcs", + "url": "https://github.com/droundy/arrayref" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#arrayvec@0.7.6", + "author": "bluss", + "name": "arrayvec", + "version": "0.7.6", + "description": "A vector with fixed capacity, backed by an array (it can be stored on the stack too). Implements fixed capacity ArrayVec and ArrayString.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/arrayvec@0.7.6", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/arrayvec/" + }, + { + "type": "vcs", + "url": "https://github.com/bluss/arrayvec" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "author": "David Tolnay ", + "name": "async-trait", + "version": "0.1.89", + "description": "Type erasure for async trait methods", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/async-trait@0.1.89", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/async-trait" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/async-trait" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#atomic-waker@1.1.2", + "author": "Stjepan Glavina , Contributors to futures-rs", + "name": "atomic-waker", + "version": "1.1.2", + "description": "A synchronization primitive for task wakeup", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/atomic-waker@1.1.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/smol-rs/atomic-waker" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0", + "author": "Josh Stone ", + "name": "autocfg", + "version": "1.5.0", + "description": "Automatic cfg for Rust compiler features", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/autocfg@1.5.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/autocfg/" + }, + { + "type": "vcs", + "url": "https://github.com/cuviper/autocfg" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#aws-lc-rs@1.15.4", + "author": "AWS-LibCrypto", + "name": "aws-lc-rs", + "version": "1.15.4", + "description": "aws-lc-rs is a cryptographic library using AWS-LC for its cryptographic operations. This library strives to be API-compatible with the popular Rust library named ring.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256" + } + ], + "licenses": [ + { + "expression": "ISC AND (Apache-2.0 OR ISC)" + } + ], + "purl": "pkg:cargo/aws-lc-rs@1.15.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/crate/aws-lc-rs" + }, + { + "type": "website", + "url": "https://github.com/aws/aws-lc-rs" + }, + { + "type": "other", + "url": "aws_lc_rs_1_15_4_sys" + }, + { + "type": "vcs", + "url": "https://github.com/aws/aws-lc-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#aws-lc-sys@0.37.0", + "author": "AWS-LC", + "name": "aws-lc-sys", + "version": "0.37.0", + "description": "AWS-LC is a general-purpose cryptographic library maintained by the AWS Cryptography team for AWS and their customers. It іs based on code from the Google BoringSSL project and the OpenSSL project.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "5c34dda4df7017c8db52132f0f8a2e0f8161649d15723ed63fc00c82d0f2081a" + } + ], + "licenses": [ + { + "expression": "ISC AND (Apache-2.0 OR ISC) AND OpenSSL" + } + ], + "purl": "pkg:cargo/aws-lc-sys@0.37.0", + "externalReferences": [ + { + "type": "other", + "url": "aws_lc_0_37_0" + }, + { + "type": "vcs", + "url": "https://github.com/aws/aws-lc-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#axum-core@0.5.6", + "name": "axum-core", + "version": "0.5.6", + "description": "Core types and traits for axum", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/axum-core@0.5.6", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/tokio-rs/axum" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/axum" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#axum@0.8.8", + "name": "axum", + "version": "0.8.8", + "description": "Web framework that focuses on ergonomics and modularity", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/axum@0.8.8", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/tokio-rs/axum" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/axum" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "author": "Marshall Pierce ", + "name": "base64", + "version": "0.22.1", + "description": "encodes and decodes base64 as bytes or utf8", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/base64@0.22.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/base64" + }, + { + "type": "vcs", + "url": "https://github.com/marshallpierce/rust-base64" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bincode@1.3.3", + "author": "Ty Overby , Francesco Mazzoli , David Tolnay , Zoey Riordan ", + "name": "bincode", + "version": "1.3.3", + "description": "A binary serialization / deserialization strategy that uses Serde for transforming structs into bytes and vice versa!", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/bincode@1.3.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/bincode" + }, + { + "type": "vcs", + "url": "https://github.com/servo/bincode" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bitflags@2.10.0", + "author": "The Rust Project Developers", + "name": "bitflags", + "version": "2.10.0", + "description": "A macro to generate structures which behave like bitflags. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/bitflags@2.10.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/bitflags" + }, + { + "type": "website", + "url": "https://github.com/bitflags/bitflags" + }, + { + "type": "vcs", + "url": "https://github.com/bitflags/bitflags" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#blake3@1.8.3", + "author": "Jack O'Connor , Samuel Neves", + "name": "blake3", + "version": "1.8.3", + "description": "the BLAKE3 hash function", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d" + } + ], + "licenses": [ + { + "expression": "CC0-1.0 OR Apache-2.0 OR Apache-2.0 WITH LLVM-exception" + } + ], + "purl": "pkg:cargo/blake3@1.8.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/blake3" + }, + { + "type": "vcs", + "url": "https://github.com/BLAKE3-team/BLAKE3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#block-buffer@0.10.4", + "author": "RustCrypto Developers", + "name": "block-buffer", + "version": "0.10.4", + "description": "Buffer type for block processing of data", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/block-buffer@0.10.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/block-buffer" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/utils" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bstr@1.12.1", + "author": "Andrew Gallant ", + "name": "bstr", + "version": "1.12.1", + "description": "A string type that is not required to be valid UTF-8.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/bstr@1.12.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/bstr" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/bstr" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/bstr" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.25.0", + "author": "Lokathor ", + "name": "bytemuck", + "version": "1.25.0", + "description": "A crate for mucking around with piles of bytes.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + } + ], + "licenses": [ + { + "expression": "Zlib OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/bytemuck@1.25.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Lokathor/bytemuck" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#byteorder@1.5.0", + "author": "Andrew Gallant ", + "name": "byteorder", + "version": "1.5.0", + "description": "Library for reading/writing numbers in big-endian and little-endian.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/byteorder@1.5.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/byteorder" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/byteorder" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/byteorder" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "author": "Carl Lerche , Sean McArthur ", + "name": "bytes", + "version": "1.11.1", + "description": "Types and traits for working with bytes", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/bytes@1.11.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/tokio-rs/bytes" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.55", + "author": "Alex Crichton ", + "name": "cc", + "version": "1.2.55", + "description": "A build-time dependency for Cargo build scripts to assist in invoking the native C compiler to compile native C code into a static archive to be linked into Rust code. ", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/cc@1.2.55", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/cc" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/cc-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/cc-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cfg-if@0.1.10", + "author": "Alex Crichton ", + "name": "cfg-if", + "version": "0.1.10", + "description": "A macro to ergonomically define an item depending on a large number of #[cfg] parameters. Structured like an if-else chain, the first matching branch is the item that gets emitted. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/cfg-if@0.1.10", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/cfg-if" + }, + { + "type": "website", + "url": "https://github.com/alexcrichton/cfg-if" + }, + { + "type": "vcs", + "url": "https://github.com/alexcrichton/cfg-if" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "author": "Alex Crichton ", + "name": "cfg-if", + "version": "1.0.4", + "description": "A macro to ergonomically define an item depending on a large number of #[cfg] parameters. Structured like an if-else chain, the first matching branch is the item that gets emitted. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/cfg-if@1.0.4", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-lang/cfg-if" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cfg_aliases@0.2.1", + "author": "Zicklag ", + "name": "cfg_aliases", + "version": "0.2.1", + "description": "A tiny utility to help save you a lot of effort with long winded `#[cfg()]` checks.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/cfg_aliases@0.2.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/cfg_aliases" + }, + { + "type": "website", + "url": "https://github.com/katharostech/cfg_aliases" + }, + { + "type": "vcs", + "url": "https://github.com/katharostech/cfg_aliases" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.43", + "name": "chrono", + "version": "0.4.43", + "description": "Date and time library for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/chrono@0.4.43", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/chrono/" + }, + { + "type": "website", + "url": "https://github.com/chronotope/chrono" + }, + { + "type": "vcs", + "url": "https://github.com/chronotope/chrono" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap@4.5.57", + "name": "clap", + "version": "4.5.57", + "description": "A simple to use, efficient, and full-featured Command Line Argument Parser", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/clap@4.5.57", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/clap-rs/clap" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap_builder@4.5.57", + "name": "clap_builder", + "version": "4.5.57", + "description": "A simple to use, efficient, and full-featured Command Line Argument Parser", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/clap_builder@4.5.57", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/clap-rs/clap" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap_derive@4.5.55", + "name": "clap_derive", + "version": "4.5.55", + "description": "Parse command line argument by defining a struct, derive crate.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/clap_derive@4.5.55", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/clap-rs/clap" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap_lex@0.7.7", + "name": "clap_lex", + "version": "0.7.7", + "description": "Minimal, flexible command line parser", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/clap_lex@0.7.7", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/clap-rs/clap" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cmake@0.1.57", + "author": "Alex Crichton ", + "name": "cmake", + "version": "0.1.57", + "description": "A build dependency for running `cmake` to build a native library ", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/cmake@0.1.57", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/cmake" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/cmake-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/cmake-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#colorchoice@1.0.4", + "name": "colorchoice", + "version": "1.0.4", + "description": "Global override of color control", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/colorchoice@1.0.4", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-cli/anstyle.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#colored@3.1.1", + "author": "Thomas Wickham ", + "name": "colored", + "version": "3.1.1", + "description": "The most simple way to add colors in your terminal", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" + } + ], + "licenses": [ + { + "expression": "MPL-2.0" + } + ], + "purl": "pkg:cargo/colored@3.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/mackwic/colored" + }, + { + "type": "vcs", + "url": "https://github.com/mackwic/colored" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#const-str@1.1.0", + "author": "Nugine ", + "name": "const-str", + "version": "1.1.0", + "description": "compile-time string operations", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "18f12cc9948ed9604230cdddc7c86e270f9401ccbe3c2e98a4378c5e7632212f" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/const-str@1.1.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Nugine/const-str" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#const_panic@0.2.15", + "author": "rodrimati1992 ", + "name": "const_panic", + "version": "0.2.15", + "description": "const panic with formatting", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e262cdaac42494e3ae34c43969f9cdeb7da178bdb4b66fa6a1ea2edb4c8ae652" + } + ], + "licenses": [ + { + "expression": "Zlib" + } + ], + "purl": "pkg:cargo/const_panic@0.2.15", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rodrimati1992/const_panic/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#constant_time_eq@0.4.2", + "author": "Cesar Eduardo Barros ", + "name": "constant_time_eq", + "version": "0.4.2", + "description": "Compares two equal-sized byte strings in constant time.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + } + ], + "licenses": [ + { + "expression": "CC0-1.0 OR MIT-0 OR Apache-2.0" + } + ], + "purl": "pkg:cargo/constant_time_eq@0.4.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/constant_time_eq" + }, + { + "type": "vcs", + "url": "https://github.com/cesarb/constant_time_eq" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#countio@0.3.0", + "author": "Oleh Martsokha ", + "name": "countio", + "version": "0.3.0", + "description": "Byte counting for std::io::{Read, Write, Seek} and its async variants from futures and tokio. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b9702aee5d1d744c01d82f6915644f950f898e014903385464c773b96fefdecb" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/countio@0.3.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/countio" + }, + { + "type": "website", + "url": "https://github.com/spire-rs/countio" + }, + { + "type": "vcs", + "url": "https://github.com/spire-rs/countio" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17", + "author": "RustCrypto Developers", + "name": "cpufeatures", + "version": "0.2.17", + "description": "Lightweight runtime CPU feature detection for aarch64, loongarch64, and x86/x86_64 targets, with no_std support and support for mobile targets including Android and iOS ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/cpufeatures@0.2.17", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/cpufeatures" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/utils" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-channel@0.5.15", + "name": "crossbeam-channel", + "version": "0.5.15", + "description": "Multi-producer multi-consumer channels for message passing", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/crossbeam-channel@0.5.15", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel" + }, + { + "type": "vcs", + "url": "https://github.com/crossbeam-rs/crossbeam" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-queue@0.3.12", + "name": "crossbeam-queue", + "version": "0.3.12", + "description": "Concurrent queues", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/crossbeam-queue@0.3.12", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-queue" + }, + { + "type": "vcs", + "url": "https://github.com/crossbeam-rs/crossbeam" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21", + "name": "crossbeam-utils", + "version": "0.8.21", + "description": "Utilities for concurrent programming", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/crossbeam-utils@0.8.21", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils" + }, + { + "type": "vcs", + "url": "https://github.com/crossbeam-rs/crossbeam" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crypto-common@0.1.7", + "author": "RustCrypto Developers", + "name": "crypto-common", + "version": "0.1.7", + "description": "Common cryptographic traits", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/crypto-common@0.1.7", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/crypto-common" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/traits" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#csv-core@0.1.13", + "author": "Andrew Gallant ", + "name": "csv-core", + "version": "0.1.13", + "description": "Bare bones CSV parsing with no_std support.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/csv-core@0.1.13", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/csv-core" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/rust-csv" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/rust-csv" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#csv@1.4.0", + "author": "Andrew Gallant ", + "name": "csv", + "version": "1.4.0", + "description": "Fast CSV parsing with support for serde.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/csv@1.4.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/csv" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/rust-csv" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/rust-csv" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ctor-proc-macro@0.0.7", + "author": "Matt Mastracci ", + "name": "ctor-proc-macro", + "version": "0.0.7", + "description": "proc-macro support for the ctor crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/ctor-proc-macro@0.0.7", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/mmastrac/rust-ctor" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ctor@0.6.3", + "author": "Matt Mastracci ", + "name": "ctor", + "version": "0.6.3", + "description": "__attribute__((constructor)) for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "424e0138278faeb2b401f174ad17e715c829512d74f3d1e81eb43365c2e0590e" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/ctor@0.6.3", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/mmastrac/rust-ctor" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#deranged@0.5.5", + "author": "Jacob Pratt ", + "name": "deranged", + "version": "0.5.5", + "description": "Ranged integers", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/deranged@0.5.5", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/jhpratt/deranged" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#derivative@2.2.0", + "author": "mcarton ", + "name": "derivative", + "version": "2.2.0", + "description": "A set of alternative `derive` attributes for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/derivative@2.2.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://mcarton.github.io/rust-derivative/" + }, + { + "type": "vcs", + "url": "https://github.com/mcarton/rust-derivative" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7", + "author": "RustCrypto Developers", + "name": "digest", + "version": "0.10.7", + "description": "Traits for cryptographic hash functions and message authentication codes", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/digest@0.10.7", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/digest" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/traits" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dirs-sys@0.5.0", + "author": "Simon Ochsenreither ", + "name": "dirs-sys", + "version": "0.5.0", + "description": "System-level helper functions for the dirs and directories crates.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/dirs-sys@0.5.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/dirs-dev/dirs-sys-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0", + "author": "Simon Ochsenreither ", + "name": "dirs", + "version": "6.0.0", + "description": "A tiny low-level library that provides platform-specific standard locations of directories for config, cache and other data on Linux, Windows, macOS and Redox by leveraging the mechanisms defined by the XDG base/user directory specifications on Linux, the Known Folder API on Windows, and the Standard Directory guidelines on macOS.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/dirs@6.0.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/soc/dirs-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "author": "Jane Lusby ", + "name": "displaydoc", + "version": "0.2.5", + "description": "A derive macro for implementing the display Trait via a doc comment and string interpolation ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/displaydoc@0.2.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/displaydoc" + }, + { + "type": "website", + "url": "https://github.com/yaahc/displaydoc" + }, + { + "type": "vcs", + "url": "https://github.com/yaahc/displaydoc" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#doxygen-rs@0.4.2", + "name": "doxygen-rs", + "version": "0.4.2", + "description": "Transform Doxygen to Rustdoc", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "415b6ec780d34dcf624666747194393603d0373b7141eef01d12ee58881507d9" + } + ], + "licenses": [ + { + "expression": "BSD-3-Clause" + } + ], + "purl": "pkg:cargo/doxygen-rs@0.4.2", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/Techie-Pi/doxygen-rs/" + }, + { + "type": "vcs", + "url": "https://github.com/Techie-Pi/doxygen-rs/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dtor-proc-macro@0.0.6", + "author": "Matt Mastracci ", + "name": "dtor-proc-macro", + "version": "0.0.6", + "description": "proc-macro support for the dtor crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/dtor-proc-macro@0.0.6", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/mmastrac/rust-ctor" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dtor@0.1.1", + "author": "Matt Mastracci ", + "name": "dtor", + "version": "0.1.1", + "description": "__attribute__((destructor)) for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/dtor@0.1.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/mmastrac/rust-ctor" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dunce@1.0.5", + "author": "Kornel ", + "name": "dunce", + "version": "1.0.5", + "description": "Normalize Windows paths to the most compatible format, avoiding UNC where possible", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + } + ], + "licenses": [ + { + "expression": "CC0-1.0 OR MIT-0 OR Apache-2.0" + } + ], + "purl": "pkg:cargo/dunce@1.0.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/dunce" + }, + { + "type": "website", + "url": "https://lib.rs/crates/dunce" + }, + { + "type": "vcs", + "url": "https://gitlab.com/kornelski/dunce" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#duration-str@0.19.0", + "author": "baoyachi ", + "name": "duration-str", + "version": "0.19.0", + "description": "duration string parser", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "12494809f9915b6132014cc259c4e204ab53ab6c6dd2225672703b5359267d82" + } + ], + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/duration-str@0.19.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/baoyachi/duration-str" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#either@1.15.0", + "author": "bluss", + "name": "either", + "version": "1.15.0", + "description": "The enum `Either` with variants `Left` and `Right` is a general purpose sum type with two cases. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/either@1.15.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/either/1/" + }, + { + "type": "vcs", + "url": "https://github.com/rayon-rs/either" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#equivalent@1.0.2", + "name": "equivalent", + "version": "1.0.2", + "description": "Traits for key comparison in maps.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/equivalent@1.0.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/indexmap-rs/equivalent" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#errno@0.3.14", + "author": "Chris Wong , Dan Gohman ", + "name": "errno", + "version": "0.3.14", + "description": "Cross-platform interface to the `errno` variable.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/errno@0.3.14", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/errno" + }, + { + "type": "vcs", + "url": "https://github.com/lambda-fairy/rust-errno" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0", + "author": "Stjepan Glavina ", + "name": "fastrand", + "version": "2.3.0", + "description": "A simple and fast random number generator", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/fastrand@2.3.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/smol-rs/fastrand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#find-msvc-tools@0.1.9", + "name": "find-msvc-tools", + "version": "0.1.9", + "description": "Find windows-specific tools, read MSVC versions from the registry and from COM interfaces", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/find-msvc-tools@0.1.9", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/find-msvc-tools" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/cc-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#fnv@1.0.7", + "author": "Alex Crichton ", + "name": "fnv", + "version": "1.0.7", + "description": "Fowler–Noll–Vo hash function", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/fnv@1.0.7", + "externalReferences": [ + { + "type": "documentation", + "url": "https://doc.servo.org/fnv/" + }, + { + "type": "vcs", + "url": "https://github.com/servo/rust-fnv" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.2", + "author": "The rust-url developers", + "name": "form_urlencoded", + "version": "1.2.2", + "description": "Parser and serializer for the application/x-www-form-urlencoded syntax, as used by HTML forms.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/form_urlencoded@1.2.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/servo/rust-url" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#fs_extra@1.3.0", + "author": "Denis Kurilenko ", + "name": "fs_extra", + "version": "1.3.0", + "description": "Expanding std::fs and std::io. Recursively copy folders with information about process and much more.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/fs_extra@1.3.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/fs_extra" + }, + { + "type": "website", + "url": "https://github.com/webdesus/fs_extra" + }, + { + "type": "vcs", + "url": "https://github.com/webdesus/fs_extra" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.31", + "name": "futures-channel", + "version": "0.3.31", + "description": "Channels for asynchronous communication using futures-rs. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-channel@0.3.31", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "name": "futures-core", + "version": "0.3.31", + "description": "The core traits and types in for the `futures` library. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-core@0.3.31", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-executor@0.3.31", + "name": "futures-executor", + "version": "0.3.31", + "description": "Executors for asynchronous tasks based on the futures-rs library. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-executor@0.3.31", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.31", + "name": "futures-io", + "version": "0.3.31", + "description": "The `AsyncRead`, `AsyncWrite`, `AsyncSeek`, and `AsyncBufRead` traits for the futures-rs library. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-io@0.3.31", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-macro@0.3.31", + "name": "futures-macro", + "version": "0.3.31", + "description": "The futures-rs procedural macro implementations. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-macro@0.3.31", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.31", + "name": "futures-sink", + "version": "0.3.31", + "description": "The asynchronous `Sink` trait for the futures-rs library. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-sink@0.3.31", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.31", + "name": "futures-task", + "version": "0.3.31", + "description": "Tools for working with tasks. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-task@0.3.31", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31", + "name": "futures-util", + "version": "0.3.31", + "description": "Common utilities and extension traits for the futures-rs library. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures-util@0.3.31", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.31", + "name": "futures", + "version": "0.3.31", + "description": "An implementation of futures and streams featuring zero allocations, composability, and iterator-like interfaces. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/futures@0.3.31", + "externalReferences": [ + { + "type": "website", + "url": "https://rust-lang.github.io/futures-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/futures-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#gearhash@0.1.3", + "author": "Sam Rijs ", + "name": "gearhash", + "version": "0.1.3", + "description": "Fast, SIMD-accelerated hash function for content-defined chunking", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c8cf82cf76cd16485e56295a1377c775ce708c9f1a0be6b029076d60a245d213" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/gearhash@0.1.3", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/srijs/rust-gearhash" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#generic-array@0.14.7", + "author": "Bartłomiej Kamiński , Aaron Trent ", + "name": "generic-array", + "version": "0.14.7", + "description": "Generic types implementing functionality of arrays", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/generic-array@0.14.7", + "externalReferences": [ + { + "type": "documentation", + "url": "http://fizyk20.github.io/generic-array/generic_array/" + }, + { + "type": "vcs", + "url": "https://github.com/fizyk20/generic-array.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.2.17", + "author": "The Rand Project Developers", + "name": "getrandom", + "version": "0.2.17", + "description": "A small cross-platform library for retrieving random data from system source", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/getrandom@0.2.17", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/getrandom" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/getrandom" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4", + "author": "The Rand Project Developers", + "name": "getrandom", + "version": "0.3.4", + "description": "A small cross-platform library for retrieving random data from system source", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/getrandom@0.3.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/getrandom" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/getrandom" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.1", + "author": "The Rand Project Developers", + "name": "getrandom", + "version": "0.4.1", + "description": "A small cross-platform library for retrieving random data from system source", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/getrandom@0.4.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/getrandom" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/getrandom" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#git-version-macro@0.3.9", + "author": "David Roundy , Maarten de Vries , Mara Bos ", + "name": "git-version-macro", + "version": "0.3.9", + "description": "Internal macro crate for git-version.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" + } + ], + "licenses": [ + { + "expression": "BSD-2-Clause" + } + ], + "purl": "pkg:cargo/git-version-macro@0.3.9", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/fusion-engineering/rust-git-version" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#git-version@0.3.9", + "author": "Mara Bos , Maarten de Vries , David Roundy ", + "name": "git-version", + "version": "0.3.9", + "description": "Compile the git version (tag name, or hash otherwise) and dirty state into your program.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" + } + ], + "licenses": [ + { + "expression": "BSD-2-Clause" + } + ], + "purl": "pkg:cargo/git-version@0.3.9", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/git-version/" + }, + { + "type": "vcs", + "url": "https://github.com/fusion-engineering/rust-git-version" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#h2@0.4.13", + "author": "Carl Lerche , Sean McArthur ", + "name": "h2", + "version": "0.4.13", + "description": "An HTTP/2 client and server", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/h2@0.4.13", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/h2" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/h2" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#half@2.7.1", + "author": "Kathryn Long ", + "name": "half", + "version": "2.7.1", + "description": "Half-precision floating point f16 and bf16 types for Rust implementing the IEEE 754-2008 standard binary16 and bfloat16 types.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/half@2.7.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/VoidStarKat/half-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.16.1", + "author": "Amanieu d'Antras ", + "name": "hashbrown", + "version": "0.16.1", + "description": "A Rust port of Google's SwissTable hash map", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/hashbrown@0.16.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-lang/hashbrown" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#headers-core@0.3.0", + "author": "Sean McArthur ", + "name": "headers-core", + "version": "0.3.0", + "description": "typed HTTP headers core trait", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/headers-core@0.3.0", + "externalReferences": [ + { + "type": "website", + "url": "https://hyper.rs" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/headers" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#headers@0.4.1", + "author": "Sean McArthur ", + "name": "headers", + "version": "0.4.1", + "description": "typed HTTP headers", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/headers@0.4.1", + "externalReferences": [ + { + "type": "website", + "url": "https://hyper.rs" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/headers" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heapify@0.2.0", + "name": "heapify", + "version": "0.2.0", + "description": "Convenience functions to turn slices into max-heaps.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "0049b265b7f201ca9ab25475b22b47fe444060126a51abe00f77d986fc5cc52e" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/heapify@0.2.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/ethereal-sheep/heapify" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heck@0.5.0", + "name": "heck", + "version": "0.5.0", + "description": "heck is a case conversion library.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/heck@0.5.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/withoutboats/heck" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heed-traits@0.20.0", + "author": "Kerollmops ", + "name": "heed-traits", + "version": "0.20.0", + "description": "The traits used inside of the fully typed LMDB wrapper, heed", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "eb3130048d404c57ce5a1ac61a903696e8fcde7e8c2991e9fcfc1f27c3ef74ff" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/heed-traits@0.20.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Kerollmops/heed" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heed-types@0.21.0", + "author": "Kerollmops ", + "name": "heed-types", + "version": "0.21.0", + "description": "The types used with the fully typed LMDB wrapper, heed", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "13c255bdf46e07fb840d120a36dcc81f385140d7191c76a7391672675c01a55d" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/heed-types@0.21.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Kerollmops/heed" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heed@0.22.0", + "author": "Kerollmops ", + "name": "heed", + "version": "0.22.0", + "description": "A fully typed LMDB (mdb.master) wrapper with minimum overhead", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6a56c94661ddfb51aa9cdfbf102cfcc340aa69267f95ebccc4af08d7c530d393" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/heed@0.22.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Kerollmops/heed" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.3", + "author": "Carl Lerche , Lucio Franco , Sean McArthur ", + "name": "http-body-util", + "version": "0.1.3", + "description": "Combinators and adapters for HTTP request or response bodies. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/http-body-util@0.1.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/http-body-util" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/http-body" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "author": "Carl Lerche , Lucio Franco , Sean McArthur ", + "name": "http-body", + "version": "1.0.1", + "description": "Trait representing an asynchronous, streaming, HTTP request or response body. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/http-body@1.0.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/http-body" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/http-body" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "author": "Alex Crichton , Carl Lerche , Sean McArthur ", + "name": "http", + "version": "1.4.0", + "description": "A set of types for representing HTTP requests and responses. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/http@1.4.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/http" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/http" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1", + "author": "Sean McArthur ", + "name": "httparse", + "version": "1.10.1", + "description": "A tiny, safe, speedy, zero-copy HTTP/1.x parser.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/httparse@1.10.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/httparse" + }, + { + "type": "vcs", + "url": "https://github.com/seanmonstar/httparse" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#httpdate@1.0.3", + "author": "Pyfisch ", + "name": "httpdate", + "version": "1.0.3", + "description": "HTTP date parsing and formatting", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/httpdate@1.0.3", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/pyfisch/httpdate" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#hyper-rustls@0.27.7", + "name": "hyper-rustls", + "version": "0.27.7", + "description": "Rustls+hyper integration for pure rust HTTPS", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR ISC OR MIT" + } + ], + "purl": "pkg:cargo/hyper-rustls@0.27.7", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/hyper-rustls/" + }, + { + "type": "website", + "url": "https://github.com/rustls/hyper-rustls" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/hyper-rustls" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.20", + "author": "Sean McArthur ", + "name": "hyper-util", + "version": "0.1.20", + "description": "hyper utilities", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/hyper-util@0.1.20", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/hyper-util" + }, + { + "type": "website", + "url": "https://hyper.rs" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/hyper-util" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "author": "Sean McArthur ", + "name": "hyper", + "version": "1.8.1", + "description": "A protective and efficient HTTP library for all.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/hyper@1.8.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/hyper" + }, + { + "type": "website", + "url": "https://hyper.rs" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/hyper" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#iana-time-zone@0.1.65", + "author": "Andrew Straw , René Kijewski , Ryan Lopopolo ", + "name": "iana-time-zone", + "version": "0.1.65", + "description": "get the IANA time zone for the current system", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/iana-time-zone@0.1.65", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/strawlab/iana-time-zone" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1", + "author": "The ICU4X Project Developers", + "name": "icu_collections", + "version": "2.1.1", + "description": "Collection of API for use in ICU libraries.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_collections@2.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_locale_core@2.1.1", + "author": "The ICU4X Project Developers", + "name": "icu_locale_core", + "version": "2.1.1", + "description": "API for managing Unicode Language and Locale Identifiers", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_locale_core@2.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer@2.1.1", + "author": "The ICU4X Project Developers", + "name": "icu_normalizer", + "version": "2.1.1", + "description": "API for normalizing text into Unicode Normalization Forms", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_normalizer@2.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer_data@2.1.1", + "author": "The ICU4X Project Developers", + "name": "icu_normalizer_data", + "version": "2.1.1", + "description": "Data for the icu_normalizer crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_normalizer_data@2.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2", + "author": "The ICU4X Project Developers", + "name": "icu_properties", + "version": "2.1.2", + "description": "Definitions for Unicode properties", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_properties@2.1.2", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_properties_data@2.1.2", + "author": "The ICU4X Project Developers", + "name": "icu_properties_data", + "version": "2.1.2", + "description": "Data for the icu_properties crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_properties_data@2.1.2", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_provider@2.1.1", + "author": "The ICU4X Project Developers", + "name": "icu_provider", + "version": "2.1.1", + "description": "Trait and struct definitions for the ICU data provider", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/icu_provider@2.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#idna@1.1.0", + "author": "The rust-url developers", + "name": "idna", + "version": "1.1.0", + "description": "IDNA (Internationalizing Domain Names in Applications) and Punycode.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/idna@1.1.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/servo/rust-url/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#idna_adapter@1.2.1", + "author": "The rust-url developers", + "name": "idna_adapter", + "version": "1.2.1", + "description": "Back end adapter for idna", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/idna_adapter@1.2.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/idna_adapter/latest/idna_adapter/" + }, + { + "type": "website", + "url": "https://docs.rs/crate/idna_adapter/latest" + }, + { + "type": "vcs", + "url": "https://github.com/hsivonen/idna_adapter" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#indexmap@2.13.0", + "name": "indexmap", + "version": "2.13.0", + "description": "A hash table with consistent order and fast iteration.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/indexmap@2.13.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/indexmap/" + }, + { + "type": "vcs", + "url": "https://github.com/indexmap-rs/indexmap" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#indoc@2.0.7", + "author": "David Tolnay ", + "name": "indoc", + "version": "2.0.7", + "description": "Indented document literals", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/indoc@2.0.7", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/indoc" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/indoc" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ipnet@2.11.0", + "author": "Kris Price ", + "name": "ipnet", + "version": "2.11.0", + "description": "Provides types and useful methods for working with IPv4 and IPv6 network addresses, commonly called IP prefixes. The new `IpNet`, `Ipv4Net`, and `Ipv6Net` types build on the existing `IpAddr`, `Ipv4Addr`, and `Ipv6Addr` types already provided in Rust's standard library and align to their design to stay consistent. The module also provides useful traits that extend `Ipv4Addr` and `Ipv6Addr` with methods for `Add`, `Sub`, `BitAnd`, and `BitOr` operations. The module only uses stable feature so it is guaranteed to compile using the stable toolchain.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/ipnet@2.11.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/ipnet" + }, + { + "type": "vcs", + "url": "https://github.com/krisprice/ipnet" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#iri-string@0.7.10", + "author": "YOSHIOKA Takuma ", + "name": "iri-string", + "version": "0.7.10", + "description": "IRI as string types", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/iri-string@0.7.10", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/lo48576/iri-string" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#is_terminal_polyfill@1.70.2", + "name": "is_terminal_polyfill", + "version": "1.70.2", + "description": "Polyfill for `is_terminal` stdlib feature for use with older MSRVs", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/is_terminal_polyfill@1.70.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/polyfill-rs/is_terminal_polyfill" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#itertools@0.14.0", + "author": "bluss", + "name": "itertools", + "version": "0.14.0", + "description": "Extra iterator adaptors, iterator methods, free functions, and macros.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/itertools@0.14.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/itertools/" + }, + { + "type": "vcs", + "url": "https://github.com/rust-itertools/itertools" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.17", + "author": "David Tolnay ", + "name": "itoa", + "version": "1.0.17", + "description": "Fast integer primitive to string conversion", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/itoa@1.0.17", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/itoa" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/itoa" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#jobserver@0.1.34", + "author": "Alex Crichton ", + "name": "jobserver", + "version": "0.1.34", + "description": "An implementation of the GNU Make jobserver for Rust. ", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/jobserver@0.1.34", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/jobserver" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/jobserver-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/jobserver-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#konst@0.4.3", + "author": "rodrimati1992 ", + "name": "konst", + "version": "0.4.3", + "description": "Const equivalents of std features: comparison, destructuring, iteration, and parsing", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f660d5f887e3562f9ab6f4a14988795b694099d66b4f5dedc02d197ba9becb1d" + } + ], + "licenses": [ + { + "expression": "Zlib" + } + ], + "purl": "pkg:cargo/konst@0.4.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/konst/" + }, + { + "type": "vcs", + "url": "https://github.com/rodrimati1992/konst/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#konst_proc_macros@0.4.1", + "author": "rodrimati1992 ", + "name": "konst_proc_macros", + "version": "0.4.1", + "description": "Implementation detail of the `konst` crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e037a2e1d8d5fdbd49b16a4ea09d5d6401c1f29eca5ff29d03d3824dba16256a" + } + ], + "licenses": [ + { + "expression": "Zlib" + } + ], + "purl": "pkg:cargo/konst_proc_macros@0.4.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/konst/" + }, + { + "type": "vcs", + "url": "https://github.com/rodrimati1992/konst/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "author": "Marvin Löbel ", + "name": "lazy_static", + "version": "1.5.0", + "description": "A macro for declaring lazily evaluated statics in Rust.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/lazy_static@1.5.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/lazy_static" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang-nursery/lazy-static.rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "author": "The Rust Project Developers", + "name": "libc", + "version": "0.2.181", + "description": "Raw FFI bindings to platform libraries like libc.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/libc@0.2.181", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-lang/libc" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#libm@0.2.16", + "author": "Alex Crichton , Amanieu d'Antras , Jorge Aparicio , Trevor Gross ", + "name": "libm", + "version": "0.2.16", + "description": "libm in pure Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/libm@0.2.16", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-lang/compiler-builtins" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.11.0", + "author": "Dan Gohman ", + "name": "linux-raw-sys", + "version": "0.11.0", + "description": "Generated bindings for Linux's userspace API", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/linux-raw-sys@0.11.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/linux-raw-sys" + }, + { + "type": "vcs", + "url": "https://github.com/sunfishcode/linux-raw-sys" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#litemap@0.8.1", + "author": "The ICU4X Project Developers", + "name": "litemap", + "version": "0.8.1", + "description": "A key-value Map implementation based on a flat, sorted Vec.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/litemap@0.8.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/litemap" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lmdb-master-sys@0.2.5", + "author": "Kerollmops , Dan Burkert , Victor Porof ", + "name": "lmdb-master-sys", + "version": "0.2.5", + "description": "Rust bindings for liblmdb on the mdb.master branch.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "864808e0b19fb6dd3b70ba94ee671b82fce17554cf80aeb0a155c65bb08027df" + } + ], + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/lmdb-master-sys@0.2.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/lmdb-master-sys" + }, + { + "type": "vcs", + "url": "https://github.com/meilisearch/heed/tree/main/lmdb-master-sys" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lock_api@0.4.14", + "author": "Amanieu d'Antras ", + "name": "lock_api", + "version": "0.4.14", + "description": "Wrappers to create fully-featured Mutex and RwLock types. Compatible with no_std.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/lock_api@0.4.14", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Amanieu/parking_lot" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29", + "author": "The Rust Project Developers", + "name": "log", + "version": "0.4.29", + "description": "A lightweight logging facade for Rust ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/log@0.4.29", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/log" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/log" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lru-slab@0.1.2", + "author": "Benjamin Saunders ", + "name": "lru-slab", + "version": "0.1.2", + "description": "Pre-allocated storage with constant-time LRU tracking", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0 OR Zlib" + } + ], + "purl": "pkg:cargo/lru-slab@0.1.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Ralith/lru-slab" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lz4_flex@0.12.0", + "author": "Pascal Seitz , Arthur Silva , ticki ", + "name": "lz4_flex", + "version": "0.12.0", + "description": "Fastest LZ4 implementation in Rust, no unsafe by default.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ab6473172471198271ff72e9379150e9dfd70d8e533e0752a27e515b48dd375e" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/lz4_flex@0.12.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/pseitz/lz4_flex" + }, + { + "type": "vcs", + "url": "https://github.com/pseitz/lz4_flex" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#matchers@0.2.0", + "author": "Eliza Weisman ", + "name": "matchers", + "version": "0.2.0", + "description": "Regex matching on character and byte streams. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/matchers@0.2.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/matchers/" + }, + { + "type": "website", + "url": "https://github.com/hawkw/matchers" + }, + { + "type": "vcs", + "url": "https://github.com/hawkw/matchers" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#matchit@0.8.4", + "author": "Ibraheem Ahmed ", + "name": "matchit", + "version": "0.8.4", + "description": "A high performance, zero-copy URL router.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + } + ], + "licenses": [ + { + "expression": "MIT AND BSD-3-Clause" + } + ], + "purl": "pkg:cargo/matchit@0.8.4", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/ibraheemdev/matchit" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#matrixmultiply@0.3.10", + "author": "bluss, R. Janis Goldschmidt", + "name": "matrixmultiply", + "version": "0.3.10", + "description": "General matrix multiplication for f32 and f64 matrices. Operates on matrices with general layout (they can use arbitrary row and column stride). Detects and uses AVX or SSE2 on x86 platforms transparently for higher performance. Uses a microkernel strategy, so that the implementation is easy to parallelize and optimize. Supports multithreading.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/matrixmultiply@0.3.10", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/matrixmultiply/" + }, + { + "type": "vcs", + "url": "https://github.com/bluss/matrixmultiply/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "author": "Andrew Gallant , bluss", + "name": "memchr", + "version": "2.8.0", + "description": "Provides extremely fast (uses SIMD on x86_64, aarch64 and wasm32) routines for 1, 2 or 3 byte search and single substring search. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/memchr@2.8.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/memchr/" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/memchr" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/memchr" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#memoffset@0.9.1", + "author": "Gilad Naaman ", + "name": "memoffset", + "version": "0.9.1", + "description": "offset_of functionality for Rust structs.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/memoffset@0.9.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Gilnaa/memoffset" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#mime@0.3.17", + "author": "Sean McArthur ", + "name": "mime", + "version": "0.3.17", + "description": "Strongly Typed Mimes", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/mime@0.3.17", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/mime" + }, + { + "type": "vcs", + "url": "https://github.com/hyperium/mime" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#mime_guess@2.0.5", + "author": "Austin Bonander ", + "name": "mime_guess", + "version": "2.0.5", + "description": "A simple crate for detection of a file's MIME type by its extension.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/mime_guess@2.0.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/mime_guess/" + }, + { + "type": "vcs", + "url": "https://github.com/abonander/mime_guess" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#mio@1.1.1", + "author": "Carl Lerche , Thomas de Zeeuw , Tokio Contributors ", + "name": "mio", + "version": "1.1.1", + "description": "Lightweight non-blocking I/O.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/mio@1.1.1", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/tokio-rs/mio" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/mio" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "author": "Thom Chiovoloni ", + "name": "more-asserts", + "version": "0.3.1", + "description": "Small library providing additional assert_* and debug_assert_* macros.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1fafa6961cabd9c63bcd77a45d7e3b7f3b552b70417831fb0f56db717e72407e" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT OR Apache-2.0 OR CC0-1.0" + } + ], + "purl": "pkg:cargo/more-asserts@0.3.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/more-asserts" + }, + { + "type": "website", + "url": "https://github.com/thomcc/rust-more-asserts" + }, + { + "type": "vcs", + "url": "https://github.com/thomcc/rust-more-asserts" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#nalgebra@0.33.2", + "author": "Sébastien Crozet ", + "name": "nalgebra", + "version": "0.33.2", + "description": "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" + } + ], + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/nalgebra@0.33.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://www.nalgebra.org/docs" + }, + { + "type": "website", + "url": "https://nalgebra.org" + }, + { + "type": "vcs", + "url": "https://github.com/dimforge/nalgebra" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#nu-ansi-term@0.50.3", + "author": "ogham@bsago.me, Ryan Scheel (Havvy) , Josh Triplett , The Nushell Project Developers", + "name": "nu-ansi-term", + "version": "0.50.3", + "description": "Library for ANSI terminal colors and styles (bold, underline)", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/nu-ansi-term@0.50.3", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/nushell/nu-ansi-term" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-bigint@0.4.6", + "author": "The Rust Project Developers", + "name": "num-bigint", + "version": "0.4.6", + "description": "Big integer implementation for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/num-bigint@0.4.6", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/num-bigint" + }, + { + "type": "website", + "url": "https://github.com/rust-num/num-bigint" + }, + { + "type": "vcs", + "url": "https://github.com/rust-num/num-bigint" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-complex@0.4.6", + "author": "The Rust Project Developers", + "name": "num-complex", + "version": "0.4.6", + "description": "Complex numbers implementation for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/num-complex@0.4.6", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/num-complex" + }, + { + "type": "website", + "url": "https://github.com/rust-num/num-complex" + }, + { + "type": "vcs", + "url": "https://github.com/rust-num/num-complex" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-conv@0.2.0", + "author": "Jacob Pratt ", + "name": "num-conv", + "version": "0.2.0", + "description": "`num_conv` is a crate to convert between integer types without using `as` casts. This provides better certainty when refactoring, makes the exact behavior of code more explicit, and allows using turbofish syntax. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/num-conv@0.2.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/jhpratt/num-conv" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-integer@0.1.46", + "author": "The Rust Project Developers", + "name": "num-integer", + "version": "0.1.46", + "description": "Integer traits and functions", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/num-integer@0.1.46", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/num-integer" + }, + { + "type": "website", + "url": "https://github.com/rust-num/num-integer" + }, + { + "type": "vcs", + "url": "https://github.com/rust-num/num-integer" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-rational@0.4.2", + "author": "The Rust Project Developers", + "name": "num-rational", + "version": "0.4.2", + "description": "Rational numbers implementation for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/num-rational@0.4.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/num-rational" + }, + { + "type": "website", + "url": "https://github.com/rust-num/num-rational" + }, + { + "type": "vcs", + "url": "https://github.com/rust-num/num-rational" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19", + "author": "The Rust Project Developers", + "name": "num-traits", + "version": "0.2.19", + "description": "Numeric traits for generic mathematics", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/num-traits@0.2.19", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/num-traits" + }, + { + "type": "website", + "url": "https://github.com/rust-num/num-traits" + }, + { + "type": "vcs", + "url": "https://github.com/rust-num/num-traits" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3", + "author": "Aleksey Kladov ", + "name": "once_cell", + "version": "1.21.3", + "description": "Single assignment cells and lazy values.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/once_cell@1.21.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/once_cell" + }, + { + "type": "vcs", + "url": "https://github.com/matklad/once_cell" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#oneshot@0.1.13", + "author": "Linus Färnstrand ", + "name": "oneshot", + "version": "0.1.13", + "description": "Oneshot spsc channel with (potentially) lock-free non-blocking send, and a receiver supporting both thread blocking receive operations as well as Future based async polling. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "269bca4c2591a28585d6bf10d9ed0332b7d76900a1b02bec41bdc3a2cdcda107" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/oneshot@0.1.13", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/faern/oneshot" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#openssl-probe@0.2.1", + "author": "Alex Crichton ", + "name": "openssl-probe", + "version": "0.2.1", + "description": "A library for helping to find system-wide trust anchor (\"root\") certificate locations based on paths typically used by `openssl`. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/openssl-probe@0.2.1", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/rustls/openssl-probe" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/openssl-probe" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#option-ext@0.2.0", + "author": "Simon Ochsenreither ", + "name": "option-ext", + "version": "0.2.0", + "description": "Extends `Option` with additional operations", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + } + ], + "licenses": [ + { + "expression": "MPL-2.0" + } + ], + "purl": "pkg:cargo/option-ext@0.2.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/option-ext/" + }, + { + "type": "website", + "url": "https://github.com/soc/option-ext" + }, + { + "type": "vcs", + "url": "https://github.com/soc/option-ext.git" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#os_str_bytes@6.6.1", + "author": "dylni", + "name": "os_str_bytes", + "version": "6.6.1", + "description": "Convert between byte sequences and platform-native strings ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/os_str_bytes@6.6.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/dylni/os_str_bytes" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#page_size@0.6.0", + "author": "Philip Woods ", + "name": "page_size", + "version": "0.6.0", + "description": "Provides an easy, fast, cross-platform way to retrieve the memory page size", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/page_size@0.6.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/page_size/" + }, + { + "type": "website", + "url": "https://github.com/Elzair/page_size_rs" + }, + { + "type": "vcs", + "url": "https://github.com/Elzair/page_size_rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#parking_lot@0.12.5", + "author": "Amanieu d'Antras ", + "name": "parking_lot", + "version": "0.12.5", + "description": "More compact and efficient implementations of the standard synchronization primitives.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/parking_lot@0.12.5", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Amanieu/parking_lot" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#parking_lot_core@0.9.12", + "author": "Amanieu d'Antras ", + "name": "parking_lot_core", + "version": "0.9.12", + "description": "An advanced API for creating custom synchronization primitives.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/parking_lot_core@0.9.12", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Amanieu/parking_lot" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#paste@1.0.15", + "author": "David Tolnay ", + "name": "paste", + "version": "1.0.15", + "description": "Macros for all your token pasting needs", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/paste@1.0.15", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/paste" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/paste" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2", + "author": "The rust-url developers", + "name": "percent-encoding", + "version": "2.3.2", + "description": "Percent encoding and decoding", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/percent-encoding@2.3.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/servo/rust-url/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#phf@0.11.3", + "author": "Steven Fackler ", + "name": "phf", + "version": "0.11.3", + "description": "Runtime support for perfect hash function data structures", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/phf@0.11.3", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-phf/rust-phf" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#phf_generator@0.11.3", + "author": "Steven Fackler ", + "name": "phf_generator", + "version": "0.11.3", + "description": "PHF generation logic", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/phf_generator@0.11.3", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-phf/rust-phf" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#phf_macros@0.11.3", + "author": "Steven Fackler ", + "name": "phf_macros", + "version": "0.11.3", + "description": "Macros to generate types in the phf crate", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/phf_macros@0.11.3", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-phf/rust-phf" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.11.3", + "author": "Steven Fackler ", + "name": "phf_shared", + "version": "0.11.3", + "description": "Support code shared by PHF libraries", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/phf_shared@0.11.3", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-phf/rust-phf" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project-internal@1.1.10", + "name": "pin-project-internal", + "version": "1.1.10", + "description": "Implementation detail of the `pin-project` crate. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/pin-project-internal@1.1.10", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/taiki-e/pin-project" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "name": "pin-project-lite", + "version": "0.2.16", + "description": "A lightweight version of pin-project written with declarative macros. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/pin-project-lite@0.2.16", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/taiki-e/pin-project-lite" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.10", + "name": "pin-project", + "version": "1.1.10", + "description": "A crate for safe and ergonomic pin-projection. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/pin-project@1.1.10", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/taiki-e/pin-project" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-utils@0.1.0", + "author": "Josef Brandl ", + "name": "pin-utils", + "version": "0.1.0", + "description": "Utilities for pinning ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pin-utils@0.1.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/pin-utils" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang-nursery/pin-utils" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#potential_utf@0.1.4", + "author": "The ICU4X Project Developers", + "name": "potential_utf", + "version": "0.1.4", + "description": "Unvalidated string and character types", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/potential_utf@0.1.4", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0", + "author": "Jacob Pratt ", + "name": "powerfmt", + "version": "0.2.0", + "description": " `powerfmt` is a library that provides utilities for formatting values. This crate makes it significantly easier to support filling to a minimum width with alignment, avoid heap allocation, and avoid repetitive calculations. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/powerfmt@0.2.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/jhpratt/powerfmt" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ppv-lite86@0.2.21", + "author": "The CryptoCorrosion Contributors", + "name": "ppv-lite86", + "version": "0.2.21", + "description": "Cross-platform cryptography-oriented low-level SIMD library.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/ppv-lite86@0.2.21", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/cryptocorrosion/cryptocorrosion" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "author": "David Tolnay , Alex Crichton ", + "name": "proc-macro2", + "version": "1.0.106", + "description": "A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/proc-macro2@1.0.106", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/proc-macro2" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/proc-macro2" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#prometheus@0.14.0", + "author": "overvenus@gmail.com, siddontang@gmail.com, vistaswx@gmail.com", + "name": "prometheus", + "version": "0.14.0", + "description": "Prometheus instrumentation library for Rust applications.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3ca5326d8d0b950a9acd87e6a3f94745394f62e4dae1b1ee22b2bc0c394af43a" + } + ], + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/prometheus@0.14.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/prometheus" + }, + { + "type": "website", + "url": "https://github.com/tikv/rust-prometheus" + }, + { + "type": "vcs", + "url": "https://github.com/tikv/rust-prometheus" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#protobuf-support@3.7.2", + "author": "Stepan Koltsov ", + "name": "protobuf-support", + "version": "3.7.2", + "description": "Code supporting protobuf implementation. None of code in this crate is public API. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/protobuf-support@3.7.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://github.com/stepancheg/rust-protobuf/blob/master/README.md" + }, + { + "type": "website", + "url": "https://github.com/stepancheg/rust-protobuf/" + }, + { + "type": "vcs", + "url": "https://github.com/stepancheg/rust-protobuf/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#protobuf@3.7.2", + "author": "Stepan Koltsov ", + "name": "protobuf", + "version": "3.7.2", + "description": "Rust implementation of Google protocol buffers ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/protobuf@3.7.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://github.com/stepancheg/rust-protobuf/blob/master/README.md" + }, + { + "type": "website", + "url": "https://github.com/stepancheg/rust-protobuf/" + }, + { + "type": "vcs", + "url": "https://github.com/stepancheg/rust-protobuf/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-build-config@0.26.0", + "author": "PyO3 Project and Contributors ", + "name": "pyo3-build-config", + "version": "0.26.0", + "description": "Build configuration for the PyO3 ecosystem", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pyo3-build-config@0.26.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/pyo3/pyo3" + }, + { + "type": "vcs", + "url": "https://github.com/pyo3/pyo3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-ffi@0.26.0", + "author": "PyO3 Project and Contributors ", + "name": "pyo3-ffi", + "version": "0.26.0", + "description": "Python-API bindings for the PyO3 ecosystem", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pyo3-ffi@0.26.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/pyo3/pyo3" + }, + { + "type": "other", + "url": "python" + }, + { + "type": "vcs", + "url": "https://github.com/pyo3/pyo3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros-backend@0.26.0", + "author": "PyO3 Project and Contributors ", + "name": "pyo3-macros-backend", + "version": "0.26.0", + "description": "Code generation for PyO3 package", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pyo3-macros-backend@0.26.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/pyo3/pyo3" + }, + { + "type": "vcs", + "url": "https://github.com/pyo3/pyo3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros@0.26.0", + "author": "PyO3 Project and Contributors ", + "name": "pyo3-macros", + "version": "0.26.0", + "description": "Proc macros for PyO3 package", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pyo3-macros@0.26.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/pyo3/pyo3" + }, + { + "type": "vcs", + "url": "https://github.com/pyo3/pyo3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3@0.26.0", + "author": "PyO3 Project and Contributors ", + "name": "pyo3", + "version": "0.26.0", + "description": "Bindings to Python interpreter", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/pyo3@0.26.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/crate/pyo3/" + }, + { + "type": "website", + "url": "https://github.com/pyo3/pyo3" + }, + { + "type": "vcs", + "url": "https://github.com/pyo3/pyo3" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quinn-proto@0.11.13", + "name": "quinn-proto", + "version": "0.11.13", + "description": "State machine for the QUIC transport protocol", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/quinn-proto@0.11.13", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/quinn-rs/quinn" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quinn-udp@0.5.14", + "name": "quinn-udp", + "version": "0.5.14", + "description": "UDP sockets with ECN information for the QUIC transport protocol", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/quinn-udp@0.5.14", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/quinn-rs/quinn" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quinn@0.11.9", + "name": "quinn", + "version": "0.11.9", + "description": "Versatile QUIC transport protocol implementation", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/quinn@0.11.9", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/quinn-rs/quinn" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "author": "David Tolnay ", + "name": "quote", + "version": "1.0.44", + "description": "Quasi-quoting macro quote!(...)", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/quote@1.0.44", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/quote/" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/quote" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand@0.8.5", + "author": "The Rand Project Developers, The Rust Project Developers", + "name": "rand", + "version": "0.8.5", + "description": "Random number generators and other randomness functionality. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand@0.8.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "author": "The Rand Project Developers, The Rust Project Developers", + "name": "rand", + "version": "0.9.2", + "description": "Random number generators and other randomness functionality. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand@0.9.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.3.1", + "author": "The Rand Project Developers, The Rust Project Developers, The CryptoCorrosion Contributors", + "name": "rand_chacha", + "version": "0.3.1", + "description": "ChaCha random number generator ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand_chacha@0.3.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand_chacha" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.9.0", + "author": "The Rand Project Developers, The Rust Project Developers, The CryptoCorrosion Contributors", + "name": "rand_chacha", + "version": "0.9.0", + "description": "ChaCha random number generator ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand_chacha@0.9.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand_chacha" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.6.4", + "author": "The Rand Project Developers, The Rust Project Developers", + "name": "rand_core", + "version": "0.6.4", + "description": "Core random number generator traits and tools for implementation. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand_core@0.6.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand_core" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.9.5", + "author": "The Rand Project Developers, The Rust Project Developers", + "name": "rand_core", + "version": "0.9.5", + "description": "Core random number generator traits and tools for implementation. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand_core@0.9.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand_core" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_distr@0.4.3", + "author": "The Rand Project Developers", + "name": "rand_distr", + "version": "0.4.3", + "description": "Sampling from random number distributions ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rand_distr@0.4.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rand_distr" + }, + { + "type": "website", + "url": "https://rust-random.github.io/book" + }, + { + "type": "vcs", + "url": "https://github.com/rust-random/rand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rawpointer@0.2.1", + "author": "bluss", + "name": "rawpointer", + "version": "0.2.1", + "description": "Extra methods for raw pointers and `NonNull`. For example `.post_inc()` and `.pre_dec()` (c.f. `ptr++` and `--ptr`), `offset` and `add` for `NonNull`, and the function `ptrdistance`. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rawpointer@0.2.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rawpointer/" + }, + { + "type": "vcs", + "url": "https://github.com/bluss/rawpointer/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14", + "author": "The Rust Project Developers, Andrew Gallant ", + "name": "regex-automata", + "version": "0.4.14", + "description": "Automata construction and matching using regular expressions.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/regex-automata@0.4.14", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/regex-automata" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/regex/tree/master/regex-automata" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/regex" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.9", + "author": "The Rust Project Developers, Andrew Gallant ", + "name": "regex-syntax", + "version": "0.8.9", + "description": "A regular expression parser.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/regex-syntax@0.8.9", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/regex-syntax" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/regex/tree/master/regex-syntax" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/regex" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#regex@1.12.3", + "author": "The Rust Project Developers, Andrew Gallant ", + "name": "regex", + "version": "1.12.3", + "description": "An implementation of regular expressions for Rust. This implementation uses finite automata and guarantees linear time matching on all inputs. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/regex@1.12.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/regex" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/regex" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/regex" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest-middleware@0.5.1", + "author": "Rodrigo Gryzinski ", + "name": "reqwest-middleware", + "version": "0.5.1", + "description": "Wrapper around reqwest to allow for client middleware chains.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "199dda04a536b532d0cc04d7979e39b1c763ea749bf91507017069c00b96056f" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/reqwest-middleware@0.5.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/TrueLayer/reqwest-middleware" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest-retry@0.9.1", + "author": "Rodrigo Gryzinski ", + "name": "reqwest-retry", + "version": "0.9.1", + "description": "Retry middleware for reqwest.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "fe2412db2af7d2268e7a5406be0431f37d9eb67ff390f35b395716f5f06c2eaa" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/reqwest-retry@0.9.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/TrueLayer/reqwest-middleware" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "author": "Sean McArthur ", + "name": "reqwest", + "version": "0.13.2", + "description": "higher level HTTP client library", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/reqwest@0.13.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/reqwest" + }, + { + "type": "vcs", + "url": "https://github.com/seanmonstar/reqwest" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#retry-policies@0.5.1", + "author": "Luca Palmieri ", + "name": "retry-policies", + "version": "0.5.1", + "description": "A collection of plug-and-play retry policies for Rust projects.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "46a4bd6027df676bcb752d3724db0ea3c0c5fc1dd0376fec51ac7dcaf9cc69be" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/retry-policies@0.5.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/TrueLayer/retry-policies" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14", + "name": "ring", + "version": "0.17.14", + "description": "An experiment.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 AND ISC" + } + ], + "purl": "pkg:cargo/ring@0.17.14", + "externalReferences": [ + { + "type": "other", + "url": "ring_core_0_17_14_" + }, + { + "type": "vcs", + "url": "https://github.com/briansmith/ring" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rust_decimal@1.40.0", + "author": "Paul Mason ", + "name": "rust_decimal", + "version": "1.40.0", + "description": "Decimal number implementation written in pure Rust suitable for financial and fixed-precision calculations.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "61f703d19852dbf87cbc513643fa81428361eb6940f1ac14fd58155d295a3eb0" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/rust_decimal@1.40.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rust_decimal/" + }, + { + "type": "vcs", + "url": "https://github.com/paupino/rust-decimal" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustc-hash@2.1.1", + "author": "The Rust Project Developers", + "name": "rustc-hash", + "version": "2.1.1", + "description": "A speedy, non-cryptographic hashing algorithm used by rustc", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/rustc-hash@2.1.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rust-lang/rustc-hash" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3", + "author": "Dan Gohman , Jakub Konka ", + "name": "rustix", + "version": "1.1.3", + "description": "Safe Rust bindings to POSIX/Unix/Linux/Winsock-like syscalls", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/rustix@1.1.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rustix" + }, + { + "type": "vcs", + "url": "https://github.com/bytecodealliance/rustix" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-native-certs@0.8.3", + "name": "rustls-native-certs", + "version": "0.8.3", + "description": "rustls-native-certs allows rustls to use the platform native certificate store", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR ISC OR MIT" + } + ], + "purl": "pkg:cargo/rustls-native-certs@0.8.3", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/rustls/rustls-native-certs" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/rustls-native-certs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "name": "rustls-pki-types", + "version": "1.14.0", + "description": "Shared types for the rustls PKI ecosystem", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rustls-pki-types@1.14.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rustls-pki-types" + }, + { + "type": "website", + "url": "https://github.com/rustls/pki-types" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/pki-types" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-platform-verifier@0.6.2", + "name": "rustls-platform-verifier", + "version": "0.6.2", + "description": "rustls-platform-verifier supports verifying TLS certificates in rustls with the operating system verifier", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rustls-platform-verifier@0.6.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rustls/rustls-platform-verifier" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-webpki@0.103.9", + "name": "rustls-webpki", + "version": "0.103.9", + "description": "Web PKI X.509 Certificate Verification.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" + } + ], + "licenses": [ + { + "expression": "ISC" + } + ], + "purl": "pkg:cargo/rustls-webpki@0.103.9", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/rustls/webpki" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.36", + "name": "rustls", + "version": "0.23.36", + "description": "Rustls is a modern TLS library written in Rust.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR ISC OR MIT" + } + ], + "purl": "pkg:cargo/rustls@0.23.36", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/rustls/rustls" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/rustls" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22", + "author": "David Tolnay ", + "name": "rustversion", + "version": "1.0.22", + "description": "Conditional compilation according to rustc compiler version", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/rustversion@1.0.22", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/rustversion" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/rustversion" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.23", + "author": "David Tolnay ", + "name": "ryu", + "version": "1.0.23", + "description": "Fast floating point to string conversion", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR BSL-1.0" + } + ], + "purl": "pkg:cargo/ryu@1.0.23", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/ryu" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/ryu" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#safe-transmute@0.11.3", + "author": "наб , Eduardo Pinho , Lukas Kalbertodt , Philipp Tessenow , Marijn Suijten ", + "name": "safe-transmute", + "version": "0.11.3", + "description": "A safeguarded transmute() for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3944826ff8fa8093089aba3acb4ef44b9446a99a16f3bf4e74af3f77d340ab7d" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/safe-transmute@0.11.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://rawcdn.githack.com/nabijaczleweli/safe-transmute-rs/doc/safe_transmute/index.html" + }, + { + "type": "vcs", + "url": "https://github.com/nabijaczleweli/safe-transmute-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#safe_arch@0.7.4", + "author": "Lokathor ", + "name": "safe_arch", + "version": "0.7.4", + "description": "Crate that exposes `core::arch` safely via `#[cfg()]`.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" + } + ], + "licenses": [ + { + "expression": "Zlib OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/safe_arch@0.7.4", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Lokathor/safe_arch" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#same-file@1.0.6", + "author": "Andrew Gallant ", + "name": "same-file", + "version": "1.0.6", + "description": "A simple crate for determining whether two file paths point to the same file. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/same-file@1.0.6", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/same-file" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/same-file" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/same-file" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#scoped-tls@1.0.1", + "author": "Alex Crichton ", + "name": "scoped-tls", + "version": "1.0.1", + "description": "Library implementation of the standard library's old `scoped_thread_local!` macro for providing scoped access to thread local storage (TLS) so any type can be stored into TLS. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/scoped-tls@1.0.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/scoped-tls" + }, + { + "type": "website", + "url": "https://github.com/alexcrichton/scoped-tls" + }, + { + "type": "vcs", + "url": "https://github.com/alexcrichton/scoped-tls" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#scopeguard@1.2.0", + "author": "bluss", + "name": "scopeguard", + "version": "1.2.0", + "description": "A RAII scope guard that will run a given closure when it goes out of scope, even if the code between panics (assuming unwinding panic). Defines the macros `defer!`, `defer_on_unwind!`, `defer_on_success!` as shorthands for guards with one of the implemented strategies. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/scopeguard@1.2.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/scopeguard/" + }, + { + "type": "vcs", + "url": "https://github.com/bluss/scopeguard" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "author": "Erick Tryzelaar , David Tolnay ", + "name": "serde", + "version": "1.0.228", + "description": "A generic serialization/deserialization framework", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde@1.0.228", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/serde" + }, + { + "type": "website", + "url": "https://serde.rs" + }, + { + "type": "vcs", + "url": "https://github.com/serde-rs/serde" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228", + "author": "Erick Tryzelaar , David Tolnay ", + "name": "serde_core", + "version": "1.0.228", + "description": "Serde traits only, with no support for derive -- use the `serde` crate instead", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde_core@1.0.228", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/serde_core" + }, + { + "type": "website", + "url": "https://serde.rs" + }, + { + "type": "vcs", + "url": "https://github.com/serde-rs/serde" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.228", + "author": "Erick Tryzelaar , David Tolnay ", + "name": "serde_derive", + "version": "1.0.228", + "description": "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde_derive@1.0.228", + "externalReferences": [ + { + "type": "documentation", + "url": "https://serde.rs/derive.html" + }, + { + "type": "website", + "url": "https://serde.rs" + }, + { + "type": "vcs", + "url": "https://github.com/serde-rs/serde" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "author": "Erick Tryzelaar , David Tolnay ", + "name": "serde_json", + "version": "1.0.149", + "description": "A JSON serialization file format", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde_json@1.0.149", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/serde_json" + }, + { + "type": "vcs", + "url": "https://github.com/serde-rs/json" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_path_to_error@0.1.20", + "author": "David Tolnay ", + "name": "serde_path_to_error", + "version": "0.1.20", + "description": "Path to the element that failed to deserialize", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde_path_to_error@0.1.20", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/serde_path_to_error" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/path-to-error" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_repr@0.1.20", + "author": "David Tolnay ", + "name": "serde_repr", + "version": "0.1.20", + "description": "Derive Serialize and Deserialize that delegates to the underlying repr of a C-like enum.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde_repr@0.1.20", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/serde_repr" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/serde-repr" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_urlencoded@0.7.1", + "author": "Anthony Ramine ", + "name": "serde_urlencoded", + "version": "0.7.1", + "description": "`x-www-form-urlencoded` meets Serde", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/serde_urlencoded@0.7.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/serde_urlencoded/0.7.1/serde_urlencoded/" + }, + { + "type": "vcs", + "url": "https://github.com/nox/serde_urlencoded" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sha1@0.10.6", + "author": "RustCrypto Developers", + "name": "sha1", + "version": "0.10.6", + "description": "SHA-1 hash function", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/sha1@0.10.6", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/sha1" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/hashes" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sha2-asm@0.6.4", + "author": "RustCrypto Developers", + "name": "sha2-asm", + "version": "0.6.4", + "description": "Assembly implementation of SHA-2 compression functions", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b845214d6175804686b2bd482bcffe96651bb2d1200742b712003504a2dac1ab" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/sha2-asm@0.6.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/sha2-asm" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/asm-hashes" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sha2@0.10.9", + "author": "RustCrypto Developers", + "name": "sha2", + "version": "0.10.9", + "description": "Pure Rust implementation of the SHA-2 hash function family including SHA-224, SHA-256, SHA-384, and SHA-512. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/sha2@0.10.9", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/sha2" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/hashes" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sharded-slab@0.1.7", + "author": "Eliza Weisman ", + "name": "sharded-slab", + "version": "0.1.7", + "description": "A lock-free concurrent slab. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/sharded-slab@0.1.7", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/sharded-slab/" + }, + { + "type": "website", + "url": "https://github.com/hawkw/sharded-slab" + }, + { + "type": "vcs", + "url": "https://github.com/hawkw/sharded-slab" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#shellexpand@3.1.1", + "author": "Vladimir Matveev , Ian Jackson ", + "name": "shellexpand", + "version": "3.1.1", + "description": "Shell-like expansions in strings", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/shellexpand@3.1.1", + "externalReferences": [ + { + "type": "documentation", + "url": "http://docs.rs/shellexpand/" + }, + { + "type": "vcs", + "url": "https://gitlab.com/ijackson/rust-shellexpand" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#shlex@1.3.0", + "author": "comex , Fenhl , Adrian Taylor , Alex Touchet , Daniel Parks , Garrett Berg ", + "name": "shlex", + "version": "1.3.0", + "description": "Split a string into shell words, like Python's shlex.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/shlex@1.3.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/comex/rust-shlex" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#signal-hook-registry@1.4.8", + "author": "Michal 'vorner' Vaner , Masaki Hara ", + "name": "signal-hook-registry", + "version": "1.4.8", + "description": "Backend crate for signal-hook", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/signal-hook-registry@1.4.8", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/signal-hook-registry" + }, + { + "type": "vcs", + "url": "https://github.com/vorner/signal-hook" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18", + "author": "Michal 'vorner' Vaner , Thomas Himmelstoss ", + "name": "signal-hook", + "version": "0.3.18", + "description": "Unix signal handling", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/signal-hook@0.3.18", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/signal-hook" + }, + { + "type": "vcs", + "url": "https://github.com/vorner/signal-hook" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#simba@0.9.1", + "author": "sebcrozet ", + "name": "simba", + "version": "0.9.1", + "description": "SIMD algebra for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95" + } + ], + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/simba@0.9.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/simba" + }, + { + "type": "vcs", + "url": "https://github.com/dimforge/simba" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#siphasher@1.0.2", + "author": "Frank Denis ", + "name": "siphasher", + "version": "1.0.2", + "description": "SipHash-2-4, SipHash-1-3 and 128-bit variants in pure Rust", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/siphasher@1.0.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/siphasher" + }, + { + "type": "website", + "url": "https://docs.rs/siphasher" + }, + { + "type": "vcs", + "url": "https://github.com/jedisct1/rust-siphash" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#slab@0.4.12", + "author": "Carl Lerche ", + "name": "slab", + "version": "0.4.12", + "description": "Pre-allocated storage for a uniform data type", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/slab@0.4.12", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/tokio-rs/slab" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1", + "author": "The Servo Project Developers", + "name": "smallvec", + "version": "1.15.1", + "description": "'Small vector' optimization: store up to a small number of items on the stack", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/smallvec@1.15.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/smallvec/" + }, + { + "type": "vcs", + "url": "https://github.com/servo/rust-smallvec" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.2", + "author": "Alex Crichton , Thomas de Zeeuw ", + "name": "socket2", + "version": "0.6.2", + "description": "Utilities for handling networking sockets with a maximal amount of configuration possible intended. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/socket2@0.6.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/socket2" + }, + { + "type": "website", + "url": "https://github.com/rust-lang/socket2" + }, + { + "type": "vcs", + "url": "https://github.com/rust-lang/socket2" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#stable_deref_trait@1.2.1", + "author": "Robert Grosse ", + "name": "stable_deref_trait", + "version": "1.2.1", + "description": "An unsafe marker trait for types like Box and Rc that dereference to a stable address even when moved, and hence can be used with libraries such as owning_ref and rental. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/stable_deref_trait@1.2.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/stable_deref_trait/1.2.1/stable_deref_trait" + }, + { + "type": "vcs", + "url": "https://github.com/storyyeller/stable_deref_trait" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#static_assertions@1.1.0", + "author": "Nikolai Vazquez", + "name": "static_assertions", + "version": "1.1.0", + "description": "Compile-time assertions to ensure that invariants are met.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/static_assertions@1.1.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/static_assertions/" + }, + { + "type": "website", + "url": "https://github.com/nvzqz/static-assertions-rs" + }, + { + "type": "vcs", + "url": "https://github.com/nvzqz/static-assertions-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#statrs@0.18.0", + "author": "Michael Ma", + "name": "statrs", + "version": "0.18.0", + "description": "Statistical computing library for Rust", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/statrs@0.18.0", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/statrs-dev/statrs" + }, + { + "type": "vcs", + "url": "https://github.com/statrs-dev/statrs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#strsim@0.11.1", + "author": "Danny Guo , maxbachmann ", + "name": "strsim", + "version": "0.11.1", + "description": "Implementations of string similarity metrics. Includes Hamming, Levenshtein, OSA, Damerau-Levenshtein, Jaro, Jaro-Winkler, and Sørensen-Dice. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/strsim@0.11.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/strsim/" + }, + { + "type": "website", + "url": "https://github.com/rapidfuzz/strsim-rs" + }, + { + "type": "vcs", + "url": "https://github.com/rapidfuzz/strsim-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#subtle@2.6.1", + "author": "Isis Lovecruft , Henry de Valence ", + "name": "subtle", + "version": "2.6.1", + "description": "Pure-Rust traits and utilities for constant-time cryptographic implementations.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + } + ], + "licenses": [ + { + "expression": "BSD-3-Clause" + } + ], + "purl": "pkg:cargo/subtle@2.6.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/subtle" + }, + { + "type": "website", + "url": "https://dalek.rs/" + }, + { + "type": "vcs", + "url": "https://github.com/dalek-cryptography/subtle" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#syn@1.0.109", + "author": "David Tolnay ", + "name": "syn", + "version": "1.0.109", + "description": "Parser for Rust source code", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/syn@1.0.109", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/syn" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/syn" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114", + "author": "David Tolnay ", + "name": "syn", + "version": "2.0.114", + "description": "Parser for Rust source code", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/syn@2.0.114", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/syn" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/syn" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2", + "author": "Actyx AG ", + "name": "sync_wrapper", + "version": "1.0.2", + "description": "A tool for enlisting the compiler's help in proving the absence of concurrency", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + } + ], + "licenses": [ + { + "expression": "Apache-2.0" + } + ], + "purl": "pkg:cargo/sync_wrapper@1.0.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/sync_wrapper" + }, + { + "type": "website", + "url": "https://docs.rs/sync_wrapper" + }, + { + "type": "vcs", + "url": "https://github.com/Actyx/sync_wrapper" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#synchronoise@1.0.1", + "author": "QuietMisdreavus ", + "name": "synchronoise", + "version": "1.0.1", + "description": "Synchronization primitives that build upon the standard library", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "3dbc01390fc626ce8d1cffe3376ded2b72a11bb70e1c75f404a210e4daa4def2" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/synchronoise@1.0.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/synchronoise/" + }, + { + "type": "vcs", + "url": "https://github.com/QuietMisdreavus/synchronoise" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#synstructure@0.13.2", + "author": "Nika Layzell ", + "name": "synstructure", + "version": "0.13.2", + "description": "Helper methods and macros for custom derives", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/synstructure@0.13.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/synstructure" + }, + { + "type": "vcs", + "url": "https://github.com/mystor/synstructure" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sysinfo@0.38.1", + "author": "Guillaume Gomez ", + "name": "sysinfo", + "version": "0.38.1", + "description": "Library to get system information such as processes, CPUs, disks, components and networks", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "5792d209c2eac902426c0c4a166c9f72147db453af548cf9bf3242644c4d4fe3" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/sysinfo@0.38.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/GuillaumeGomez/sysinfo" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#target-lexicon@0.13.4", + "author": "Dan Gohman ", + "name": "target-lexicon", + "version": "0.13.4", + "description": "LLVM target triple types", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 WITH LLVM-exception" + } + ], + "purl": "pkg:cargo/target-lexicon@0.13.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/target-lexicon/" + }, + { + "type": "vcs", + "url": "https://github.com/bytecodealliance/target-lexicon" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.25.0", + "author": "Steven Allen , The Rust Project Developers, Ashley Mannix , Jason White ", + "name": "tempfile", + "version": "3.25.0", + "description": "A library for managing temporary files and directories.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/tempfile@3.25.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/tempfile" + }, + { + "type": "website", + "url": "https://stebalien.com/projects/tempfile-rs/" + }, + { + "type": "vcs", + "url": "https://github.com/Stebalien/tempfile" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@1.0.69", + "author": "David Tolnay ", + "name": "thiserror-impl", + "version": "1.0.69", + "description": "Implementation detail of the `thiserror` crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/thiserror-impl@1.0.69", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/dtolnay/thiserror" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@2.0.18", + "author": "David Tolnay ", + "name": "thiserror-impl", + "version": "2.0.18", + "description": "Implementation detail of the `thiserror` crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/thiserror-impl@2.0.18", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/dtolnay/thiserror" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror@1.0.69", + "author": "David Tolnay ", + "name": "thiserror", + "version": "1.0.69", + "description": "derive(Error)", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/thiserror@1.0.69", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/thiserror" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/thiserror" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "author": "David Tolnay ", + "name": "thiserror", + "version": "2.0.18", + "description": "derive(Error)", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/thiserror@2.0.18", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/thiserror" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/thiserror" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thread_local@1.1.9", + "author": "Amanieu d'Antras ", + "name": "thread_local", + "version": "1.1.9", + "description": "Per-object thread-local storage", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/thread_local@1.1.9", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/thread_local/" + }, + { + "type": "vcs", + "url": "https://github.com/Amanieu/thread_local-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.8", + "author": "Jacob Pratt , Time contributors", + "name": "time-core", + "version": "0.1.8", + "description": "This crate is an implementation detail and should not be relied upon directly.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/time-core@0.1.8", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/time-rs/time" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#time-macros@0.2.27", + "author": "Jacob Pratt , Time contributors", + "name": "time-macros", + "version": "0.2.27", + "description": " Procedural macros for the time crate. This crate is an implementation detail and should not be relied upon directly. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/time-macros@0.2.27", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/time-rs/time" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#time@0.3.47", + "author": "Jacob Pratt , Time contributors", + "name": "time", + "version": "0.3.47", + "description": "Date and time library. Fully interoperable with the standard library. Mostly compatible with #![no_std].", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/time@0.3.47", + "externalReferences": [ + { + "type": "website", + "url": "https://time-rs.github.io" + }, + { + "type": "vcs", + "url": "https://github.com/time-rs/time" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tinystr@0.8.2", + "author": "The ICU4X Project Developers", + "name": "tinystr", + "version": "0.8.2", + "description": "A small ASCII-only bounded length string representation.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/tinystr@0.8.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tinyvec@1.10.0", + "author": "Lokathor ", + "name": "tinyvec", + "version": "1.10.0", + "description": "`tinyvec` provides 100% safe vec-like data structures.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" + } + ], + "licenses": [ + { + "expression": "Zlib OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/tinyvec@1.10.0", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Lokathor/tinyvec" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tinyvec_macros@0.1.1", + "author": "Soveu ", + "name": "tinyvec_macros", + "version": "0.1.1", + "description": "Some macros for tiny containers", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0 OR Zlib" + } + ], + "purl": "pkg:cargo/tinyvec_macros@0.1.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Soveu/tinyvec_macros" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-macros@2.6.0", + "author": "Tokio Contributors ", + "name": "tokio-macros", + "version": "2.6.0", + "description": "Tokio's proc macros. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tokio-macros@2.6.0", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tokio" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-retry@0.3.0", + "author": "Sam Rijs ", + "name": "tokio-retry", + "version": "0.3.0", + "description": "Extensible, asynchronous retry behaviours for futures/tokio", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tokio-retry@0.3.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/tokio-retry" + }, + { + "type": "vcs", + "url": "https://github.com/srijs/rust-tokio-retry" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-rustls@0.26.4", + "name": "tokio-rustls", + "version": "0.26.4", + "description": "Asynchronous TLS/SSL streams for Tokio using Rustls.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/tokio-rustls@0.26.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/tokio-rustls" + }, + { + "type": "website", + "url": "https://github.com/rustls/tokio-rustls" + }, + { + "type": "vcs", + "url": "https://github.com/rustls/tokio-rustls" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "author": "Tokio Contributors ", + "name": "tokio-util", + "version": "0.7.18", + "description": "Additional utilities for working with Tokio. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tokio-util@0.7.18", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tokio" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "author": "Tokio Contributors ", + "name": "tokio", + "version": "1.49.0", + "description": "An event-driven, non-blocking I/O platform for writing asynchronous I/O backed applications. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tokio@1.49.0", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tokio" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower-http@0.6.8", + "author": "Tower Maintainers ", + "name": "tower-http", + "version": "0.6.8", + "description": "Tower middleware and utilities for HTTP clients and servers", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tower-http@0.6.8", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/tower-rs/tower-http" + }, + { + "type": "vcs", + "url": "https://github.com/tower-rs/tower-http" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3", + "author": "Tower Maintainers ", + "name": "tower-layer", + "version": "0.3.3", + "description": "Decorates a `Service` to allow easy composition between `Service`s. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tower-layer@0.3.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/tower-layer/0.3.3" + }, + { + "type": "website", + "url": "https://github.com/tower-rs/tower" + }, + { + "type": "vcs", + "url": "https://github.com/tower-rs/tower" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3", + "author": "Tower Maintainers ", + "name": "tower-service", + "version": "0.3.3", + "description": "Trait representing an asynchronous, request / response based, client or server. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tower-service@0.3.3", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/tower-service/0.3.3" + }, + { + "type": "website", + "url": "https://github.com/tower-rs/tower" + }, + { + "type": "vcs", + "url": "https://github.com/tower-rs/tower" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower@0.5.3", + "author": "Tower Maintainers ", + "name": "tower", + "version": "0.5.3", + "description": "Tower is a library of modular and reusable components for building robust clients and servers. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tower@0.5.3", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/tower-rs/tower" + }, + { + "type": "vcs", + "url": "https://github.com/tower-rs/tower" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-appender@0.2.4", + "author": "Zeki Sherif , Tokio Contributors ", + "name": "tracing-appender", + "version": "0.2.4", + "description": "Provides utilities for file appenders and making non-blocking writers. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-appender@0.2.4", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-attributes@0.1.31", + "author": "Tokio Contributors , Eliza Weisman , David Barsky ", + "name": "tracing-attributes", + "version": "0.1.31", + "description": "Procedural macro attributes for automatically instrumenting functions. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-attributes@0.1.31", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36", + "author": "Tokio Contributors ", + "name": "tracing-core", + "version": "0.1.36", + "description": "Core primitives for application-level tracing. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-core@0.1.36", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-log@0.2.0", + "author": "Tokio Contributors ", + "name": "tracing-log", + "version": "0.2.0", + "description": "Provides compatibility between `tracing` and the `log` crate. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-log@0.2.0", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-serde@0.2.0", + "author": "Tokio Contributors ", + "name": "tracing-serde", + "version": "0.2.0", + "description": "A compatibility layer for serializing trace data with `serde` ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-serde@0.2.0", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.22", + "author": "Eliza Weisman , David Barsky , Tokio Contributors ", + "name": "tracing-subscriber", + "version": "0.3.22", + "description": "Utilities for implementing and composing `tracing` subscribers. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing-subscriber@0.3.22", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "author": "Eliza Weisman , Tokio Contributors ", + "name": "tracing", + "version": "0.1.44", + "description": "Application-level tracing for Rust. ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/tracing@0.1.44", + "externalReferences": [ + { + "type": "website", + "url": "https://tokio.rs" + }, + { + "type": "vcs", + "url": "https://github.com/tokio-rs/tracing" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#try-lock@0.2.5", + "author": "Sean McArthur ", + "name": "try-lock", + "version": "0.2.5", + "description": "A lightweight atomic lock.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/try-lock@0.2.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/try-lock" + }, + { + "type": "website", + "url": "https://github.com/seanmonstar/try-lock" + }, + { + "type": "vcs", + "url": "https://github.com/seanmonstar/try-lock" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#twox-hash@2.1.2", + "author": "Jake Goulding ", + "name": "twox-hash", + "version": "2.1.2", + "description": "A Rust implementation of the XXHash and XXH3 algorithms", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/twox-hash@2.1.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/twox-hash/" + }, + { + "type": "vcs", + "url": "https://github.com/shepmaster/twox-hash" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0", + "author": "Paho Lurie-Gregg , Andre Bogus ", + "name": "typenum", + "version": "1.19.0", + "description": "Typenum is a Rust library for type-level numbers evaluated at compile time. It currently supports bits, unsigned integers, and signed integers. It also provides a type-level array of type-level numbers, but its implementation is incomplete.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/typenum@1.19.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/typenum" + }, + { + "type": "vcs", + "url": "https://github.com/paholg/typenum" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#typewit@1.14.2", + "author": "rodrimati1992 ", + "name": "typewit", + "version": "1.14.2", + "description": "type-witness-based abstractions, mostly for emulating polymorphism in const fns", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "f8c1ae7cc0fdb8b842d65d127cb981574b0d2b249b74d1c7a2986863dc134f71" + } + ], + "licenses": [ + { + "expression": "Zlib" + } + ], + "purl": "pkg:cargo/typewit@1.14.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/typewit/" + }, + { + "type": "vcs", + "url": "https://github.com/rodrimati1992/typewit/" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ulid@1.2.1", + "author": "dylanhart ", + "name": "ulid", + "version": "1.2.1", + "description": "a Universally Unique Lexicographically Sortable Identifier implementation", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "470dbf6591da1b39d43c14523b2b469c86879a53e8b758c8e090a470fe7b1fbe" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/ulid@1.2.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/dylanhart/ulid-rs" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#unicase@2.9.0", + "author": "Sean McArthur ", + "name": "unicase", + "version": "2.9.0", + "description": "A case-insensitive wrapper around strings.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/unicase@2.9.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/unicase" + }, + { + "type": "vcs", + "url": "https://github.com/seanmonstar/unicase" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.23", + "author": "David Tolnay ", + "name": "unicode-ident", + "version": "1.0.23", + "description": "Determine whether characters have the XID_Start or XID_Continue properties according to Unicode Standard Annex #31", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" + } + ], + "licenses": [ + { + "expression": "(MIT OR Apache-2.0) AND Unicode-3.0" + } + ], + "purl": "pkg:cargo/unicode-ident@1.0.23", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/unicode-ident" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/unicode-ident" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#unindent@0.2.4", + "author": "David Tolnay ", + "name": "unindent", + "version": "0.2.4", + "description": "Remove a column of leading whitespace from a string", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/unindent@0.2.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/unindent" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/indoc" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#untrusted@0.9.0", + "author": "Brian Smith ", + "name": "untrusted", + "version": "0.9.0", + "description": "Safe, fast, zero-panic, zero-crashing, zero-allocation parsing of untrusted inputs in Rust.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + } + ], + "licenses": [ + { + "expression": "ISC" + } + ], + "purl": "pkg:cargo/untrusted@0.9.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://briansmith.org/rustdoc/untrusted/" + }, + { + "type": "vcs", + "url": "https://github.com/briansmith/untrusted" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#url@2.5.8", + "author": "The rust-url developers", + "name": "url", + "version": "2.5.8", + "description": "URL library for Rust, based on the WHATWG URL Standard", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/url@2.5.8", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/url" + }, + { + "type": "vcs", + "url": "https://github.com/servo/rust-url" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#urlencoding@2.1.3", + "author": "Kornel , Bertram Truong ", + "name": "urlencoding", + "version": "2.1.3", + "description": "A Rust library for doing URL percentage encoding.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/urlencoding@2.1.3", + "externalReferences": [ + { + "type": "website", + "url": "https://lib.rs/urlencoding" + }, + { + "type": "vcs", + "url": "https://github.com/kornelski/rust_urlencoding" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#utf8_iter@1.0.4", + "author": "Henri Sivonen ", + "name": "utf8_iter", + "version": "1.0.4", + "description": "Iterator by char over potentially-invalid UTF-8 in &[u8]", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/utf8_iter@1.0.4", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/utf8_iter/" + }, + { + "type": "website", + "url": "https://docs.rs/utf8_iter/" + }, + { + "type": "vcs", + "url": "https://github.com/hsivonen/utf8_iter" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#utf8parse@0.2.2", + "author": "Joe Wilm , Christian Duerr ", + "name": "utf8parse", + "version": "0.2.2", + "description": "Table-driven UTF-8 parser", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/utf8parse@0.2.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/utf8parse/" + }, + { + "type": "vcs", + "url": "https://github.com/alacritty/vte" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#uuid@1.20.0", + "author": "Ashley Mannix, Dylan DPC, Hunar Roop Kahlon", + "name": "uuid", + "version": "1.20.0", + "description": "A library to generate and parse UUIDs.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/uuid@1.20.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/uuid" + }, + { + "type": "website", + "url": "https://github.com/uuid-rs/uuid" + }, + { + "type": "vcs", + "url": "https://github.com/uuid-rs/uuid" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#version_check@0.9.5", + "author": "Sergio Benitez ", + "name": "version_check", + "version": "0.9.5", + "description": "Tiny crate to check the version of the installed/running rustc.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-256", + "content": "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + } + ], + "licenses": [ + { + "expression": "MIT OR Apache-2.0" + } + ], + "purl": "pkg:cargo/version_check@0.9.5", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/version_check/" + }, + { + "type": "vcs", + "url": "https://github.com/SergioBenitez/version_check" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#walkdir@2.5.0", + "author": "Andrew Gallant ", + "name": "walkdir", + "version": "2.5.0", + "description": "Recursively walk a directory.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" + } + ], + "licenses": [ + { + "expression": "Unlicense OR MIT" + } + ], + "purl": "pkg:cargo/walkdir@2.5.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/walkdir/" + }, + { + "type": "website", + "url": "https://github.com/BurntSushi/walkdir" + }, + { + "type": "vcs", + "url": "https://github.com/BurntSushi/walkdir" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#want@0.3.1", + "author": "Sean McArthur ", + "name": "want", + "version": "0.3.1", + "description": "Detect when another Future wants a result.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/want@0.3.1", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/want" + }, + { + "type": "vcs", + "url": "https://github.com/seanmonstar/want" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#warp@0.4.2", + "author": "Sean McArthur ", + "name": "warp", + "version": "0.4.2", + "description": "serve the web at warp speeds", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "51d06d9202adc1f15d709c4f4a2069be5428aa912cc025d6f268ac441ab066b0" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/warp@0.4.2", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/warp" + }, + { + "type": "vcs", + "url": "https://github.com/seanmonstar/warp" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#whoami@2.1.0", + "name": "whoami", + "version": "2.1.0", + "description": "Rust library for getting information about the current user and environment", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "8fae98cf96deed1b7572272dfc777713c249ae40aa1cf8862e091e8b745f5361" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR BSL-1.0 OR MIT" + } + ], + "purl": "pkg:cargo/whoami@2.1.0", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/whoami" + }, + { + "type": "website", + "url": "https://github.com/ardaku/whoami/releases" + }, + { + "type": "vcs", + "url": "https://github.com/ardaku/whoami" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#wide@0.7.33", + "author": "Lokathor ", + "name": "wide", + "version": "0.7.33", + "description": "A crate to help you go wide.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" + } + ], + "licenses": [ + { + "expression": "Zlib OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/wide@0.7.33", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/Lokathor/wide" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#winnow@0.7.14", + "name": "winnow", + "version": "0.7.14", + "description": "A byte-oriented, zero-copy, parser combinators library", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/winnow@0.7.14", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/winnow-rs/winnow" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2", + "author": "The ICU4X Project Developers", + "name": "writeable", + "version": "0.6.2", + "description": "A more efficient alternative to fmt::Display", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/writeable@0.6.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#yoke-derive@0.8.1", + "author": "Manish Goregaokar ", + "name": "yoke-derive", + "version": "0.8.1", + "description": "Custom derive for the yoke crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/yoke-derive@0.8.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "author": "Manish Goregaokar ", + "name": "yoke", + "version": "0.8.1", + "description": "Abstraction allowing borrowed data to be carried along with the backing data it borrows from", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/yoke@0.8.1", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerocopy-derive@0.8.39", + "author": "Joshua Liebow-Feeser , Jack Wrenn ", + "name": "zerocopy-derive", + "version": "0.8.39", + "description": "Custom derive for traits from the zerocopy crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" + } + ], + "licenses": [ + { + "expression": "BSD-2-Clause OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/zerocopy-derive@0.8.39", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/google/zerocopy" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.8.39", + "author": "Joshua Liebow-Feeser , Jack Wrenn ", + "name": "zerocopy", + "version": "0.8.39", + "description": "Zerocopy makes zero-cost memory manipulation effortless. We write \"unsafe\" so you don't have to.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" + } + ], + "licenses": [ + { + "expression": "BSD-2-Clause OR Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/zerocopy@0.8.39", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/google/zerocopy" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerofrom-derive@0.1.6", + "author": "Manish Goregaokar ", + "name": "zerofrom-derive", + "version": "0.1.6", + "description": "Custom derive for the zerofrom crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/zerofrom-derive@0.1.6", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6", + "author": "Manish Goregaokar ", + "name": "zerofrom", + "version": "0.1.6", + "description": "ZeroFrom trait for constructing", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/zerofrom@0.1.6", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.2", + "author": "The RustCrypto Project Developers", + "name": "zeroize", + "version": "1.8.2", + "description": "Securely clear secrets from memory with a simple trait built on stable Rust primitives which guarantee memory is zeroed using an operation will not be 'optimized away' by the compiler. Uses a portable pure Rust implementation that works everywhere, even WASM! ", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "purl": "pkg:cargo/zeroize@1.8.2", + "externalReferences": [ + { + "type": "website", + "url": "https://github.com/RustCrypto/utils/tree/master/zeroize" + }, + { + "type": "vcs", + "url": "https://github.com/RustCrypto/utils" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerotrie@0.2.3", + "author": "The ICU4X Project Developers", + "name": "zerotrie", + "version": "0.2.3", + "description": "A data structure that efficiently maps strings to integers", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/zerotrie@0.2.3", + "externalReferences": [ + { + "type": "website", + "url": "https://icu4x.unicode.org" + }, + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerovec-derive@0.11.2", + "author": "Manish Goregaokar ", + "name": "zerovec-derive", + "version": "0.11.2", + "description": "Custom derive for the zerovec crate", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/zerovec-derive@0.11.2", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5", + "author": "The ICU4X Project Developers", + "name": "zerovec", + "version": "0.11.5", + "description": "Zero-copy vector backed by a byte array", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" + } + ], + "licenses": [ + { + "expression": "Unicode-3.0" + } + ], + "purl": "pkg:cargo/zerovec@0.11.5", + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/unicode-org/icu4x" + } + ] + }, + { + "type": "library", + "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#zmij@1.0.20", + "author": "David Tolnay ", + "name": "zmij", + "version": "1.0.20", + "description": "A double-to-string conversion algorithm based on Schubfach and yy", + "scope": "required", + "hashes": [ + { + "alg": "SHA-256", + "content": "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7" + } + ], + "licenses": [ + { + "expression": "MIT" + } + ], + "purl": "pkg:cargo/zmij@1.0.20", + "externalReferences": [ + { + "type": "documentation", + "url": "https://docs.rs/zmij" + }, + { + "type": "vcs", + "url": "https://github.com/dtolnay/zmij" + } + ] + } + ], + "dependencies": [ + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/cas_client#0.14.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.101", + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#axum@0.8.8", + "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "path+file:///home/runner/work/xet-core/xet-core/cas_object#0.1.0", + "path+file:///home/runner/work/xet-core/xet-core/cas_types#0.1.0", + "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.43", + "registry+https://github.com/rust-lang/crates.io-index#clap@4.5.57", + "path+file:///home/runner/work/xet-core/xet-core/deduplication#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/error_printer#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/file_utils#0.14.2", + "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#heed@0.22.0", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "path+file:///home/runner/work/xet-core/xet-core/mdb_shard#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "registry+https://github.com/rust-lang/crates.io-index#reqwest-middleware@0.5.1", + "registry+https://github.com/rust-lang/crates.io-index#reqwest-retry@0.9.1", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "registry+https://github.com/rust-lang/crates.io-index#statrs@0.18.0", + "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.25.0", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-retry@0.3.0", + "registry+https://github.com/rust-lang/crates.io-index#tower-http@0.6.8", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "registry+https://github.com/rust-lang/crates.io-index#tracing-log@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.22", + "registry+https://github.com/rust-lang/crates.io-index#url@2.5.8", + "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#warp@0.4.2", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#0.1.0" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/cas_object#0.1.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.101", + "registry+https://github.com/rust-lang/crates.io-index#blake3@1.8.3", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#clap@4.5.57", + "registry+https://github.com/rust-lang/crates.io-index#countio@0.3.0", + "registry+https://github.com/rust-lang/crates.io-index#csv@1.4.0", + "path+file:///home/runner/work/xet-core/xet-core/deduplication#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#half@2.7.1", + "registry+https://github.com/rust-lang/crates.io-index#lz4_flex@0.12.0", + "path+file:///home/runner/work/xet-core/xet-core/mdb_shard#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#0.1.0" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/cas_types#0.1.0", + "dependsOn": [ + "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_repr@0.1.20", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/data#0.14.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.101", + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "path+file:///home/runner/work/xet-core/xet-core/cas_client#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/cas_object#0.1.0", + "path+file:///home/runner/work/xet-core/xet-core/cas_types#0.1.0", + "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.43", + "registry+https://github.com/rust-lang/crates.io-index#clap@4.5.57", + "path+file:///home/runner/work/xet-core/xet-core/deduplication#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/error_printer#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/file_reconstruction#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "path+file:///home/runner/work/xet-core/xet-core/hub_client#0.1.0", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "path+file:///home/runner/work/xet-core/xet-core/mdb_shard#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "path+file:///home/runner/work/xet-core/xet-core/progress_tracking#0.1.0", + "registry+https://github.com/rust-lang/crates.io-index#prometheus@0.14.0", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "registry+https://github.com/rust-lang/crates.io-index#regex@1.12.3", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "registry+https://github.com/rust-lang/crates.io-index#sha2@0.10.9", + "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.25.0", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "registry+https://github.com/rust-lang/crates.io-index#ulid@1.2.1", + "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#walkdir@2.5.0", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#0.1.0" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/deduplication#0.14.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#gearhash@0.1.3", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "path+file:///home/runner/work/xet-core/xet-core/mdb_shard#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "path+file:///home/runner/work/xet-core/xet-core/progress_tracking#0.1.0", + "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#0.1.0" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/error_printer#0.14.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/file_reconstruction#0.14.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "path+file:///home/runner/work/xet-core/xet-core/cas_client#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/cas_types#0.1.0", + "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "path+file:///home/runner/work/xet-core/xet-core/progress_tracking#0.1.0", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/xet_config#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#0.1.0" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/file_utils#0.14.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#colored@3.1.1", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "registry+https://github.com/rust-lang/crates.io-index#whoami@2.1.0" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/hf_xet#1.3.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "path+file:///home/runner/work/xet-core/xet-core/cas_client#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.43", + "path+file:///home/runner/work/xet-core/xet-core/data#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/error_printer#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#itertools@0.14.0", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "path+file:///home/runner/work/xet-core/xet-core/progress_tracking#0.1.0", + "registry+https://github.com/rust-lang/crates.io-index#pyo3@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/xet_config#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/xet_logging#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#0.1.0" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/hub_client#0.1.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.101", + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "path+file:///home/runner/work/xet-core/xet-core/cas_client#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "registry+https://github.com/rust-lang/crates.io-index#reqwest-middleware@0.5.1", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#urlencoding@2.1.3" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/mdb_shard#0.14.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.101", + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#blake3@1.8.3", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#clap@4.5.57", + "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#heapify@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#itertools@0.14.0", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "registry+https://github.com/rust-lang/crates.io-index#regex@1.12.3", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#static_assertions@1.1.0", + "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.25.0", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#uuid@1.20.0", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#0.1.0" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "registry+https://github.com/rust-lang/crates.io-index#blake3@1.8.3", + "registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.25.0", + "registry+https://github.com/rust-lang/crates.io-index#heed@0.22.0", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "registry+https://github.com/rust-lang/crates.io-index#safe-transmute@0.11.3", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/progress_tracking#0.1.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#bincode@1.3.3", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.43", + "registry+https://github.com/rust-lang/crates.io-index#ctor@0.6.3", + "registry+https://github.com/rust-lang/crates.io-index#derivative@2.2.0", + "registry+https://github.com/rust-lang/crates.io-index#duration-str@0.19.0", + "path+file:///home/runner/work/xet-core/xet-core/error_printer#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.10", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#shellexpand@3.1.1", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/xet_config#0.14.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#const-str@1.1.0", + "registry+https://github.com/rust-lang/crates.io-index#konst@0.4.3", + "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/xet_logging#0.14.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.43", + "path+file:///home/runner/work/xet-core/xet-core/error_printer#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#git-version@0.3.9", + "registry+https://github.com/rust-lang/crates.io-index#sysinfo@0.38.1", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "registry+https://github.com/rust-lang/crates.io-index#tracing-appender@0.2.4", + "registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.22", + "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#0.1.0" + ] + }, + { + "ref": "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#0.1.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0", + "path+file:///home/runner/work/xet-core/xet-core/error_printer#0.14.5", + "registry+https://github.com/rust-lang/crates.io-index#oneshot@0.1.13", + "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5", + "path+file:///home/runner/work/xet-core/xet-core/xet_config#0.14.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#aho-corasick@1.1.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#anstream@0.6.21", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anstyle@1.0.13", + "registry+https://github.com/rust-lang/crates.io-index#anstyle-parse@0.2.7", + "registry+https://github.com/rust-lang/crates.io-index#anstyle-query@1.1.5", + "registry+https://github.com/rust-lang/crates.io-index#colorchoice@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#is_terminal_polyfill@1.70.2", + "registry+https://github.com/rust-lang/crates.io-index#utf8parse@0.2.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle-parse@0.2.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#utf8parse@0.2.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle-query@1.1.5", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle@1.0.13", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.101", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#approx@0.5.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#arrayref@0.3.9", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#arrayvec@0.7.6", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#atomic-waker@1.1.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#aws-lc-rs@1.15.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aws-lc-sys@0.37.0", + "registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#aws-lc-sys@0.37.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.55", + "registry+https://github.com/rust-lang/crates.io-index#cmake@0.1.57", + "registry+https://github.com/rust-lang/crates.io-index#dunce@1.0.5", + "registry+https://github.com/rust-lang/crates.io-index#fs_extra@1.3.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#axum-core@0.5.6", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.3", + "registry+https://github.com/rust-lang/crates.io-index#mime@0.3.17", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2", + "registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#axum@0.8.8", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#axum-core@0.5.6", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.2", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.3", + "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.20", + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.17", + "registry+https://github.com/rust-lang/crates.io-index#matchit@0.8.4", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#mime@0.3.17", + "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "registry+https://github.com/rust-lang/crates.io-index#serde_path_to_error@0.1.20", + "registry+https://github.com/rust-lang/crates.io-index#serde_urlencoded@0.7.1", + "registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tower@0.5.3", + "registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#bincode@1.3.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#bitflags@2.10.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#blake3@1.8.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#arrayref@0.3.9", + "registry+https://github.com/rust-lang/crates.io-index#arrayvec@0.7.6", + "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.55", + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#constant_time_eq@0.4.2", + "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#block-buffer@0.10.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#generic-array@0.14.7" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#bstr@1.12.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.25.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#byteorder@1.5.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.55", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#find-msvc-tools@0.1.9", + "registry+https://github.com/rust-lang/crates.io-index#jobserver@0.1.34", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#shlex@1.3.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cfg-if@0.1.10", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cfg_aliases@0.2.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.43", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#iana-time-zone@0.1.65", + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#clap@4.5.57", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#clap_builder@4.5.57", + "registry+https://github.com/rust-lang/crates.io-index#clap_derive@4.5.55" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#clap_builder@4.5.57", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anstream@0.6.21", + "registry+https://github.com/rust-lang/crates.io-index#anstyle@1.0.13", + "registry+https://github.com/rust-lang/crates.io-index#clap_lex@0.7.7", + "registry+https://github.com/rust-lang/crates.io-index#strsim@0.11.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#clap_derive@4.5.55", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#heck@0.5.0", + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#clap_lex@0.7.7", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cmake@0.1.57", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.55" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#colorchoice@1.0.4", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#colored@3.1.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#const-str@1.1.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#const_panic@0.2.15", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#typewit@1.14.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#constant_time_eq@0.4.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#countio@0.3.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.31" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-channel@0.5.15", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-queue@0.3.12", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#crypto-common@0.1.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#generic-array@0.14.7", + "registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#csv-core@0.1.13", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#csv@1.4.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#csv-core@0.1.13", + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.17", + "registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.23", + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ctor-proc-macro@0.0.7", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ctor@0.6.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#ctor-proc-macro@0.0.7", + "registry+https://github.com/rust-lang/crates.io-index#dtor@0.1.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#deranged@0.5.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#derivative@2.2.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@1.0.109" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#block-buffer@0.10.4", + "registry+https://github.com/rust-lang/crates.io-index#crypto-common@0.1.7" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#dirs-sys@0.5.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#option-ext@0.2.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#dirs-sys@0.5.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#doxygen-rs@0.4.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#phf@0.11.3" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#dtor-proc-macro@0.0.6", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#dtor@0.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#dtor-proc-macro@0.0.6" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#dunce@1.0.5", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#duration-str@0.19.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.43", + "registry+https://github.com/rust-lang/crates.io-index#rust_decimal@1.40.0", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#time@0.3.47", + "registry+https://github.com/rust-lang/crates.io-index#winnow@0.7.14" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#either@1.15.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#equivalent@1.0.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#errno@0.3.14", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#find-msvc-tools@0.1.9", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#fnv@1.0.7", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#fs_extra@1.3.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.31", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.31" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-executor@0.3.31", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.31", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-macro@0.3.31", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.31", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.31", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-macro@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#pin-utils@0.1.0", + "registry+https://github.com/rust-lang/crates.io-index#slab@0.4.12" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.31", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-executor@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#gearhash@0.1.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@0.1.10" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#generic-array@0.14.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0", + "registry+https://github.com/rust-lang/crates.io-index#version_check@0.9.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.2.17", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#git-version-macro@0.3.9", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#git-version@0.3.9", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#git-version-macro@0.3.9" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#h2@0.4.13", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#atomic-waker@1.1.2", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#fnv@1.0.7", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#indexmap@2.13.0", + "registry+https://github.com/rust-lang/crates.io-index#slab@0.4.12", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#half@2.7.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.8.39" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.16.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#headers-core@0.3.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#headers@0.4.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#headers-core@0.3.0", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#httpdate@1.0.3", + "registry+https://github.com/rust-lang/crates.io-index#mime@0.3.17", + "registry+https://github.com/rust-lang/crates.io-index#sha1@0.10.6" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#heapify@0.2.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#heck@0.5.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#heed-traits@0.20.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#heed-types@0.21.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bincode@1.3.3", + "registry+https://github.com/rust-lang/crates.io-index#byteorder@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#heed-traits@0.20.0", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#heed@0.22.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bitflags@2.10.0", + "registry+https://github.com/rust-lang/crates.io-index#byteorder@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#heed-traits@0.20.0", + "registry+https://github.com/rust-lang/crates.io-index#heed-types@0.21.0", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#lmdb-master-sys@0.2.5", + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3", + "registry+https://github.com/rust-lang/crates.io-index#page_size@0.6.0", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#synchronoise@1.0.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.17" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#httpdate@1.0.3", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#hyper-rustls@0.27.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.20", + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.36", + "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-rustls@0.26.4", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.20", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "registry+https://github.com/rust-lang/crates.io-index#ipnet@2.11.0", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.2", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#atomic-waker@1.1.2", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#h2@0.4.13", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1", + "registry+https://github.com/rust-lang/crates.io-index#httpdate@1.0.3", + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.17", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#pin-utils@0.1.0", + "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#want@0.3.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#iana-time-zone@0.1.65", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "registry+https://github.com/rust-lang/crates.io-index#potential_utf@0.1.4", + "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_locale_core@2.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "registry+https://github.com/rust-lang/crates.io-index#litemap@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#tinystr@0.8.2", + "registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer@2.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer_data@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2", + "registry+https://github.com/rust-lang/crates.io-index#icu_provider@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer_data@2.1.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#icu_locale_core@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#icu_properties_data@2.1.2", + "registry+https://github.com/rust-lang/crates.io-index#icu_provider@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#zerotrie@0.2.3", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_properties_data@2.1.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#icu_provider@2.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "registry+https://github.com/rust-lang/crates.io-index#icu_locale_core@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2", + "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6", + "registry+https://github.com/rust-lang/crates.io-index#zerotrie@0.2.3", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#idna@1.1.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#idna_adapter@1.2.1", + "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1", + "registry+https://github.com/rust-lang/crates.io-index#utf8_iter@1.0.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#idna_adapter@1.2.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#indexmap@2.13.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#equivalent@1.0.2", + "registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.16.1", + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#indoc@2.0.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ipnet@2.11.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#iri-string@0.7.10", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#is_terminal_polyfill@1.70.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#itertools@0.14.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#either@1.15.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.17", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#jobserver@0.1.34", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#konst@0.4.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#const_panic@0.2.15", + "registry+https://github.com/rust-lang/crates.io-index#konst_proc_macros@0.4.1", + "registry+https://github.com/rust-lang/crates.io-index#typewit@1.14.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#konst_proc_macros@0.4.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#libm@0.2.16", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.11.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#litemap@0.8.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#lmdb-master-sys@0.2.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.55", + "registry+https://github.com/rust-lang/crates.io-index#doxygen-rs@0.4.2", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#lock_api@0.4.14", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#scopeguard@1.2.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#lru-slab@0.1.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#lz4_flex@0.12.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#twox-hash@2.1.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#matchers@0.2.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#matchit@0.8.4", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#matrixmultiply@0.3.10", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#rawpointer@0.2.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#memoffset@0.9.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#mime@0.3.17", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#mime_guess@2.0.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#mime@0.3.17", + "registry+https://github.com/rust-lang/crates.io-index#unicase@2.9.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#mio@1.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#nalgebra@0.33.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#approx@0.5.1", + "registry+https://github.com/rust-lang/crates.io-index#matrixmultiply@0.3.10", + "registry+https://github.com/rust-lang/crates.io-index#num-complex@0.4.6", + "registry+https://github.com/rust-lang/crates.io-index#num-rational@0.4.2", + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.8.5", + "registry+https://github.com/rust-lang/crates.io-index#rand_distr@0.4.3", + "registry+https://github.com/rust-lang/crates.io-index#simba@0.9.1", + "registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#nu-ansi-term@0.50.3", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#num-bigint@0.4.6", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#num-integer@0.1.46", + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#num-complex@0.4.6", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#num-conv@0.2.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#num-integer@0.1.46", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#num-rational@0.4.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#num-bigint@0.4.6", + "registry+https://github.com/rust-lang/crates.io-index#num-integer@0.1.46", + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#libm@0.2.16" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#oneshot@0.1.13", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#openssl-probe@0.2.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#option-ext@0.2.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#os_str_bytes@6.6.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#page_size@0.6.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#parking_lot@0.12.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#lock_api@0.4.14", + "registry+https://github.com/rust-lang/crates.io-index#parking_lot_core@0.9.12" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#parking_lot_core@0.9.12", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#paste@1.0.15", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#phf@0.11.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#phf_macros@0.11.3", + "registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.11.3" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#phf_generator@0.11.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.11.3", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.8.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#phf_macros@0.11.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#phf_generator@0.11.3", + "registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.11.3", + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.11.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#siphasher@1.0.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project-internal@1.1.10", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.10", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#pin-project-internal@1.1.10" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pin-utils@0.1.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#potential_utf@0.1.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ppv-lite86@0.2.21", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.8.39" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.23" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#prometheus@0.14.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#fnv@1.0.7", + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#parking_lot@0.12.5", + "registry+https://github.com/rust-lang/crates.io-index#protobuf@3.7.2", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#protobuf-support@3.7.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#thiserror@1.0.69" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#protobuf@3.7.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3", + "registry+https://github.com/rust-lang/crates.io-index#protobuf-support@3.7.2", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@1.0.69" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-build-config@0.26.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#target-lexicon@0.13.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-ffi@0.26.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-build-config@0.26.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros-backend@0.26.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#heck@0.5.0", + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-build-config@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros@0.26.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros-backend@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3@0.26.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#indoc@2.0.7", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#memoffset@0.9.1", + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-build-config@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-ffi@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros@0.26.0", + "registry+https://github.com/rust-lang/crates.io-index#unindent@0.2.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#quinn-proto@0.11.13", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aws-lc-rs@1.15.4", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#lru-slab@0.1.2", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "registry+https://github.com/rust-lang/crates.io-index#rustc-hash@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.36", + "registry+https://github.com/rust-lang/crates.io-index#slab@0.4.12", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tinyvec@1.10.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#quinn-udp@0.5.14", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg_aliases@0.2.1", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.2", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#quinn@0.11.9", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#cfg_aliases@0.2.1", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#quinn-proto@0.11.13", + "registry+https://github.com/rust-lang/crates.io-index#quinn-udp@0.5.14", + "registry+https://github.com/rust-lang/crates.io-index#rustc-hash@2.1.1", + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.36", + "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.2", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand@0.8.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.3.1", + "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.6.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.9.0", + "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.9.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.3.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#ppv-lite86@0.2.21", + "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.6.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.9.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#ppv-lite86@0.2.21", + "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.9.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.6.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.2.17" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.9.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rand_distr@0.4.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.8.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rawpointer@0.2.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aho-corasick@1.1.4", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.9" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.9", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#regex@1.12.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aho-corasick@1.1.4", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14", + "registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.9" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest-middleware@0.5.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.101", + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest-retry@0.9.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.101", + "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89", + "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "registry+https://github.com/rust-lang/crates.io-index#reqwest-middleware@0.5.1", + "registry+https://github.com/rust-lang/crates.io-index#retry-policies@0.5.1", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.3", + "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "registry+https://github.com/rust-lang/crates.io-index#hyper-rustls@0.27.7", + "registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.20", + "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29", + "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#quinn@0.11.9", + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.36", + "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "registry+https://github.com/rust-lang/crates.io-index#rustls-platform-verifier@0.6.2", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-rustls@0.26.4", + "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "registry+https://github.com/rust-lang/crates.io-index#tower@0.5.3", + "registry+https://github.com/rust-lang/crates.io-index#tower-http@0.6.8", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#url@2.5.8" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#retry-policies@0.5.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.55", + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#untrusted@0.9.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rust_decimal@1.40.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#arrayvec@0.7.6", + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustc-hash@2.1.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bitflags@2.10.0", + "registry+https://github.com/rust-lang/crates.io-index#errno@0.3.14", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.11.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-native-certs@0.8.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#openssl-probe@0.2.1", + "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-platform-verifier@0.6.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29", + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.36", + "registry+https://github.com/rust-lang/crates.io-index#rustls-native-certs@0.8.3", + "registry+https://github.com/rust-lang/crates.io-index#rustls-webpki@0.103.9" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-webpki@0.103.9", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aws-lc-rs@1.15.4", + "registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14", + "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "registry+https://github.com/rust-lang/crates.io-index#untrusted@0.9.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.36", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#aws-lc-rs@1.15.4", + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3", + "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0", + "registry+https://github.com/rust-lang/crates.io-index#rustls-webpki@0.103.9", + "registry+https://github.com/rust-lang/crates.io-index#subtle@2.6.1", + "registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.23", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#safe-transmute@0.11.3", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#safe_arch@0.7.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.25.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#same-file@1.0.6", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#scoped-tls@1.0.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#scopeguard@1.2.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.228", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.17", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0", + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#zmij@1.0.20" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde_path_to_error@0.1.20", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.17", + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde_repr@0.1.20", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#serde_urlencoded@0.7.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.2", + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.17", + "registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.23", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#sha1@0.10.6", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#sha2-asm@0.6.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.55" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#sha2@0.10.9", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4", + "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17", + "registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7", + "registry+https://github.com/rust-lang/crates.io-index#sha2-asm@0.6.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#sharded-slab@0.1.7", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#shellexpand@3.1.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bstr@1.12.1", + "registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0", + "registry+https://github.com/rust-lang/crates.io-index#os_str_bytes@6.6.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#shlex@1.3.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#signal-hook-registry@1.4.8", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#errno@0.3.14", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#signal-hook-registry@1.4.8" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#simba@0.9.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#approx@0.5.1", + "registry+https://github.com/rust-lang/crates.io-index#num-complex@0.4.6", + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19", + "registry+https://github.com/rust-lang/crates.io-index#paste@1.0.15", + "registry+https://github.com/rust-lang/crates.io-index#wide@0.7.33" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#siphasher@1.0.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#slab@0.4.12", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#stable_deref_trait@1.2.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#static_assertions@1.1.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#statrs@0.18.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#approx@0.5.1", + "registry+https://github.com/rust-lang/crates.io-index#nalgebra@0.33.2", + "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.8.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#strsim@0.11.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#subtle@2.6.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#syn@1.0.109", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.23" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.23" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#synchronoise@1.0.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#crossbeam-queue@0.3.12" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#synstructure@0.13.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#sysinfo@0.38.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#target-lexicon@0.13.4", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.25.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0", + "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.1", + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3", + "registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@1.0.69", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@2.0.18", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror@1.0.69", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@1.0.69" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@2.0.18" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#thread_local@1.1.9", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.8", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#time-macros@0.2.27", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#num-conv@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.8" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#time@0.3.47", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#deranged@0.5.5", + "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.17", + "registry+https://github.com/rust-lang/crates.io-index#num-conv@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.8", + "registry+https://github.com/rust-lang/crates.io-index#time-macros@0.2.27" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tinystr@0.8.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tinyvec@1.10.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#tinyvec_macros@0.1.1" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tinyvec_macros@0.1.1", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-macros@2.6.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-retry@0.3.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.10", + "registry+https://github.com/rust-lang/crates.io-index#rand@0.8.5", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-rustls@0.26.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.36", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181", + "registry+https://github.com/rust-lang/crates.io-index#mio@1.1.1", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.2", + "registry+https://github.com/rust-lang/crates.io-index#tokio-macros@2.6.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tower-http@0.6.8", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bitflags@2.10.0", + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#iri-string@0.7.10", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#tower@0.5.3", + "registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tower@0.5.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-appender@0.2.4", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#crossbeam-channel@0.5.15", + "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18", + "registry+https://github.com/rust-lang/crates.io-index#time@0.3.47", + "registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.22" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-attributes@0.1.31", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-log@0.2.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29", + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3", + "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-serde@0.2.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.22", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#matchers@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#nu-ansi-term@0.50.3", + "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3", + "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "registry+https://github.com/rust-lang/crates.io-index#sharded-slab@0.1.7", + "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1", + "registry+https://github.com/rust-lang/crates.io-index#thread_local@1.1.9", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36", + "registry+https://github.com/rust-lang/crates.io-index#tracing-log@0.2.0", + "registry+https://github.com/rust-lang/crates.io-index#tracing-serde@0.2.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29", + "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16", + "registry+https://github.com/rust-lang/crates.io-index#tracing-attributes@0.1.31", + "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#try-lock@0.2.5", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#twox-hash@2.1.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#typewit@1.14.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#ulid@1.2.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#unicase@2.9.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.23", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#unindent@0.2.4", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#untrusted@0.9.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#url@2.5.8", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.2", + "registry+https://github.com/rust-lang/crates.io-index#idna@1.1.0", + "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#urlencoding@2.1.3", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#utf8_iter@1.0.4", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#utf8parse@0.2.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#uuid@1.20.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#version_check@0.9.5", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#walkdir@2.5.0", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#same-file@1.0.6" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#want@0.3.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#try-lock@0.2.5" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#warp@0.4.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1", + "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31", + "registry+https://github.com/rust-lang/crates.io-index#headers@0.4.1", + "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0", + "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.3", + "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1", + "registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.20", + "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29", + "registry+https://github.com/rust-lang/crates.io-index#mime@0.3.17", + "registry+https://github.com/rust-lang/crates.io-index#mime_guess@2.0.5", + "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2", + "registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.10", + "registry+https://github.com/rust-lang/crates.io-index#scoped-tls@1.0.1", + "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228", + "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149", + "registry+https://github.com/rust-lang/crates.io-index#serde_urlencoded@0.7.1", + "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0", + "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18", + "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3", + "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#whoami@2.1.0", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#wide@0.7.33", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.25.0", + "registry+https://github.com/rust-lang/crates.io-index#safe_arch@0.7.4" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#winnow@0.7.14", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#yoke-derive@0.8.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114", + "registry+https://github.com/rust-lang/crates.io-index#synstructure@0.13.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#stable_deref_trait@1.2.1", + "registry+https://github.com/rust-lang/crates.io-index#yoke-derive@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerocopy-derive@0.8.39", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.8.39", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#zerocopy-derive@0.8.39" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerofrom-derive@0.1.6", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114", + "registry+https://github.com/rust-lang/crates.io-index#synstructure@0.13.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#zerofrom-derive@0.1.6" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.2", + "dependsOn": [] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerotrie@0.2.3", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5", + "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerovec-derive@0.11.2", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106", + "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44", + "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5", + "dependsOn": [ + "registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1", + "registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6", + "registry+https://github.com/rust-lang/crates.io-index#zerovec-derive@0.11.2" + ] + }, + { + "ref": "registry+https://github.com/rust-lang/crates.io-index#zmij@1.0.20", + "dependsOn": [] + } + ] +} \ No newline at end of file diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17a440f722d918e7d21d22cad78ae0ce16b2eaa3 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/_identifier.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/_identifier.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..863ae99e277d085c9c30264eee33f7abfe2300fd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/_identifier.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/async_utils.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/async_utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0bfa6426b969889d86919939380cca1fd3a74b5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/async_utils.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/bccache.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/bccache.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..124c58b4e497fbb7260b98ea07d3967f9358c64a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/bccache.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/constants.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/constants.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e0193eaa1753f124a573b41383252f7ad2a7385e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/constants.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/debug.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/debug.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b762002143b9d435bbd0aba3fccfa3b26a0e844b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/debug.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/defaults.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/defaults.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff98d03674d8208f41f79bb4ae7480a291ba0911 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/defaults.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/environment.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/environment.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e138e2b9809df37429dd321428d2425ee9ebad5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/environment.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/exceptions.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/exceptions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81663ae379080c630f31a4c80c9164e9bd5cd4be Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/exceptions.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/ext.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/ext.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab84cf72342574febbe7a5c23bb2716bbe1a0043 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/ext.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/filters.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/filters.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94f335dec42f680dbdccc47cc392fd51ee0ab821 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/filters.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/idtracking.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/idtracking.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60c6a427a854d9498ac3c891840d986829ab9302 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/idtracking.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/lexer.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/lexer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..46670e5fc10ea3b322e5af8edd2fdecdc0bd7786 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/lexer.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/loaders.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/loaders.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ce5f8b60028773bcca51021c56b2df59f22aa8d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/loaders.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/meta.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/meta.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f1ffaede5dbe17e0263a0123395f0fd1c52b353 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/meta.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/nativetypes.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/nativetypes.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1bd2c652bd0a9aa28f8116580cce6ce66cf4a6df Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/nativetypes.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/nodes.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/nodes.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff7e09f9e4fdb54de3ca0ba05342772df5212abb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/nodes.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/optimizer.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/optimizer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3886e74b25d20f81039e5c5c6b8d3f4831d32052 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/optimizer.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/parser.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/parser.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e59884c5c61270cb17cad7dd283da8767e436986 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/parser.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/runtime.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/runtime.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..626bf7a3beeeb380b3a6c94381dec59fc384cf46 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/runtime.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/sandbox.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/sandbox.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b21cab1cad15ac0ee01394055123fae16610bfb9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/sandbox.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/tests.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/tests.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ad860b45cc105979323032974a68594bf58ce97 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/tests.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/utils.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..45795228c54ab6779dc8e8fdb0ef7d92b145a1ae Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/utils.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/visitor.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/visitor.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ab209f01242fd537f8fa76dec7281f0e945c80f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/jinja2/__pycache__/visitor.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4dede3c5999742b936c7d98e8b7f7cb8d11bfb63 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_base.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_base.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..966e71f40b735194108f31440ebc213613b87fd1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_base.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_fp.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_fp.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e423319c60e89d520ca34092a1e00506c551d5dc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_fp.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_iv.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_iv.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..db09b39cbcaad28ecafd68b0b0b60c5e895cd64c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_iv.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_mp.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_mp.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39b1d088861adc54e79e7d770d485dc3070ba9b3 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_mp.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_mp_python.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_mp_python.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ba838003e37eeffd44ea9b4f966f8977ff796c6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/ctx_mp_python.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/identification.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/identification.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8edbf4b11be2ee2d390d1df1a0657be781e27b5e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/identification.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/math2.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/math2.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c472794f19c19ec6ea10876f57433ae791d846d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/math2.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/rational.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/rational.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e5a1a83a0174a14c76485c3210cdb0e13e343ce Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/rational.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/usertools.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/usertools.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d19289b71812998de315395b8df18a513ad54f65 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/usertools.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/visualization.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/visualization.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..883b3bd3c5865baf1c1ba3db8ead2667e903d607 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/__pycache__/visualization.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..040a3806b968f75b8d1a88ae37a4979fe83d466a --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/__init__.py @@ -0,0 +1,6 @@ +from . import calculus +# XXX: hack to set methods +from . import approximation +from . import differentiation +from . import extrapolation +from . import polynomials diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/approximation.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/approximation.py new file mode 100644 index 0000000000000000000000000000000000000000..7ca5cc598fb53491cb6ae4a41a40477c58544d53 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/approximation.py @@ -0,0 +1,246 @@ +from ..libmp.backend import xrange +from .calculus import defun + +#----------------------------------------------------------------------------# +# Approximation methods # +#----------------------------------------------------------------------------# + +# The Chebyshev approximation formula is given at: +# http://mathworld.wolfram.com/ChebyshevApproximationFormula.html + +# The only major changes in the following code is that we return the +# expanded polynomial coefficients instead of Chebyshev coefficients, +# and that we automatically transform [a,b] -> [-1,1] and back +# for convenience. + +# Coefficient in Chebyshev approximation +def chebcoeff(ctx,f,a,b,j,N): + s = ctx.mpf(0) + h = ctx.mpf(0.5) + for k in range(1, N+1): + t = ctx.cospi((k-h)/N) + s += f(t*(b-a)*h + (b+a)*h) * ctx.cospi(j*(k-h)/N) + return 2*s/N + +# Generate Chebyshev polynomials T_n(ax+b) in expanded form +def chebT(ctx, a=1, b=0): + Tb = [1] + yield Tb + Ta = [b, a] + while 1: + yield Ta + # Recurrence: T[n+1](ax+b) = 2*(ax+b)*T[n](ax+b) - T[n-1](ax+b) + Tmp = [0] + [2*a*t for t in Ta] + for i, c in enumerate(Ta): Tmp[i] += 2*b*c + for i, c in enumerate(Tb): Tmp[i] -= c + Ta, Tb = Tmp, Ta + +@defun +def chebyfit(ctx, f, interval, N, error=False): + r""" + Computes a polynomial of degree `N-1` that approximates the + given function `f` on the interval `[a, b]`. With ``error=True``, + :func:`~mpmath.chebyfit` also returns an accurate estimate of the + maximum absolute error; that is, the maximum value of + `|f(x) - P(x)|` for `x \in [a, b]`. + + :func:`~mpmath.chebyfit` uses the Chebyshev approximation formula, + which gives a nearly optimal solution: that is, the maximum + error of the approximating polynomial is very close to + the smallest possible for any polynomial of the same degree. + + Chebyshev approximation is very useful if one needs repeated + evaluation of an expensive function, such as function defined + implicitly by an integral or a differential equation. (For + example, it could be used to turn a slow mpmath function + into a fast machine-precision version of the same.) + + **Examples** + + Here we use :func:`~mpmath.chebyfit` to generate a low-degree approximation + of `f(x) = \cos(x)`, valid on the interval `[1, 2]`:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> poly, err = chebyfit(cos, [1, 2], 5, error=True) + >>> nprint(poly) + [0.00291682, 0.146166, -0.732491, 0.174141, 0.949553] + >>> nprint(err, 12) + 1.61351758081e-5 + + The polynomial can be evaluated using ``polyval``:: + + >>> nprint(polyval(poly, 1.6), 12) + -0.0291858904138 + >>> nprint(cos(1.6), 12) + -0.0291995223013 + + Sampling the true error at 1000 points shows that the error + estimate generated by ``chebyfit`` is remarkably good:: + + >>> error = lambda x: abs(cos(x) - polyval(poly, x)) + >>> nprint(max([error(1+n/1000.) for n in range(1000)]), 12) + 1.61349954245e-5 + + **Choice of degree** + + The degree `N` can be set arbitrarily high, to obtain an + arbitrarily good approximation. As a rule of thumb, an + `N`-term Chebyshev approximation is good to `N/(b-a)` decimal + places on a unit interval (although this depends on how + well-behaved `f` is). The cost grows accordingly: ``chebyfit`` + evaluates the function `(N^2)/2` times to compute the + coefficients and an additional `N` times to estimate the error. + + **Possible issues** + + One should be careful to use a sufficiently high working + precision both when calling ``chebyfit`` and when evaluating + the resulting polynomial, as the polynomial is sometimes + ill-conditioned. It is for example difficult to reach + 15-digit accuracy when evaluating the polynomial using + machine precision floats, no matter the theoretical + accuracy of the polynomial. (The option to return the + coefficients in Chebyshev form should be made available + in the future.) + + It is important to note the Chebyshev approximation works + poorly if `f` is not smooth. A function containing singularities, + rapid oscillation, etc can be approximated more effectively by + multiplying it by a weight function that cancels out the + nonsmooth features, or by dividing the interval into several + segments. + """ + a, b = ctx._as_points(interval) + orig = ctx.prec + try: + ctx.prec = orig + int(N**0.5) + 20 + c = [chebcoeff(ctx,f,a,b,k,N) for k in range(N)] + d = [ctx.zero] * N + d[0] = -c[0]/2 + h = ctx.mpf(0.5) + T = chebT(ctx, ctx.mpf(2)/(b-a), ctx.mpf(-1)*(b+a)/(b-a)) + for (k, Tk) in zip(range(N), T): + for i in range(len(Tk)): + d[i] += c[k]*Tk[i] + d = d[::-1] + # Estimate maximum error + err = ctx.zero + for k in range(N): + x = ctx.cos(ctx.pi*k/N) * (b-a)*h + (b+a)*h + err = max(err, abs(f(x) - ctx.polyval(d, x))) + finally: + ctx.prec = orig + if error: + return d, +err + else: + return d + +@defun +def fourier(ctx, f, interval, N): + r""" + Computes the Fourier series of degree `N` of the given function + on the interval `[a, b]`. More precisely, :func:`~mpmath.fourier` returns + two lists `(c, s)` of coefficients (the cosine series and sine + series, respectively), such that + + .. math :: + + f(x) \sim \sum_{k=0}^N + c_k \cos(k m x) + s_k \sin(k m x) + + where `m = 2 \pi / (b-a)`. + + Note that many texts define the first coefficient as `2 c_0` instead + of `c_0`. The easiest way to evaluate the computed series correctly + is to pass it to :func:`~mpmath.fourierval`. + + **Examples** + + The function `f(x) = x` has a simple Fourier series on the standard + interval `[-\pi, \pi]`. The cosine coefficients are all zero (because + the function has odd symmetry), and the sine coefficients are + rational numbers:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> c, s = fourier(lambda x: x, [-pi, pi], 5) + >>> nprint(c) + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] + >>> nprint(s) + [0.0, 2.0, -1.0, 0.666667, -0.5, 0.4] + + This computes a Fourier series of a nonsymmetric function on + a nonstandard interval:: + + >>> I = [-1, 1.5] + >>> f = lambda x: x**2 - 4*x + 1 + >>> cs = fourier(f, I, 4) + >>> nprint(cs[0]) + [0.583333, 1.12479, -1.27552, 0.904708, -0.441296] + >>> nprint(cs[1]) + [0.0, -2.6255, 0.580905, 0.219974, -0.540057] + + It is instructive to plot a function along with its truncated + Fourier series:: + + >>> plot([f, lambda x: fourierval(cs, I, x)], I) #doctest: +SKIP + + Fourier series generally converge slowly (and may not converge + pointwise). For example, if `f(x) = \cosh(x)`, a 10-term Fourier + series gives an `L^2` error corresponding to 2-digit accuracy:: + + >>> I = [-1, 1] + >>> cs = fourier(cosh, I, 9) + >>> g = lambda x: (cosh(x) - fourierval(cs, I, x))**2 + >>> nprint(sqrt(quad(g, I))) + 0.00467963 + + :func:`~mpmath.fourier` uses numerical quadrature. For nonsmooth functions, + the accuracy (and speed) can be improved by including all singular + points in the interval specification:: + + >>> nprint(fourier(abs, [-1, 1], 0), 10) + ([0.5000441648], [0.0]) + >>> nprint(fourier(abs, [-1, 0, 1], 0), 10) + ([0.5], [0.0]) + + """ + interval = ctx._as_points(interval) + a = interval[0] + b = interval[-1] + L = b-a + cos_series = [] + sin_series = [] + cutoff = ctx.eps*10 + for n in xrange(N+1): + m = 2*n*ctx.pi/L + an = 2*ctx.quadgl(lambda t: f(t)*ctx.cos(m*t), interval)/L + bn = 2*ctx.quadgl(lambda t: f(t)*ctx.sin(m*t), interval)/L + if n == 0: + an /= 2 + if abs(an) < cutoff: an = ctx.zero + if abs(bn) < cutoff: bn = ctx.zero + cos_series.append(an) + sin_series.append(bn) + return cos_series, sin_series + +@defun +def fourierval(ctx, series, interval, x): + """ + Evaluates a Fourier series (in the format computed by + by :func:`~mpmath.fourier` for the given interval) at the point `x`. + + The series should be a pair `(c, s)` where `c` is the + cosine series and `s` is the sine series. The two lists + need not have the same length. + """ + cs, ss = series + ab = ctx._as_points(interval) + a = interval[0] + b = interval[-1] + m = 2*ctx.pi/(ab[-1]-ab[0]) + s = ctx.zero + s += ctx.fsum(cs[n]*ctx.cos(m*n*x) for n in xrange(len(cs)) if cs[n]) + s += ctx.fsum(ss[n]*ctx.sin(m*n*x) for n in xrange(len(ss)) if ss[n]) + return s diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/calculus.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/calculus.py new file mode 100644 index 0000000000000000000000000000000000000000..24256f121d6c07e5ce954f2a5f5024f156f64016 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/calculus.py @@ -0,0 +1,6 @@ +class CalculusMethods(object): + pass + +def defun(f): + setattr(CalculusMethods, f.__name__, f) + return f diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/differentiation.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/differentiation.py new file mode 100644 index 0000000000000000000000000000000000000000..f8186bebd4476476eded9e4b2f8dc3eb23ef5ff9 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/differentiation.py @@ -0,0 +1,647 @@ +from ..libmp.backend import xrange +from .calculus import defun + +try: + iteritems = dict.iteritems +except AttributeError: + iteritems = dict.items + +#----------------------------------------------------------------------------# +# Differentiation # +#----------------------------------------------------------------------------# + +@defun +def difference(ctx, s, n): + r""" + Given a sequence `(s_k)` containing at least `n+1` items, returns the + `n`-th forward difference, + + .. math :: + + \Delta^n = \sum_{k=0}^{\infty} (-1)^{k+n} {n \choose k} s_k. + """ + n = int(n) + d = ctx.zero + b = (-1) ** (n & 1) + for k in xrange(n+1): + d += b * s[k] + b = (b * (k-n)) // (k+1) + return d + +def hsteps(ctx, f, x, n, prec, **options): + singular = options.get('singular') + addprec = options.get('addprec', 10) + direction = options.get('direction', 0) + workprec = (prec+2*addprec) * (n+1) + orig = ctx.prec + try: + ctx.prec = workprec + h = options.get('h') + if h is None: + if options.get('relative'): + hextramag = int(ctx.mag(x)) + else: + hextramag = 0 + h = ctx.ldexp(1, -prec-addprec-hextramag) + else: + h = ctx.convert(h) + # Directed: steps x, x+h, ... x+n*h + direction = options.get('direction', 0) + if direction: + h *= ctx.sign(direction) + steps = xrange(n+1) + norm = h + # Central: steps x-n*h, x-(n-2)*h ..., x, ..., x+(n-2)*h, x+n*h + else: + steps = xrange(-n, n+1, 2) + norm = (2*h) + # Perturb + if singular: + x += 0.5*h + values = [f(x+k*h) for k in steps] + return values, norm, workprec + finally: + ctx.prec = orig + + +@defun +def diff(ctx, f, x, n=1, **options): + r""" + Numerically computes the derivative of `f`, `f'(x)`, or generally for + an integer `n \ge 0`, the `n`-th derivative `f^{(n)}(x)`. + A few basic examples are:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> diff(lambda x: x**2 + x, 1.0) + 3.0 + >>> diff(lambda x: x**2 + x, 1.0, 2) + 2.0 + >>> diff(lambda x: x**2 + x, 1.0, 3) + 0.0 + >>> nprint([diff(exp, 3, n) for n in range(5)]) # exp'(x) = exp(x) + [20.0855, 20.0855, 20.0855, 20.0855, 20.0855] + + Even more generally, given a tuple of arguments `(x_1, \ldots, x_k)` + and order `(n_1, \ldots, n_k)`, the partial derivative + `f^{(n_1,\ldots,n_k)}(x_1,\ldots,x_k)` is evaluated. For example:: + + >>> diff(lambda x,y: 3*x*y + 2*y - x, (0.25, 0.5), (0,1)) + 2.75 + >>> diff(lambda x,y: 3*x*y + 2*y - x, (0.25, 0.5), (1,1)) + 3.0 + + **Options** + + The following optional keyword arguments are recognized: + + ``method`` + Supported methods are ``'step'`` or ``'quad'``: derivatives may be + computed using either a finite difference with a small step + size `h` (default), or numerical quadrature. + ``direction`` + Direction of finite difference: can be -1 for a left + difference, 0 for a central difference (default), or +1 + for a right difference; more generally can be any complex number. + ``addprec`` + Extra precision for `h` used to account for the function's + sensitivity to perturbations (default = 10). + ``relative`` + Choose `h` relative to the magnitude of `x`, rather than an + absolute value; useful for large or tiny `x` (default = False). + ``h`` + As an alternative to ``addprec`` and ``relative``, manually + select the step size `h`. + ``singular`` + If True, evaluation exactly at the point `x` is avoided; this is + useful for differentiating functions with removable singularities. + Default = False. + ``radius`` + Radius of integration contour (with ``method = 'quad'``). + Default = 0.25. A larger radius typically is faster and more + accurate, but it must be chosen so that `f` has no + singularities within the radius from the evaluation point. + + A finite difference requires `n+1` function evaluations and must be + performed at `(n+1)` times the target precision. Accordingly, `f` must + support fast evaluation at high precision. + + With integration, a larger number of function evaluations is + required, but not much extra precision is required. For high order + derivatives, this method may thus be faster if f is very expensive to + evaluate at high precision. + + **Further examples** + + The direction option is useful for computing left- or right-sided + derivatives of nonsmooth functions:: + + >>> diff(abs, 0, direction=0) + 0.0 + >>> diff(abs, 0, direction=1) + 1.0 + >>> diff(abs, 0, direction=-1) + -1.0 + + More generally, if the direction is nonzero, a right difference + is computed where the step size is multiplied by sign(direction). + For example, with direction=+j, the derivative from the positive + imaginary direction will be computed:: + + >>> diff(abs, 0, direction=j) + (0.0 - 1.0j) + + With integration, the result may have a small imaginary part + even even if the result is purely real:: + + >>> diff(sqrt, 1, method='quad') # doctest:+ELLIPSIS + (0.5 - 4.59...e-26j) + >>> chop(_) + 0.5 + + Adding precision to obtain an accurate value:: + + >>> diff(cos, 1e-30) + 0.0 + >>> diff(cos, 1e-30, h=0.0001) + -9.99999998328279e-31 + >>> diff(cos, 1e-30, addprec=100) + -1.0e-30 + + """ + partial = False + try: + orders = list(n) + x = list(x) + partial = True + except TypeError: + pass + if partial: + x = [ctx.convert(_) for _ in x] + return _partial_diff(ctx, f, x, orders, options) + method = options.get('method', 'step') + if n == 0 and method != 'quad' and not options.get('singular'): + return f(ctx.convert(x)) + prec = ctx.prec + try: + if method == 'step': + values, norm, workprec = hsteps(ctx, f, x, n, prec, **options) + ctx.prec = workprec + v = ctx.difference(values, n) / norm**n + elif method == 'quad': + ctx.prec += 10 + radius = ctx.convert(options.get('radius', 0.25)) + def g(t): + rei = radius*ctx.expj(t) + z = x + rei + return f(z) / rei**n + d = ctx.quadts(g, [0, 2*ctx.pi]) + v = d * ctx.factorial(n) / (2*ctx.pi) + else: + raise ValueError("unknown method: %r" % method) + finally: + ctx.prec = prec + return +v + +def _partial_diff(ctx, f, xs, orders, options): + if not orders: + return f() + if not sum(orders): + return f(*xs) + i = 0 + for i in range(len(orders)): + if orders[i]: + break + order = orders[i] + def fdiff_inner(*f_args): + def inner(t): + return f(*(f_args[:i] + (t,) + f_args[i+1:])) + return ctx.diff(inner, f_args[i], order, **options) + orders[i] = 0 + return _partial_diff(ctx, fdiff_inner, xs, orders, options) + +@defun +def diffs(ctx, f, x, n=None, **options): + r""" + Returns a generator that yields the sequence of derivatives + + .. math :: + + f(x), f'(x), f''(x), \ldots, f^{(k)}(x), \ldots + + With ``method='step'``, :func:`~mpmath.diffs` uses only `O(k)` + function evaluations to generate the first `k` derivatives, + rather than the roughly `O(k^2)` evaluations + required if one calls :func:`~mpmath.diff` `k` separate times. + + With `n < \infty`, the generator stops as soon as the + `n`-th derivative has been generated. If the exact number of + needed derivatives is known in advance, this is further + slightly more efficient. + + Options are the same as for :func:`~mpmath.diff`. + + **Examples** + + >>> from mpmath import * + >>> mp.dps = 15 + >>> nprint(list(diffs(cos, 1, 5))) + [0.540302, -0.841471, -0.540302, 0.841471, 0.540302, -0.841471] + >>> for i, d in zip(range(6), diffs(cos, 1)): + ... print("%s %s" % (i, d)) + ... + 0 0.54030230586814 + 1 -0.841470984807897 + 2 -0.54030230586814 + 3 0.841470984807897 + 4 0.54030230586814 + 5 -0.841470984807897 + + """ + if n is None: + n = ctx.inf + else: + n = int(n) + if options.get('method', 'step') != 'step': + k = 0 + while k < n + 1: + yield ctx.diff(f, x, k, **options) + k += 1 + return + singular = options.get('singular') + if singular: + yield ctx.diff(f, x, 0, singular=True) + else: + yield f(ctx.convert(x)) + if n < 1: + return + if n == ctx.inf: + A, B = 1, 2 + else: + A, B = 1, n+1 + while 1: + callprec = ctx.prec + y, norm, workprec = hsteps(ctx, f, x, B, callprec, **options) + for k in xrange(A, B): + try: + ctx.prec = workprec + d = ctx.difference(y, k) / norm**k + finally: + ctx.prec = callprec + yield +d + if k >= n: + return + A, B = B, int(A*1.4+1) + B = min(B, n) + +def iterable_to_function(gen): + gen = iter(gen) + data = [] + def f(k): + for i in xrange(len(data), k+1): + data.append(next(gen)) + return data[k] + return f + +@defun +def diffs_prod(ctx, factors): + r""" + Given a list of `N` iterables or generators yielding + `f_k(x), f'_k(x), f''_k(x), \ldots` for `k = 1, \ldots, N`, + generate `g(x), g'(x), g''(x), \ldots` where + `g(x) = f_1(x) f_2(x) \cdots f_N(x)`. + + At high precision and for large orders, this is typically more efficient + than numerical differentiation if the derivatives of each `f_k(x)` + admit direct computation. + + Note: This function does not increase the working precision internally, + so guard digits may have to be added externally for full accuracy. + + **Examples** + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> f = lambda x: exp(x)*cos(x)*sin(x) + >>> u = diffs(f, 1) + >>> v = mp.diffs_prod([diffs(exp,1), diffs(cos,1), diffs(sin,1)]) + >>> next(u); next(v) + 1.23586333600241 + 1.23586333600241 + >>> next(u); next(v) + 0.104658952245596 + 0.104658952245596 + >>> next(u); next(v) + -5.96999877552086 + -5.96999877552086 + >>> next(u); next(v) + -12.4632923122697 + -12.4632923122697 + + """ + N = len(factors) + if N == 1: + for c in factors[0]: + yield c + else: + u = iterable_to_function(ctx.diffs_prod(factors[:N//2])) + v = iterable_to_function(ctx.diffs_prod(factors[N//2:])) + n = 0 + while 1: + #yield sum(binomial(n,k)*u(n-k)*v(k) for k in xrange(n+1)) + s = u(n) * v(0) + a = 1 + for k in xrange(1,n+1): + a = a * (n-k+1) // k + s += a * u(n-k) * v(k) + yield s + n += 1 + +def dpoly(n, _cache={}): + """ + nth differentiation polynomial for exp (Faa di Bruno's formula). + + TODO: most exponents are zero, so maybe a sparse representation + would be better. + """ + if n in _cache: + return _cache[n] + if not _cache: + _cache[0] = {(0,):1} + R = dpoly(n-1) + R = dict((c+(0,),v) for (c,v) in iteritems(R)) + Ra = {} + for powers, count in iteritems(R): + powers1 = (powers[0]+1,) + powers[1:] + if powers1 in Ra: + Ra[powers1] += count + else: + Ra[powers1] = count + for powers, count in iteritems(R): + if not sum(powers): + continue + for k,p in enumerate(powers): + if p: + powers2 = powers[:k] + (p-1,powers[k+1]+1) + powers[k+2:] + if powers2 in Ra: + Ra[powers2] += p*count + else: + Ra[powers2] = p*count + _cache[n] = Ra + return _cache[n] + +@defun +def diffs_exp(ctx, fdiffs): + r""" + Given an iterable or generator yielding `f(x), f'(x), f''(x), \ldots` + generate `g(x), g'(x), g''(x), \ldots` where `g(x) = \exp(f(x))`. + + At high precision and for large orders, this is typically more efficient + than numerical differentiation if the derivatives of `f(x)` + admit direct computation. + + Note: This function does not increase the working precision internally, + so guard digits may have to be added externally for full accuracy. + + **Examples** + + The derivatives of the gamma function can be computed using + logarithmic differentiation:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> + >>> def diffs_loggamma(x): + ... yield loggamma(x) + ... i = 0 + ... while 1: + ... yield psi(i,x) + ... i += 1 + ... + >>> u = diffs_exp(diffs_loggamma(3)) + >>> v = diffs(gamma, 3) + >>> next(u); next(v) + 2.0 + 2.0 + >>> next(u); next(v) + 1.84556867019693 + 1.84556867019693 + >>> next(u); next(v) + 2.49292999190269 + 2.49292999190269 + >>> next(u); next(v) + 3.44996501352367 + 3.44996501352367 + + """ + fn = iterable_to_function(fdiffs) + f0 = ctx.exp(fn(0)) + yield f0 + i = 1 + while 1: + s = ctx.mpf(0) + for powers, c in iteritems(dpoly(i)): + s += c*ctx.fprod(fn(k+1)**p for (k,p) in enumerate(powers) if p) + yield s * f0 + i += 1 + +@defun +def differint(ctx, f, x, n=1, x0=0): + r""" + Calculates the Riemann-Liouville differintegral, or fractional + derivative, defined by + + .. math :: + + \,_{x_0}{\mathbb{D}}^n_xf(x) = \frac{1}{\Gamma(m-n)} \frac{d^m}{dx^m} + \int_{x_0}^{x}(x-t)^{m-n-1}f(t)dt + + where `f` is a given (presumably well-behaved) function, + `x` is the evaluation point, `n` is the order, and `x_0` is + the reference point of integration (`m` is an arbitrary + parameter selected automatically). + + With `n = 1`, this is just the standard derivative `f'(x)`; with `n = 2`, + the second derivative `f''(x)`, etc. With `n = -1`, it gives + `\int_{x_0}^x f(t) dt`, with `n = -2` + it gives `\int_{x_0}^x \left( \int_{x_0}^t f(u) du \right) dt`, etc. + + As `n` is permitted to be any number, this operator generalizes + iterated differentiation and iterated integration to a single + operator with a continuous order parameter. + + **Examples** + + There is an exact formula for the fractional derivative of a + monomial `x^p`, which may be used as a reference. For example, + the following gives a half-derivative (order 0.5):: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> x = mpf(3); p = 2; n = 0.5 + >>> differint(lambda t: t**p, x, n) + 7.81764019044672 + >>> gamma(p+1)/gamma(p-n+1) * x**(p-n) + 7.81764019044672 + + Another useful test function is the exponential function, whose + integration / differentiation formula easy generalizes + to arbitrary order. Here we first compute a third derivative, + and then a triply nested integral. (The reference point `x_0` + is set to `-\infty` to avoid nonzero endpoint terms.):: + + >>> differint(lambda x: exp(pi*x), -1.5, 3) + 0.278538406900792 + >>> exp(pi*-1.5) * pi**3 + 0.278538406900792 + >>> differint(lambda x: exp(pi*x), 3.5, -3, -inf) + 1922.50563031149 + >>> exp(pi*3.5) / pi**3 + 1922.50563031149 + + However, for noninteger `n`, the differentiation formula for the + exponential function must be modified to give the same result as the + Riemann-Liouville differintegral:: + + >>> x = mpf(3.5) + >>> c = pi + >>> n = 1+2*j + >>> differint(lambda x: exp(c*x), x, n) + (-123295.005390743 + 140955.117867654j) + >>> x**(-n) * exp(c)**x * (x*c)**n * gammainc(-n, 0, x*c) / gamma(-n) + (-123295.005390743 + 140955.117867654j) + + + """ + m = max(int(ctx.ceil(ctx.re(n)))+1, 1) + r = m-n-1 + g = lambda x: ctx.quad(lambda t: (x-t)**r * f(t), [x0, x]) + return ctx.diff(g, x, m) / ctx.gamma(m-n) + +@defun +def diffun(ctx, f, n=1, **options): + r""" + Given a function `f`, returns a function `g(x)` that evaluates the nth + derivative `f^{(n)}(x)`:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> cos2 = diffun(sin) + >>> sin2 = diffun(sin, 4) + >>> cos(1.3), cos2(1.3) + (0.267498828624587, 0.267498828624587) + >>> sin(1.3), sin2(1.3) + (0.963558185417193, 0.963558185417193) + + The function `f` must support arbitrary precision evaluation. + See :func:`~mpmath.diff` for additional details and supported + keyword options. + """ + if n == 0: + return f + def g(x): + return ctx.diff(f, x, n, **options) + return g + +@defun +def taylor(ctx, f, x, n, **options): + r""" + Produces a degree-`n` Taylor polynomial around the point `x` of the + given function `f`. The coefficients are returned as a list. + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> nprint(chop(taylor(sin, 0, 5))) + [0.0, 1.0, 0.0, -0.166667, 0.0, 0.00833333] + + The coefficients are computed using high-order numerical + differentiation. The function must be possible to evaluate + to arbitrary precision. See :func:`~mpmath.diff` for additional details + and supported keyword options. + + Note that to evaluate the Taylor polynomial as an approximation + of `f`, e.g. with :func:`~mpmath.polyval`, the coefficients must be reversed, + and the point of the Taylor expansion must be subtracted from + the argument: + + >>> p = taylor(exp, 2.0, 10) + >>> polyval(p[::-1], 2.5 - 2.0) + 12.1824939606092 + >>> exp(2.5) + 12.1824939607035 + + """ + gen = enumerate(ctx.diffs(f, x, n, **options)) + if options.get("chop", True): + return [ctx.chop(d)/ctx.factorial(i) for i, d in gen] + else: + return [d/ctx.factorial(i) for i, d in gen] + +@defun +def pade(ctx, a, L, M): + r""" + Computes a Pade approximation of degree `(L, M)` to a function. + Given at least `L+M+1` Taylor coefficients `a` approximating + a function `A(x)`, :func:`~mpmath.pade` returns coefficients of + polynomials `P, Q` satisfying + + .. math :: + + P = \sum_{k=0}^L p_k x^k + + Q = \sum_{k=0}^M q_k x^k + + Q_0 = 1 + + A(x) Q(x) = P(x) + O(x^{L+M+1}) + + `P(x)/Q(x)` can provide a good approximation to an analytic function + beyond the radius of convergence of its Taylor series (example + from G.A. Baker 'Essentials of Pade Approximants' Academic Press, + Ch.1A):: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> one = mpf(1) + >>> def f(x): + ... return sqrt((one + 2*x)/(one + x)) + ... + >>> a = taylor(f, 0, 6) + >>> p, q = pade(a, 3, 3) + >>> x = 10 + >>> polyval(p[::-1], x)/polyval(q[::-1], x) + 1.38169105566806 + >>> f(x) + 1.38169855941551 + + """ + # To determine L+1 coefficients of P and M coefficients of Q + # L+M+1 coefficients of A must be provided + if len(a) < L+M+1: + raise ValueError("L+M+1 Coefficients should be provided") + + if M == 0: + if L == 0: + return [ctx.one], [ctx.one] + else: + return a[:L+1], [ctx.one] + + # Solve first + # a[L]*q[1] + ... + a[L-M+1]*q[M] = -a[L+1] + # ... + # a[L+M-1]*q[1] + ... + a[L]*q[M] = -a[L+M] + A = ctx.matrix(M) + for j in range(M): + for i in range(min(M, L+j+1)): + A[j, i] = a[L+j-i] + v = -ctx.matrix(a[(L+1):(L+M+1)]) + x = ctx.lu_solve(A, v) + q = [ctx.one] + list(x) + # compute p + p = [0]*(L+1) + for i in range(L+1): + s = a[i] + for j in range(1, min(M,i) + 1): + s += q[j]*a[i-j] + p[i] = s + return p, q diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/extrapolation.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/extrapolation.py new file mode 100644 index 0000000000000000000000000000000000000000..7df0fea3c62c9b71ee24d3f39fd9b7fd3318ed23 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/extrapolation.py @@ -0,0 +1,2115 @@ +try: + from itertools import izip +except ImportError: + izip = zip + +from ..libmp.backend import xrange +from .calculus import defun + +try: + next = next +except NameError: + next = lambda _: _.next() + +@defun +def richardson(ctx, seq): + r""" + Given a list ``seq`` of the first `N` elements of a slowly convergent + infinite sequence, :func:`~mpmath.richardson` computes the `N`-term + Richardson extrapolate for the limit. + + :func:`~mpmath.richardson` returns `(v, c)` where `v` is the estimated + limit and `c` is the magnitude of the largest weight used during the + computation. The weight provides an estimate of the precision + lost to cancellation. Due to cancellation effects, the sequence must + be typically be computed at a much higher precision than the target + accuracy of the extrapolation. + + **Applicability and issues** + + The `N`-step Richardson extrapolation algorithm used by + :func:`~mpmath.richardson` is described in [1]. + + Richardson extrapolation only works for a specific type of sequence, + namely one converging like partial sums of + `P(1)/Q(1) + P(2)/Q(2) + \ldots` where `P` and `Q` are polynomials. + When the sequence does not convergence at such a rate + :func:`~mpmath.richardson` generally produces garbage. + + Richardson extrapolation has the advantage of being fast: the `N`-term + extrapolate requires only `O(N)` arithmetic operations, and usually + produces an estimate that is accurate to `O(N)` digits. Contrast with + the Shanks transformation (see :func:`~mpmath.shanks`), which requires + `O(N^2)` operations. + + :func:`~mpmath.richardson` is unable to produce an estimate for the + approximation error. One way to estimate the error is to perform + two extrapolations with slightly different `N` and comparing the + results. + + Richardson extrapolation does not work for oscillating sequences. + As a simple workaround, :func:`~mpmath.richardson` detects if the last + three elements do not differ monotonically, and in that case + applies extrapolation only to the even-index elements. + + **Example** + + Applying Richardson extrapolation to the Leibniz series for `\pi`:: + + >>> from mpmath import * + >>> mp.dps = 30; mp.pretty = True + >>> S = [4*sum(mpf(-1)**n/(2*n+1) for n in range(m)) + ... for m in range(1,30)] + >>> v, c = richardson(S[:10]) + >>> v + 3.2126984126984126984126984127 + >>> nprint([v-pi, c]) + [0.0711058, 2.0] + + >>> v, c = richardson(S[:30]) + >>> v + 3.14159265468624052829954206226 + >>> nprint([v-pi, c]) + [1.09645e-9, 20833.3] + + **References** + + 1. [BenderOrszag]_ pp. 375-376 + + """ + if len(seq) < 3: + raise ValueError("seq should be of minimum length 3") + if ctx.sign(seq[-1]-seq[-2]) != ctx.sign(seq[-2]-seq[-3]): + seq = seq[::2] + N = len(seq)//2-1 + s = ctx.zero + # The general weight is c[k] = (N+k)**N * (-1)**(k+N) / k! / (N-k)! + # To avoid repeated factorials, we simplify the quotient + # of successive weights to obtain a recurrence relation + c = (-1)**N * N**N / ctx.mpf(ctx._ifac(N)) + maxc = 1 + for k in xrange(N+1): + s += c * seq[N+k] + maxc = max(abs(c), maxc) + c *= (k-N)*ctx.mpf(k+N+1)**N + c /= ((1+k)*ctx.mpf(k+N)**N) + return s, maxc + +@defun +def shanks(ctx, seq, table=None, randomized=False): + r""" + Given a list ``seq`` of the first `N` elements of a slowly + convergent infinite sequence `(A_k)`, :func:`~mpmath.shanks` computes the iterated + Shanks transformation `S(A), S(S(A)), \ldots, S^{N/2}(A)`. The Shanks + transformation often provides strong convergence acceleration, + especially if the sequence is oscillating. + + The iterated Shanks transformation is computed using the Wynn + epsilon algorithm (see [1]). :func:`~mpmath.shanks` returns the full + epsilon table generated by Wynn's algorithm, which can be read + off as follows: + + * The table is a list of lists forming a lower triangular matrix, + where higher row and column indices correspond to more accurate + values. + * The columns with even index hold dummy entries (required for the + computation) and the columns with odd index hold the actual + extrapolates. + * The last element in the last row is typically the most + accurate estimate of the limit. + * The difference to the third last element in the last row + provides an estimate of the approximation error. + * The magnitude of the second last element provides an estimate + of the numerical accuracy lost to cancellation. + + For convenience, so the extrapolation is stopped at an odd index + so that ``shanks(seq)[-1][-1]`` always gives an estimate of the + limit. + + Optionally, an existing table can be passed to :func:`~mpmath.shanks`. + This can be used to efficiently extend a previous computation after + new elements have been appended to the sequence. The table will + then be updated in-place. + + **The Shanks transformation** + + The Shanks transformation is defined as follows (see [2]): given + the input sequence `(A_0, A_1, \ldots)`, the transformed sequence is + given by + + .. math :: + + S(A_k) = \frac{A_{k+1}A_{k-1}-A_k^2}{A_{k+1}+A_{k-1}-2 A_k} + + The Shanks transformation gives the exact limit `A_{\infty}` in a + single step if `A_k = A + a q^k`. Note in particular that it + extrapolates the exact sum of a geometric series in a single step. + + Applying the Shanks transformation once often improves convergence + substantially for an arbitrary sequence, but the optimal effect is + obtained by applying it iteratively: + `S(S(A_k)), S(S(S(A_k))), \ldots`. + + Wynn's epsilon algorithm provides an efficient way to generate + the table of iterated Shanks transformations. It reduces the + computation of each element to essentially a single division, at + the cost of requiring dummy elements in the table. See [1] for + details. + + **Precision issues** + + Due to cancellation effects, the sequence must be typically be + computed at a much higher precision than the target accuracy + of the extrapolation. + + If the Shanks transformation converges to the exact limit (such + as if the sequence is a geometric series), then a division by + zero occurs. By default, :func:`~mpmath.shanks` handles this case by + terminating the iteration and returning the table it has + generated so far. With *randomized=True*, it will instead + replace the zero by a pseudorandom number close to zero. + (TODO: find a better solution to this problem.) + + **Examples** + + We illustrate by applying Shanks transformation to the Leibniz + series for `\pi`:: + + >>> from mpmath import * + >>> mp.dps = 50 + >>> S = [4*sum(mpf(-1)**n/(2*n+1) for n in range(m)) + ... for m in range(1,30)] + >>> + >>> T = shanks(S[:7]) + >>> for row in T: + ... nprint(row) + ... + [-0.75] + [1.25, 3.16667] + [-1.75, 3.13333, -28.75] + [2.25, 3.14524, 82.25, 3.14234] + [-2.75, 3.13968, -177.75, 3.14139, -969.937] + [3.25, 3.14271, 327.25, 3.14166, 3515.06, 3.14161] + + The extrapolated accuracy is about 4 digits, and about 4 digits + may have been lost due to cancellation:: + + >>> L = T[-1] + >>> nprint([abs(L[-1] - pi), abs(L[-1] - L[-3]), abs(L[-2])]) + [2.22532e-5, 4.78309e-5, 3515.06] + + Now we extend the computation:: + + >>> T = shanks(S[:25], T) + >>> L = T[-1] + >>> nprint([abs(L[-1] - pi), abs(L[-1] - L[-3]), abs(L[-2])]) + [3.75527e-19, 1.48478e-19, 2.96014e+17] + + The value for pi is now accurate to 18 digits. About 18 digits may + also have been lost to cancellation. + + Here is an example with a geometric series, where the convergence + is immediate (the sum is exactly 1):: + + >>> mp.dps = 15 + >>> for row in shanks([0.5, 0.75, 0.875, 0.9375, 0.96875]): + ... nprint(row) + [4.0] + [8.0, 1.0] + + **References** + + 1. [GravesMorris]_ + + 2. [BenderOrszag]_ pp. 368-375 + + """ + if len(seq) < 2: + raise ValueError("seq should be of minimum length 2") + if table: + START = len(table) + else: + START = 0 + table = [] + STOP = len(seq) - 1 + if STOP & 1: + STOP -= 1 + one = ctx.one + eps = +ctx.eps + if randomized: + from random import Random + rnd = Random() + rnd.seed(START) + for i in xrange(START, STOP): + row = [] + for j in xrange(i+1): + if j == 0: + a, b = 0, seq[i+1]-seq[i] + else: + if j == 1: + a = seq[i] + else: + a = table[i-1][j-2] + b = row[j-1] - table[i-1][j-1] + if not b: + if randomized: + b = (1 + rnd.getrandbits(10))*eps + elif i & 1: + return table[:-1] + else: + return table + row.append(a + one/b) + table.append(row) + return table + + +class levin_class: + # levin: Copyright 2013 Timo Hartmann (thartmann15 at gmail.com) + r""" + This interface implements Levin's (nonlinear) sequence transformation for + convergence acceleration and summation of divergent series. It performs + better than the Shanks/Wynn-epsilon algorithm for logarithmic convergent + or alternating divergent series. + + Let *A* be the series we want to sum: + + .. math :: + + A = \sum_{k=0}^{\infty} a_k + + Attention: all `a_k` must be non-zero! + + Let `s_n` be the partial sums of this series: + + .. math :: + + s_n = \sum_{k=0}^n a_k. + + **Methods** + + Calling ``levin`` returns an object with the following methods. + + ``update(...)`` works with the list of individual terms `a_k` of *A*, and + ``update_step(...)`` works with the list of partial sums `s_k` of *A*: + + .. code :: + + v, e = ...update([a_0, a_1,..., a_k]) + v, e = ...update_psum([s_0, s_1,..., s_k]) + + ``step(...)`` works with the individual terms `a_k` and ``step_psum(...)`` + works with the partial sums `s_k`: + + .. code :: + + v, e = ...step(a_k) + v, e = ...step_psum(s_k) + + *v* is the current estimate for *A*, and *e* is an error estimate which is + simply the difference between the current estimate and the last estimate. + One should not mix ``update``, ``update_psum``, ``step`` and ``step_psum``. + + **A word of caution** + + One can only hope for good results (i.e. convergence acceleration or + resummation) if the `s_n` have some well defind asymptotic behavior for + large `n` and are not erratic or random. Furthermore one usually needs very + high working precision because of the numerical cancellation. If the working + precision is insufficient, levin may produce silently numerical garbage. + Furthermore even if the Levin-transformation converges, in the general case + there is no proof that the result is mathematically sound. Only for very + special classes of problems one can prove that the Levin-transformation + converges to the expected result (for example Stieltjes-type integrals). + Furthermore the Levin-transform is quite expensive (i.e. slow) in comparison + to Shanks/Wynn-epsilon, Richardson & co. + In summary one can say that the Levin-transformation is powerful but + unreliable and that it may need a copious amount of working precision. + + The Levin transform has several variants differing in the choice of weights. + Some variants are better suited for the possible flavours of convergence + behaviour of *A* than other variants: + + .. code :: + + convergence behaviour levin-u levin-t levin-v shanks/wynn-epsilon + + logarithmic + - + - + linear + + + + + alternating divergent + + + + + + "+" means the variant is suitable,"-" means the variant is not suitable; + for comparison the Shanks/Wynn-epsilon transform is listed, too. + + The variant is controlled though the variant keyword (i.e. ``variant="u"``, + ``variant="t"`` or ``variant="v"``). Overall "u" is probably the best choice. + + Finally it is possible to use the Sidi-S transform instead of the Levin transform + by using the keyword ``method='sidi'``. The Sidi-S transform works better than the + Levin transformation for some divergent series (see the examples). + + Parameters: + + .. code :: + + method "levin" or "sidi" chooses either the Levin or the Sidi-S transformation + variant "u","t" or "v" chooses the weight variant. + + The Levin transform is also accessible through the nsum interface. + ``method="l"`` or ``method="levin"`` select the normal Levin transform while + ``method="sidi"`` + selects the Sidi-S transform. The variant is in both cases selected through the + levin_variant keyword. The stepsize in :func:`~mpmath.nsum` must not be chosen too large, otherwise + it will miss the point where the Levin transform converges resulting in numerical + overflow/garbage. For highly divergent series a copious amount of working precision + must be chosen. + + **Examples** + + First we sum the zeta function:: + + >>> from mpmath import mp + >>> mp.prec = 53 + >>> eps = mp.mpf(mp.eps) + >>> with mp.extraprec(2 * mp.prec): # levin needs a high working precision + ... L = mp.levin(method = "levin", variant = "u") + ... S, s, n = [], 0, 1 + ... while 1: + ... s += mp.one / (n * n) + ... n += 1 + ... S.append(s) + ... v, e = L.update_psum(S) + ... if e < eps: + ... break + ... if n > 1000: raise RuntimeError("iteration limit exceeded") + >>> print(mp.chop(v - mp.pi ** 2 / 6)) + 0.0 + >>> w = mp.nsum(lambda n: 1 / (n*n), [1, mp.inf], method = "levin", levin_variant = "u") + >>> print(mp.chop(v - w)) + 0.0 + + Now we sum the zeta function outside its range of convergence + (attention: This does not work at the negative integers!):: + + >>> eps = mp.mpf(mp.eps) + >>> with mp.extraprec(2 * mp.prec): # levin needs a high working precision + ... L = mp.levin(method = "levin", variant = "v") + ... A, n = [], 1 + ... while 1: + ... s = mp.mpf(n) ** (2 + 3j) + ... n += 1 + ... A.append(s) + ... v, e = L.update(A) + ... if e < eps: + ... break + ... if n > 1000: raise RuntimeError("iteration limit exceeded") + >>> print(mp.chop(v - mp.zeta(-2-3j))) + 0.0 + >>> w = mp.nsum(lambda n: n ** (2 + 3j), [1, mp.inf], method = "levin", levin_variant = "v") + >>> print(mp.chop(v - w)) + 0.0 + + Now we sum the divergent asymptotic expansion of an integral related to the + exponential integral (see also [2] p.373). The Sidi-S transform works best here:: + + >>> z = mp.mpf(10) + >>> exact = mp.quad(lambda x: mp.exp(-x)/(1+x/z),[0,mp.inf]) + >>> # exact = z * mp.exp(z) * mp.expint(1,z) # this is the symbolic expression for the integral + >>> eps = mp.mpf(mp.eps) + >>> with mp.extraprec(2 * mp.prec): # high working precisions are mandatory for divergent resummation + ... L = mp.levin(method = "sidi", variant = "t") + ... n = 0 + ... while 1: + ... s = (-1)**n * mp.fac(n) * z ** (-n) + ... v, e = L.step(s) + ... n += 1 + ... if e < eps: + ... break + ... if n > 1000: raise RuntimeError("iteration limit exceeded") + >>> print(mp.chop(v - exact)) + 0.0 + >>> w = mp.nsum(lambda n: (-1) ** n * mp.fac(n) * z ** (-n), [0, mp.inf], method = "sidi", levin_variant = "t") + >>> print(mp.chop(v - w)) + 0.0 + + Another highly divergent integral is also summable:: + + >>> z = mp.mpf(2) + >>> eps = mp.mpf(mp.eps) + >>> exact = mp.quad(lambda x: mp.exp( -x * x / 2 - z * x ** 4), [0,mp.inf]) * 2 / mp.sqrt(2 * mp.pi) + >>> # exact = mp.exp(mp.one / (32 * z)) * mp.besselk(mp.one / 4, mp.one / (32 * z)) / (4 * mp.sqrt(z * mp.pi)) # this is the symbolic expression for the integral + >>> with mp.extraprec(7 * mp.prec): # we need copious amount of precision to sum this highly divergent series + ... L = mp.levin(method = "levin", variant = "t") + ... n, s = 0, 0 + ... while 1: + ... s += (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4 ** n)) + ... n += 1 + ... v, e = L.step_psum(s) + ... if e < eps: + ... break + ... if n > 1000: raise RuntimeError("iteration limit exceeded") + >>> print(mp.chop(v - exact)) + 0.0 + >>> w = mp.nsum(lambda n: (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4 ** n)), + ... [0, mp.inf], method = "levin", levin_variant = "t", workprec = 8*mp.prec, steps = [2] + [1 for x in xrange(1000)]) + >>> print(mp.chop(v - w)) + 0.0 + + These examples run with 15-20 decimal digits precision. For higher precision the + working precision must be raised. + + **Examples for nsum** + + Here we calculate Euler's constant as the constant term in the Laurent + expansion of `\zeta(s)` at `s=1`. This sum converges extremly slowly because of + the logarithmic convergence behaviour of the Dirichlet series for zeta:: + + >>> mp.dps = 30 + >>> z = mp.mpf(10) ** (-10) + >>> a = mp.nsum(lambda n: n**(-(1+z)), [1, mp.inf], method = "l") - 1 / z + >>> print(mp.chop(a - mp.euler, tol = 1e-10)) + 0.0 + + The Sidi-S transform performs excellently for the alternating series of `\log(2)`:: + + >>> a = mp.nsum(lambda n: (-1)**(n-1) / n, [1, mp.inf], method = "sidi") + >>> print(mp.chop(a - mp.log(2))) + 0.0 + + Hypergeometric series can also be summed outside their range of convergence. + The stepsize in :func:`~mpmath.nsum` must not be chosen too large, otherwise it will miss the + point where the Levin transform converges resulting in numerical overflow/garbage:: + + >>> z = 2 + 1j + >>> exact = mp.hyp2f1(2 / mp.mpf(3), 4 / mp.mpf(3), 1 / mp.mpf(3), z) + >>> f = lambda n: mp.rf(2 / mp.mpf(3), n) * mp.rf(4 / mp.mpf(3), n) * z**n / (mp.rf(1 / mp.mpf(3), n) * mp.fac(n)) + >>> v = mp.nsum(f, [0, mp.inf], method = "levin", steps = [10 for x in xrange(1000)]) + >>> print(mp.chop(exact-v)) + 0.0 + + References: + + [1] E.J. Weniger - "Nonlinear Sequence Transformations for the Acceleration of + Convergence and the Summation of Divergent Series" arXiv:math/0306302 + + [2] A. Sidi - "Pratical Extrapolation Methods" + + [3] H.H.H. Homeier - "Scalar Levin-Type Sequence Transformations" arXiv:math/0005209 + + """ + + def __init__(self, method = "levin", variant = "u"): + self.variant = variant + self.n = 0 + self.a0 = 0 + self.theta = 1 + self.A = [] + self.B = [] + self.last = 0 + self.last_s = False + + if method == "levin": + self.factor = self.factor_levin + elif method == "sidi": + self.factor = self.factor_sidi + else: + raise ValueError("levin: unknown method \"%s\"" % method) + + def factor_levin(self, i): + # original levin + # [1] p.50,e.7.5-7 (with n-j replaced by i) + return (self.theta + i) * (self.theta + self.n - 1) ** (self.n - i - 2) / self.ctx.mpf(self.theta + self.n) ** (self.n - i - 1) + + def factor_sidi(self, i): + # sidi analogon to levin (factorial series) + # [1] p.59,e.8.3-16 (with n-j replaced by i) + return (self.theta + self.n - 1) * (self.theta + self.n - 2) / self.ctx.mpf((self.theta + 2 * self.n - i - 2) * (self.theta + 2 * self.n - i - 3)) + + def run(self, s, a0, a1 = 0): + if self.variant=="t": + # levin t + w=a0 + elif self.variant=="u": + # levin u + w=a0*(self.theta+self.n) + elif self.variant=="v": + # levin v + w=a0*a1/(a0-a1) + else: + assert False, "unknown variant" + + if w==0: + raise ValueError("levin: zero weight") + + self.A.append(s/w) + self.B.append(1/w) + + for i in range(self.n-1,-1,-1): + if i==self.n-1: + f=1 + else: + f=self.factor(i) + + self.A[i]=self.A[i+1]-f*self.A[i] + self.B[i]=self.B[i+1]-f*self.B[i] + + self.n+=1 + + ########################################################################### + + def update_psum(self,S): + """ + This routine applies the convergence acceleration to the list of partial sums. + + A = sum(a_k, k = 0..infinity) + s_n = sum(a_k, k = 0..n) + + v, e = ...update_psum([s_0, s_1,..., s_k]) + + output: + v current estimate of the series A + e an error estimate which is simply the difference between the current + estimate and the last estimate. + """ + + if self.variant!="v": + if self.n==0: + self.run(S[0],S[0]) + while self.n>> from mpmath import mp + >>> AC = mp.cohen_alt() + >>> S, s, n = [], 0, 1 + >>> while 1: + ... s += -((-1) ** n) * mp.one / (n * n) + ... n += 1 + ... S.append(s) + ... v, e = AC.update_psum(S) + ... if e < mp.eps: + ... break + ... if n > 1000: raise RuntimeError("iteration limit exceeded") + >>> print(mp.chop(v - mp.pi ** 2 / 12)) + 0.0 + + Here we compute the product `\prod_{n=1}^{\infty} \Gamma(1+1/(2n-1)) / \Gamma(1+1/(2n))`:: + + >>> A = [] + >>> AC = mp.cohen_alt() + >>> n = 1 + >>> while 1: + ... A.append( mp.loggamma(1 + mp.one / (2 * n - 1))) + ... A.append(-mp.loggamma(1 + mp.one / (2 * n))) + ... n += 1 + ... v, e = AC.update(A) + ... if e < mp.eps: + ... break + ... if n > 1000: raise RuntimeError("iteration limit exceeded") + >>> v = mp.exp(v) + >>> print(mp.chop(v - 1.06215090557106, tol = 1e-12)) + 0.0 + + ``cohen_alt`` is also accessible through the :func:`~mpmath.nsum` interface:: + + >>> v = mp.nsum(lambda n: (-1)**(n-1) / n, [1, mp.inf], method = "a") + >>> print(mp.chop(v - mp.log(2))) + 0.0 + >>> v = mp.nsum(lambda n: (-1)**n / (2 * n + 1), [0, mp.inf], method = "a") + >>> print(mp.chop(v - mp.pi / 4)) + 0.0 + >>> v = mp.nsum(lambda n: (-1)**n * mp.log(n) * n, [1, mp.inf], method = "a") + >>> print(mp.chop(v - mp.diff(lambda s: mp.altzeta(s), -1))) + 0.0 + + """ + + def __init__(self): + self.last=0 + + def update(self, A): + """ + This routine applies the convergence acceleration to the list of individual terms. + + A = sum(a_k, k = 0..infinity) + + v, e = ...update([a_0, a_1,..., a_k]) + + output: + v current estimate of the series A + e an error estimate which is simply the difference between the current + estimate and the last estimate. + """ + + n = len(A) + d = (3 + self.ctx.sqrt(8)) ** n + d = (d + 1 / d) / 2 + b = -self.ctx.one + c = -d + s = 0 + + for k in xrange(n): + c = b - c + if k % 2 == 0: + s = s + c * A[k] + else: + s = s - c * A[k] + b = 2 * (k + n) * (k - n) * b / ((2 * k + 1) * (k + self.ctx.one)) + + value = s / d + + err = abs(value - self.last) + self.last = value + + return value, err + + def update_psum(self, S): + """ + This routine applies the convergence acceleration to the list of partial sums. + + A = sum(a_k, k = 0..infinity) + s_n = sum(a_k ,k = 0..n) + + v, e = ...update_psum([s_0, s_1,..., s_k]) + + output: + v current estimate of the series A + e an error estimate which is simply the difference between the current + estimate and the last estimate. + """ + + n = len(S) + d = (3 + self.ctx.sqrt(8)) ** n + d = (d + 1 / d) / 2 + b = self.ctx.one + s = 0 + + for k in xrange(n): + b = 2 * (n + k) * (n - k) * b / ((2 * k + 1) * (k + self.ctx.one)) + s += b * S[k] + + value = s / d + + err = abs(value - self.last) + self.last = value + + return value, err + +def cohen_alt(ctx): + L = cohen_alt_class() + L.ctx = ctx + return L + +cohen_alt.__doc__ = cohen_alt_class.__doc__ +defun(cohen_alt) + + +@defun +def sumap(ctx, f, interval, integral=None, error=False): + r""" + Evaluates an infinite series of an analytic summand *f* using the + Abel-Plana formula + + .. math :: + + \sum_{k=0}^{\infty} f(k) = \int_0^{\infty} f(t) dt + \frac{1}{2} f(0) + + i \int_0^{\infty} \frac{f(it)-f(-it)}{e^{2\pi t}-1} dt. + + Unlike the Euler-Maclaurin formula (see :func:`~mpmath.sumem`), + the Abel-Plana formula does not require derivatives. However, + it only works when `|f(it)-f(-it)|` does not + increase too rapidly with `t`. + + **Examples** + + The Abel-Plana formula is particularly useful when the summand + decreases like a power of `k`; for example when the sum is a pure + zeta function:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> sumap(lambda k: 1/k**2.5, [1,inf]) + 1.34148725725091717975677 + >>> zeta(2.5) + 1.34148725725091717975677 + >>> sumap(lambda k: 1/(k+1j)**(2.5+2.5j), [1,inf]) + (-3.385361068546473342286084 - 0.7432082105196321803869551j) + >>> zeta(2.5+2.5j, 1+1j) + (-3.385361068546473342286084 - 0.7432082105196321803869551j) + + If the series is alternating, numerical quadrature along the real + line is likely to give poor results, so it is better to evaluate + the first term symbolically whenever possible: + + >>> n=3; z=-0.75 + >>> I = expint(n,-log(z)) + >>> chop(sumap(lambda k: z**k / k**n, [1,inf], integral=I)) + -0.6917036036904594510141448 + >>> polylog(n,z) + -0.6917036036904594510141448 + + """ + prec = ctx.prec + try: + ctx.prec += 10 + a, b = interval + if b != ctx.inf: + raise ValueError("b should be equal to ctx.inf") + g = lambda x: f(x+a) + if integral is None: + i1, err1 = ctx.quad(g, [0,ctx.inf], error=True) + else: + i1, err1 = integral, 0 + j = ctx.j + p = ctx.pi * 2 + if ctx._is_real_type(i1): + h = lambda t: -2 * ctx.im(g(j*t)) / ctx.expm1(p*t) + else: + h = lambda t: j*(g(j*t)-g(-j*t)) / ctx.expm1(p*t) + i2, err2 = ctx.quad(h, [0,ctx.inf], error=True) + err = err1+err2 + v = i1+i2+0.5*g(ctx.mpf(0)) + finally: + ctx.prec = prec + if error: + return +v, err + return +v + + +@defun +def sumem(ctx, f, interval, tol=None, reject=10, integral=None, + adiffs=None, bdiffs=None, verbose=False, error=False, + _fast_abort=False): + r""" + Uses the Euler-Maclaurin formula to compute an approximation accurate + to within ``tol`` (which defaults to the present epsilon) of the sum + + .. math :: + + S = \sum_{k=a}^b f(k) + + where `(a,b)` are given by ``interval`` and `a` or `b` may be + infinite. The approximation is + + .. math :: + + S \sim \int_a^b f(x) \,dx + \frac{f(a)+f(b)}{2} + + \sum_{k=1}^{\infty} \frac{B_{2k}}{(2k)!} + \left(f^{(2k-1)}(b)-f^{(2k-1)}(a)\right). + + The last sum in the Euler-Maclaurin formula is not generally + convergent (a notable exception is if `f` is a polynomial, in + which case Euler-Maclaurin actually gives an exact result). + + The summation is stopped as soon as the quotient between two + consecutive terms falls below *reject*. That is, by default + (*reject* = 10), the summation is continued as long as each + term adds at least one decimal. + + Although not convergent, convergence to a given tolerance can + often be "forced" if `b = \infty` by summing up to `a+N` and then + applying the Euler-Maclaurin formula to the sum over the range + `(a+N+1, \ldots, \infty)`. This procedure is implemented by + :func:`~mpmath.nsum`. + + By default numerical quadrature and differentiation is used. + If the symbolic values of the integral and endpoint derivatives + are known, it is more efficient to pass the value of the + integral explicitly as ``integral`` and the derivatives + explicitly as ``adiffs`` and ``bdiffs``. The derivatives + should be given as iterables that yield + `f(a), f'(a), f''(a), \ldots` (and the equivalent for `b`). + + **Examples** + + Summation of an infinite series, with automatic and symbolic + integral and derivative values (the second should be much faster):: + + >>> from mpmath import * + >>> mp.dps = 50; mp.pretty = True + >>> sumem(lambda n: 1/n**2, [32, inf]) + 0.03174336652030209012658168043874142714132886413417 + >>> I = mpf(1)/32 + >>> D = adiffs=((-1)**n*fac(n+1)*32**(-2-n) for n in range(999)) + >>> sumem(lambda n: 1/n**2, [32, inf], integral=I, adiffs=D) + 0.03174336652030209012658168043874142714132886413417 + + An exact evaluation of a finite polynomial sum:: + + >>> sumem(lambda n: n**5-12*n**2+3*n, [-100000, 200000]) + 10500155000624963999742499550000.0 + >>> print(sum(n**5-12*n**2+3*n for n in range(-100000, 200001))) + 10500155000624963999742499550000 + + """ + tol = tol or +ctx.eps + interval = ctx._as_points(interval) + a = ctx.convert(interval[0]) + b = ctx.convert(interval[-1]) + err = ctx.zero + prev = 0 + M = 10000 + if a == ctx.ninf: adiffs = (0 for n in xrange(M)) + else: adiffs = adiffs or ctx.diffs(f, a) + if b == ctx.inf: bdiffs = (0 for n in xrange(M)) + else: bdiffs = bdiffs or ctx.diffs(f, b) + orig = ctx.prec + #verbose = 1 + try: + ctx.prec += 10 + s = ctx.zero + for k, (da, db) in enumerate(izip(adiffs, bdiffs)): + if k & 1: + term = (db-da) * ctx.bernoulli(k+1) / ctx.factorial(k+1) + mag = abs(term) + if verbose: + print("term", k, "magnitude =", ctx.nstr(mag)) + if k > 4 and mag < tol: + s += term + break + elif k > 4 and abs(prev) / mag < reject: + err += mag + if _fast_abort: + return [s, (s, err)][error] + if verbose: + print("Failed to converge") + break + else: + s += term + prev = term + # Endpoint correction + if a != ctx.ninf: s += f(a)/2 + if b != ctx.inf: s += f(b)/2 + # Tail integral + if verbose: + print("Integrating f(x) from x = %s to %s" % (ctx.nstr(a), ctx.nstr(b))) + if integral: + s += integral + else: + integral, ierr = ctx.quad(f, interval, error=True) + if verbose: + print("Integration error:", ierr) + s += integral + err += ierr + finally: + ctx.prec = orig + if error: + return s, err + else: + return s + +@defun +def adaptive_extrapolation(ctx, update, emfun, kwargs): + option = kwargs.get + if ctx._fixed_precision: + tol = option('tol', ctx.eps*2**10) + else: + tol = option('tol', ctx.eps/2**10) + verbose = option('verbose', False) + maxterms = option('maxterms', ctx.dps*10) + method = set(option('method', 'r+s').split('+')) + skip = option('skip', 0) + steps = iter(option('steps', xrange(10, 10**9, 10))) + strict = option('strict') + #steps = (10 for i in xrange(1000)) + summer=[] + if 'd' in method or 'direct' in method: + TRY_RICHARDSON = TRY_SHANKS = TRY_EULER_MACLAURIN = False + else: + TRY_RICHARDSON = ('r' in method) or ('richardson' in method) + TRY_SHANKS = ('s' in method) or ('shanks' in method) + TRY_EULER_MACLAURIN = ('e' in method) or \ + ('euler-maclaurin' in method) + + def init_levin(m): + variant = kwargs.get("levin_variant", "u") + if isinstance(variant, str): + if variant == "all": + variant = ["u", "v", "t"] + else: + variant = [variant] + for s in variant: + L = levin_class(method = m, variant = s) + L.ctx = ctx + L.name = m + "(" + s + ")" + summer.append(L) + + if ('l' in method) or ('levin' in method): + init_levin("levin") + + if ('sidi' in method): + init_levin("sidi") + + if ('a' in method) or ('alternating' in method): + L = cohen_alt_class() + L.ctx = ctx + L.name = "alternating" + summer.append(L) + + last_richardson_value = 0 + shanks_table = [] + index = 0 + step = 10 + partial = [] + best = ctx.zero + orig = ctx.prec + try: + if 'workprec' in kwargs: + ctx.prec = kwargs['workprec'] + elif TRY_RICHARDSON or TRY_SHANKS or len(summer)!=0: + ctx.prec = (ctx.prec+10) * 4 + else: + ctx.prec += 30 + while 1: + if index >= maxterms: + break + + # Get new batch of terms + try: + step = next(steps) + except StopIteration: + pass + if verbose: + print("-"*70) + print("Adding terms #%i-#%i" % (index, index+step)) + update(partial, xrange(index, index+step)) + index += step + + # Check direct error + best = partial[-1] + error = abs(best - partial[-2]) + if verbose: + print("Direct error: %s" % ctx.nstr(error)) + if error <= tol: + return best + + # Check each extrapolation method + if TRY_RICHARDSON: + value, maxc = ctx.richardson(partial) + # Convergence + richardson_error = abs(value - last_richardson_value) + if verbose: + print("Richardson error: %s" % ctx.nstr(richardson_error)) + # Convergence + if richardson_error <= tol: + return value + last_richardson_value = value + # Unreliable due to cancellation + if ctx.eps*maxc > tol: + if verbose: + print("Ran out of precision for Richardson") + TRY_RICHARDSON = False + if richardson_error < error: + error = richardson_error + best = value + if TRY_SHANKS: + shanks_table = ctx.shanks(partial, shanks_table, randomized=True) + row = shanks_table[-1] + if len(row) == 2: + est1 = row[-1] + shanks_error = 0 + else: + est1, maxc, est2 = row[-1], abs(row[-2]), row[-3] + shanks_error = abs(est1-est2) + if verbose: + print("Shanks error: %s" % ctx.nstr(shanks_error)) + if shanks_error <= tol: + return est1 + if ctx.eps*maxc > tol: + if verbose: + print("Ran out of precision for Shanks") + TRY_SHANKS = False + if shanks_error < error: + error = shanks_error + best = est1 + for L in summer: + est, lerror = L.update_psum(partial) + if verbose: + print("%s error: %s" % (L.name, ctx.nstr(lerror))) + if lerror <= tol: + return est + if lerror < error: + error = lerror + best = est + if TRY_EULER_MACLAURIN: + if ctx.almosteq(ctx.mpc(ctx.sign(partial[-1]) / ctx.sign(partial[-2])), -1): + if verbose: + print ("NOT using Euler-Maclaurin: the series appears" + " to be alternating, so numerical\n quadrature" + " will most likely fail") + TRY_EULER_MACLAURIN = False + else: + value, em_error = emfun(index, tol) + value += partial[-1] + if verbose: + print("Euler-Maclaurin error: %s" % ctx.nstr(em_error)) + if em_error <= tol: + return value + if em_error < error: + best = value + finally: + ctx.prec = orig + if strict: + raise ctx.NoConvergence + if verbose: + print("Warning: failed to converge to target accuracy") + return best + +@defun +def nsum(ctx, f, *intervals, **options): + r""" + Computes the sum + + .. math :: S = \sum_{k=a}^b f(k) + + where `(a, b)` = *interval*, and where `a = -\infty` and/or + `b = \infty` are allowed, or more generally + + .. math :: S = \sum_{k_1=a_1}^{b_1} \cdots + \sum_{k_n=a_n}^{b_n} f(k_1,\ldots,k_n) + + if multiple intervals are given. + + Two examples of infinite series that can be summed by :func:`~mpmath.nsum`, + where the first converges rapidly and the second converges slowly, + are:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> nsum(lambda n: 1/fac(n), [0, inf]) + 2.71828182845905 + >>> nsum(lambda n: 1/n**2, [1, inf]) + 1.64493406684823 + + When appropriate, :func:`~mpmath.nsum` applies convergence acceleration to + accurately estimate the sums of slowly convergent series. If the series is + finite, :func:`~mpmath.nsum` currently does not attempt to perform any + extrapolation, and simply calls :func:`~mpmath.fsum`. + + Multidimensional infinite series are reduced to a single-dimensional + series over expanding hypercubes; if both infinite and finite dimensions + are present, the finite ranges are moved innermost. For more advanced + control over the summation order, use nested calls to :func:`~mpmath.nsum`, + or manually rewrite the sum as a single-dimensional series. + + **Options** + + *tol* + Desired maximum final error. Defaults roughly to the + epsilon of the working precision. + + *method* + Which summation algorithm to use (described below). + Default: ``'richardson+shanks'``. + + *maxterms* + Cancel after at most this many terms. Default: 10*dps. + + *steps* + An iterable giving the number of terms to add between + each extrapolation attempt. The default sequence is + [10, 20, 30, 40, ...]. For example, if you know that + approximately 100 terms will be required, efficiency might be + improved by setting this to [100, 10]. Then the first + extrapolation will be performed after 100 terms, the second + after 110, etc. + + *verbose* + Print details about progress. + + *ignore* + If enabled, any term that raises ``ArithmeticError`` + or ``ValueError`` (e.g. through division by zero) is replaced + by a zero. This is convenient for lattice sums with + a singular term near the origin. + + **Methods** + + Unfortunately, an algorithm that can efficiently sum any infinite + series does not exist. :func:`~mpmath.nsum` implements several different + algorithms that each work well in different cases. The *method* + keyword argument selects a method. + + The default method is ``'r+s'``, i.e. both Richardson extrapolation + and Shanks transformation is attempted. A slower method that + handles more cases is ``'r+s+e'``. For very high precision + summation, or if the summation needs to be fast (for example if + multiple sums need to be evaluated), it is a good idea to + investigate which one method works best and only use that. + + ``'richardson'`` / ``'r'``: + Uses Richardson extrapolation. Provides useful extrapolation + when `f(k) \sim P(k)/Q(k)` or when `f(k) \sim (-1)^k P(k)/Q(k)` + for polynomials `P` and `Q`. See :func:`~mpmath.richardson` for + additional information. + + ``'shanks'`` / ``'s'``: + Uses Shanks transformation. Typically provides useful + extrapolation when `f(k) \sim c^k` or when successive terms + alternate signs. Is able to sum some divergent series. + See :func:`~mpmath.shanks` for additional information. + + ``'levin'`` / ``'l'``: + Uses the Levin transformation. It performs better than the Shanks + transformation for logarithmic convergent or alternating divergent + series. The ``'levin_variant'``-keyword selects the variant. Valid + choices are "u", "t", "v" and "all" whereby "all" uses all three + u,t and v simultanously (This is good for performance comparison in + conjunction with "verbose=True"). Instead of the Levin transform one can + also use the Sidi-S transform by selecting the method ``'sidi'``. + See :func:`~mpmath.levin` for additional details. + + ``'alternating'`` / ``'a'``: + This is the convergence acceleration of alternating series developped + by Cohen, Villegras and Zagier. + See :func:`~mpmath.cohen_alt` for additional details. + + ``'euler-maclaurin'`` / ``'e'``: + Uses the Euler-Maclaurin summation formula to approximate + the remainder sum by an integral. This requires high-order + numerical derivatives and numerical integration. The advantage + of this algorithm is that it works regardless of the + decay rate of `f`, as long as `f` is sufficiently smooth. + See :func:`~mpmath.sumem` for additional information. + + ``'direct'`` / ``'d'``: + Does not perform any extrapolation. This can be used + (and should only be used for) rapidly convergent series. + The summation automatically stops when the terms + decrease below the target tolerance. + + **Basic examples** + + A finite sum:: + + >>> nsum(lambda k: 1/k, [1, 6]) + 2.45 + + Summation of a series going to negative infinity and a doubly + infinite series:: + + >>> nsum(lambda k: 1/k**2, [-inf, -1]) + 1.64493406684823 + >>> nsum(lambda k: 1/(1+k**2), [-inf, inf]) + 3.15334809493716 + + :func:`~mpmath.nsum` handles sums of complex numbers:: + + >>> nsum(lambda k: (0.5+0.25j)**k, [0, inf]) + (1.6 + 0.8j) + + The following sum converges very rapidly, so it is most + efficient to sum it by disabling convergence acceleration:: + + >>> mp.dps = 1000 + >>> a = nsum(lambda k: -(-1)**k * k**2 / fac(2*k), [1, inf], + ... method='direct') + >>> b = (cos(1)+sin(1))/4 + >>> abs(a-b) < mpf('1e-998') + True + + **Examples with Richardson extrapolation** + + Richardson extrapolation works well for sums over rational + functions, as well as their alternating counterparts:: + + >>> mp.dps = 50 + >>> nsum(lambda k: 1 / k**3, [1, inf], + ... method='richardson') + 1.2020569031595942853997381615114499907649862923405 + >>> zeta(3) + 1.2020569031595942853997381615114499907649862923405 + + >>> nsum(lambda n: (n + 3)/(n**3 + n**2), [1, inf], + ... method='richardson') + 2.9348022005446793094172454999380755676568497036204 + >>> pi**2/2-2 + 2.9348022005446793094172454999380755676568497036204 + + >>> nsum(lambda k: (-1)**k / k**3, [1, inf], + ... method='richardson') + -0.90154267736969571404980362113358749307373971925537 + >>> -3*zeta(3)/4 + -0.90154267736969571404980362113358749307373971925538 + + **Examples with Shanks transformation** + + The Shanks transformation works well for geometric series + and typically provides excellent acceleration for Taylor + series near the border of their disk of convergence. + Here we apply it to a series for `\log(2)`, which can be + seen as the Taylor series for `\log(1+x)` with `x = 1`:: + + >>> nsum(lambda k: -(-1)**k/k, [1, inf], + ... method='shanks') + 0.69314718055994530941723212145817656807550013436025 + >>> log(2) + 0.69314718055994530941723212145817656807550013436025 + + Here we apply it to a slowly convergent geometric series:: + + >>> nsum(lambda k: mpf('0.995')**k, [0, inf], + ... method='shanks') + 200.0 + + Finally, Shanks' method works very well for alternating series + where `f(k) = (-1)^k g(k)`, and often does so regardless of + the exact decay rate of `g(k)`:: + + >>> mp.dps = 15 + >>> nsum(lambda k: (-1)**(k+1) / k**1.5, [1, inf], + ... method='shanks') + 0.765147024625408 + >>> (2-sqrt(2))*zeta(1.5)/2 + 0.765147024625408 + + The following slowly convergent alternating series has no known + closed-form value. Evaluating the sum a second time at higher + precision indicates that the value is probably correct:: + + >>> nsum(lambda k: (-1)**k / log(k), [2, inf], + ... method='shanks') + 0.924299897222939 + >>> mp.dps = 30 + >>> nsum(lambda k: (-1)**k / log(k), [2, inf], + ... method='shanks') + 0.92429989722293885595957018136 + + **Examples with Levin transformation** + + The following example calculates Euler's constant as the constant term in + the Laurent expansion of zeta(s) at s=1. This sum converges extremly slow + because of the logarithmic convergence behaviour of the Dirichlet series + for zeta. + + >>> mp.dps = 30 + >>> z = mp.mpf(10) ** (-10) + >>> a = mp.nsum(lambda n: n**(-(1+z)), [1, mp.inf], method = "levin") - 1 / z + >>> print(mp.chop(a - mp.euler, tol = 1e-10)) + 0.0 + + Now we sum the zeta function outside its range of convergence + (attention: This does not work at the negative integers!): + + >>> mp.dps = 15 + >>> w = mp.nsum(lambda n: n ** (2 + 3j), [1, mp.inf], method = "levin", levin_variant = "v") + >>> print(mp.chop(w - mp.zeta(-2-3j))) + 0.0 + + The next example resummates an asymptotic series expansion of an integral + related to the exponential integral. + + >>> mp.dps = 15 + >>> z = mp.mpf(10) + >>> # exact = mp.quad(lambda x: mp.exp(-x)/(1+x/z),[0,mp.inf]) + >>> exact = z * mp.exp(z) * mp.expint(1,z) # this is the symbolic expression for the integral + >>> w = mp.nsum(lambda n: (-1) ** n * mp.fac(n) * z ** (-n), [0, mp.inf], method = "sidi", levin_variant = "t") + >>> print(mp.chop(w - exact)) + 0.0 + + Following highly divergent asymptotic expansion needs some care. Firstly we + need copious amount of working precision. Secondly the stepsize must not be + chosen to large, otherwise nsum may miss the point where the Levin transform + converges and reach the point where only numerical garbage is produced due to + numerical cancellation. + + >>> mp.dps = 15 + >>> z = mp.mpf(2) + >>> # exact = mp.quad(lambda x: mp.exp( -x * x / 2 - z * x ** 4), [0,mp.inf]) * 2 / mp.sqrt(2 * mp.pi) + >>> exact = mp.exp(mp.one / (32 * z)) * mp.besselk(mp.one / 4, mp.one / (32 * z)) / (4 * mp.sqrt(z * mp.pi)) # this is the symbolic expression for the integral + >>> w = mp.nsum(lambda n: (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4 ** n)), + ... [0, mp.inf], method = "levin", levin_variant = "t", workprec = 8*mp.prec, steps = [2] + [1 for x in xrange(1000)]) + >>> print(mp.chop(w - exact)) + 0.0 + + The hypergeoemtric function can also be summed outside its range of convergence: + + >>> mp.dps = 15 + >>> z = 2 + 1j + >>> exact = mp.hyp2f1(2 / mp.mpf(3), 4 / mp.mpf(3), 1 / mp.mpf(3), z) + >>> f = lambda n: mp.rf(2 / mp.mpf(3), n) * mp.rf(4 / mp.mpf(3), n) * z**n / (mp.rf(1 / mp.mpf(3), n) * mp.fac(n)) + >>> v = mp.nsum(f, [0, mp.inf], method = "levin", steps = [10 for x in xrange(1000)]) + >>> print(mp.chop(exact-v)) + 0.0 + + **Examples with Cohen's alternating series resummation** + + The next example sums the alternating zeta function: + + >>> v = mp.nsum(lambda n: (-1)**(n-1) / n, [1, mp.inf], method = "a") + >>> print(mp.chop(v - mp.log(2))) + 0.0 + + The derivate of the alternating zeta function outside its range of + convergence: + + >>> v = mp.nsum(lambda n: (-1)**n * mp.log(n) * n, [1, mp.inf], method = "a") + >>> print(mp.chop(v - mp.diff(lambda s: mp.altzeta(s), -1))) + 0.0 + + **Examples with Euler-Maclaurin summation** + + The sum in the following example has the wrong rate of convergence + for either Richardson or Shanks to be effective. + + >>> f = lambda k: log(k)/k**2.5 + >>> mp.dps = 15 + >>> nsum(f, [1, inf], method='euler-maclaurin') + 0.38734195032621 + >>> -diff(zeta, 2.5) + 0.38734195032621 + + Increasing ``steps`` improves speed at higher precision:: + + >>> mp.dps = 50 + >>> nsum(f, [1, inf], method='euler-maclaurin', steps=[250]) + 0.38734195032620997271199237593105101319948228874688 + >>> -diff(zeta, 2.5) + 0.38734195032620997271199237593105101319948228874688 + + **Divergent series** + + The Shanks transformation is able to sum some *divergent* + series. In particular, it is often able to sum Taylor series + beyond their radius of convergence (this is due to a relation + between the Shanks transformation and Pade approximations; + see :func:`~mpmath.pade` for an alternative way to evaluate divergent + Taylor series). Furthermore the Levin-transform examples above + contain some divergent series resummation. + + Here we apply it to `\log(1+x)` far outside the region of + convergence:: + + >>> mp.dps = 50 + >>> nsum(lambda k: -(-9)**k/k, [1, inf], + ... method='shanks') + 2.3025850929940456840179914546843642076011014886288 + >>> log(10) + 2.3025850929940456840179914546843642076011014886288 + + A particular type of divergent series that can be summed + using the Shanks transformation is geometric series. + The result is the same as using the closed-form formula + for an infinite geometric series:: + + >>> mp.dps = 15 + >>> for n in range(-8, 8): + ... if n == 1: + ... continue + ... print("%s %s %s" % (mpf(n), mpf(1)/(1-n), + ... nsum(lambda k: n**k, [0, inf], method='shanks'))) + ... + -8.0 0.111111111111111 0.111111111111111 + -7.0 0.125 0.125 + -6.0 0.142857142857143 0.142857142857143 + -5.0 0.166666666666667 0.166666666666667 + -4.0 0.2 0.2 + -3.0 0.25 0.25 + -2.0 0.333333333333333 0.333333333333333 + -1.0 0.5 0.5 + 0.0 1.0 1.0 + 2.0 -1.0 -1.0 + 3.0 -0.5 -0.5 + 4.0 -0.333333333333333 -0.333333333333333 + 5.0 -0.25 -0.25 + 6.0 -0.2 -0.2 + 7.0 -0.166666666666667 -0.166666666666667 + + **Multidimensional sums** + + Any combination of finite and infinite ranges is allowed for the + summation indices:: + + >>> mp.dps = 15 + >>> nsum(lambda x,y: x+y, [2,3], [4,5]) + 28.0 + >>> nsum(lambda x,y: x/2**y, [1,3], [1,inf]) + 6.0 + >>> nsum(lambda x,y: y/2**x, [1,inf], [1,3]) + 6.0 + >>> nsum(lambda x,y,z: z/(2**x*2**y), [1,inf], [1,inf], [3,4]) + 7.0 + >>> nsum(lambda x,y,z: y/(2**x*2**z), [1,inf], [3,4], [1,inf]) + 7.0 + >>> nsum(lambda x,y,z: x/(2**z*2**y), [3,4], [1,inf], [1,inf]) + 7.0 + + Some nice examples of double series with analytic solutions or + reductions to single-dimensional series (see [1]):: + + >>> nsum(lambda m, n: 1/2**(m*n), [1,inf], [1,inf]) + 1.60669515241529 + >>> nsum(lambda n: 1/(2**n-1), [1,inf]) + 1.60669515241529 + + >>> nsum(lambda i,j: (-1)**(i+j)/(i**2+j**2), [1,inf], [1,inf]) + 0.278070510848213 + >>> pi*(pi-3*ln2)/12 + 0.278070510848213 + + >>> nsum(lambda i,j: (-1)**(i+j)/(i+j)**2, [1,inf], [1,inf]) + 0.129319852864168 + >>> altzeta(2) - altzeta(1) + 0.129319852864168 + + >>> nsum(lambda i,j: (-1)**(i+j)/(i+j)**3, [1,inf], [1,inf]) + 0.0790756439455825 + >>> altzeta(3) - altzeta(2) + 0.0790756439455825 + + >>> nsum(lambda m,n: m**2*n/(3**m*(n*3**m+m*3**n)), + ... [1,inf], [1,inf]) + 0.28125 + >>> mpf(9)/32 + 0.28125 + + >>> nsum(lambda i,j: fac(i-1)*fac(j-1)/fac(i+j), + ... [1,inf], [1,inf], workprec=400) + 1.64493406684823 + >>> zeta(2) + 1.64493406684823 + + A hard example of a multidimensional sum is the Madelung constant + in three dimensions (see [2]). The defining sum converges very + slowly and only conditionally, so :func:`~mpmath.nsum` is lucky to + obtain an accurate value through convergence acceleration. The + second evaluation below uses a much more efficient, rapidly + convergent 2D sum:: + + >>> nsum(lambda x,y,z: (-1)**(x+y+z)/(x*x+y*y+z*z)**0.5, + ... [-inf,inf], [-inf,inf], [-inf,inf], ignore=True) + -1.74756459463318 + >>> nsum(lambda x,y: -12*pi*sech(0.5*pi * \ + ... sqrt((2*x+1)**2+(2*y+1)**2))**2, [0,inf], [0,inf]) + -1.74756459463318 + + Another example of a lattice sum in 2D:: + + >>> nsum(lambda x,y: (-1)**(x+y) / (x**2+y**2), [-inf,inf], + ... [-inf,inf], ignore=True) + -2.1775860903036 + >>> -pi*ln2 + -2.1775860903036 + + An example of an Eisenstein series:: + + >>> nsum(lambda m,n: (m+n*1j)**(-4), [-inf,inf], [-inf,inf], + ... ignore=True) + (3.1512120021539 + 0.0j) + + **References** + + 1. [Weisstein]_ http://mathworld.wolfram.com/DoubleSeries.html, + 2. [Weisstein]_ http://mathworld.wolfram.com/MadelungConstants.html + + """ + infinite, g = standardize(ctx, f, intervals, options) + if not infinite: + return +g() + + def update(partial_sums, indices): + if partial_sums: + psum = partial_sums[-1] + else: + psum = ctx.zero + for k in indices: + psum = psum + g(ctx.mpf(k)) + partial_sums.append(psum) + + prec = ctx.prec + + def emfun(point, tol): + workprec = ctx.prec + ctx.prec = prec + 10 + v = ctx.sumem(g, [point, ctx.inf], tol, error=1) + ctx.prec = workprec + return v + + return +ctx.adaptive_extrapolation(update, emfun, options) + + +def wrapsafe(f): + def g(*args): + try: + return f(*args) + except (ArithmeticError, ValueError): + return 0 + return g + +def standardize(ctx, f, intervals, options): + if options.get("ignore"): + f = wrapsafe(f) + finite = [] + infinite = [] + for k, points in enumerate(intervals): + a, b = ctx._as_points(points) + if b < a: + return False, (lambda: ctx.zero) + if a == ctx.ninf or b == ctx.inf: + infinite.append((k, (a,b))) + else: + finite.append((k, (int(a), int(b)))) + if finite: + f = fold_finite(ctx, f, finite) + if not infinite: + return False, lambda: f(*([0]*len(intervals))) + if infinite: + f = standardize_infinite(ctx, f, infinite) + f = fold_infinite(ctx, f, infinite) + args = [0] * len(intervals) + d = infinite[0][0] + def g(k): + args[d] = k + return f(*args) + return True, g + +# backwards compatible itertools.product +def cartesian_product(args): + pools = map(tuple, args) + result = [[]] + for pool in pools: + result = [x+[y] for x in result for y in pool] + for prod in result: + yield tuple(prod) + +def fold_finite(ctx, f, intervals): + if not intervals: + return f + indices = [v[0] for v in intervals] + points = [v[1] for v in intervals] + ranges = [xrange(a, b+1) for (a,b) in points] + def g(*args): + args = list(args) + s = ctx.zero + for xs in cartesian_product(ranges): + for dim, x in zip(indices, xs): + args[dim] = ctx.mpf(x) + s += f(*args) + return s + #print "Folded finite", indices + return g + +# Standardize each interval to [0,inf] +def standardize_infinite(ctx, f, intervals): + if not intervals: + return f + dim, [a,b] = intervals[-1] + if a == ctx.ninf: + if b == ctx.inf: + def g(*args): + args = list(args) + k = args[dim] + if k: + s = f(*args) + args[dim] = -k + s += f(*args) + return s + else: + return f(*args) + else: + def g(*args): + args = list(args) + args[dim] = b - args[dim] + return f(*args) + else: + def g(*args): + args = list(args) + args[dim] += a + return f(*args) + #print "Standardized infinity along dimension", dim, a, b + return standardize_infinite(ctx, g, intervals[:-1]) + +def fold_infinite(ctx, f, intervals): + if len(intervals) < 2: + return f + dim1 = intervals[-2][0] + dim2 = intervals[-1][0] + # Assume intervals are [0,inf] x [0,inf] x ... + def g(*args): + args = list(args) + #args.insert(dim2, None) + n = int(args[dim1]) + s = ctx.zero + #y = ctx.mpf(n) + args[dim2] = ctx.mpf(n) #y + for x in xrange(n+1): + args[dim1] = ctx.mpf(x) + s += f(*args) + args[dim1] = ctx.mpf(n) #ctx.mpf(n) + for y in xrange(n): + args[dim2] = ctx.mpf(y) + s += f(*args) + return s + #print "Folded infinite from", len(intervals), "to", (len(intervals)-1) + return fold_infinite(ctx, g, intervals[:-1]) + +@defun +def nprod(ctx, f, interval, nsum=False, **kwargs): + r""" + Computes the product + + .. math :: + + P = \prod_{k=a}^b f(k) + + where `(a, b)` = *interval*, and where `a = -\infty` and/or + `b = \infty` are allowed. + + By default, :func:`~mpmath.nprod` uses the same extrapolation methods as + :func:`~mpmath.nsum`, except applied to the partial products rather than + partial sums, and the same keyword options as for :func:`~mpmath.nsum` are + supported. If ``nsum=True``, the product is instead computed via + :func:`~mpmath.nsum` as + + .. math :: + + P = \exp\left( \sum_{k=a}^b \log(f(k)) \right). + + This is slower, but can sometimes yield better results. It is + also required (and used automatically) when Euler-Maclaurin + summation is requested. + + **Examples** + + A simple finite product:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> nprod(lambda k: k, [1, 4]) + 24.0 + + A large number of infinite products have known exact values, + and can therefore be used as a reference. Most of the following + examples are taken from MathWorld [1]. + + A few infinite products with simple values are:: + + >>> 2*nprod(lambda k: (4*k**2)/(4*k**2-1), [1, inf]) + 3.141592653589793238462643 + >>> nprod(lambda k: (1+1/k)**2/(1+2/k), [1, inf]) + 2.0 + >>> nprod(lambda k: (k**3-1)/(k**3+1), [2, inf]) + 0.6666666666666666666666667 + >>> nprod(lambda k: (1-1/k**2), [2, inf]) + 0.5 + + Next, several more infinite products with more complicated + values:: + + >>> nprod(lambda k: exp(1/k**2), [1, inf]); exp(pi**2/6) + 5.180668317897115748416626 + 5.180668317897115748416626 + + >>> nprod(lambda k: (k**2-1)/(k**2+1), [2, inf]); pi*csch(pi) + 0.2720290549821331629502366 + 0.2720290549821331629502366 + + >>> nprod(lambda k: (k**4-1)/(k**4+1), [2, inf]) + 0.8480540493529003921296502 + >>> pi*sinh(pi)/(cosh(sqrt(2)*pi)-cos(sqrt(2)*pi)) + 0.8480540493529003921296502 + + >>> nprod(lambda k: (1+1/k+1/k**2)**2/(1+2/k+3/k**2), [1, inf]) + 1.848936182858244485224927 + >>> 3*sqrt(2)*cosh(pi*sqrt(3)/2)**2*csch(pi*sqrt(2))/pi + 1.848936182858244485224927 + + >>> nprod(lambda k: (1-1/k**4), [2, inf]); sinh(pi)/(4*pi) + 0.9190194775937444301739244 + 0.9190194775937444301739244 + + >>> nprod(lambda k: (1-1/k**6), [2, inf]) + 0.9826842777421925183244759 + >>> (1+cosh(pi*sqrt(3)))/(12*pi**2) + 0.9826842777421925183244759 + + >>> nprod(lambda k: (1+1/k**2), [2, inf]); sinh(pi)/(2*pi) + 1.838038955187488860347849 + 1.838038955187488860347849 + + >>> nprod(lambda n: (1+1/n)**n * exp(1/(2*n)-1), [1, inf]) + 1.447255926890365298959138 + >>> exp(1+euler/2)/sqrt(2*pi) + 1.447255926890365298959138 + + The following two products are equivalent and can be evaluated in + terms of a Jacobi theta function. Pi can be replaced by any value + (as long as convergence is preserved):: + + >>> nprod(lambda k: (1-pi**-k)/(1+pi**-k), [1, inf]) + 0.3838451207481672404778686 + >>> nprod(lambda k: tanh(k*log(pi)/2), [1, inf]) + 0.3838451207481672404778686 + >>> jtheta(4,0,1/pi) + 0.3838451207481672404778686 + + This product does not have a known closed form value:: + + >>> nprod(lambda k: (1-1/2**k), [1, inf]) + 0.2887880950866024212788997 + + A product taken from `-\infty`:: + + >>> nprod(lambda k: 1-k**(-3), [-inf,-2]) + 0.8093965973662901095786805 + >>> cosh(pi*sqrt(3)/2)/(3*pi) + 0.8093965973662901095786805 + + A doubly infinite product:: + + >>> nprod(lambda k: exp(1/(1+k**2)), [-inf, inf]) + 23.41432688231864337420035 + >>> exp(pi/tanh(pi)) + 23.41432688231864337420035 + + A product requiring the use of Euler-Maclaurin summation to compute + an accurate value:: + + >>> nprod(lambda k: (1-1/k**2.5), [2, inf], method='e') + 0.696155111336231052898125 + + **References** + + 1. [Weisstein]_ http://mathworld.wolfram.com/InfiniteProduct.html + + """ + if nsum or ('e' in kwargs.get('method', '')): + orig = ctx.prec + try: + # TODO: we are evaluating log(1+eps) -> eps, which is + # inaccurate. This currently works because nsum greatly + # increases the working precision. But we should be + # more intelligent and handle the precision here. + ctx.prec += 10 + v = ctx.nsum(lambda n: ctx.ln(f(n)), interval, **kwargs) + finally: + ctx.prec = orig + return +ctx.exp(v) + + a, b = ctx._as_points(interval) + if a == ctx.ninf: + if b == ctx.inf: + return f(0) * ctx.nprod(lambda k: f(-k) * f(k), [1, ctx.inf], **kwargs) + return ctx.nprod(f, [-b, ctx.inf], **kwargs) + elif b != ctx.inf: + return ctx.fprod(f(ctx.mpf(k)) for k in xrange(int(a), int(b)+1)) + + a = int(a) + + def update(partial_products, indices): + if partial_products: + pprod = partial_products[-1] + else: + pprod = ctx.one + for k in indices: + pprod = pprod * f(a + ctx.mpf(k)) + partial_products.append(pprod) + + return +ctx.adaptive_extrapolation(update, None, kwargs) + + +@defun +def limit(ctx, f, x, direction=1, exp=False, **kwargs): + r""" + Computes an estimate of the limit + + .. math :: + + \lim_{t \to x} f(t) + + where `x` may be finite or infinite. + + For finite `x`, :func:`~mpmath.limit` evaluates `f(x + d/n)` for + consecutive integer values of `n`, where the approach direction + `d` may be specified using the *direction* keyword argument. + For infinite `x`, :func:`~mpmath.limit` evaluates values of + `f(\mathrm{sign}(x) \cdot n)`. + + If the approach to the limit is not sufficiently fast to give + an accurate estimate directly, :func:`~mpmath.limit` attempts to find + the limit using Richardson extrapolation or the Shanks + transformation. You can select between these methods using + the *method* keyword (see documentation of :func:`~mpmath.nsum` for + more information). + + **Options** + + The following options are available with essentially the + same meaning as for :func:`~mpmath.nsum`: *tol*, *method*, *maxterms*, + *steps*, *verbose*. + + If the option *exp=True* is set, `f` will be + sampled at exponentially spaced points `n = 2^1, 2^2, 2^3, \ldots` + instead of the linearly spaced points `n = 1, 2, 3, \ldots`. + This can sometimes improve the rate of convergence so that + :func:`~mpmath.limit` may return a more accurate answer (and faster). + However, do note that this can only be used if `f` + supports fast and accurate evaluation for arguments that + are extremely close to the limit point (or if infinite, + very large arguments). + + **Examples** + + A basic evaluation of a removable singularity:: + + >>> from mpmath import * + >>> mp.dps = 30; mp.pretty = True + >>> limit(lambda x: (x-sin(x))/x**3, 0) + 0.166666666666666666666666666667 + + Computing the exponential function using its limit definition:: + + >>> limit(lambda n: (1+3/n)**n, inf) + 20.0855369231876677409285296546 + >>> exp(3) + 20.0855369231876677409285296546 + + A limit for `\pi`:: + + >>> f = lambda n: 2**(4*n+1)*fac(n)**4/(2*n+1)/fac(2*n)**2 + >>> limit(f, inf) + 3.14159265358979323846264338328 + + Calculating the coefficient in Stirling's formula:: + + >>> limit(lambda n: fac(n) / (sqrt(n)*(n/e)**n), inf) + 2.50662827463100050241576528481 + >>> sqrt(2*pi) + 2.50662827463100050241576528481 + + Evaluating Euler's constant `\gamma` using the limit representation + + .. math :: + + \gamma = \lim_{n \rightarrow \infty } \left[ \left( + \sum_{k=1}^n \frac{1}{k} \right) - \log(n) \right] + + (which converges notoriously slowly):: + + >>> f = lambda n: sum([mpf(1)/k for k in range(1,int(n)+1)]) - log(n) + >>> limit(f, inf) + 0.577215664901532860606512090082 + >>> +euler + 0.577215664901532860606512090082 + + With default settings, the following limit converges too slowly + to be evaluated accurately. Changing to exponential sampling + however gives a perfect result:: + + >>> f = lambda x: sqrt(x**3+x**2)/(sqrt(x**3)+x) + >>> limit(f, inf) + 0.992831158558330281129249686491 + >>> limit(f, inf, exp=True) + 1.0 + + """ + + if ctx.isinf(x): + direction = ctx.sign(x) + g = lambda k: f(ctx.mpf(k+1)*direction) + else: + direction *= ctx.one + g = lambda k: f(x + direction/(k+1)) + if exp: + h = g + g = lambda k: h(2**k) + + def update(values, indices): + for k in indices: + values.append(g(k+1)) + + # XXX: steps used by nsum don't work well + if not 'steps' in kwargs: + kwargs['steps'] = [10] + + return +ctx.adaptive_extrapolation(update, None, kwargs) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/inverselaplace.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/inverselaplace.py new file mode 100644 index 0000000000000000000000000000000000000000..d2206b05c1601ee781b09dcbedf3c0fcd89cfa59 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/inverselaplace.py @@ -0,0 +1,973 @@ +# contributed to mpmath by Kristopher L. Kuhlman, February 2017 +# contributed to mpmath by Guillermo Navas-Palencia, February 2022 + +class InverseLaplaceTransform(object): + r""" + Inverse Laplace transform methods are implemented using this + class, in order to simplify the code and provide a common + infrastructure. + + Implement a custom inverse Laplace transform algorithm by + subclassing :class:`InverseLaplaceTransform` and implementing the + appropriate methods. The subclass can then be used by + :func:`~mpmath.invertlaplace` by passing it as the *method* + argument. + """ + + def __init__(self, ctx): + self.ctx = ctx + + def calc_laplace_parameter(self, t, **kwargs): + r""" + Determine the vector of Laplace parameter values needed for an + algorithm, this will depend on the choice of algorithm (de + Hoog is default), the algorithm-specific parameters passed (or + default ones), and desired time. + """ + raise NotImplementedError + + def calc_time_domain_solution(self, fp): + r""" + Compute the time domain solution, after computing the + Laplace-space function evaluations at the abscissa required + for the algorithm. Abscissa computed for one algorithm are + typically not useful for another algorithm. + """ + raise NotImplementedError + + +class FixedTalbot(InverseLaplaceTransform): + + def calc_laplace_parameter(self, t, **kwargs): + r"""The "fixed" Talbot method deforms the Bromwich contour towards + `-\infty` in the shape of a parabola. Traditionally the Talbot + algorithm has adjustable parameters, but the "fixed" version + does not. The `r` parameter could be passed in as a parameter, + if you want to override the default given by (Abate & Valko, + 2004). + + The Laplace parameter is sampled along a parabola opening + along the negative imaginary axis, with the base of the + parabola along the real axis at + `p=\frac{r}{t_\mathrm{max}}`. As the number of terms used in + the approximation (degree) grows, the abscissa required for + function evaluation tend towards `-\infty`, requiring high + precision to prevent overflow. If any poles, branch cuts or + other singularities exist such that the deformed Bromwich + contour lies to the left of the singularity, the method will + fail. + + **Optional arguments** + + :class:`~mpmath.calculus.inverselaplace.FixedTalbot.calc_laplace_parameter` + recognizes the following keywords + + *tmax* + maximum time associated with vector of times + (typically just the time requested) + *degree* + integer order of approximation (M = number of terms) + *r* + abscissa for `p_0` (otherwise computed using rule + of thumb `2M/5`) + + The working precision will be increased according to a rule of + thumb. If 'degree' is not specified, the working precision and + degree are chosen to hopefully achieve the dps of the calling + context. If 'degree' is specified, the working precision is + chosen to achieve maximum resulting precision for the + specified degree. + + .. math :: + + p_0=\frac{r}{t} + + .. math :: + + p_i=\frac{i r \pi}{Mt_\mathrm{max}}\left[\cot\left( + \frac{i\pi}{M}\right) + j \right] \qquad 1\le i 0: + self.degree += 1 + + M = self.degree + + # this is adjusting the dps of the calling context + # hopefully the caller doesn't monkey around with it + # between calling this routine and calc_time_domain_solution() + self.dps_orig = self.ctx.dps + self.ctx.dps = self.dps_goal + + self.V = self._coeff() + self.p = self.ctx.matrix(self.ctx.arange(1, M+1))*self.ctx.ln2/self.t + + # NB: p is real (mpf) + + def _coeff(self): + r"""Salzer summation weights (aka, "Stehfest coefficients") + only depend on the approximation order (M) and the precision""" + + M = self.degree + M2 = int(M/2) # checked earlier that M is even + + V = self.ctx.matrix(M, 1) + + # Salzer summation weights + # get very large in magnitude and oscillate in sign, + # if the precision is not high enough, there will be + # catastrophic cancellation + for k in range(1, M+1): + z = self.ctx.matrix(min(k, M2)+1, 1) + for j in range(int((k+1)/2), min(k, M2)+1): + z[j] = (self.ctx.power(j, M2)*self.ctx.fac(2*j)/ + (self.ctx.fac(M2-j)*self.ctx.fac(j)* + self.ctx.fac(j-1)*self.ctx.fac(k-j)* + self.ctx.fac(2*j-k))) + V[k-1] = self.ctx.power(-1, k+M2)*self.ctx.fsum(z) + + return V + + def calc_time_domain_solution(self, fp, t, manual_prec=False): + r"""Compute time-domain Stehfest algorithm solution. + + .. math :: + + f(t,M) = \frac{\log 2}{t} \sum_{k=1}^{M} V_k \bar{f}\left( + p_k \right) + + where + + .. math :: + + V_k = (-1)^{k + N/2} \sum^{\min(k,N/2)}_{i=\lfloor(k+1)/2 \rfloor} + \frac{i^{\frac{N}{2}}(2i)!}{\left(\frac{N}{2}-i \right)! \, i! \, + \left(i-1 \right)! \, \left(k-i\right)! \, \left(2i-k \right)!} + + As the degree increases, the abscissa (`p_k`) only increase + linearly towards `\infty`, but the Stehfest coefficients + (`V_k`) alternate in sign and increase rapidly in sign, + requiring high precision to prevent overflow or loss of + significance when evaluating the sum. + + **References** + + 1. Widder, D. (1941). *The Laplace Transform*. Princeton. + 2. Stehfest, H. (1970). Algorithm 368: numerical inversion of + Laplace transforms. *Communications of the ACM* 13(1):47-49, + http://dx.doi.org/10.1145/361953.361969 + + """ + + # required + self.t = self.ctx.convert(t) + + # assume fp was computed from p matrix returned from + # calc_laplace_parameter(), so is already + # a list or matrix of mpmath 'mpf' types + + result = self.ctx.fdot(self.V, fp)*self.ctx.ln2/self.t + + # setting dps back to value when calc_laplace_parameter was called + if not manual_prec: + self.ctx.dps = self.dps_orig + + # ignore any small imaginary part + return result.real + + +# **************************************** + +class deHoog(InverseLaplaceTransform): + + def calc_laplace_parameter(self, t, **kwargs): + r"""the de Hoog, Knight & Stokes algorithm is an + accelerated form of the Fourier series numerical + inverse Laplace transform algorithms. + + .. math :: + + p_k = \gamma + \frac{jk}{T} \qquad 0 \le k < 2M+1 + + where + + .. math :: + + \gamma = \alpha - \frac{\log \mathrm{tol}}{2T}, + + `j=\sqrt{-1}`, `T = 2t_\mathrm{max}` is a scaled time, + `\alpha=10^{-\mathrm{dps\_goal}}` is the real part of the + rightmost pole or singularity, which is chosen based on the + desired accuracy (assuming the rightmost singularity is 0), + and `\mathrm{tol}=10\alpha` is the desired tolerance, which is + chosen in relation to `\alpha`.` + + When increasing the degree, the abscissa increase towards + `j\infty`, but more slowly than the fixed Talbot + algorithm. The de Hoog et al. algorithm typically does better + with oscillatory functions of time, and less well-behaved + functions. The method tends to be slower than the Talbot and + Stehfest algorithsm, especially so at very high precision + (e.g., `>500` digits precision). + + """ + + # required + # ------------------------------ + self.t = self.ctx.convert(t) + + # optional + # ------------------------------ + self.tmax = kwargs.get('tmax', self.t) + + # empirical relationships used here based on a linear fit of + # requested and delivered dps for exponentially decaying time + # functions for requested dps up to 512. + + if 'degree' in kwargs: + self.degree = kwargs['degree'] + self.dps_goal = int(1.38*self.degree) + else: + self.dps_goal = int(self.ctx.dps*1.36) + self.degree = max(10, self.dps_goal) + + # 2*M+1 terms in approximation + M = self.degree + + # adjust alpha component of abscissa of convergence for higher + # precision + tmp = self.ctx.power(10.0, -self.dps_goal) + self.alpha = self.ctx.convert(kwargs.get('alpha', tmp)) + + # desired tolerance (here simply related to alpha) + self.tol = self.ctx.convert(kwargs.get('tol', self.alpha*10.0)) + self.np = 2*self.degree+1 # number of terms in approximation + + # this is adjusting the dps of the calling context + # hopefully the caller doesn't monkey around with it + # between calling this routine and calc_time_domain_solution() + self.dps_orig = self.ctx.dps + self.ctx.dps = self.dps_goal + + # scaling factor (likely tun-able, but 2 is typical) + self.scale = kwargs.get('scale', 2) + self.T = self.ctx.convert(kwargs.get('T', self.scale*self.tmax)) + + self.p = self.ctx.matrix(2*M+1, 1) + self.gamma = self.alpha - self.ctx.log(self.tol)/(self.scale*self.T) + self.p = (self.gamma + self.ctx.pi* + self.ctx.matrix(self.ctx.arange(self.np))/self.T*1j) + + # NB: p is complex (mpc) + + def calc_time_domain_solution(self, fp, t, manual_prec=False): + r"""Calculate time-domain solution for + de Hoog, Knight & Stokes algorithm. + + The un-accelerated Fourier series approach is: + + .. math :: + + f(t,2M+1) = \frac{e^{\gamma t}}{T} \sum_{k=0}^{2M}{}^{'} + \Re\left[\bar{f}\left( p_k \right) + e^{i\pi t/T} \right], + + where the prime on the summation indicates the first term is halved. + + This simplistic approach requires so many function evaluations + that it is not practical. Non-linear acceleration is + accomplished via Pade-approximation and an analytic expression + for the remainder of the continued fraction. See the original + paper (reference 2 below) a detailed description of the + numerical approach. + + **References** + + 1. Davies, B. (2005). *Integral Transforms and their + Applications*, Third Edition. Springer. + 2. de Hoog, F., J. Knight, A. Stokes (1982). An improved + method for numerical inversion of Laplace transforms. *SIAM + Journal of Scientific and Statistical Computing* 3:357-366, + http://dx.doi.org/10.1137/0903022 + + """ + + M = self.degree + np = self.np + T = self.T + + self.t = self.ctx.convert(t) + + # would it be useful to try re-using + # space between e&q and A&B? + e = self.ctx.zeros(np, M+1) + q = self.ctx.matrix(2*M, M) + d = self.ctx.matrix(np, 1) + A = self.ctx.zeros(np+1, 1) + B = self.ctx.ones(np+1, 1) + + # initialize Q-D table + e[:, 0] = 0.0 + 0j + q[0, 0] = fp[1]/(fp[0]/2) + for i in range(1, 2*M): + q[i, 0] = fp[i+1]/fp[i] + + # rhombus rule for filling triangular Q-D table (e & q) + for r in range(1, M+1): + # start with e, column 1, 0:2*M-2 + mr = 2*(M-r) + 1 + e[0:mr, r] = q[1:mr+1, r-1] - q[0:mr, r-1] + e[1:mr+1, r-1] + if not r == M: + rq = r+1 + mr = 2*(M-rq)+1 + 2 + for i in range(mr): + q[i, rq-1] = q[i+1, rq-2]*e[i+1, rq-1]/e[i, rq-1] + + # build up continued fraction coefficients (d) + d[0] = fp[0]/2 + for r in range(1, M+1): + d[2*r-1] = -q[0, r-1] # even terms + d[2*r] = -e[0, r] # odd terms + + # seed A and B for recurrence + A[0] = 0.0 + 0.0j + A[1] = d[0] + B[0:2] = 1.0 + 0.0j + + # base of the power series + z = self.ctx.expjpi(self.t/T) # i*pi is already in fcn + + # coefficients of Pade approximation (A & B) + # using recurrence for all but last term + for i in range(1, 2*M): + A[i+1] = A[i] + d[i]*A[i-1]*z + B[i+1] = B[i] + d[i]*B[i-1]*z + + # "improved remainder" to continued fraction + brem = (1 + (d[2*M-1] - d[2*M])*z)/2 + # powm1(x,y) computes x^y - 1 more accurately near zero + rem = brem*self.ctx.powm1(1 + d[2*M]*z/brem, + self.ctx.fraction(1, 2)) + + # last term of recurrence using new remainder + A[np] = A[2*M] + rem*A[2*M-1] + B[np] = B[2*M] + rem*B[2*M-1] + + # diagonal Pade approximation + # F=A/B represents accelerated trapezoid rule + result = self.ctx.exp(self.gamma*self.t)/T*(A[np]/B[np]).real + + # setting dps back to value when calc_laplace_parameter was called + if not manual_prec: + self.ctx.dps = self.dps_orig + + return result + + +# **************************************** + +class Cohen(InverseLaplaceTransform): + + def calc_laplace_parameter(self, t, **kwargs): + r"""The Cohen algorithm accelerates the convergence of the nearly + alternating series resulting from the application of the trapezoidal + rule to the Bromwich contour inversion integral. + + .. math :: + + p_k = \frac{\gamma}{2 t} + \frac{\pi i k}{t} \qquad 0 \le k < M + + where + + .. math :: + + \gamma = \frac{2}{3} (d + \log(10) + \log(2 t)), + + `d = \mathrm{dps\_goal}`, which is chosen based on the desired + accuracy using the method developed in [1] to improve numerical + stability. The Cohen algorithm shows robustness similar to the de Hoog + et al. algorithm, but it is faster than the fixed Talbot algorithm. + + **Optional arguments** + + *degree* + integer order of the approximation (M = number of terms) + *alpha* + abscissa for `p_0` (controls the discretization error) + + The working precision will be increased according to a rule of + thumb. If 'degree' is not specified, the working precision and + degree are chosen to hopefully achieve the dps of the calling + context. If 'degree' is specified, the working precision is + chosen to achieve maximum resulting precision for the + specified degree. + + **References** + + 1. P. Glasserman, J. Ruiz-Mata (2006). Computing the credit loss + distribution in the Gaussian copula model: a comparison of methods. + *Journal of Credit Risk* 2(4):33-66, 10.21314/JCR.2006.057 + + """ + self.t = self.ctx.convert(t) + + if 'degree' in kwargs: + self.degree = kwargs['degree'] + self.dps_goal = int(1.5 * self.degree) + else: + self.dps_goal = int(self.ctx.dps * 1.74) + self.degree = max(22, int(1.31 * self.dps_goal)) + + M = self.degree + 1 + + # this is adjusting the dps of the calling context hopefully + # the caller doesn't monkey around with it between calling + # this routine and calc_time_domain_solution() + self.dps_orig = self.ctx.dps + self.ctx.dps = self.dps_goal + + ttwo = 2 * self.t + tmp = self.ctx.dps * self.ctx.log(10) + self.ctx.log(ttwo) + tmp = self.ctx.fraction(2, 3) * tmp + self.alpha = self.ctx.convert(kwargs.get('alpha', tmp)) + + # all but time-dependent part of p + a_t = self.alpha / ttwo + p_t = self.ctx.pi * 1j / self.t + + self.p = self.ctx.matrix(M, 1) + self.p[0] = a_t + + for i in range(1, M): + self.p[i] = a_t + i * p_t + + def calc_time_domain_solution(self, fp, t, manual_prec=False): + r"""Calculate time-domain solution for Cohen algorithm. + + The accelerated nearly alternating series is: + + .. math :: + + f(t, M) = \frac{e^{\gamma / 2}}{t} \left[\frac{1}{2} + \Re\left(\bar{f}\left(\frac{\gamma}{2t}\right) \right) - + \sum_{k=0}^{M-1}\frac{c_{M,k}}{d_M}\Re\left(\bar{f} + \left(\frac{\gamma + 2(k+1) \pi i}{2t}\right)\right)\right], + + where coefficients `\frac{c_{M, k}}{d_M}` are described in [1]. + + 1. H. Cohen, F. Rodriguez Villegas, D. Zagier (2000). Convergence + acceleration of alternating series. *Experiment. Math* 9(1):3-12 + + """ + self.t = self.ctx.convert(t) + + n = self.degree + M = n + 1 + + A = self.ctx.matrix(M, 1) + for i in range(M): + A[i] = fp[i].real + + d = (3 + self.ctx.sqrt(8)) ** n + d = (d + 1 / d) / 2 + b = -self.ctx.one + c = -d + s = 0 + + for k in range(n): + c = b - c + s = s + c * A[k + 1] + b = 2 * (k + n) * (k - n) * b / ((2 * k + 1) * (k + self.ctx.one)) + + result = self.ctx.exp(self.alpha / 2) / self.t * (A[0] / 2 - s / d) + + # setting dps back to value when calc_laplace_parameter was + # called, unless flag is set. + if not manual_prec: + self.ctx.dps = self.dps_orig + + return result + + +# **************************************** + +class LaplaceTransformInversionMethods(object): + def __init__(ctx, *args, **kwargs): + ctx._fixed_talbot = FixedTalbot(ctx) + ctx._stehfest = Stehfest(ctx) + ctx._de_hoog = deHoog(ctx) + ctx._cohen = Cohen(ctx) + + def invertlaplace(ctx, f, t, **kwargs): + r"""Computes the numerical inverse Laplace transform for a + Laplace-space function at a given time. The function being + evaluated is assumed to be a real-valued function of time. + + The user must supply a Laplace-space function `\bar{f}(p)`, + and a desired time at which to estimate the time-domain + solution `f(t)`. + + A few basic examples of Laplace-space functions with known + inverses (see references [1,2]) : + + .. math :: + + \mathcal{L}\left\lbrace f(t) \right\rbrace=\bar{f}(p) + + .. math :: + + \mathcal{L}^{-1}\left\lbrace \bar{f}(p) \right\rbrace = f(t) + + .. math :: + + \bar{f}(p) = \frac{1}{(p+1)^2} + + .. math :: + + f(t) = t e^{-t} + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> tt = [0.001, 0.01, 0.1, 1, 10] + >>> fp = lambda p: 1/(p+1)**2 + >>> ft = lambda t: t*exp(-t) + >>> ft(tt[0]),ft(tt[0])-invertlaplace(fp,tt[0],method='talbot') + (0.000999000499833375, 8.57923043561212e-20) + >>> ft(tt[1]),ft(tt[1])-invertlaplace(fp,tt[1],method='talbot') + (0.00990049833749168, 3.27007646698047e-19) + >>> ft(tt[2]),ft(tt[2])-invertlaplace(fp,tt[2],method='talbot') + (0.090483741803596, -1.75215800052168e-18) + >>> ft(tt[3]),ft(tt[3])-invertlaplace(fp,tt[3],method='talbot') + (0.367879441171442, 1.2428864009344e-17) + >>> ft(tt[4]),ft(tt[4])-invertlaplace(fp,tt[4],method='talbot') + (0.000453999297624849, 4.04513489306658e-20) + + The methods also work for higher precision: + + >>> mp.dps = 100; mp.pretty = True + >>> nstr(ft(tt[0]),15),nstr(ft(tt[0])-invertlaplace(fp,tt[0],method='talbot'),15) + ('0.000999000499833375', '-4.96868310693356e-105') + >>> nstr(ft(tt[1]),15),nstr(ft(tt[1])-invertlaplace(fp,tt[1],method='talbot'),15) + ('0.00990049833749168', '1.23032291513122e-104') + + .. math :: + + \bar{f}(p) = \frac{1}{p^2+1} + + .. math :: + + f(t) = \mathrm{J}_0(t) + + >>> mp.dps = 15; mp.pretty = True + >>> fp = lambda p: 1/sqrt(p*p + 1) + >>> ft = lambda t: besselj(0,t) + >>> ft(tt[0]),ft(tt[0])-invertlaplace(fp,tt[0],method='dehoog') + (0.999999750000016, -6.09717765032273e-18) + >>> ft(tt[1]),ft(tt[1])-invertlaplace(fp,tt[1],method='dehoog') + (0.99997500015625, -5.61756281076169e-17) + + .. math :: + + \bar{f}(p) = \frac{\log p}{p} + + .. math :: + + f(t) = -\gamma -\log t + + >>> mp.dps = 15; mp.pretty = True + >>> fp = lambda p: log(p)/p + >>> ft = lambda t: -euler-log(t) + >>> ft(tt[0]),ft(tt[0])-invertlaplace(fp,tt[0],method='stehfest') + (6.3305396140806, -1.92126634837863e-16) + >>> ft(tt[1]),ft(tt[1])-invertlaplace(fp,tt[1],method='stehfest') + (4.02795452108656, -4.81486093200704e-16) + + **Options** + + :func:`~mpmath.invertlaplace` recognizes the following optional + keywords valid for all methods: + + *method* + Chooses numerical inverse Laplace transform algorithm + (described below). + *degree* + Number of terms used in the approximation + + **Algorithms** + + Mpmath implements four numerical inverse Laplace transform + algorithms, attributed to: Talbot, Stehfest, and de Hoog, + Knight and Stokes. These can be selected by using + *method='talbot'*, *method='stehfest'*, *method='dehoog'* or + *method='cohen'* or by passing the classes *method=FixedTalbot*, + *method=Stehfest*, *method=deHoog*, or *method=Cohen*. The functions + :func:`~mpmath.invlaptalbot`, :func:`~mpmath.invlapstehfest`, + :func:`~mpmath.invlapdehoog`, and :func:`~mpmath.invlapcohen` + are also available as shortcuts. + + All four algorithms implement a heuristic balance between the + requested precision and the precision used internally for the + calculations. This has been tuned for a typical exponentially + decaying function and precision up to few hundred decimal + digits. + + The Laplace transform converts the variable time (i.e., along + a line) into a parameter given by the right half of the + complex `p`-plane. Singularities, poles, and branch cuts in + the complex `p`-plane contain all the information regarding + the time behavior of the corresponding function. Any numerical + method must therefore sample `p`-plane "close enough" to the + singularities to accurately characterize them, while not + getting too close to have catastrophic cancellation, overflow, + or underflow issues. Most significantly, if one or more of the + singularities in the `p`-plane is not on the left side of the + Bromwich contour, its effects will be left out of the computed + solution, and the answer will be completely wrong. + + *Talbot* + + The fixed Talbot method is high accuracy and fast, but the + method can catastrophically fail for certain classes of time-domain + behavior, including a Heaviside step function for positive + time (e.g., `H(t-2)`), or some oscillatory behaviors. The + Talbot method usually has adjustable parameters, but the + "fixed" variety implemented here does not. This method + deforms the Bromwich integral contour in the shape of a + parabola towards `-\infty`, which leads to problems + when the solution has a decaying exponential in it (e.g., a + Heaviside step function is equivalent to multiplying by a + decaying exponential in Laplace space). + + *Stehfest* + + The Stehfest algorithm only uses abscissa along the real axis + of the complex `p`-plane to estimate the time-domain + function. Oscillatory time-domain functions have poles away + from the real axis, so this method does not work well with + oscillatory functions, especially high-frequency ones. This + method also depends on summation of terms in a series that + grows very large, and will have catastrophic cancellation + during summation if the working precision is too low. + + *de Hoog et al.* + + The de Hoog, Knight, and Stokes method is essentially a + Fourier-series quadrature-type approximation to the Bromwich + contour integral, with non-linear series acceleration and an + analytical expression for the remainder term. This method is + typically one of the most robust. This method also involves the + greatest amount of overhead, so it is typically the slowest of the + four methods at high precision. + + *Cohen* + + The Cohen method is a trapezoidal rule approximation to the Bromwich + contour integral, with linear acceleration for alternating + series. This method is as robust as the de Hoog et al method and the + fastest of the four methods at high precision, and is therefore the + default method. + + **Singularities** + + All numerical inverse Laplace transform methods have problems + at large time when the Laplace-space function has poles, + singularities, or branch cuts to the right of the origin in + the complex plane. For simple poles in `\bar{f}(p)` at the + `p`-plane origin, the time function is constant in time (e.g., + `\mathcal{L}\left\lbrace 1 \right\rbrace=1/p` has a pole at + `p=0`). A pole in `\bar{f}(p)` to the left of the origin is a + decreasing function of time (e.g., `\mathcal{L}\left\lbrace + e^{-t/2} \right\rbrace=1/(p+1/2)` has a pole at `p=-1/2`), and + a pole to the right of the origin leads to an increasing + function in time (e.g., `\mathcal{L}\left\lbrace t e^{t/4} + \right\rbrace = 1/(p-1/4)^2` has a pole at `p=1/4`). When + singularities occur off the real `p` axis, the time-domain + function is oscillatory. For example `\mathcal{L}\left\lbrace + \mathrm{J}_0(t) \right\rbrace=1/\sqrt{p^2+1}` has a branch cut + starting at `p=j=\sqrt{-1}` and is a decaying oscillatory + function, This range of behaviors is illustrated in Duffy [3] + Figure 4.10.4, p. 228. + + In general as `p \rightarrow \infty` `t \rightarrow 0` and + vice-versa. All numerical inverse Laplace transform methods + require their abscissa to shift closer to the origin for + larger times. If the abscissa shift left of the rightmost + singularity in the Laplace domain, the answer will be + completely wrong (the effect of singularities to the right of + the Bromwich contour are not included in the results). + + For example, the following exponentially growing function has + a pole at `p=3`: + + .. math :: + + \bar{f}(p)=\frac{1}{p^2-9} + + .. math :: + + f(t)=\frac{1}{3}\sinh 3t + + >>> mp.dps = 15; mp.pretty = True + >>> fp = lambda p: 1/(p*p-9) + >>> ft = lambda t: sinh(3*t)/3 + >>> tt = [0.01,0.1,1.0,10.0] + >>> ft(tt[0]),invertlaplace(fp,tt[0],method='talbot') + (0.0100015000675014, 0.0100015000675014) + >>> ft(tt[1]),invertlaplace(fp,tt[1],method='talbot') + (0.101506764482381, 0.101506764482381) + >>> ft(tt[2]),invertlaplace(fp,tt[2],method='talbot') + (3.33929164246997, 3.33929164246997) + >>> ft(tt[3]),invertlaplace(fp,tt[3],method='talbot') + (1781079096920.74, -1.61331069624091e-14) + + **References** + + 1. [DLMF]_ section 1.14 (http://dlmf.nist.gov/1.14T4) + 2. Cohen, A.M. (2007). Numerical Methods for Laplace Transform + Inversion, Springer. + 3. Duffy, D.G. (1998). Advanced Engineering Mathematics, CRC Press. + + **Numerical Inverse Laplace Transform Reviews** + + 1. Bellman, R., R.E. Kalaba, J.A. Lockett (1966). *Numerical + inversion of the Laplace transform: Applications to Biology, + Economics, Engineering, and Physics*. Elsevier. + 2. Davies, B., B. Martin (1979). Numerical inversion of the + Laplace transform: a survey and comparison of methods. *Journal + of Computational Physics* 33:1-32, + http://dx.doi.org/10.1016/0021-9991(79)90025-1 + 3. Duffy, D.G. (1993). On the numerical inversion of Laplace + transforms: Comparison of three new methods on characteristic + problems from applications. *ACM Transactions on Mathematical + Software* 19(3):333-359, http://dx.doi.org/10.1145/155743.155788 + 4. Kuhlman, K.L., (2013). Review of Inverse Laplace Transform + Algorithms for Laplace-Space Numerical Approaches, *Numerical + Algorithms*, 63(2):339-355. + http://dx.doi.org/10.1007/s11075-012-9625-3 + + """ + + rule = kwargs.get('method', 'cohen') + if type(rule) is str: + lrule = rule.lower() + if lrule == 'talbot': + rule = ctx._fixed_talbot + elif lrule == 'stehfest': + rule = ctx._stehfest + elif lrule == 'dehoog': + rule = ctx._de_hoog + elif rule == 'cohen': + rule = ctx._cohen + else: + raise ValueError("unknown invlap algorithm: %s" % rule) + else: + rule = rule(ctx) + + # determine the vector of Laplace-space parameter + # needed for the requested method and desired time + rule.calc_laplace_parameter(t, **kwargs) + + # compute the Laplace-space function evalutations + # at the required abscissa. + fp = [f(p) for p in rule.p] + + # compute the time-domain solution from the + # Laplace-space function evaluations + return rule.calc_time_domain_solution(fp, t) + + # shortcuts for the above function for specific methods + def invlaptalbot(ctx, *args, **kwargs): + kwargs['method'] = 'talbot' + return ctx.invertlaplace(*args, **kwargs) + + def invlapstehfest(ctx, *args, **kwargs): + kwargs['method'] = 'stehfest' + return ctx.invertlaplace(*args, **kwargs) + + def invlapdehoog(ctx, *args, **kwargs): + kwargs['method'] = 'dehoog' + return ctx.invertlaplace(*args, **kwargs) + + def invlapcohen(ctx, *args, **kwargs): + kwargs['method'] = 'cohen' + return ctx.invertlaplace(*args, **kwargs) + + +# **************************************** + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/odes.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/odes.py new file mode 100644 index 0000000000000000000000000000000000000000..ac6bd3cb056c8841e6cf77ba4d08a0b1abb2f2c9 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/odes.py @@ -0,0 +1,288 @@ +from bisect import bisect +from ..libmp.backend import xrange + +class ODEMethods(object): + pass + +def ode_taylor(ctx, derivs, x0, y0, tol_prec, n): + h = tol = ctx.ldexp(1, -tol_prec) + dim = len(y0) + xs = [x0] + ys = [y0] + x = x0 + y = y0 + orig = ctx.prec + try: + ctx.prec = orig*(1+n) + # Use n steps with Euler's method to get + # evaluation points for derivatives + for i in range(n): + fxy = derivs(x, y) + y = [y[i]+h*fxy[i] for i in xrange(len(y))] + x += h + xs.append(x) + ys.append(y) + # Compute derivatives + ser = [[] for d in range(dim)] + for j in range(n+1): + s = [0]*dim + b = (-1) ** (j & 1) + k = 1 + for i in range(j+1): + for d in range(dim): + s[d] += b * ys[i][d] + b = (b * (j-k+1)) // (-k) + k += 1 + scale = h**(-j) / ctx.fac(j) + for d in range(dim): + s[d] = s[d] * scale + ser[d].append(s[d]) + finally: + ctx.prec = orig + # Estimate radius for which we can get full accuracy. + # XXX: do this right for zeros + radius = ctx.one + for ts in ser: + if ts[-1]: + radius = min(radius, ctx.nthroot(tol/abs(ts[-1]), n)) + radius /= 2 # XXX + return ser, x0+radius + +def odefun(ctx, F, x0, y0, tol=None, degree=None, method='taylor', verbose=False): + r""" + Returns a function `y(x) = [y_0(x), y_1(x), \ldots, y_n(x)]` + that is a numerical solution of the `n+1`-dimensional first-order + ordinary differential equation (ODE) system + + .. math :: + + y_0'(x) = F_0(x, [y_0(x), y_1(x), \ldots, y_n(x)]) + + y_1'(x) = F_1(x, [y_0(x), y_1(x), \ldots, y_n(x)]) + + \vdots + + y_n'(x) = F_n(x, [y_0(x), y_1(x), \ldots, y_n(x)]) + + The derivatives are specified by the vector-valued function + *F* that evaluates + `[y_0', \ldots, y_n'] = F(x, [y_0, \ldots, y_n])`. + The initial point `x_0` is specified by the scalar argument *x0*, + and the initial value `y(x_0) = [y_0(x_0), \ldots, y_n(x_0)]` is + specified by the vector argument *y0*. + + For convenience, if the system is one-dimensional, you may optionally + provide just a scalar value for *y0*. In this case, *F* should accept + a scalar *y* argument and return a scalar. The solution function + *y* will return scalar values instead of length-1 vectors. + + Evaluation of the solution function `y(x)` is permitted + for any `x \ge x_0`. + + A high-order ODE can be solved by transforming it into first-order + vector form. This transformation is described in standard texts + on ODEs. Examples will also be given below. + + **Options, speed and accuracy** + + By default, :func:`~mpmath.odefun` uses a high-order Taylor series + method. For reasonably well-behaved problems, the solution will + be fully accurate to within the working precision. Note that + *F* must be possible to evaluate to very high precision + for the generation of Taylor series to work. + + To get a faster but less accurate solution, you can set a large + value for *tol* (which defaults roughly to *eps*). If you just + want to plot the solution or perform a basic simulation, + *tol = 0.01* is likely sufficient. + + The *degree* argument controls the degree of the solver (with + *method='taylor'*, this is the degree of the Taylor series + expansion). A higher degree means that a longer step can be taken + before a new local solution must be generated from *F*, + meaning that fewer steps are required to get from `x_0` to a given + `x_1`. On the other hand, a higher degree also means that each + local solution becomes more expensive (i.e., more evaluations of + *F* are required per step, and at higher precision). + + The optimal setting therefore involves a tradeoff. Generally, + decreasing the *degree* for Taylor series is likely to give faster + solution at low precision, while increasing is likely to be better + at higher precision. + + The function + object returned by :func:`~mpmath.odefun` caches the solutions at all step + points and uses polynomial interpolation between step points. + Therefore, once `y(x_1)` has been evaluated for some `x_1`, + `y(x)` can be evaluated very quickly for any `x_0 \le x \le x_1`. + and continuing the evaluation up to `x_2 > x_1` is also fast. + + **Examples of first-order ODEs** + + We will solve the standard test problem `y'(x) = y(x), y(0) = 1` + which has explicit solution `y(x) = \exp(x)`:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> f = odefun(lambda x, y: y, 0, 1) + >>> for x in [0, 1, 2.5]: + ... print((f(x), exp(x))) + ... + (1.0, 1.0) + (2.71828182845905, 2.71828182845905) + (12.1824939607035, 12.1824939607035) + + The solution with high precision:: + + >>> mp.dps = 50 + >>> f = odefun(lambda x, y: y, 0, 1) + >>> f(1) + 2.7182818284590452353602874713526624977572470937 + >>> exp(1) + 2.7182818284590452353602874713526624977572470937 + + Using the more general vectorized form, the test problem + can be input as (note that *f* returns a 1-element vector):: + + >>> mp.dps = 15 + >>> f = odefun(lambda x, y: [y[0]], 0, [1]) + >>> f(1) + [2.71828182845905] + + :func:`~mpmath.odefun` can solve nonlinear ODEs, which are generally + impossible (and at best difficult) to solve analytically. As + an example of a nonlinear ODE, we will solve `y'(x) = x \sin(y(x))` + for `y(0) = \pi/2`. An exact solution happens to be known + for this problem, and is given by + `y(x) = 2 \tan^{-1}\left(\exp\left(x^2/2\right)\right)`:: + + >>> f = odefun(lambda x, y: x*sin(y), 0, pi/2) + >>> for x in [2, 5, 10]: + ... print((f(x), 2*atan(exp(mpf(x)**2/2)))) + ... + (2.87255666284091, 2.87255666284091) + (3.14158520028345, 3.14158520028345) + (3.14159265358979, 3.14159265358979) + + If `F` is independent of `y`, an ODE can be solved using direct + integration. We can therefore obtain a reference solution with + :func:`~mpmath.quad`:: + + >>> f = lambda x: (1+x**2)/(1+x**3) + >>> g = odefun(lambda x, y: f(x), pi, 0) + >>> g(2*pi) + 0.72128263801696 + >>> quad(f, [pi, 2*pi]) + 0.72128263801696 + + **Examples of second-order ODEs** + + We will solve the harmonic oscillator equation `y''(x) + y(x) = 0`. + To do this, we introduce the helper functions `y_0 = y, y_1 = y_0'` + whereby the original equation can be written as `y_1' + y_0' = 0`. Put + together, we get the first-order, two-dimensional vector ODE + + .. math :: + + \begin{cases} + y_0' = y_1 \\ + y_1' = -y_0 + \end{cases} + + To get a well-defined IVP, we need two initial values. With + `y(0) = y_0(0) = 1` and `-y'(0) = y_1(0) = 0`, the problem will of + course be solved by `y(x) = y_0(x) = \cos(x)` and + `-y'(x) = y_1(x) = \sin(x)`. We check this:: + + >>> f = odefun(lambda x, y: [-y[1], y[0]], 0, [1, 0]) + >>> for x in [0, 1, 2.5, 10]: + ... nprint(f(x), 15) + ... nprint([cos(x), sin(x)], 15) + ... print("---") + ... + [1.0, 0.0] + [1.0, 0.0] + --- + [0.54030230586814, 0.841470984807897] + [0.54030230586814, 0.841470984807897] + --- + [-0.801143615546934, 0.598472144103957] + [-0.801143615546934, 0.598472144103957] + --- + [-0.839071529076452, -0.54402111088937] + [-0.839071529076452, -0.54402111088937] + --- + + Note that we get both the sine and the cosine solutions + simultaneously. + + **TODO** + + * Better automatic choice of degree and step size + * Make determination of Taylor series convergence radius + more robust + * Allow solution for `x < x_0` + * Allow solution for complex `x` + * Test for difficult (ill-conditioned) problems + * Implement Runge-Kutta and other algorithms + + """ + if tol: + tol_prec = int(-ctx.log(tol, 2))+10 + else: + tol_prec = ctx.prec+10 + degree = degree or (3 + int(3*ctx.dps/2.)) + workprec = ctx.prec + 40 + try: + len(y0) + return_vector = True + except TypeError: + F_ = F + F = lambda x, y: [F_(x, y[0])] + y0 = [y0] + return_vector = False + ser, xb = ode_taylor(ctx, F, x0, y0, tol_prec, degree) + series_boundaries = [x0, xb] + series_data = [(ser, x0, xb)] + # We will be working with vectors of Taylor series + def mpolyval(ser, a): + return [ctx.polyval(s[::-1], a) for s in ser] + # Find nearest expansion point; compute if necessary + def get_series(x): + if x < x0: + raise ValueError + n = bisect(series_boundaries, x) + if n < len(series_boundaries): + return series_data[n-1] + while 1: + ser, xa, xb = series_data[-1] + if verbose: + print("Computing Taylor series for [%f, %f]" % (xa, xb)) + y = mpolyval(ser, xb-xa) + xa = xb + ser, xb = ode_taylor(ctx, F, xb, y, tol_prec, degree) + series_boundaries.append(xb) + series_data.append((ser, xa, xb)) + if x <= xb: + return series_data[-1] + # Evaluation function + def interpolant(x): + x = ctx.convert(x) + orig = ctx.prec + try: + ctx.prec = workprec + ser, xa, xb = get_series(x) + y = mpolyval(ser, x-xa) + finally: + ctx.prec = orig + if return_vector: + return [+yk for yk in y] + else: + return +y[0] + return interpolant + +ODEMethods.odefun = odefun + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/optimization.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/optimization.py new file mode 100644 index 0000000000000000000000000000000000000000..69724f78336ee24856366db48917a47108b1b416 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/optimization.py @@ -0,0 +1,1102 @@ +from __future__ import print_function + +from copy import copy + +from ..libmp.backend import xrange + +class OptimizationMethods(object): + def __init__(ctx): + pass + +############## +# 1D-SOLVERS # +############## + +class Newton: + """ + 1d-solver generating pairs of approximative root and error. + + Needs starting points x0 close to the root. + + Pro: + + * converges fast + * sometimes more robust than secant with bad second starting point + + Contra: + + * converges slowly for multiple roots + * needs first derivative + * 2 function evaluations per iteration + """ + maxsteps = 20 + + def __init__(self, ctx, f, x0, **kwargs): + self.ctx = ctx + if len(x0) == 1: + self.x0 = x0[0] + else: + raise ValueError('expected 1 starting point, got %i' % len(x0)) + self.f = f + if not 'df' in kwargs: + def df(x): + return self.ctx.diff(f, x) + else: + df = kwargs['df'] + self.df = df + + def __iter__(self): + f = self.f + df = self.df + x0 = self.x0 + while True: + x1 = x0 - f(x0) / df(x0) + error = abs(x1 - x0) + x0 = x1 + yield (x1, error) + +class Secant: + """ + 1d-solver generating pairs of approximative root and error. + + Needs starting points x0 and x1 close to the root. + x1 defaults to x0 + 0.25. + + Pro: + + * converges fast + + Contra: + + * converges slowly for multiple roots + """ + maxsteps = 30 + + def __init__(self, ctx, f, x0, **kwargs): + self.ctx = ctx + if len(x0) == 1: + self.x0 = x0[0] + self.x1 = self.x0 + 0.25 + elif len(x0) == 2: + self.x0 = x0[0] + self.x1 = x0[1] + else: + raise ValueError('expected 1 or 2 starting points, got %i' % len(x0)) + self.f = f + + def __iter__(self): + f = self.f + x0 = self.x0 + x1 = self.x1 + f0 = f(x0) + while True: + f1 = f(x1) + l = x1 - x0 + if not l: + break + s = (f1 - f0) / l + if not s: + break + x0, x1 = x1, x1 - f1/s + f0 = f1 + yield x1, abs(l) + +class MNewton: + """ + 1d-solver generating pairs of approximative root and error. + + Needs starting point x0 close to the root. + Uses modified Newton's method that converges fast regardless of the + multiplicity of the root. + + Pro: + + * converges fast for multiple roots + + Contra: + + * needs first and second derivative of f + * 3 function evaluations per iteration + """ + maxsteps = 20 + + def __init__(self, ctx, f, x0, **kwargs): + self.ctx = ctx + if not len(x0) == 1: + raise ValueError('expected 1 starting point, got %i' % len(x0)) + self.x0 = x0[0] + self.f = f + if not 'df' in kwargs: + def df(x): + return self.ctx.diff(f, x) + else: + df = kwargs['df'] + self.df = df + if not 'd2f' in kwargs: + def d2f(x): + return self.ctx.diff(df, x) + else: + d2f = kwargs['df'] + self.d2f = d2f + + def __iter__(self): + x = self.x0 + f = self.f + df = self.df + d2f = self.d2f + while True: + prevx = x + fx = f(x) + if fx == 0: + break + dfx = df(x) + d2fx = d2f(x) + # x = x - F(x)/F'(x) with F(x) = f(x)/f'(x) + x -= fx / (dfx - fx * d2fx / dfx) + error = abs(x - prevx) + yield x, error + +class Halley: + """ + 1d-solver generating pairs of approximative root and error. + + Needs a starting point x0 close to the root. + Uses Halley's method with cubic convergence rate. + + Pro: + + * converges even faster the Newton's method + * useful when computing with *many* digits + + Contra: + + * needs first and second derivative of f + * 3 function evaluations per iteration + * converges slowly for multiple roots + """ + + maxsteps = 20 + + def __init__(self, ctx, f, x0, **kwargs): + self.ctx = ctx + if not len(x0) == 1: + raise ValueError('expected 1 starting point, got %i' % len(x0)) + self.x0 = x0[0] + self.f = f + if not 'df' in kwargs: + def df(x): + return self.ctx.diff(f, x) + else: + df = kwargs['df'] + self.df = df + if not 'd2f' in kwargs: + def d2f(x): + return self.ctx.diff(df, x) + else: + d2f = kwargs['df'] + self.d2f = d2f + + def __iter__(self): + x = self.x0 + f = self.f + df = self.df + d2f = self.d2f + while True: + prevx = x + fx = f(x) + dfx = df(x) + d2fx = d2f(x) + x -= 2*fx*dfx / (2*dfx**2 - fx*d2fx) + error = abs(x - prevx) + yield x, error + +class Muller: + """ + 1d-solver generating pairs of approximative root and error. + + Needs starting points x0, x1 and x2 close to the root. + x1 defaults to x0 + 0.25; x2 to x1 + 0.25. + Uses Muller's method that converges towards complex roots. + + Pro: + + * converges fast (somewhat faster than secant) + * can find complex roots + + Contra: + + * converges slowly for multiple roots + * may have complex values for real starting points and real roots + + http://en.wikipedia.org/wiki/Muller's_method + """ + maxsteps = 30 + + def __init__(self, ctx, f, x0, **kwargs): + self.ctx = ctx + if len(x0) == 1: + self.x0 = x0[0] + self.x1 = self.x0 + 0.25 + self.x2 = self.x1 + 0.25 + elif len(x0) == 2: + self.x0 = x0[0] + self.x1 = x0[1] + self.x2 = self.x1 + 0.25 + elif len(x0) == 3: + self.x0 = x0[0] + self.x1 = x0[1] + self.x2 = x0[2] + else: + raise ValueError('expected 1, 2 or 3 starting points, got %i' + % len(x0)) + self.f = f + self.verbose = kwargs['verbose'] + + def __iter__(self): + f = self.f + x0 = self.x0 + x1 = self.x1 + x2 = self.x2 + fx0 = f(x0) + fx1 = f(x1) + fx2 = f(x2) + while True: + # TODO: maybe refactoring with function for divided differences + # calculate divided differences + fx2x1 = (fx1 - fx2) / (x1 - x2) + fx2x0 = (fx0 - fx2) / (x0 - x2) + fx1x0 = (fx0 - fx1) / (x0 - x1) + w = fx2x1 + fx2x0 - fx1x0 + fx2x1x0 = (fx1x0 - fx2x1) / (x0 - x2) + if w == 0 and fx2x1x0 == 0: + if self.verbose: + print('canceled with') + print('x0 =', x0, ', x1 =', x1, 'and x2 =', x2) + break + x0 = x1 + fx0 = fx1 + x1 = x2 + fx1 = fx2 + # denominator should be as large as possible => choose sign + r = self.ctx.sqrt(w**2 - 4*fx2*fx2x1x0) + if abs(w - r) > abs(w + r): + r = -r + x2 -= 2*fx2 / (w + r) + fx2 = f(x2) + error = abs(x2 - x1) + yield x2, error + +# TODO: consider raising a ValueError when there's no sign change in a and b +class Bisection: + """ + 1d-solver generating pairs of approximative root and error. + + Uses bisection method to find a root of f in [a, b]. + Might fail for multiple roots (needs sign change). + + Pro: + + * robust and reliable + + Contra: + + * converges slowly + * needs sign change + """ + maxsteps = 100 + + def __init__(self, ctx, f, x0, **kwargs): + self.ctx = ctx + if len(x0) != 2: + raise ValueError('expected interval of 2 points, got %i' % len(x0)) + self.f = f + self.a = x0[0] + self.b = x0[1] + + def __iter__(self): + f = self.f + a = self.a + b = self.b + l = b - a + fb = f(b) + while True: + m = self.ctx.ldexp(a + b, -1) + fm = f(m) + sign = fm * fb + if sign < 0: + a = m + elif sign > 0: + b = m + fb = fm + else: + yield m, self.ctx.zero + l /= 2 + yield (a + b)/2, abs(l) + +def _getm(method): + """ + Return a function to calculate m for Illinois-like methods. + """ + if method == 'illinois': + def getm(fz, fb): + return 0.5 + elif method == 'pegasus': + def getm(fz, fb): + return fb/(fb + fz) + elif method == 'anderson': + def getm(fz, fb): + m = 1 - fz/fb + if m > 0: + return m + else: + return 0.5 + else: + raise ValueError("method '%s' not recognized" % method) + return getm + +class Illinois: + """ + 1d-solver generating pairs of approximative root and error. + + Uses Illinois method or similar to find a root of f in [a, b]. + Might fail for multiple roots (needs sign change). + Combines bisect with secant (improved regula falsi). + + The only difference between the methods is the scaling factor m, which is + used to ensure convergence (you can choose one using the 'method' keyword): + + Illinois method ('illinois'): + m = 0.5 + + Pegasus method ('pegasus'): + m = fb/(fb + fz) + + Anderson-Bjoerk method ('anderson'): + m = 1 - fz/fb if positive else 0.5 + + Pro: + + * converges very fast + + Contra: + + * has problems with multiple roots + * needs sign change + """ + maxsteps = 30 + + def __init__(self, ctx, f, x0, **kwargs): + self.ctx = ctx + if len(x0) != 2: + raise ValueError('expected interval of 2 points, got %i' % len(x0)) + self.a = x0[0] + self.b = x0[1] + self.f = f + self.tol = kwargs['tol'] + self.verbose = kwargs['verbose'] + self.method = kwargs.get('method', 'illinois') + self.getm = _getm(self.method) + if self.verbose: + print('using %s method' % self.method) + + def __iter__(self): + method = self.method + f = self.f + a = self.a + b = self.b + fa = f(a) + fb = f(b) + m = None + while True: + l = b - a + if l == 0: + break + s = (fb - fa) / l + z = a - fa/s + fz = f(z) + if abs(fz) < self.tol: + # TODO: better condition (when f is very flat) + if self.verbose: + print('canceled with z =', z) + yield z, l + break + if fz * fb < 0: # root in [z, b] + a = b + fa = fb + b = z + fb = fz + else: # root in [a, z] + m = self.getm(fz, fb) + b = z + fb = fz + fa = m*fa # scale down to ensure convergence + if self.verbose and m and not method == 'illinois': + print('m:', m) + yield (a + b)/2, abs(l) + +def Pegasus(*args, **kwargs): + """ + 1d-solver generating pairs of approximative root and error. + + Uses Pegasus method to find a root of f in [a, b]. + Wrapper for illinois to use method='pegasus'. + """ + kwargs['method'] = 'pegasus' + return Illinois(*args, **kwargs) + +def Anderson(*args, **kwargs): + """ + 1d-solver generating pairs of approximative root and error. + + Uses Anderson-Bjoerk method to find a root of f in [a, b]. + Wrapper for illinois to use method='pegasus'. + """ + kwargs['method'] = 'anderson' + return Illinois(*args, **kwargs) + +# TODO: check whether it's possible to combine it with Illinois stuff +class Ridder: + """ + 1d-solver generating pairs of approximative root and error. + + Ridders' method to find a root of f in [a, b]. + Is told to perform as well as Brent's method while being simpler. + + Pro: + + * very fast + * simpler than Brent's method + + Contra: + + * two function evaluations per step + * has problems with multiple roots + * needs sign change + + http://en.wikipedia.org/wiki/Ridders'_method + """ + maxsteps = 30 + + def __init__(self, ctx, f, x0, **kwargs): + self.ctx = ctx + self.f = f + if len(x0) != 2: + raise ValueError('expected interval of 2 points, got %i' % len(x0)) + self.x1 = x0[0] + self.x2 = x0[1] + self.verbose = kwargs['verbose'] + self.tol = kwargs['tol'] + + def __iter__(self): + ctx = self.ctx + f = self.f + x1 = self.x1 + fx1 = f(x1) + x2 = self.x2 + fx2 = f(x2) + while True: + x3 = 0.5*(x1 + x2) + fx3 = f(x3) + x4 = x3 + (x3 - x1) * ctx.sign(fx1 - fx2) * fx3 / ctx.sqrt(fx3**2 - fx1*fx2) + fx4 = f(x4) + if abs(fx4) < self.tol: + # TODO: better condition (when f is very flat) + if self.verbose: + print('canceled with f(x4) =', fx4) + yield x4, abs(x1 - x2) + break + if fx4 * fx2 < 0: # root in [x4, x2] + x1 = x4 + fx1 = fx4 + else: # root in [x1, x4] + x2 = x4 + fx2 = fx4 + error = abs(x1 - x2) + yield (x1 + x2)/2, error + +class ANewton: + """ + EXPERIMENTAL 1d-solver generating pairs of approximative root and error. + + Uses Newton's method modified to use Steffensens method when convergence is + slow. (I.e. for multiple roots.) + """ + maxsteps = 20 + + def __init__(self, ctx, f, x0, **kwargs): + self.ctx = ctx + if not len(x0) == 1: + raise ValueError('expected 1 starting point, got %i' % len(x0)) + self.x0 = x0[0] + self.f = f + if not 'df' in kwargs: + def df(x): + return self.ctx.diff(f, x) + else: + df = kwargs['df'] + self.df = df + def phi(x): + return x - f(x) / df(x) + self.phi = phi + self.verbose = kwargs['verbose'] + + def __iter__(self): + x0 = self.x0 + f = self.f + df = self.df + phi = self.phi + error = 0 + counter = 0 + while True: + prevx = x0 + try: + x0 = phi(x0) + except ZeroDivisionError: + if self.verbose: + print('ZeroDivisionError: canceled with x =', x0) + break + preverror = error + error = abs(prevx - x0) + # TODO: decide not to use convergence acceleration + if error and abs(error - preverror) / error < 1: + if self.verbose: + print('converging slowly') + counter += 1 + if counter >= 3: + # accelerate convergence + phi = steffensen(phi) + counter = 0 + if self.verbose: + print('accelerating convergence') + yield x0, error + +# TODO: add Brent + +############################ +# MULTIDIMENSIONAL SOLVERS # +############################ + +def jacobian(ctx, f, x): + """ + Calculate the Jacobian matrix of a function at the point x0. + + This is the first derivative of a vectorial function: + + f : R^m -> R^n with m >= n + """ + x = ctx.matrix(x) + h = ctx.sqrt(ctx.eps) + fx = ctx.matrix(f(*x)) + m = len(fx) + n = len(x) + J = ctx.matrix(m, n) + for j in xrange(n): + xj = x.copy() + xj[j] += h + Jj = (ctx.matrix(f(*xj)) - fx) / h + for i in xrange(m): + J[i,j] = Jj[i] + return J + +# TODO: test with user-specified jacobian matrix +class MDNewton: + """ + Find the root of a vector function numerically using Newton's method. + + f is a vector function representing a nonlinear equation system. + + x0 is the starting point close to the root. + + J is a function returning the Jacobian matrix for a point. + + Supports overdetermined systems. + + Use the 'norm' keyword to specify which norm to use. Defaults to max-norm. + The function to calculate the Jacobian matrix can be given using the + keyword 'J'. Otherwise it will be calculated numerically. + + Please note that this method converges only locally. Especially for high- + dimensional systems it is not trivial to find a good starting point being + close enough to the root. + + It is recommended to use a faster, low-precision solver from SciPy [1] or + OpenOpt [2] to get an initial guess. Afterwards you can use this method for + root-polishing to any precision. + + [1] http://scipy.org + + [2] http://openopt.org/Welcome + """ + maxsteps = 10 + + def __init__(self, ctx, f, x0, **kwargs): + self.ctx = ctx + self.f = f + if isinstance(x0, (tuple, list)): + x0 = ctx.matrix(x0) + assert x0.cols == 1, 'need a vector' + self.x0 = x0 + if 'J' in kwargs: + self.J = kwargs['J'] + else: + def J(*x): + return ctx.jacobian(f, x) + self.J = J + self.norm = kwargs['norm'] + self.verbose = kwargs['verbose'] + + def __iter__(self): + f = self.f + x0 = self.x0 + norm = self.norm + J = self.J + fx = self.ctx.matrix(f(*x0)) + fxnorm = norm(fx) + cancel = False + while not cancel: + # get direction of descent + fxn = -fx + Jx = J(*x0) + s = self.ctx.lu_solve(Jx, fxn) + if self.verbose: + print('Jx:') + print(Jx) + print('s:', s) + # damping step size TODO: better strategy (hard task) + l = self.ctx.one + x1 = x0 + s + while True: + if x1 == x0: + if self.verbose: + print("canceled, won't get more excact") + cancel = True + break + fx = self.ctx.matrix(f(*x1)) + newnorm = norm(fx) + if newnorm < fxnorm: + # new x accepted + fxnorm = newnorm + x0 = x1 + break + l /= 2 + x1 = x0 + l*s + yield (x0, fxnorm) + +############# +# UTILITIES # +############# + +str2solver = {'newton':Newton, 'secant':Secant, 'mnewton':MNewton, + 'halley':Halley, 'muller':Muller, 'bisect':Bisection, + 'illinois':Illinois, 'pegasus':Pegasus, 'anderson':Anderson, + 'ridder':Ridder, 'anewton':ANewton, 'mdnewton':MDNewton} + +def findroot(ctx, f, x0, solver='secant', tol=None, verbose=False, verify=True, **kwargs): + r""" + Find an approximate solution to `f(x) = 0`, using *x0* as starting point or + interval for *x*. + + Multidimensional overdetermined systems are supported. + You can specify them using a function or a list of functions. + + Mathematically speaking, this function returns `x` such that + `|f(x)|^2 \leq \mathrm{tol}` is true within the current working precision. + If the computed value does not meet this criterion, an exception is raised. + This exception can be disabled with *verify=False*. + + For interval arithmetic (``iv.findroot()``), please note that + the returned interval ``x`` is not guaranteed to contain `f(x)=0`! + It is only some `x` for which `|f(x)|^2 \leq \mathrm{tol}` certainly holds + regardless of numerical error. This may be improved in the future. + + **Arguments** + + *f* + one dimensional function + *x0* + starting point, several starting points or interval (depends on solver) + *tol* + the returned solution has an error smaller than this + *verbose* + print additional information for each iteration if true + *verify* + verify the solution and raise a ValueError if `|f(x)|^2 > \mathrm{tol}` + *solver* + a generator for *f* and *x0* returning approximative solution and error + *maxsteps* + after how many steps the solver will cancel + *df* + first derivative of *f* (used by some solvers) + *d2f* + second derivative of *f* (used by some solvers) + *multidimensional* + force multidimensional solving + *J* + Jacobian matrix of *f* (used by multidimensional solvers) + *norm* + used vector norm (used by multidimensional solvers) + + solver has to be callable with ``(f, x0, **kwargs)`` and return an generator + yielding pairs of approximative solution and estimated error (which is + expected to be positive). + You can use the following string aliases: + 'secant', 'mnewton', 'halley', 'muller', 'illinois', 'pegasus', 'anderson', + 'ridder', 'anewton', 'bisect' + + See mpmath.calculus.optimization for their documentation. + + **Examples** + + The function :func:`~mpmath.findroot` locates a root of a given function using the + secant method by default. A simple example use of the secant method is to + compute `\pi` as the root of `\sin x` closest to `x_0 = 3`:: + + >>> from mpmath import * + >>> mp.dps = 30; mp.pretty = True + >>> findroot(sin, 3) + 3.14159265358979323846264338328 + + The secant method can be used to find complex roots of analytic functions, + although it must in that case generally be given a nonreal starting value + (or else it will never leave the real line):: + + >>> mp.dps = 15 + >>> findroot(lambda x: x**3 + 2*x + 1, j) + (0.226698825758202 + 1.46771150871022j) + + A nice application is to compute nontrivial roots of the Riemann zeta + function with many digits (good initial values are needed for convergence):: + + >>> mp.dps = 30 + >>> findroot(zeta, 0.5+14j) + (0.5 + 14.1347251417346937904572519836j) + + The secant method can also be used as an optimization algorithm, by passing + it a derivative of a function. The following example locates the positive + minimum of the gamma function:: + + >>> mp.dps = 20 + >>> findroot(lambda x: diff(gamma, x), 1) + 1.4616321449683623413 + + Finally, a useful application is to compute inverse functions, such as the + Lambert W function which is the inverse of `w e^w`, given the first + term of the solution's asymptotic expansion as the initial value. In basic + cases, this gives identical results to mpmath's built-in ``lambertw`` + function:: + + >>> def lambert(x): + ... return findroot(lambda w: w*exp(w) - x, log(1+x)) + ... + >>> mp.dps = 15 + >>> lambert(1); lambertw(1) + 0.567143290409784 + 0.567143290409784 + >>> lambert(1000); lambert(1000) + 5.2496028524016 + 5.2496028524016 + + Multidimensional functions are also supported:: + + >>> f = [lambda x1, x2: x1**2 + x2, + ... lambda x1, x2: 5*x1**2 - 3*x1 + 2*x2 - 3] + >>> findroot(f, (0, 0)) + [-0.618033988749895] + [-0.381966011250105] + >>> findroot(f, (10, 10)) + [ 1.61803398874989] + [-2.61803398874989] + + You can verify this by solving the system manually. + + Please note that the following (more general) syntax also works:: + + >>> def f(x1, x2): + ... return x1**2 + x2, 5*x1**2 - 3*x1 + 2*x2 - 3 + ... + >>> findroot(f, (0, 0)) + [-0.618033988749895] + [-0.381966011250105] + + + **Multiple roots** + + For multiple roots all methods of the Newtonian family (including secant) + converge slowly. Consider this example:: + + >>> f = lambda x: (x - 1)**99 + >>> findroot(f, 0.9, verify=False) + 0.918073542444929 + + Even for a very close starting point the secant method converges very + slowly. Use ``verbose=True`` to illustrate this. + + It is possible to modify Newton's method to make it converge regardless of + the root's multiplicity:: + + >>> findroot(f, -10, solver='mnewton') + 1.0 + + This variant uses the first and second derivative of the function, which is + not very efficient. + + Alternatively you can use an experimental Newtonian solver that keeps track + of the speed of convergence and accelerates it using Steffensen's method if + necessary:: + + >>> findroot(f, -10, solver='anewton', verbose=True) + x: -9.88888888888888888889 + error: 0.111111111111111111111 + converging slowly + x: -9.77890011223344556678 + error: 0.10998877665544332211 + converging slowly + x: -9.67002233332199662166 + error: 0.108877778911448945119 + converging slowly + accelerating convergence + x: -9.5622443299551077669 + error: 0.107778003366888854764 + converging slowly + x: 0.99999999999999999214 + error: 10.562244329955107759 + x: 1.0 + error: 7.8598304758094664213e-18 + ZeroDivisionError: canceled with x = 1.0 + 1.0 + + **Complex roots** + + For complex roots it's recommended to use Muller's method as it converges + even for real starting points very fast:: + + >>> findroot(lambda x: x**4 + x + 1, (0, 1, 2), solver='muller') + (0.727136084491197 + 0.934099289460529j) + + + **Intersection methods** + + When you need to find a root in a known interval, it's highly recommended to + use an intersection-based solver like ``'anderson'`` or ``'ridder'``. + Usually they converge faster and more reliable. They have however problems + with multiple roots and usually need a sign change to find a root:: + + >>> findroot(lambda x: x**3, (-1, 1), solver='anderson') + 0.0 + + Be careful with symmetric functions:: + + >>> findroot(lambda x: x**2, (-1, 1), solver='anderson') #doctest:+ELLIPSIS + Traceback (most recent call last): + ... + ZeroDivisionError + + It fails even for better starting points, because there is no sign change:: + + >>> findroot(lambda x: x**2, (-1, .5), solver='anderson') + Traceback (most recent call last): + ... + ValueError: Could not find root within given tolerance. (1.0 > 2.16840434497100886801e-19) + Try another starting point or tweak arguments. + + """ + prec = ctx.prec + try: + ctx.prec += 20 + + # initialize arguments + if tol is None: + tol = ctx.eps * 2**10 + + kwargs['verbose'] = kwargs.get('verbose', verbose) + + if 'd1f' in kwargs: + kwargs['df'] = kwargs['d1f'] + + kwargs['tol'] = tol + if isinstance(x0, (list, tuple)): + x0 = [ctx.convert(x) for x in x0] + else: + x0 = [ctx.convert(x0)] + + if isinstance(solver, str): + try: + solver = str2solver[solver] + except KeyError: + raise ValueError('could not recognize solver') + + # accept list of functions + if isinstance(f, (list, tuple)): + f2 = copy(f) + def tmp(*args): + return [fn(*args) for fn in f2] + f = tmp + + # detect multidimensional functions + try: + fx = f(*x0) + multidimensional = isinstance(fx, (list, tuple, ctx.matrix)) + except TypeError: + fx = f(x0[0]) + multidimensional = False + if 'multidimensional' in kwargs: + multidimensional = kwargs['multidimensional'] + if multidimensional: + # only one multidimensional solver available at the moment + solver = MDNewton + if not 'norm' in kwargs: + norm = lambda x: ctx.norm(x, 'inf') + kwargs['norm'] = norm + else: + norm = kwargs['norm'] + else: + norm = abs + + # happily return starting point if it's a root + if norm(fx) == 0: + if multidimensional: + return ctx.matrix(x0) + else: + return x0[0] + + # use solver + iterations = solver(ctx, f, x0, **kwargs) + if 'maxsteps' in kwargs: + maxsteps = kwargs['maxsteps'] + else: + maxsteps = iterations.maxsteps + i = 0 + for x, error in iterations: + if verbose: + print('x: ', x) + print('error:', error) + i += 1 + if error < tol * max(1, norm(x)) or i >= maxsteps: + break + else: + if not i: + raise ValueError('Could not find root using the given solver.\n' + 'Try another starting point or tweak arguments.') + if not isinstance(x, (list, tuple, ctx.matrix)): + xl = [x] + else: + xl = x + if verify and norm(f(*xl))**2 > tol: # TODO: better condition? + raise ValueError('Could not find root within given tolerance. ' + '(%s > %s)\n' + 'Try another starting point or tweak arguments.' + % (norm(f(*xl))**2, tol)) + return x + finally: + ctx.prec = prec + + +def multiplicity(ctx, f, root, tol=None, maxsteps=10, **kwargs): + """ + Return the multiplicity of a given root of f. + + Internally, numerical derivatives are used. This might be inefficient for + higher order derviatives. Due to this, ``multiplicity`` cancels after + evaluating 10 derivatives by default. You can be specify the n-th derivative + using the dnf keyword. + + >>> from mpmath import * + >>> multiplicity(lambda x: sin(x) - 1, pi/2) + 2 + + """ + if tol is None: + tol = ctx.eps ** 0.8 + kwargs['d0f'] = f + for i in xrange(maxsteps): + dfstr = 'd' + str(i) + 'f' + if dfstr in kwargs: + df = kwargs[dfstr] + else: + df = lambda x: ctx.diff(f, x, i) + if not abs(df(root)) < tol: + break + return i + +def steffensen(f): + """ + linear convergent function -> quadratic convergent function + + Steffensen's method for quadratic convergence of a linear converging + sequence. + Don not use it for higher rates of convergence. + It may even work for divergent sequences. + + Definition: + F(x) = (x*f(f(x)) - f(x)**2) / (f(f(x)) - 2*f(x) + x) + + Example + ....... + + You can use Steffensen's method to accelerate a fixpoint iteration of linear + (or less) convergence. + + x* is a fixpoint of the iteration x_{k+1} = phi(x_k) if x* = phi(x*). For + phi(x) = x**2 there are two fixpoints: 0 and 1. + + Let's try Steffensen's method: + + >>> f = lambda x: x**2 + >>> from mpmath.calculus.optimization import steffensen + >>> F = steffensen(f) + >>> for x in [0.5, 0.9, 2.0]: + ... fx = Fx = x + ... for i in xrange(9): + ... try: + ... fx = f(fx) + ... except OverflowError: + ... pass + ... try: + ... Fx = F(Fx) + ... except ZeroDivisionError: + ... pass + ... print('%20g %20g' % (fx, Fx)) + 0.25 -0.5 + 0.0625 0.1 + 0.00390625 -0.0011236 + 1.52588e-05 1.41691e-09 + 2.32831e-10 -2.84465e-27 + 5.42101e-20 2.30189e-80 + 2.93874e-39 -1.2197e-239 + 8.63617e-78 0 + 7.45834e-155 0 + 0.81 1.02676 + 0.6561 1.00134 + 0.430467 1 + 0.185302 1 + 0.0343368 1 + 0.00117902 1 + 1.39008e-06 1 + 1.93233e-12 1 + 3.73392e-24 1 + 4 1.6 + 16 1.2962 + 256 1.10194 + 65536 1.01659 + 4.29497e+09 1.00053 + 1.84467e+19 1 + 3.40282e+38 1 + 1.15792e+77 1 + 1.34078e+154 1 + + Unmodified, the iteration converges only towards 0. Modified it converges + not only much faster, it converges even to the repelling fixpoint 1. + """ + def F(x): + fx = f(x) + ffx = f(fx) + return (x*ffx - fx**2) / (ffx - 2*fx + x) + return F + +OptimizationMethods.jacobian = jacobian +OptimizationMethods.findroot = findroot +OptimizationMethods.multiplicity = multiplicity + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/polynomials.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/polynomials.py new file mode 100644 index 0000000000000000000000000000000000000000..ba75c1e88cbc5d40aa590a786c0af5229f193103 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/polynomials.py @@ -0,0 +1,213 @@ +from ..libmp.backend import xrange +from .calculus import defun + +#----------------------------------------------------------------------------# +# Polynomials # +#----------------------------------------------------------------------------# + +# XXX: extra precision +@defun +def polyval(ctx, coeffs, x, derivative=False): + r""" + Given coefficients `[c_n, \ldots, c_2, c_1, c_0]` and a number `x`, + :func:`~mpmath.polyval` evaluates the polynomial + + .. math :: + + P(x) = c_n x^n + \ldots + c_2 x^2 + c_1 x + c_0. + + If *derivative=True* is set, :func:`~mpmath.polyval` simultaneously + evaluates `P(x)` with the derivative, `P'(x)`, and returns the + tuple `(P(x), P'(x))`. + + >>> from mpmath import * + >>> mp.pretty = True + >>> polyval([3, 0, 2], 0.5) + 2.75 + >>> polyval([3, 0, 2], 0.5, derivative=True) + (2.75, 3.0) + + The coefficients and the evaluation point may be any combination + of real or complex numbers. + """ + if not coeffs: + return ctx.zero + p = ctx.convert(coeffs[0]) + q = ctx.zero + for c in coeffs[1:]: + if derivative: + q = p + x*q + p = c + x*p + if derivative: + return p, q + else: + return p + +@defun +def polyroots(ctx, coeffs, maxsteps=50, cleanup=True, extraprec=10, + error=False, roots_init=None): + """ + Computes all roots (real or complex) of a given polynomial. + + The roots are returned as a sorted list, where real roots appear first + followed by complex conjugate roots as adjacent elements. The polynomial + should be given as a list of coefficients, in the format used by + :func:`~mpmath.polyval`. The leading coefficient must be nonzero. + + With *error=True*, :func:`~mpmath.polyroots` returns a tuple *(roots, err)* + where *err* is an estimate of the maximum error among the computed roots. + + **Examples** + + Finding the three real roots of `x^3 - x^2 - 14x + 24`:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> nprint(polyroots([1,-1,-14,24]), 4) + [-4.0, 2.0, 3.0] + + Finding the two complex conjugate roots of `4x^2 + 3x + 2`, with an + error estimate:: + + >>> roots, err = polyroots([4,3,2], error=True) + >>> for r in roots: + ... print(r) + ... + (-0.375 + 0.59947894041409j) + (-0.375 - 0.59947894041409j) + >>> + >>> err + 2.22044604925031e-16 + >>> + >>> polyval([4,3,2], roots[0]) + (2.22044604925031e-16 + 0.0j) + >>> polyval([4,3,2], roots[1]) + (2.22044604925031e-16 + 0.0j) + + The following example computes all the 5th roots of unity; that is, + the roots of `x^5 - 1`:: + + >>> mp.dps = 20 + >>> for r in polyroots([1, 0, 0, 0, 0, -1]): + ... print(r) + ... + 1.0 + (-0.8090169943749474241 + 0.58778525229247312917j) + (-0.8090169943749474241 - 0.58778525229247312917j) + (0.3090169943749474241 + 0.95105651629515357212j) + (0.3090169943749474241 - 0.95105651629515357212j) + + **Precision and conditioning** + + The roots are computed to the current working precision accuracy. If this + accuracy cannot be achieved in ``maxsteps`` steps, then a + ``NoConvergence`` exception is raised. The algorithm internally is using + the current working precision extended by ``extraprec``. If + ``NoConvergence`` was raised, that is caused either by not having enough + extra precision to achieve convergence (in which case increasing + ``extraprec`` should fix the problem) or too low ``maxsteps`` (in which + case increasing ``maxsteps`` should fix the problem), or a combination of + both. + + The user should always do a convergence study with regards to + ``extraprec`` to ensure accurate results. It is possible to get + convergence to a wrong answer with too low ``extraprec``. + + Provided there are no repeated roots, :func:`~mpmath.polyroots` can + typically compute all roots of an arbitrary polynomial to high precision:: + + >>> mp.dps = 60 + >>> for r in polyroots([1, 0, -10, 0, 1]): + ... print(r) + ... + -3.14626436994197234232913506571557044551247712918732870123249 + -0.317837245195782244725757617296174288373133378433432554879127 + 0.317837245195782244725757617296174288373133378433432554879127 + 3.14626436994197234232913506571557044551247712918732870123249 + >>> + >>> sqrt(3) + sqrt(2) + 3.14626436994197234232913506571557044551247712918732870123249 + >>> sqrt(3) - sqrt(2) + 0.317837245195782244725757617296174288373133378433432554879127 + + **Algorithm** + + :func:`~mpmath.polyroots` implements the Durand-Kerner method [1], which + uses complex arithmetic to locate all roots simultaneously. + The Durand-Kerner method can be viewed as approximately performing + simultaneous Newton iteration for all the roots. In particular, + the convergence to simple roots is quadratic, just like Newton's + method. + + Although all roots are internally calculated using complex arithmetic, any + root found to have an imaginary part smaller than the estimated numerical + error is truncated to a real number (small real parts are also chopped). + Real roots are placed first in the returned list, sorted by value. The + remaining complex roots are sorted by their real parts so that conjugate + roots end up next to each other. + + **References** + + 1. http://en.wikipedia.org/wiki/Durand-Kerner_method + + """ + if len(coeffs) <= 1: + if not coeffs or not coeffs[0]: + raise ValueError("Input to polyroots must not be the zero polynomial") + # Constant polynomial with no roots + return [] + + orig = ctx.prec + tol = +ctx.eps + with ctx.extraprec(extraprec): + deg = len(coeffs) - 1 + # Must be monic + lead = ctx.convert(coeffs[0]) + if lead == 1: + coeffs = [ctx.convert(c) for c in coeffs] + else: + coeffs = [c/lead for c in coeffs] + f = lambda x: ctx.polyval(coeffs, x) + if roots_init is None: + roots = [ctx.mpc((0.4+0.9j)**n) for n in xrange(deg)] + else: + roots = [None]*deg; + deg_init = min(deg, len(roots_init)) + roots[:deg_init] = list(roots_init[:deg_init]) + roots[deg_init:] = [ctx.mpc((0.4+0.9j)**n) for n + in xrange(deg_init,deg)] + err = [ctx.one for n in xrange(deg)] + # Durand-Kerner iteration until convergence + for step in xrange(maxsteps): + if abs(max(err)) < tol: + break + for i in xrange(deg): + p = roots[i] + x = f(p) + for j in range(deg): + if i != j: + try: + x /= (p-roots[j]) + except ZeroDivisionError: + continue + roots[i] = p - x + err[i] = abs(x) + if abs(max(err)) >= tol: + raise ctx.NoConvergence("Didn't converge in maxsteps=%d steps." \ + % maxsteps) + # Remove small real or imaginary parts + if cleanup: + for i in xrange(deg): + if abs(roots[i]) < tol: + roots[i] = ctx.zero + elif abs(ctx._im(roots[i])) < tol: + roots[i] = roots[i].real + elif abs(ctx._re(roots[i])) < tol: + roots[i] = roots[i].imag * 1j + roots.sort(key=lambda x: (abs(ctx._im(x)), ctx._re(x))) + if error: + err = max(err) + err = max(err, ctx.ldexp(1, -orig+1)) + return [+r for r in roots], +err + else: + return [+r for r in roots] diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/quadrature.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/quadrature.py new file mode 100644 index 0000000000000000000000000000000000000000..0545b3ad3e6f70a44f4ec31a0c3bcfb4ffde422b --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/calculus/quadrature.py @@ -0,0 +1,1115 @@ +import math + +from ..libmp.backend import xrange + +class QuadratureRule(object): + """ + Quadrature rules are implemented using this class, in order to + simplify the code and provide a common infrastructure + for tasks such as error estimation and node caching. + + You can implement a custom quadrature rule by subclassing + :class:`QuadratureRule` and implementing the appropriate + methods. The subclass can then be used by :func:`~mpmath.quad` by + passing it as the *method* argument. + + :class:`QuadratureRule` instances are supposed to be singletons. + :class:`QuadratureRule` therefore implements instance caching + in :func:`~mpmath.__new__`. + """ + + def __init__(self, ctx): + self.ctx = ctx + self.standard_cache = {} + self.transformed_cache = {} + self.interval_count = {} + + def clear(self): + """ + Delete cached node data. + """ + self.standard_cache = {} + self.transformed_cache = {} + self.interval_count = {} + + def calc_nodes(self, degree, prec, verbose=False): + r""" + Compute nodes for the standard interval `[-1, 1]`. Subclasses + should probably implement only this method, and use + :func:`~mpmath.get_nodes` method to retrieve the nodes. + """ + raise NotImplementedError + + def get_nodes(self, a, b, degree, prec, verbose=False): + """ + Return nodes for given interval, degree and precision. The + nodes are retrieved from a cache if already computed; + otherwise they are computed by calling :func:`~mpmath.calc_nodes` + and are then cached. + + Subclasses should probably not implement this method, + but just implement :func:`~mpmath.calc_nodes` for the actual + node computation. + """ + key = (a, b, degree, prec) + if key in self.transformed_cache: + return self.transformed_cache[key] + orig = self.ctx.prec + try: + self.ctx.prec = prec+20 + # Get nodes on standard interval + if (degree, prec) in self.standard_cache: + nodes = self.standard_cache[degree, prec] + else: + nodes = self.calc_nodes(degree, prec, verbose) + self.standard_cache[degree, prec] = nodes + # Transform to general interval + nodes = self.transform_nodes(nodes, a, b, verbose) + if key in self.interval_count: + self.transformed_cache[key] = nodes + else: + self.interval_count[key] = True + finally: + self.ctx.prec = orig + return nodes + + def transform_nodes(self, nodes, a, b, verbose=False): + r""" + Rescale standardized nodes (for `[-1, 1]`) to a general + interval `[a, b]`. For a finite interval, a simple linear + change of variables is used. Otherwise, the following + transformations are used: + + .. math :: + + \lbrack a, \infty \rbrack : t = \frac{1}{x} + (a-1) + + \lbrack -\infty, b \rbrack : t = (b+1) - \frac{1}{x} + + \lbrack -\infty, \infty \rbrack : t = \frac{x}{\sqrt{1-x^2}} + + """ + ctx = self.ctx + a = ctx.convert(a) + b = ctx.convert(b) + one = ctx.one + if (a, b) == (-one, one): + return nodes + half = ctx.mpf(0.5) + new_nodes = [] + if ctx.isinf(a) or ctx.isinf(b): + if (a, b) == (ctx.ninf, ctx.inf): + p05 = -half + for x, w in nodes: + x2 = x*x + px1 = one-x2 + spx1 = px1**p05 + x = x*spx1 + w *= spx1/px1 + new_nodes.append((x, w)) + elif a == ctx.ninf: + b1 = b+1 + for x, w in nodes: + u = 2/(x+one) + x = b1-u + w *= half*u**2 + new_nodes.append((x, w)) + elif b == ctx.inf: + a1 = a-1 + for x, w in nodes: + u = 2/(x+one) + x = a1+u + w *= half*u**2 + new_nodes.append((x, w)) + elif a == ctx.inf or b == ctx.ninf: + return [(x,-w) for (x,w) in self.transform_nodes(nodes, b, a, verbose)] + else: + raise NotImplementedError + else: + # Simple linear change of variables + C = (b-a)/2 + D = (b+a)/2 + for x, w in nodes: + new_nodes.append((D+C*x, C*w)) + return new_nodes + + def guess_degree(self, prec): + """ + Given a desired precision `p` in bits, estimate the degree `m` + of the quadrature required to accomplish full accuracy for + typical integrals. By default, :func:`~mpmath.quad` will perform up + to `m` iterations. The value of `m` should be a slight + overestimate, so that "slightly bad" integrals can be dealt + with automatically using a few extra iterations. On the + other hand, it should not be too big, so :func:`~mpmath.quad` can + quit within a reasonable amount of time when it is given + an "unsolvable" integral. + + The default formula used by :func:`~mpmath.guess_degree` is tuned + for both :class:`TanhSinh` and :class:`GaussLegendre`. + The output is roughly as follows: + + +---------+---------+ + | `p` | `m` | + +=========+=========+ + | 50 | 6 | + +---------+---------+ + | 100 | 7 | + +---------+---------+ + | 500 | 10 | + +---------+---------+ + | 3000 | 12 | + +---------+---------+ + + This formula is based purely on a limited amount of + experimentation and will sometimes be wrong. + """ + # Expected degree + # XXX: use mag + g = int(4 + max(0, self.ctx.log(prec/30.0, 2))) + # Reasonable "worst case" + g += 2 + return g + + def estimate_error(self, results, prec, epsilon): + r""" + Given results from integrations `[I_1, I_2, \ldots, I_k]` done + with a quadrature of rule of degree `1, 2, \ldots, k`, estimate + the error of `I_k`. + + For `k = 2`, we estimate `|I_{\infty}-I_2|` as `|I_2-I_1|`. + + For `k > 2`, we extrapolate `|I_{\infty}-I_k| \approx |I_{k+1}-I_k|` + from `|I_k-I_{k-1}|` and `|I_k-I_{k-2}|` under the assumption + that each degree increment roughly doubles the accuracy of + the quadrature rule (this is true for both :class:`TanhSinh` + and :class:`GaussLegendre`). The extrapolation formula is given + by Borwein, Bailey & Girgensohn. Although not very conservative, + this method seems to be very robust in practice. + """ + if len(results) == 2: + return abs(results[0]-results[1]) + try: + if results[-1] == results[-2] == results[-3]: + return self.ctx.zero + D1 = self.ctx.log(abs(results[-1]-results[-2]), 10) + D2 = self.ctx.log(abs(results[-1]-results[-3]), 10) + except ValueError: + return epsilon + D3 = -prec + D4 = min(0, max(D1**2/D2, 2*D1, D3)) + return self.ctx.mpf(10) ** int(D4) + + def summation(self, f, points, prec, epsilon, max_degree, verbose=False): + """ + Main integration function. Computes the 1D integral over + the interval specified by *points*. For each subinterval, + performs quadrature of degree from 1 up to *max_degree* + until :func:`~mpmath.estimate_error` signals convergence. + + :func:`~mpmath.summation` transforms each subintegration to + the standard interval and then calls :func:`~mpmath.sum_next`. + """ + ctx = self.ctx + I = total_err = ctx.zero + for i in xrange(len(points)-1): + a, b = points[i], points[i+1] + if a == b: + continue + # XXX: we could use a single variable transformation, + # but this is not good in practice. We get better accuracy + # by having 0 as an endpoint. + if (a, b) == (ctx.ninf, ctx.inf): + _f = f + f = lambda x: _f(-x) + _f(x) + a, b = (ctx.zero, ctx.inf) + results = [] + err = ctx.zero + for degree in xrange(1, max_degree+1): + nodes = self.get_nodes(a, b, degree, prec, verbose) + if verbose: + print("Integrating from %s to %s (degree %s of %s)" % \ + (ctx.nstr(a), ctx.nstr(b), degree, max_degree)) + result = self.sum_next(f, nodes, degree, prec, results, verbose) + results.append(result) + if degree > 1: + err = self.estimate_error(results, prec, epsilon) + if verbose: + print("Estimated error:", ctx.nstr(err), " epsilon:", ctx.nstr(epsilon), " result: ", ctx.nstr(result)) + if err <= epsilon: + break + I += results[-1] + total_err += err + if total_err > epsilon: + if verbose: + print("Failed to reach full accuracy. Estimated error:", ctx.nstr(total_err)) + return I, total_err + + def sum_next(self, f, nodes, degree, prec, previous, verbose=False): + r""" + Evaluates the step sum `\sum w_k f(x_k)` where the *nodes* list + contains the `(w_k, x_k)` pairs. + + :func:`~mpmath.summation` will supply the list *results* of + values computed by :func:`~mpmath.sum_next` at previous degrees, in + case the quadrature rule is able to reuse them. + """ + return self.ctx.fdot((w, f(x)) for (x,w) in nodes) + + +class TanhSinh(QuadratureRule): + r""" + This class implements "tanh-sinh" or "doubly exponential" + quadrature. This quadrature rule is based on the Euler-Maclaurin + integral formula. By performing a change of variables involving + nested exponentials / hyperbolic functions (hence the name), the + derivatives at the endpoints vanish rapidly. Since the error term + in the Euler-Maclaurin formula depends on the derivatives at the + endpoints, a simple step sum becomes extremely accurate. In + practice, this means that doubling the number of evaluation + points roughly doubles the number of accurate digits. + + Comparison to Gauss-Legendre: + * Initial computation of nodes is usually faster + * Handles endpoint singularities better + * Handles infinite integration intervals better + * Is slower for smooth integrands once nodes have been computed + + The implementation of the tanh-sinh algorithm is based on the + description given in Borwein, Bailey & Girgensohn, "Experimentation + in Mathematics - Computational Paths to Discovery", A K Peters, + 2003, pages 312-313. In the present implementation, a few + improvements have been made: + + * A more efficient scheme is used to compute nodes (exploiting + recurrence for the exponential function) + * The nodes are computed successively instead of all at once + + **References** + + * [Bailey]_ + * http://users.cs.dal.ca/~jborwein/tanh-sinh.pdf + + """ + + def sum_next(self, f, nodes, degree, prec, previous, verbose=False): + """ + Step sum for tanh-sinh quadrature of degree `m`. We exploit the + fact that half of the abscissas at degree `m` are precisely the + abscissas from degree `m-1`. Thus reusing the result from + the previous level allows a 2x speedup. + """ + h = self.ctx.mpf(2)**(-degree) + # Abscissas overlap, so reusing saves half of the time + if previous: + S = previous[-1]/(h*2) + else: + S = self.ctx.zero + S += self.ctx.fdot((w,f(x)) for (x,w) in nodes) + return h*S + + def calc_nodes(self, degree, prec, verbose=False): + r""" + The abscissas and weights for tanh-sinh quadrature of degree + `m` are given by + + .. math:: + + x_k = \tanh(\pi/2 \sinh(t_k)) + + w_k = \pi/2 \cosh(t_k) / \cosh(\pi/2 \sinh(t_k))^2 + + where `t_k = t_0 + hk` for a step length `h \sim 2^{-m}`. The + list of nodes is actually infinite, but the weights die off so + rapidly that only a few are needed. + """ + ctx = self.ctx + nodes = [] + + extra = 20 + ctx.prec += extra + tol = ctx.ldexp(1, -prec-10) + pi4 = ctx.pi/4 + + # For simplicity, we work in steps h = 1/2^n, with the first point + # offset so that we can reuse the sum from the previous degree + + # We define degree 1 to include the "degree 0" steps, including + # the point x = 0. (It doesn't work well otherwise; not sure why.) + t0 = ctx.ldexp(1, -degree) + if degree == 1: + #nodes.append((mpf(0), pi4)) + #nodes.append((-mpf(0), pi4)) + nodes.append((ctx.zero, ctx.pi/2)) + h = t0 + else: + h = t0*2 + + # Since h is fixed, we can compute the next exponential + # by simply multiplying by exp(h) + expt0 = ctx.exp(t0) + a = pi4 * expt0 + b = pi4 / expt0 + udelta = ctx.exp(h) + urdelta = 1/udelta + + for k in xrange(0, 20*2**degree+1): + # Reference implementation: + # t = t0 + k*h + # x = tanh(pi/2 * sinh(t)) + # w = pi/2 * cosh(t) / cosh(pi/2 * sinh(t))**2 + + # Fast implementation. Note that c = exp(pi/2 * sinh(t)) + c = ctx.exp(a-b) + d = 1/c + co = (c+d)/2 + si = (c-d)/2 + x = si / co + w = (a+b) / co**2 + diff = abs(x-1) + if diff <= tol: + break + + nodes.append((x, w)) + nodes.append((-x, w)) + + a *= udelta + b *= urdelta + + if verbose and k % 300 == 150: + # Note: the number displayed is rather arbitrary. Should + # figure out how to print something that looks more like a + # percentage + print("Calculating nodes:", ctx.nstr(-ctx.log(diff, 10) / prec)) + + ctx.prec -= extra + return nodes + + +class GaussLegendre(QuadratureRule): + r""" + This class implements Gauss-Legendre quadrature, which is + exceptionally efficient for polynomials and polynomial-like (i.e. + very smooth) integrands. + + The abscissas and weights are given by roots and values of + Legendre polynomials, which are the orthogonal polynomials + on `[-1, 1]` with respect to the unit weight + (see :func:`~mpmath.legendre`). + + In this implementation, we take the "degree" `m` of the quadrature + to denote a Gauss-Legendre rule of degree `3 \cdot 2^m` (following + Borwein, Bailey & Girgensohn). This way we get quadratic, rather + than linear, convergence as the degree is incremented. + + Comparison to tanh-sinh quadrature: + * Is faster for smooth integrands once nodes have been computed + * Initial computation of nodes is usually slower + * Handles endpoint singularities worse + * Handles infinite integration intervals worse + + """ + + def calc_nodes(self, degree, prec, verbose=False): + r""" + Calculates the abscissas and weights for Gauss-Legendre + quadrature of degree of given degree (actually `3 \cdot 2^m`). + """ + ctx = self.ctx + # It is important that the epsilon is set lower than the + # "real" epsilon + epsilon = ctx.ldexp(1, -prec-8) + # Fairly high precision might be required for accurate + # evaluation of the roots + orig = ctx.prec + ctx.prec = int(prec*1.5) + if degree == 1: + x = ctx.sqrt(ctx.mpf(3)/5) + w = ctx.mpf(5)/9 + nodes = [(-x,w),(ctx.zero,ctx.mpf(8)/9),(x,w)] + ctx.prec = orig + return nodes + nodes = [] + n = 3*2**(degree-1) + upto = n//2 + 1 + for j in xrange(1, upto): + # Asymptotic formula for the roots + r = ctx.mpf(math.cos(math.pi*(j-0.25)/(n+0.5))) + # Newton iteration + while 1: + t1, t2 = 1, 0 + # Evaluates the Legendre polynomial using its defining + # recurrence relation + for j1 in xrange(1,n+1): + t3, t2, t1 = t2, t1, ((2*j1-1)*r*t1 - (j1-1)*t2)/j1 + t4 = n*(r*t1-t2)/(r**2-1) + a = t1/t4 + r = r - a + if abs(a) < epsilon: + break + x = r + w = 2/((1-r**2)*t4**2) + if verbose and j % 30 == 15: + print("Computing nodes (%i of %i)" % (j, upto)) + nodes.append((x, w)) + nodes.append((-x, w)) + ctx.prec = orig + return nodes + +class QuadratureMethods(object): + + def __init__(ctx, *args, **kwargs): + ctx._gauss_legendre = GaussLegendre(ctx) + ctx._tanh_sinh = TanhSinh(ctx) + + def quad(ctx, f, *points, **kwargs): + r""" + Computes a single, double or triple integral over a given + 1D interval, 2D rectangle, or 3D cuboid. A basic example:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> quad(sin, [0, pi]) + 2.0 + + A basic 2D integral:: + + >>> f = lambda x, y: cos(x+y/2) + >>> quad(f, [-pi/2, pi/2], [0, pi]) + 4.0 + + **Interval format** + + The integration range for each dimension may be specified + using a list or tuple. Arguments are interpreted as follows: + + ``quad(f, [x1, x2])`` -- calculates + `\int_{x_1}^{x_2} f(x) \, dx` + + ``quad(f, [x1, x2], [y1, y2])`` -- calculates + `\int_{x_1}^{x_2} \int_{y_1}^{y_2} f(x,y) \, dy \, dx` + + ``quad(f, [x1, x2], [y1, y2], [z1, z2])`` -- calculates + `\int_{x_1}^{x_2} \int_{y_1}^{y_2} \int_{z_1}^{z_2} f(x,y,z) + \, dz \, dy \, dx` + + Endpoints may be finite or infinite. An interval descriptor + may also contain more than two points. In this + case, the integration is split into subintervals, between + each pair of consecutive points. This is useful for + dealing with mid-interval discontinuities, or integrating + over large intervals where the function is irregular or + oscillates. + + **Options** + + :func:`~mpmath.quad` recognizes the following keyword arguments: + + *method* + Chooses integration algorithm (described below). + *error* + If set to true, :func:`~mpmath.quad` returns `(v, e)` where `v` is the + integral and `e` is the estimated error. + *maxdegree* + Maximum degree of the quadrature rule to try before + quitting. + *verbose* + Print details about progress. + + **Algorithms** + + Mpmath presently implements two integration algorithms: tanh-sinh + quadrature and Gauss-Legendre quadrature. These can be selected + using *method='tanh-sinh'* or *method='gauss-legendre'* or by + passing the classes *method=TanhSinh*, *method=GaussLegendre*. + The functions :func:`~mpmath.quadts` and :func:`~mpmath.quadgl` are also available + as shortcuts. + + Both algorithms have the property that doubling the number of + evaluation points roughly doubles the accuracy, so both are ideal + for high precision quadrature (hundreds or thousands of digits). + + At high precision, computing the nodes and weights for the + integration can be expensive (more expensive than computing the + function values). To make repeated integrations fast, nodes + are automatically cached. + + The advantages of the tanh-sinh algorithm are that it tends to + handle endpoint singularities well, and that the nodes are cheap + to compute on the first run. For these reasons, it is used by + :func:`~mpmath.quad` as the default algorithm. + + Gauss-Legendre quadrature often requires fewer function + evaluations, and is therefore often faster for repeated use, but + the algorithm does not handle endpoint singularities as well and + the nodes are more expensive to compute. Gauss-Legendre quadrature + can be a better choice if the integrand is smooth and repeated + integrations are required (e.g. for multiple integrals). + + See the documentation for :class:`TanhSinh` and + :class:`GaussLegendre` for additional details. + + **Examples of 1D integrals** + + Intervals may be infinite or half-infinite. The following two + examples evaluate the limits of the inverse tangent function + (`\int 1/(1+x^2) = \tan^{-1} x`), and the Gaussian integral + `\int_{\infty}^{\infty} \exp(-x^2)\,dx = \sqrt{\pi}`:: + + >>> mp.dps = 15 + >>> quad(lambda x: 2/(x**2+1), [0, inf]) + 3.14159265358979 + >>> quad(lambda x: exp(-x**2), [-inf, inf])**2 + 3.14159265358979 + + Integrals can typically be resolved to high precision. + The following computes 50 digits of `\pi` by integrating the + area of the half-circle defined by `x^2 + y^2 \le 1`, + `-1 \le x \le 1`, `y \ge 0`:: + + >>> mp.dps = 50 + >>> 2*quad(lambda x: sqrt(1-x**2), [-1, 1]) + 3.1415926535897932384626433832795028841971693993751 + + One can just as well compute 1000 digits (output truncated):: + + >>> mp.dps = 1000 + >>> 2*quad(lambda x: sqrt(1-x**2), [-1, 1]) #doctest:+ELLIPSIS + 3.141592653589793238462643383279502884...216420199 + + Complex integrals are supported. The following computes + a residue at `z = 0` by integrating counterclockwise along the + diamond-shaped path from `1` to `+i` to `-1` to `-i` to `1`:: + + >>> mp.dps = 15 + >>> chop(quad(lambda z: 1/z, [1,j,-1,-j,1])) + (0.0 + 6.28318530717959j) + + **Examples of 2D and 3D integrals** + + Here are several nice examples of analytically solvable + 2D integrals (taken from MathWorld [1]) that can be evaluated + to high precision fairly rapidly by :func:`~mpmath.quad`:: + + >>> mp.dps = 30 + >>> f = lambda x, y: (x-1)/((1-x*y)*log(x*y)) + >>> quad(f, [0, 1], [0, 1]) + 0.577215664901532860606512090082 + >>> +euler + 0.577215664901532860606512090082 + + >>> f = lambda x, y: 1/sqrt(1+x**2+y**2) + >>> quad(f, [-1, 1], [-1, 1]) + 3.17343648530607134219175646705 + >>> 4*log(2+sqrt(3))-2*pi/3 + 3.17343648530607134219175646705 + + >>> f = lambda x, y: 1/(1-x**2 * y**2) + >>> quad(f, [0, 1], [0, 1]) + 1.23370055013616982735431137498 + >>> pi**2 / 8 + 1.23370055013616982735431137498 + + >>> quad(lambda x, y: 1/(1-x*y), [0, 1], [0, 1]) + 1.64493406684822643647241516665 + >>> pi**2 / 6 + 1.64493406684822643647241516665 + + Multiple integrals may be done over infinite ranges:: + + >>> mp.dps = 15 + >>> print(quad(lambda x,y: exp(-x-y), [0, inf], [1, inf])) + 0.367879441171442 + >>> print(1/e) + 0.367879441171442 + + For nonrectangular areas, one can call :func:`~mpmath.quad` recursively. + For example, we can replicate the earlier example of calculating + `\pi` by integrating over the unit-circle, and actually use double + quadrature to actually measure the area circle:: + + >>> f = lambda x: quad(lambda y: 1, [-sqrt(1-x**2), sqrt(1-x**2)]) + >>> quad(f, [-1, 1]) + 3.14159265358979 + + Here is a simple triple integral:: + + >>> mp.dps = 15 + >>> f = lambda x,y,z: x*y/(1+z) + >>> quad(f, [0,1], [0,1], [1,2], method='gauss-legendre') + 0.101366277027041 + >>> (log(3)-log(2))/4 + 0.101366277027041 + + **Singularities** + + Both tanh-sinh and Gauss-Legendre quadrature are designed to + integrate smooth (infinitely differentiable) functions. Neither + algorithm copes well with mid-interval singularities (such as + mid-interval discontinuities in `f(x)` or `f'(x)`). + The best solution is to split the integral into parts:: + + >>> mp.dps = 15 + >>> quad(lambda x: abs(sin(x)), [0, 2*pi]) # Bad + 3.99900894176779 + >>> quad(lambda x: abs(sin(x)), [0, pi, 2*pi]) # Good + 4.0 + + The tanh-sinh rule often works well for integrands having a + singularity at one or both endpoints:: + + >>> mp.dps = 15 + >>> quad(log, [0, 1], method='tanh-sinh') # Good + -1.0 + >>> quad(log, [0, 1], method='gauss-legendre') # Bad + -0.999932197413801 + + However, the result may still be inaccurate for some functions:: + + >>> quad(lambda x: 1/sqrt(x), [0, 1], method='tanh-sinh') + 1.99999999946942 + + This problem is not due to the quadrature rule per se, but to + numerical amplification of errors in the nodes. The problem can be + circumvented by temporarily increasing the precision:: + + >>> mp.dps = 30 + >>> a = quad(lambda x: 1/sqrt(x), [0, 1], method='tanh-sinh') + >>> mp.dps = 15 + >>> +a + 2.0 + + **Highly variable functions** + + For functions that are smooth (in the sense of being infinitely + differentiable) but contain sharp mid-interval peaks or many + "bumps", :func:`~mpmath.quad` may fail to provide full accuracy. For + example, with default settings, :func:`~mpmath.quad` is able to integrate + `\sin(x)` accurately over an interval of length 100 but not over + length 1000:: + + >>> quad(sin, [0, 100]); 1-cos(100) # Good + 0.137681127712316 + 0.137681127712316 + >>> quad(sin, [0, 1000]); 1-cos(1000) # Bad + -37.8587612408485 + 0.437620923709297 + + One solution is to break the integration into 10 intervals of + length 100:: + + >>> quad(sin, linspace(0, 1000, 10)) # Good + 0.437620923709297 + + Another is to increase the degree of the quadrature:: + + >>> quad(sin, [0, 1000], maxdegree=10) # Also good + 0.437620923709297 + + Whether splitting the interval or increasing the degree is + more efficient differs from case to case. Another example is the + function `1/(1+x^2)`, which has a sharp peak centered around + `x = 0`:: + + >>> f = lambda x: 1/(1+x**2) + >>> quad(f, [-100, 100]) # Bad + 3.64804647105268 + >>> quad(f, [-100, 100], maxdegree=10) # Good + 3.12159332021646 + >>> quad(f, [-100, 0, 100]) # Also good + 3.12159332021646 + + **References** + + 1. http://mathworld.wolfram.com/DoubleIntegral.html + + """ + rule = kwargs.get('method', 'tanh-sinh') + if type(rule) is str: + if rule == 'tanh-sinh': + rule = ctx._tanh_sinh + elif rule == 'gauss-legendre': + rule = ctx._gauss_legendre + else: + raise ValueError("unknown quadrature rule: %s" % rule) + else: + rule = rule(ctx) + verbose = kwargs.get('verbose') + dim = len(points) + orig = prec = ctx.prec + epsilon = ctx.eps/8 + m = kwargs.get('maxdegree') or rule.guess_degree(prec) + points = [ctx._as_points(p) for p in points] + try: + ctx.prec += 20 + if dim == 1: + v, err = rule.summation(f, points[0], prec, epsilon, m, verbose) + elif dim == 2: + v, err = rule.summation(lambda x: \ + rule.summation(lambda y: f(x,y), \ + points[1], prec, epsilon, m)[0], + points[0], prec, epsilon, m, verbose) + elif dim == 3: + v, err = rule.summation(lambda x: \ + rule.summation(lambda y: \ + rule.summation(lambda z: f(x,y,z), \ + points[2], prec, epsilon, m)[0], + points[1], prec, epsilon, m)[0], + points[0], prec, epsilon, m, verbose) + else: + raise NotImplementedError("quadrature must have dim 1, 2 or 3") + finally: + ctx.prec = orig + if kwargs.get("error"): + return +v, err + return +v + + def quadts(ctx, *args, **kwargs): + """ + Performs tanh-sinh quadrature. The call + + quadts(func, *points, ...) + + is simply a shortcut for: + + quad(func, *points, ..., method=TanhSinh) + + For example, a single integral and a double integral: + + quadts(lambda x: exp(cos(x)), [0, 1]) + quadts(lambda x, y: exp(cos(x+y)), [0, 1], [0, 1]) + + See the documentation for quad for information about how points + arguments and keyword arguments are parsed. + + See documentation for TanhSinh for algorithmic information about + tanh-sinh quadrature. + """ + kwargs['method'] = 'tanh-sinh' + return ctx.quad(*args, **kwargs) + + def quadgl(ctx, *args, **kwargs): + """ + Performs Gauss-Legendre quadrature. The call + + quadgl(func, *points, ...) + + is simply a shortcut for: + + quad(func, *points, ..., method=GaussLegendre) + + For example, a single integral and a double integral: + + quadgl(lambda x: exp(cos(x)), [0, 1]) + quadgl(lambda x, y: exp(cos(x+y)), [0, 1], [0, 1]) + + See the documentation for quad for information about how points + arguments and keyword arguments are parsed. + + See documentation for TanhSinh for algorithmic information about + tanh-sinh quadrature. + """ + kwargs['method'] = 'gauss-legendre' + return ctx.quad(*args, **kwargs) + + def quadosc(ctx, f, interval, omega=None, period=None, zeros=None): + r""" + Calculates + + .. math :: + + I = \int_a^b f(x) dx + + where at least one of `a` and `b` is infinite and where + `f(x) = g(x) \cos(\omega x + \phi)` for some slowly + decreasing function `g(x)`. With proper input, :func:`~mpmath.quadosc` + can also handle oscillatory integrals where the oscillation + rate is different from a pure sine or cosine wave. + + In the standard case when `|a| < \infty, b = \infty`, + :func:`~mpmath.quadosc` works by evaluating the infinite series + + .. math :: + + I = \int_a^{x_1} f(x) dx + + \sum_{k=1}^{\infty} \int_{x_k}^{x_{k+1}} f(x) dx + + where `x_k` are consecutive zeros (alternatively + some other periodic reference point) of `f(x)`. + Accordingly, :func:`~mpmath.quadosc` requires information about the + zeros of `f(x)`. For a periodic function, you can specify + the zeros by either providing the angular frequency `\omega` + (*omega*) or the *period* `2 \pi/\omega`. In general, you can + specify the `n`-th zero by providing the *zeros* arguments. + Below is an example of each:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> f = lambda x: sin(3*x)/(x**2+1) + >>> quadosc(f, [0,inf], omega=3) + 0.37833007080198 + >>> quadosc(f, [0,inf], period=2*pi/3) + 0.37833007080198 + >>> quadosc(f, [0,inf], zeros=lambda n: pi*n/3) + 0.37833007080198 + >>> (ei(3)*exp(-3)-exp(3)*ei(-3))/2 # Computed by Mathematica + 0.37833007080198 + + Note that *zeros* was specified to multiply `n` by the + *half-period*, not the full period. In theory, it does not matter + whether each partial integral is done over a half period or a full + period. However, if done over half-periods, the infinite series + passed to :func:`~mpmath.nsum` becomes an *alternating series* and this + typically makes the extrapolation much more efficient. + + Here is an example of an integration over the entire real line, + and a half-infinite integration starting at `-\infty`:: + + >>> quadosc(lambda x: cos(x)/(1+x**2), [-inf, inf], omega=1) + 1.15572734979092 + >>> pi/e + 1.15572734979092 + >>> quadosc(lambda x: cos(x)/x**2, [-inf, -1], period=2*pi) + -0.0844109505595739 + >>> cos(1)+si(1)-pi/2 + -0.0844109505595738 + + Of course, the integrand may contain a complex exponential just as + well as a real sine or cosine:: + + >>> quadosc(lambda x: exp(3*j*x)/(1+x**2), [-inf,inf], omega=3) + (0.156410688228254 + 0.0j) + >>> pi/e**3 + 0.156410688228254 + >>> quadosc(lambda x: exp(3*j*x)/(2+x+x**2), [-inf,inf], omega=3) + (0.00317486988463794 - 0.0447701735209082j) + >>> 2*pi/sqrt(7)/exp(3*(j+sqrt(7))/2) + (0.00317486988463794 - 0.0447701735209082j) + + **Non-periodic functions** + + If `f(x) = g(x) h(x)` for some function `h(x)` that is not + strictly periodic, *omega* or *period* might not work, and it might + be necessary to use *zeros*. + + A notable exception can be made for Bessel functions which, though not + periodic, are "asymptotically periodic" in a sufficiently strong sense + that the sum extrapolation will work out:: + + >>> quadosc(j0, [0, inf], period=2*pi) + 1.0 + >>> quadosc(j1, [0, inf], period=2*pi) + 1.0 + + More properly, one should provide the exact Bessel function zeros:: + + >>> j0zero = lambda n: findroot(j0, pi*(n-0.25)) + >>> quadosc(j0, [0, inf], zeros=j0zero) + 1.0 + + For an example where *zeros* becomes necessary, consider the + complete Fresnel integrals + + .. math :: + + \int_0^{\infty} \cos x^2\,dx = \int_0^{\infty} \sin x^2\,dx + = \sqrt{\frac{\pi}{8}}. + + Although the integrands do not decrease in magnitude as + `x \to \infty`, the integrals are convergent since the oscillation + rate increases (causing consecutive periods to asymptotically + cancel out). These integrals are virtually impossible to calculate + to any kind of accuracy using standard quadrature rules. However, + if one provides the correct asymptotic distribution of zeros + (`x_n \sim \sqrt{n}`), :func:`~mpmath.quadosc` works:: + + >>> mp.dps = 30 + >>> f = lambda x: cos(x**2) + >>> quadosc(f, [0,inf], zeros=lambda n:sqrt(pi*n)) + 0.626657068657750125603941321203 + >>> f = lambda x: sin(x**2) + >>> quadosc(f, [0,inf], zeros=lambda n:sqrt(pi*n)) + 0.626657068657750125603941321203 + >>> sqrt(pi/8) + 0.626657068657750125603941321203 + + (Interestingly, these integrals can still be evaluated if one + places some other constant than `\pi` in the square root sign.) + + In general, if `f(x) \sim g(x) \cos(h(x))`, the zeros follow + the inverse-function distribution `h^{-1}(x)`:: + + >>> mp.dps = 15 + >>> f = lambda x: sin(exp(x)) + >>> quadosc(f, [1,inf], zeros=lambda n: log(n)) + -0.25024394235267 + >>> pi/2-si(e) + -0.250243942352671 + + **Non-alternating functions** + + If the integrand oscillates around a positive value, without + alternating signs, the extrapolation might fail. A simple trick + that sometimes works is to multiply or divide the frequency by 2:: + + >>> f = lambda x: 1/x**2+sin(x)/x**4 + >>> quadosc(f, [1,inf], omega=1) # Bad + 1.28642190869861 + >>> quadosc(f, [1,inf], omega=0.5) # Perfect + 1.28652953559617 + >>> 1+(cos(1)+ci(1)+sin(1))/6 + 1.28652953559617 + + **Fast decay** + + :func:`~mpmath.quadosc` is primarily useful for slowly decaying + integrands. If the integrand decreases exponentially or faster, + :func:`~mpmath.quad` will likely handle it without trouble (and generally be + much faster than :func:`~mpmath.quadosc`):: + + >>> quadosc(lambda x: cos(x)/exp(x), [0, inf], omega=1) + 0.5 + >>> quad(lambda x: cos(x)/exp(x), [0, inf]) + 0.5 + + """ + a, b = ctx._as_points(interval) + a = ctx.convert(a) + b = ctx.convert(b) + if [omega, period, zeros].count(None) != 2: + raise ValueError( \ + "must specify exactly one of omega, period, zeros") + if a == ctx.ninf and b == ctx.inf: + s1 = ctx.quadosc(f, [a, 0], omega=omega, zeros=zeros, period=period) + s2 = ctx.quadosc(f, [0, b], omega=omega, zeros=zeros, period=period) + return s1 + s2 + if a == ctx.ninf: + if zeros: + return ctx.quadosc(lambda x:f(-x), [-b,-a], lambda n: zeros(-n)) + else: + return ctx.quadosc(lambda x:f(-x), [-b,-a], omega=omega, period=period) + if b != ctx.inf: + raise ValueError("quadosc requires an infinite integration interval") + if not zeros: + if omega: + period = 2*ctx.pi/omega + zeros = lambda n: n*period/2 + #for n in range(1,10): + # p = zeros(n) + # if p > a: + # break + #if n >= 9: + # raise ValueError("zeros do not appear to be correctly indexed") + n = 1 + s = ctx.quadgl(f, [a, zeros(n)]) + def term(k): + return ctx.quadgl(f, [zeros(k), zeros(k+1)]) + s += ctx.nsum(term, [n, ctx.inf]) + return s + + def quadsubdiv(ctx, f, interval, tol=None, maxintervals=None, **kwargs): + """ + Computes the integral of *f* over the interval or path specified + by *interval*, using :func:`~mpmath.quad` together with adaptive + subdivision of the interval. + + This function gives an accurate answer for some integrals where + :func:`~mpmath.quad` fails:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> quad(lambda x: abs(sin(x)), [0, 2*pi]) + 3.99900894176779 + >>> quadsubdiv(lambda x: abs(sin(x)), [0, 2*pi]) + 4.0 + >>> quadsubdiv(sin, [0, 1000]) + 0.437620923709297 + >>> quadsubdiv(lambda x: 1/(1+x**2), [-100, 100]) + 3.12159332021646 + >>> quadsubdiv(lambda x: ceil(x), [0, 100]) + 5050.0 + >>> quadsubdiv(lambda x: sin(x+exp(x)), [0,8]) + 0.347400172657248 + + The argument *maxintervals* can be set to limit the permissible + subdivision:: + + >>> quadsubdiv(lambda x: sin(x**2), [0,100], maxintervals=5, error=True) + (-5.40487904307774, 5.011) + >>> quadsubdiv(lambda x: sin(x**2), [0,100], maxintervals=100, error=True) + (0.631417921866934, 1.10101120134116e-17) + + Subdivision does not guarantee a correct answer since, the error + estimate on subintervals may be inaccurate:: + + >>> quadsubdiv(lambda x: sech(10*x-2)**2 + sech(100*x-40)**4 + sech(1000*x-600)**6, [0,1], error=True) + (0.210802735500549, 1.0001111101e-17) + >>> mp.dps = 20 + >>> quadsubdiv(lambda x: sech(10*x-2)**2 + sech(100*x-40)**4 + sech(1000*x-600)**6, [0,1], error=True) + (0.21080273550054927738, 2.200000001e-24) + + The second answer is correct. We can get an accurate result at lower + precision by forcing a finer initial subdivision:: + + >>> mp.dps = 15 + >>> quadsubdiv(lambda x: sech(10*x-2)**2 + sech(100*x-40)**4 + sech(1000*x-600)**6, linspace(0,1,5)) + 0.210802735500549 + + The following integral is too oscillatory for convergence, but we can get a + reasonable estimate:: + + >>> v, err = fp.quadsubdiv(lambda x: fp.sin(1/x), [0,1], error=True) + >>> round(v, 6), round(err, 6) + (0.504067, 1e-06) + >>> sin(1) - ci(1) + 0.504067061906928 + + """ + queue = [] + for i in range(len(interval)-1): + queue.append((interval[i], interval[i+1])) + total = ctx.zero + total_error = ctx.zero + if maxintervals is None: + maxintervals = 10 * ctx.prec + count = 0 + quad_args = kwargs.copy() + quad_args["verbose"] = False + quad_args["error"] = True + if tol is None: + tol = +ctx.eps + orig = ctx.prec + try: + ctx.prec += 5 + while queue: + a, b = queue.pop() + s, err = ctx.quad(f, [a, b], **quad_args) + if kwargs.get("verbose"): + print("subinterval", count, a, b, err) + if err < tol or count > maxintervals: + total += s + total_error += err + else: + count += 1 + if count == maxintervals and kwargs.get("verbose"): + print("warning: number of intervals exceeded maxintervals") + if a == -ctx.inf and b == ctx.inf: + m = 0 + elif a == -ctx.inf: + m = min(b-1, 2*b) + elif b == ctx.inf: + m = max(a+1, 2*a) + else: + m = a + (b - a) / 2 + queue.append((a, m)) + queue.append((m, b)) + finally: + ctx.prec = orig + if kwargs.get("error"): + return +total, +total_error + else: + return +total + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5896ed0579eceab086dc5c67eaa649b6061a53dc --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/__init__.py @@ -0,0 +1,14 @@ +from . import functions +# Hack to update methods +from . import factorials +from . import hypergeometric +from . import expintegrals +from . import bessel +from . import orthogonal +from . import theta +from . import elliptic +from . import signals +from . import zeta +from . import rszeta +from . import zetazeros +from . import qfunctions diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/bessel.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/bessel.py new file mode 100644 index 0000000000000000000000000000000000000000..8b41d87bb0118de61d5561433dabcb181f872f84 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/bessel.py @@ -0,0 +1,1108 @@ +from .functions import defun, defun_wrapped + +@defun +def j0(ctx, x): + """Computes the Bessel function `J_0(x)`. See :func:`~mpmath.besselj`.""" + return ctx.besselj(0, x) + +@defun +def j1(ctx, x): + """Computes the Bessel function `J_1(x)`. See :func:`~mpmath.besselj`.""" + return ctx.besselj(1, x) + +@defun +def besselj(ctx, n, z, derivative=0, **kwargs): + if type(n) is int: + n_isint = True + else: + n = ctx.convert(n) + n_isint = ctx.isint(n) + if n_isint: + n = int(ctx._re(n)) + if n_isint and n < 0: + return (-1)**n * ctx.besselj(-n, z, derivative, **kwargs) + z = ctx.convert(z) + M = ctx.mag(z) + if derivative: + d = ctx.convert(derivative) + # TODO: the integer special-casing shouldn't be necessary. + # However, the hypergeometric series gets inaccurate for large d + # because of inaccurate pole cancellation at a pole far from + # zero (needs to be fixed in hypercomb or hypsum) + if ctx.isint(d) and d >= 0: + d = int(d) + orig = ctx.prec + try: + ctx.prec += 15 + v = ctx.fsum((-1)**k * ctx.binomial(d,k) * ctx.besselj(2*k+n-d,z) + for k in range(d+1)) + finally: + ctx.prec = orig + v *= ctx.mpf(2)**(-d) + else: + def h(n,d): + r = ctx.fmul(ctx.fmul(z, z, prec=ctx.prec+M), -0.25, exact=True) + B = [0.5*(n-d+1), 0.5*(n-d+2)] + T = [([2,ctx.pi,z],[d-2*n,0.5,n-d],[],B,[(n+1)*0.5,(n+2)*0.5],B+[n+1],r)] + return T + v = ctx.hypercomb(h, [n,d], **kwargs) + else: + # Fast case: J_n(x), n int, appropriate magnitude for fixed-point calculation + if (not derivative) and n_isint and abs(M) < 10 and abs(n) < 20: + try: + return ctx._besselj(n, z) + except NotImplementedError: + pass + if not z: + if not n: + v = ctx.one + n+z + elif ctx.re(n) > 0: + v = n*z + else: + v = ctx.inf + z + n + else: + #v = 0 + orig = ctx.prec + try: + # XXX: workaround for accuracy in low level hypergeometric series + # when alternating, large arguments + ctx.prec += min(3*abs(M), ctx.prec) + w = ctx.fmul(z, 0.5, exact=True) + def h(n): + r = ctx.fneg(ctx.fmul(w, w, prec=max(0,ctx.prec+M)), exact=True) + return [([w], [n], [], [n+1], [], [n+1], r)] + v = ctx.hypercomb(h, [n], **kwargs) + finally: + ctx.prec = orig + v = +v + return v + +@defun +def besseli(ctx, n, z, derivative=0, **kwargs): + n = ctx.convert(n) + z = ctx.convert(z) + if not z: + if derivative: + raise ValueError + if not n: + # I(0,0) = 1 + return 1+n+z + if ctx.isint(n): + return 0*(n+z) + r = ctx.re(n) + if r == 0: + return ctx.nan*(n+z) + elif r > 0: + return 0*(n+z) + else: + return ctx.inf+(n+z) + M = ctx.mag(z) + if derivative: + d = ctx.convert(derivative) + def h(n,d): + r = ctx.fmul(ctx.fmul(z, z, prec=ctx.prec+M), 0.25, exact=True) + B = [0.5*(n-d+1), 0.5*(n-d+2), n+1] + T = [([2,ctx.pi,z],[d-2*n,0.5,n-d],[n+1],B,[(n+1)*0.5,(n+2)*0.5],B,r)] + return T + v = ctx.hypercomb(h, [n,d], **kwargs) + else: + def h(n): + w = ctx.fmul(z, 0.5, exact=True) + r = ctx.fmul(w, w, prec=max(0,ctx.prec+M)) + return [([w], [n], [], [n+1], [], [n+1], r)] + v = ctx.hypercomb(h, [n], **kwargs) + return v + +@defun_wrapped +def bessely(ctx, n, z, derivative=0, **kwargs): + if not z: + if derivative: + # Not implemented + raise ValueError + if not n: + # ~ log(z/2) + return -ctx.inf + (n+z) + if ctx.im(n): + return ctx.nan * (n+z) + r = ctx.re(n) + q = n+0.5 + if ctx.isint(q): + if n > 0: + return -ctx.inf + (n+z) + else: + return 0 * (n+z) + if r < 0 and int(ctx.floor(q)) % 2: + return ctx.inf + (n+z) + else: + return ctx.ninf + (n+z) + # XXX: use hypercomb + ctx.prec += 10 + m, d = ctx.nint_distance(n) + if d < -ctx.prec: + h = +ctx.eps + ctx.prec *= 2 + n += h + elif d < 0: + ctx.prec -= d + # TODO: avoid cancellation for imaginary arguments + cos, sin = ctx.cospi_sinpi(n) + return (ctx.besselj(n,z,derivative,**kwargs)*cos - \ + ctx.besselj(-n,z,derivative,**kwargs))/sin + +@defun_wrapped +def besselk(ctx, n, z, **kwargs): + if not z: + return ctx.inf + M = ctx.mag(z) + if M < 1: + # Represent as limit definition + def h(n): + r = (z/2)**2 + T1 = [z, 2], [-n, n-1], [n], [], [], [1-n], r + T2 = [z, 2], [n, -n-1], [-n], [], [], [1+n], r + return T1, T2 + # We could use the limit definition always, but it leads + # to very bad cancellation (of exponentially large terms) + # for large real z + # Instead represent in terms of 2F0 + else: + ctx.prec += M + def h(n): + return [([ctx.pi/2, z, ctx.exp(-z)], [0.5,-0.5,1], [], [], \ + [n+0.5, 0.5-n], [], -1/(2*z))] + return ctx.hypercomb(h, [n], **kwargs) + +@defun_wrapped +def hankel1(ctx,n,x,**kwargs): + return ctx.besselj(n,x,**kwargs) + ctx.j*ctx.bessely(n,x,**kwargs) + +@defun_wrapped +def hankel2(ctx,n,x,**kwargs): + return ctx.besselj(n,x,**kwargs) - ctx.j*ctx.bessely(n,x,**kwargs) + +@defun_wrapped +def whitm(ctx,k,m,z,**kwargs): + if z == 0: + # M(k,m,z) = 0^(1/2+m) + if ctx.re(m) > -0.5: + return z + elif ctx.re(m) < -0.5: + return ctx.inf + z + else: + return ctx.nan * z + x = ctx.fmul(-0.5, z, exact=True) + y = 0.5+m + return ctx.exp(x) * z**y * ctx.hyp1f1(y-k, 1+2*m, z, **kwargs) + +@defun_wrapped +def whitw(ctx,k,m,z,**kwargs): + if z == 0: + g = abs(ctx.re(m)) + if g < 0.5: + return z + elif g > 0.5: + return ctx.inf + z + else: + return ctx.nan * z + x = ctx.fmul(-0.5, z, exact=True) + y = 0.5+m + return ctx.exp(x) * z**y * ctx.hyperu(y-k, 1+2*m, z, **kwargs) + +@defun +def hyperu(ctx, a, b, z, **kwargs): + a, atype = ctx._convert_param(a) + b, btype = ctx._convert_param(b) + z = ctx.convert(z) + if not z: + if ctx.re(b) <= 1: + return ctx.gammaprod([1-b],[a-b+1]) + else: + return ctx.inf + z + bb = 1+a-b + bb, bbtype = ctx._convert_param(bb) + try: + orig = ctx.prec + try: + ctx.prec += 10 + v = ctx.hypsum(2, 0, (atype, bbtype), [a, bb], -1/z, maxterms=ctx.prec) + return v / z**a + finally: + ctx.prec = orig + except ctx.NoConvergence: + pass + def h(a,b): + w = ctx.sinpi(b) + T1 = ([ctx.pi,w],[1,-1],[],[a-b+1,b],[a],[b],z) + T2 = ([-ctx.pi,w,z],[1,-1,1-b],[],[a,2-b],[a-b+1],[2-b],z) + return T1, T2 + return ctx.hypercomb(h, [a,b], **kwargs) + +@defun +def struveh(ctx,n,z, **kwargs): + n = ctx.convert(n) + z = ctx.convert(z) + # http://functions.wolfram.com/Bessel-TypeFunctions/StruveH/26/01/02/ + def h(n): + return [([z/2, 0.5*ctx.sqrt(ctx.pi)], [n+1, -1], [], [n+1.5], [1], [1.5, n+1.5], -(z/2)**2)] + return ctx.hypercomb(h, [n], **kwargs) + +@defun +def struvel(ctx,n,z, **kwargs): + n = ctx.convert(n) + z = ctx.convert(z) + # http://functions.wolfram.com/Bessel-TypeFunctions/StruveL/26/01/02/ + def h(n): + return [([z/2, 0.5*ctx.sqrt(ctx.pi)], [n+1, -1], [], [n+1.5], [1], [1.5, n+1.5], (z/2)**2)] + return ctx.hypercomb(h, [n], **kwargs) + +def _anger(ctx,which,v,z,**kwargs): + v = ctx._convert_param(v)[0] + z = ctx.convert(z) + def h(v): + b = ctx.mpq_1_2 + u = v*b + m = b*3 + a1,a2,b1,b2 = m-u, m+u, 1-u, 1+u + c, s = ctx.cospi_sinpi(u) + if which == 0: + A, B = [b*z, s], [c] + if which == 1: + A, B = [b*z, -c], [s] + w = ctx.square_exp_arg(z, mult=-0.25) + T1 = A, [1, 1], [], [a1,a2], [1], [a1,a2], w + T2 = B, [1], [], [b1,b2], [1], [b1,b2], w + return T1, T2 + return ctx.hypercomb(h, [v], **kwargs) + +@defun +def angerj(ctx, v, z, **kwargs): + return _anger(ctx, 0, v, z, **kwargs) + +@defun +def webere(ctx, v, z, **kwargs): + return _anger(ctx, 1, v, z, **kwargs) + +@defun +def lommels1(ctx, u, v, z, **kwargs): + u = ctx._convert_param(u)[0] + v = ctx._convert_param(v)[0] + z = ctx.convert(z) + def h(u,v): + b = ctx.mpq_1_2 + w = ctx.square_exp_arg(z, mult=-0.25) + return ([u-v+1, u+v+1, z], [-1, -1, u+1], [], [], [1], \ + [b*(u-v+3),b*(u+v+3)], w), + return ctx.hypercomb(h, [u,v], **kwargs) + +@defun +def lommels2(ctx, u, v, z, **kwargs): + u = ctx._convert_param(u)[0] + v = ctx._convert_param(v)[0] + z = ctx.convert(z) + # Asymptotic expansion (GR p. 947) -- need to be careful + # not to use for small arguments + # def h(u,v): + # b = ctx.mpq_1_2 + # w = -(z/2)**(-2) + # return ([z], [u-1], [], [], [b*(1-u+v)], [b*(1-u-v)], w), + def h(u,v): + b = ctx.mpq_1_2 + w = ctx.square_exp_arg(z, mult=-0.25) + T1 = [u-v+1, u+v+1, z], [-1, -1, u+1], [], [], [1], [b*(u-v+3),b*(u+v+3)], w + T2 = [2, z], [u+v-1, -v], [v, b*(u+v+1)], [b*(v-u+1)], [], [1-v], w + T3 = [2, z], [u-v-1, v], [-v, b*(u-v+1)], [b*(1-u-v)], [], [1+v], w + #c1 = ctx.cospi((u-v)*b) + #c2 = ctx.cospi((u+v)*b) + #s = ctx.sinpi(v) + #r1 = (u-v+1)*b + #r2 = (u+v+1)*b + #T2 = [c1, s, z, 2], [1, -1, -v, v], [], [-v+1], [], [-v+1], w + #T3 = [-c2, s, z, 2], [1, -1, v, -v], [], [v+1], [], [v+1], w + #T2 = [c1, s, z, 2], [1, -1, -v, v+u-1], [r1, r2], [-v+1], [], [-v+1], w + #T3 = [-c2, s, z, 2], [1, -1, v, -v+u-1], [r1, r2], [v+1], [], [v+1], w + return T1, T2, T3 + return ctx.hypercomb(h, [u,v], **kwargs) + +@defun +def ber(ctx, n, z, **kwargs): + n = ctx.convert(n) + z = ctx.convert(z) + # http://functions.wolfram.com/Bessel-TypeFunctions/KelvinBer2/26/01/02/0001/ + def h(n): + r = -(z/4)**4 + cos, sin = ctx.cospi_sinpi(-0.75*n) + T1 = [cos, z/2], [1, n], [], [n+1], [], [0.5, 0.5*(n+1), 0.5*n+1], r + T2 = [sin, z/2], [1, n+2], [], [n+2], [], [1.5, 0.5*(n+3), 0.5*n+1], r + return T1, T2 + return ctx.hypercomb(h, [n], **kwargs) + +@defun +def bei(ctx, n, z, **kwargs): + n = ctx.convert(n) + z = ctx.convert(z) + # http://functions.wolfram.com/Bessel-TypeFunctions/KelvinBei2/26/01/02/0001/ + def h(n): + r = -(z/4)**4 + cos, sin = ctx.cospi_sinpi(0.75*n) + T1 = [cos, z/2], [1, n+2], [], [n+2], [], [1.5, 0.5*(n+3), 0.5*n+1], r + T2 = [sin, z/2], [1, n], [], [n+1], [], [0.5, 0.5*(n+1), 0.5*n+1], r + return T1, T2 + return ctx.hypercomb(h, [n], **kwargs) + +@defun +def ker(ctx, n, z, **kwargs): + n = ctx.convert(n) + z = ctx.convert(z) + # http://functions.wolfram.com/Bessel-TypeFunctions/KelvinKer2/26/01/02/0001/ + def h(n): + r = -(z/4)**4 + cos1, sin1 = ctx.cospi_sinpi(0.25*n) + cos2, sin2 = ctx.cospi_sinpi(0.75*n) + T1 = [2, z, 4*cos1], [-n-3, n, 1], [-n], [], [], [0.5, 0.5*(1+n), 0.5*(n+2)], r + T2 = [2, z, -sin1], [-n-3, 2+n, 1], [-n-1], [], [], [1.5, 0.5*(3+n), 0.5*(n+2)], r + T3 = [2, z, 4*cos2], [n-3, -n, 1], [n], [], [], [0.5, 0.5*(1-n), 1-0.5*n], r + T4 = [2, z, -sin2], [n-3, 2-n, 1], [n-1], [], [], [1.5, 0.5*(3-n), 1-0.5*n], r + return T1, T2, T3, T4 + return ctx.hypercomb(h, [n], **kwargs) + +@defun +def kei(ctx, n, z, **kwargs): + n = ctx.convert(n) + z = ctx.convert(z) + # http://functions.wolfram.com/Bessel-TypeFunctions/KelvinKei2/26/01/02/0001/ + def h(n): + r = -(z/4)**4 + cos1, sin1 = ctx.cospi_sinpi(0.75*n) + cos2, sin2 = ctx.cospi_sinpi(0.25*n) + T1 = [-cos1, 2, z], [1, n-3, 2-n], [n-1], [], [], [1.5, 0.5*(3-n), 1-0.5*n], r + T2 = [-sin1, 2, z], [1, n-1, -n], [n], [], [], [0.5, 0.5*(1-n), 1-0.5*n], r + T3 = [-sin2, 2, z], [1, -n-1, n], [-n], [], [], [0.5, 0.5*(n+1), 0.5*(n+2)], r + T4 = [-cos2, 2, z], [1, -n-3, n+2], [-n-1], [], [], [1.5, 0.5*(n+3), 0.5*(n+2)], r + return T1, T2, T3, T4 + return ctx.hypercomb(h, [n], **kwargs) + +# TODO: do this more generically? +def c_memo(f): + name = f.__name__ + def f_wrapped(ctx): + cache = ctx._misc_const_cache + prec = ctx.prec + p,v = cache.get(name, (-1,0)) + if p >= prec: + return +v + else: + cache[name] = (prec, f(ctx)) + return cache[name][1] + return f_wrapped + +@c_memo +def _airyai_C1(ctx): + return 1 / (ctx.cbrt(9) * ctx.gamma(ctx.mpf(2)/3)) + +@c_memo +def _airyai_C2(ctx): + return -1 / (ctx.cbrt(3) * ctx.gamma(ctx.mpf(1)/3)) + +@c_memo +def _airybi_C1(ctx): + return 1 / (ctx.nthroot(3,6) * ctx.gamma(ctx.mpf(2)/3)) + +@c_memo +def _airybi_C2(ctx): + return ctx.nthroot(3,6) / ctx.gamma(ctx.mpf(1)/3) + +def _airybi_n2_inf(ctx): + prec = ctx.prec + try: + v = ctx.power(3,'2/3')*ctx.gamma('2/3')/(2*ctx.pi) + finally: + ctx.prec = prec + return +v + +# Derivatives at z = 0 +# TODO: could be expressed more elegantly using triple factorials +def _airyderiv_0(ctx, z, n, ntype, which): + if ntype == 'Z': + if n < 0: + return z + r = ctx.mpq_1_3 + prec = ctx.prec + try: + ctx.prec += 10 + v = ctx.gamma((n+1)*r) * ctx.power(3,n*r) / ctx.pi + if which == 0: + v *= ctx.sinpi(2*(n+1)*r) + v /= ctx.power(3,'2/3') + else: + v *= abs(ctx.sinpi(2*(n+1)*r)) + v /= ctx.power(3,'1/6') + finally: + ctx.prec = prec + return +v + z + else: + # singular (does the limit exist?) + raise NotImplementedError + +@defun +def airyai(ctx, z, derivative=0, **kwargs): + z = ctx.convert(z) + if derivative: + n, ntype = ctx._convert_param(derivative) + else: + n = 0 + # Values at infinities + if not ctx.isnormal(z) and z: + if n and ntype == 'Z': + if n == -1: + if z == ctx.inf: + return ctx.mpf(1)/3 + 1/z + if z == ctx.ninf: + return ctx.mpf(-2)/3 + 1/z + if n < -1: + if z == ctx.inf: + return z + if z == ctx.ninf: + return (-1)**n * (-z) + if (not n) and z == ctx.inf or z == ctx.ninf: + return 1/z + # TODO: limits + raise ValueError("essential singularity of Ai(z)") + # Account for exponential scaling + if z: + extraprec = max(0, int(1.5*ctx.mag(z))) + else: + extraprec = 0 + if n: + if n == 1: + def h(): + # http://functions.wolfram.com/03.07.06.0005.01 + if ctx._re(z) > 4: + ctx.prec += extraprec + w = z**1.5; r = -0.75/w; u = -2*w/3 + ctx.prec -= extraprec + C = -ctx.exp(u)/(2*ctx.sqrt(ctx.pi))*ctx.nthroot(z,4) + return ([C],[1],[],[],[(-1,6),(7,6)],[],r), + # http://functions.wolfram.com/03.07.26.0001.01 + else: + ctx.prec += extraprec + w = z**3 / 9 + ctx.prec -= extraprec + C1 = _airyai_C1(ctx) * 0.5 + C2 = _airyai_C2(ctx) + T1 = [C1,z],[1,2],[],[],[],[ctx.mpq_5_3],w + T2 = [C2],[1],[],[],[],[ctx.mpq_1_3],w + return T1, T2 + return ctx.hypercomb(h, [], **kwargs) + else: + if z == 0: + return _airyderiv_0(ctx, z, n, ntype, 0) + # http://functions.wolfram.com/03.05.20.0004.01 + def h(n): + ctx.prec += extraprec + w = z**3/9 + ctx.prec -= extraprec + q13,q23,q43 = ctx.mpq_1_3, ctx.mpq_2_3, ctx.mpq_4_3 + a1=q13; a2=1; b1=(1-n)*q13; b2=(2-n)*q13; b3=1-n*q13 + T1 = [3, z], [n-q23, -n], [a1], [b1,b2,b3], \ + [a1,a2], [b1,b2,b3], w + a1=q23; b1=(2-n)*q13; b2=1-n*q13; b3=(4-n)*q13 + T2 = [3, z, -z], [n-q43, -n, 1], [a1], [b1,b2,b3], \ + [a1,a2], [b1,b2,b3], w + return T1, T2 + v = ctx.hypercomb(h, [n], **kwargs) + if ctx._is_real_type(z) and ctx.isint(n): + v = ctx._re(v) + return v + else: + def h(): + if ctx._re(z) > 4: + # We could use 1F1, but it results in huge cancellation; + # the following expansion is better. + # TODO: asymptotic series for derivatives + ctx.prec += extraprec + w = z**1.5; r = -0.75/w; u = -2*w/3 + ctx.prec -= extraprec + C = ctx.exp(u)/(2*ctx.sqrt(ctx.pi)*ctx.nthroot(z,4)) + return ([C],[1],[],[],[(1,6),(5,6)],[],r), + else: + ctx.prec += extraprec + w = z**3 / 9 + ctx.prec -= extraprec + C1 = _airyai_C1(ctx) + C2 = _airyai_C2(ctx) + T1 = [C1],[1],[],[],[],[ctx.mpq_2_3],w + T2 = [z*C2],[1],[],[],[],[ctx.mpq_4_3],w + return T1, T2 + return ctx.hypercomb(h, [], **kwargs) + +@defun +def airybi(ctx, z, derivative=0, **kwargs): + z = ctx.convert(z) + if derivative: + n, ntype = ctx._convert_param(derivative) + else: + n = 0 + # Values at infinities + if not ctx.isnormal(z) and z: + if n and ntype == 'Z': + if z == ctx.inf: + return z + if z == ctx.ninf: + if n == -1: + return 1/z + if n == -2: + return _airybi_n2_inf(ctx) + if n < -2: + return (-1)**n * (-z) + if not n: + if z == ctx.inf: + return z + if z == ctx.ninf: + return 1/z + # TODO: limits + raise ValueError("essential singularity of Bi(z)") + if z: + extraprec = max(0, int(1.5*ctx.mag(z))) + else: + extraprec = 0 + if n: + if n == 1: + # http://functions.wolfram.com/03.08.26.0001.01 + def h(): + ctx.prec += extraprec + w = z**3 / 9 + ctx.prec -= extraprec + C1 = _airybi_C1(ctx)*0.5 + C2 = _airybi_C2(ctx) + T1 = [C1,z],[1,2],[],[],[],[ctx.mpq_5_3],w + T2 = [C2],[1],[],[],[],[ctx.mpq_1_3],w + return T1, T2 + return ctx.hypercomb(h, [], **kwargs) + else: + if z == 0: + return _airyderiv_0(ctx, z, n, ntype, 1) + def h(n): + ctx.prec += extraprec + w = z**3/9 + ctx.prec -= extraprec + q13,q23,q43 = ctx.mpq_1_3, ctx.mpq_2_3, ctx.mpq_4_3 + q16 = ctx.mpq_1_6 + q56 = ctx.mpq_5_6 + a1=q13; a2=1; b1=(1-n)*q13; b2=(2-n)*q13; b3=1-n*q13 + T1 = [3, z], [n-q16, -n], [a1], [b1,b2,b3], \ + [a1,a2], [b1,b2,b3], w + a1=q23; b1=(2-n)*q13; b2=1-n*q13; b3=(4-n)*q13 + T2 = [3, z], [n-q56, 1-n], [a1], [b1,b2,b3], \ + [a1,a2], [b1,b2,b3], w + return T1, T2 + v = ctx.hypercomb(h, [n], **kwargs) + if ctx._is_real_type(z) and ctx.isint(n): + v = ctx._re(v) + return v + else: + def h(): + ctx.prec += extraprec + w = z**3 / 9 + ctx.prec -= extraprec + C1 = _airybi_C1(ctx) + C2 = _airybi_C2(ctx) + T1 = [C1],[1],[],[],[],[ctx.mpq_2_3],w + T2 = [z*C2],[1],[],[],[],[ctx.mpq_4_3],w + return T1, T2 + return ctx.hypercomb(h, [], **kwargs) + +def _airy_zero(ctx, which, k, derivative, complex=False): + # Asymptotic formulas are given in DLMF section 9.9 + def U(t): return t**(2/3.)*(1-7/(t**2*48)) + def T(t): return t**(2/3.)*(1+5/(t**2*48)) + k = int(k) + if k < 1: + raise ValueError("k cannot be less than 1") + if not derivative in (0,1): + raise ValueError("Derivative should lie between 0 and 1") + if which == 0: + if derivative: + return ctx.findroot(lambda z: ctx.airyai(z,1), + -U(3*ctx.pi*(4*k-3)/8)) + return ctx.findroot(ctx.airyai, -T(3*ctx.pi*(4*k-1)/8)) + if which == 1 and complex == False: + if derivative: + return ctx.findroot(lambda z: ctx.airybi(z,1), + -U(3*ctx.pi*(4*k-1)/8)) + return ctx.findroot(ctx.airybi, -T(3*ctx.pi*(4*k-3)/8)) + if which == 1 and complex == True: + if derivative: + t = 3*ctx.pi*(4*k-3)/8 + 0.75j*ctx.ln2 + s = ctx.expjpi(ctx.mpf(1)/3) * T(t) + return ctx.findroot(lambda z: ctx.airybi(z,1), s) + t = 3*ctx.pi*(4*k-1)/8 + 0.75j*ctx.ln2 + s = ctx.expjpi(ctx.mpf(1)/3) * U(t) + return ctx.findroot(ctx.airybi, s) + +@defun +def airyaizero(ctx, k, derivative=0): + return _airy_zero(ctx, 0, k, derivative, False) + +@defun +def airybizero(ctx, k, derivative=0, complex=False): + return _airy_zero(ctx, 1, k, derivative, complex) + +def _scorer(ctx, z, which, kwargs): + z = ctx.convert(z) + if ctx.isinf(z): + if z == ctx.inf: + if which == 0: return 1/z + if which == 1: return z + if z == ctx.ninf: + return 1/z + raise ValueError("essential singularity") + if z: + extraprec = max(0, int(1.5*ctx.mag(z))) + else: + extraprec = 0 + if kwargs.get('derivative'): + raise NotImplementedError + # Direct asymptotic expansions, to avoid + # exponentially large cancellation + try: + if ctx.mag(z) > 3: + if which == 0 and abs(ctx.arg(z)) < ctx.pi/3 * 0.999: + def h(): + return (([ctx.pi,z],[-1,-1],[],[],[(1,3),(2,3),1],[],9/z**3),) + return ctx.hypercomb(h, [], maxterms=ctx.prec, force_series=True) + if which == 1 and abs(ctx.arg(-z)) < 2*ctx.pi/3 * 0.999: + def h(): + return (([-ctx.pi,z],[-1,-1],[],[],[(1,3),(2,3),1],[],9/z**3),) + return ctx.hypercomb(h, [], maxterms=ctx.prec, force_series=True) + except ctx.NoConvergence: + pass + def h(): + A = ctx.airybi(z, **kwargs)/3 + B = -2*ctx.pi + if which == 1: + A *= 2 + B *= -1 + ctx.prec += extraprec + w = z**3/9 + ctx.prec -= extraprec + T1 = [A], [1], [], [], [], [], 0 + T2 = [B,z], [-1,2], [], [], [1], [ctx.mpq_4_3,ctx.mpq_5_3], w + return T1, T2 + return ctx.hypercomb(h, [], **kwargs) + +@defun +def scorergi(ctx, z, **kwargs): + return _scorer(ctx, z, 0, kwargs) + +@defun +def scorerhi(ctx, z, **kwargs): + return _scorer(ctx, z, 1, kwargs) + +@defun_wrapped +def coulombc(ctx, l, eta, _cache={}): + if (l, eta) in _cache and _cache[l,eta][0] >= ctx.prec: + return +_cache[l,eta][1] + G3 = ctx.loggamma(2*l+2) + G1 = ctx.loggamma(1+l+ctx.j*eta) + G2 = ctx.loggamma(1+l-ctx.j*eta) + v = 2**l * ctx.exp((-ctx.pi*eta+G1+G2)/2 - G3) + if not (ctx.im(l) or ctx.im(eta)): + v = ctx.re(v) + _cache[l,eta] = (ctx.prec, v) + return v + +@defun_wrapped +def coulombf(ctx, l, eta, z, w=1, chop=True, **kwargs): + # Regular Coulomb wave function + # Note: w can be either 1 or -1; the other may be better in some cases + # TODO: check that chop=True chops when and only when it should + #ctx.prec += 10 + def h(l, eta): + try: + jw = ctx.j*w + jwz = ctx.fmul(jw, z, exact=True) + jwz2 = ctx.fmul(jwz, -2, exact=True) + C = ctx.coulombc(l, eta) + T1 = [C, z, ctx.exp(jwz)], [1, l+1, 1], [], [], [1+l+jw*eta], \ + [2*l+2], jwz2 + except ValueError: + T1 = [0], [-1], [], [], [], [], 0 + return (T1,) + v = ctx.hypercomb(h, [l,eta], **kwargs) + if chop and (not ctx.im(l)) and (not ctx.im(eta)) and (not ctx.im(z)) and \ + (ctx.re(z) >= 0): + v = ctx.re(v) + return v + +@defun_wrapped +def _coulomb_chi(ctx, l, eta, _cache={}): + if (l, eta) in _cache and _cache[l,eta][0] >= ctx.prec: + return _cache[l,eta][1] + def terms(): + l2 = -l-1 + jeta = ctx.j*eta + return [ctx.loggamma(1+l+jeta) * (-0.5j), + ctx.loggamma(1+l-jeta) * (0.5j), + ctx.loggamma(1+l2+jeta) * (0.5j), + ctx.loggamma(1+l2-jeta) * (-0.5j), + -(l+0.5)*ctx.pi] + v = ctx.sum_accurately(terms, 1) + _cache[l,eta] = (ctx.prec, v) + return v + +@defun_wrapped +def coulombg(ctx, l, eta, z, w=1, chop=True, **kwargs): + # Irregular Coulomb wave function + # Note: w can be either 1 or -1; the other may be better in some cases + # TODO: check that chop=True chops when and only when it should + if not ctx._im(l): + l = ctx._re(l) # XXX: for isint + def h(l, eta): + # Force perturbation for integers and half-integers + if ctx.isint(l*2): + T1 = [0], [-1], [], [], [], [], 0 + return (T1,) + l2 = -l-1 + try: + chi = ctx._coulomb_chi(l, eta) + jw = ctx.j*w + s = ctx.sin(chi); c = ctx.cos(chi) + C1 = ctx.coulombc(l,eta) + C2 = ctx.coulombc(l2,eta) + u = ctx.exp(jw*z) + x = -2*jw*z + T1 = [s, C1, z, u, c], [-1, 1, l+1, 1, 1], [], [], \ + [1+l+jw*eta], [2*l+2], x + T2 = [-s, C2, z, u], [-1, 1, l2+1, 1], [], [], \ + [1+l2+jw*eta], [2*l2+2], x + return T1, T2 + except ValueError: + T1 = [0], [-1], [], [], [], [], 0 + return (T1,) + v = ctx.hypercomb(h, [l,eta], **kwargs) + if chop and (not ctx._im(l)) and (not ctx._im(eta)) and (not ctx._im(z)) and \ + (ctx._re(z) >= 0): + v = ctx._re(v) + return v + +def mcmahon(ctx,kind,prime,v,m): + """ + Computes an estimate for the location of the Bessel function zero + j_{v,m}, y_{v,m}, j'_{v,m} or y'_{v,m} using McMahon's asymptotic + expansion (Abramowitz & Stegun 9.5.12-13, DLMF 20.21(vi)). + + Returns (r,err) where r is the estimated location of the root + and err is a positive number estimating the error of the + asymptotic expansion. + """ + u = 4*v**2 + if kind == 1 and not prime: b = (4*m+2*v-1)*ctx.pi/4 + if kind == 2 and not prime: b = (4*m+2*v-3)*ctx.pi/4 + if kind == 1 and prime: b = (4*m+2*v-3)*ctx.pi/4 + if kind == 2 and prime: b = (4*m+2*v-1)*ctx.pi/4 + if not prime: + s1 = b + s2 = -(u-1)/(8*b) + s3 = -4*(u-1)*(7*u-31)/(3*(8*b)**3) + s4 = -32*(u-1)*(83*u**2-982*u+3779)/(15*(8*b)**5) + s5 = -64*(u-1)*(6949*u**3-153855*u**2+1585743*u-6277237)/(105*(8*b)**7) + if prime: + s1 = b + s2 = -(u+3)/(8*b) + s3 = -4*(7*u**2+82*u-9)/(3*(8*b)**3) + s4 = -32*(83*u**3+2075*u**2-3039*u+3537)/(15*(8*b)**5) + s5 = -64*(6949*u**4+296492*u**3-1248002*u**2+7414380*u-5853627)/(105*(8*b)**7) + terms = [s1,s2,s3,s4,s5] + s = s1 + err = 0.0 + for i in range(1,len(terms)): + if abs(terms[i]) < abs(terms[i-1]): + s += terms[i] + else: + err = abs(terms[i]) + if i == len(terms)-1: + err = abs(terms[-1]) + return s, err + +def generalized_bisection(ctx,f,a,b,n): + """ + Given f known to have exactly n simple roots within [a,b], + return a list of n intervals isolating the roots + and having opposite signs at the endpoints. + + TODO: this can be optimized, e.g. by reusing evaluation points. + """ + if n < 1: + raise ValueError("n cannot be less than 1") + N = n+1 + points = [] + signs = [] + while 1: + points = ctx.linspace(a,b,N) + signs = [ctx.sign(f(x)) for x in points] + ok_intervals = [(points[i],points[i+1]) for i in range(N-1) \ + if signs[i]*signs[i+1] == -1] + if len(ok_intervals) == n: + return ok_intervals + N = N*2 + +def find_in_interval(ctx, f, ab): + return ctx.findroot(f, ab, solver='illinois', verify=False) + +def bessel_zero(ctx, kind, prime, v, m, isoltol=0.01, _interval_cache={}): + prec = ctx.prec + workprec = max(prec, ctx.mag(v), ctx.mag(m))+10 + try: + ctx.prec = workprec + v = ctx.mpf(v) + m = int(m) + prime = int(prime) + if v < 0: + raise ValueError("v cannot be negative") + if m < 1: + raise ValueError("m cannot be less than 1") + if not prime in (0,1): + raise ValueError("prime should lie between 0 and 1") + if kind == 1: + if prime: f = lambda x: ctx.besselj(v,x,derivative=1) + else: f = lambda x: ctx.besselj(v,x) + if kind == 2: + if prime: f = lambda x: ctx.bessely(v,x,derivative=1) + else: f = lambda x: ctx.bessely(v,x) + # The first root of J' is very close to 0 for small + # orders, and this needs to be special-cased + if kind == 1 and prime and m == 1: + if v == 0: + return ctx.zero + if v <= 1: + # TODO: use v <= j'_{v,1} < y_{v,1}? + r = 2*ctx.sqrt(v*(1+v)/(v+2)) + return find_in_interval(ctx, f, (r/10, 2*r)) + if (kind,prime,v,m) in _interval_cache: + return find_in_interval(ctx, f, _interval_cache[kind,prime,v,m]) + r, err = mcmahon(ctx, kind, prime, v, m) + if err < isoltol: + return find_in_interval(ctx, f, (r-isoltol, r+isoltol)) + # An x such that 0 < x < r_{v,1} + if kind == 1 and not prime: low = 2.4 + if kind == 1 and prime: low = 1.8 + if kind == 2 and not prime: low = 0.8 + if kind == 2 and prime: low = 2.0 + n = m+1 + while 1: + r1, err = mcmahon(ctx, kind, prime, v, n) + if err < isoltol: + r2, err2 = mcmahon(ctx, kind, prime, v, n+1) + intervals = generalized_bisection(ctx, f, low, 0.5*(r1+r2), n) + for k, ab in enumerate(intervals): + _interval_cache[kind,prime,v,k+1] = ab + return find_in_interval(ctx, f, intervals[m-1]) + else: + n = n*2 + finally: + ctx.prec = prec + +@defun +def besseljzero(ctx, v, m, derivative=0): + r""" + For a real order `\nu \ge 0` and a positive integer `m`, returns + `j_{\nu,m}`, the `m`-th positive zero of the Bessel function of the + first kind `J_{\nu}(z)` (see :func:`~mpmath.besselj`). Alternatively, + with *derivative=1*, gives the first nonnegative simple zero + `j'_{\nu,m}` of `J'_{\nu}(z)`. + + The indexing convention is that used by Abramowitz & Stegun + and the DLMF. Note the special case `j'_{0,1} = 0`, while all other + zeros are positive. In effect, only simple zeros are counted + (all zeros of Bessel functions are simple except possibly `z = 0`) + and `j_{\nu,m}` becomes a monotonic function of both `\nu` + and `m`. + + The zeros are interlaced according to the inequalities + + .. math :: + + j'_{\nu,k} < j_{\nu,k} < j'_{\nu,k+1} + + j_{\nu,1} < j_{\nu+1,2} < j_{\nu,2} < j_{\nu+1,2} < j_{\nu,3} < \cdots + + **Examples** + + Initial zeros of the Bessel functions `J_0(z), J_1(z), J_2(z)`:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> besseljzero(0,1); besseljzero(0,2); besseljzero(0,3) + 2.404825557695772768621632 + 5.520078110286310649596604 + 8.653727912911012216954199 + >>> besseljzero(1,1); besseljzero(1,2); besseljzero(1,3) + 3.831705970207512315614436 + 7.01558666981561875353705 + 10.17346813506272207718571 + >>> besseljzero(2,1); besseljzero(2,2); besseljzero(2,3) + 5.135622301840682556301402 + 8.417244140399864857783614 + 11.61984117214905942709415 + + Initial zeros of `J'_0(z), J'_1(z), J'_2(z)`:: + + 0.0 + 3.831705970207512315614436 + 7.01558666981561875353705 + >>> besseljzero(1,1,1); besseljzero(1,2,1); besseljzero(1,3,1) + 1.84118378134065930264363 + 5.331442773525032636884016 + 8.536316366346285834358961 + >>> besseljzero(2,1,1); besseljzero(2,2,1); besseljzero(2,3,1) + 3.054236928227140322755932 + 6.706133194158459146634394 + 9.969467823087595793179143 + + Zeros with large index:: + + >>> besseljzero(0,100); besseljzero(0,1000); besseljzero(0,10000) + 313.3742660775278447196902 + 3140.807295225078628895545 + 31415.14114171350798533666 + >>> besseljzero(5,100); besseljzero(5,1000); besseljzero(5,10000) + 321.1893195676003157339222 + 3148.657306813047523500494 + 31422.9947255486291798943 + >>> besseljzero(0,100,1); besseljzero(0,1000,1); besseljzero(0,10000,1) + 311.8018681873704508125112 + 3139.236339643802482833973 + 31413.57032947022399485808 + + Zeros of functions with large order:: + + >>> besseljzero(50,1) + 57.11689916011917411936228 + >>> besseljzero(50,2) + 62.80769876483536093435393 + >>> besseljzero(50,100) + 388.6936600656058834640981 + >>> besseljzero(50,1,1) + 52.99764038731665010944037 + >>> besseljzero(50,2,1) + 60.02631933279942589882363 + >>> besseljzero(50,100,1) + 387.1083151608726181086283 + + Zeros of functions with fractional order:: + + >>> besseljzero(0.5,1); besseljzero(1.5,1); besseljzero(2.25,4) + 3.141592653589793238462643 + 4.493409457909064175307881 + 15.15657692957458622921634 + + Both `J_{\nu}(z)` and `J'_{\nu}(z)` can be expressed as infinite + products over their zeros:: + + >>> v,z = 2, mpf(1) + >>> (z/2)**v/gamma(v+1) * \ + ... nprod(lambda k: 1-(z/besseljzero(v,k))**2, [1,inf]) + ... + 0.1149034849319004804696469 + >>> besselj(v,z) + 0.1149034849319004804696469 + >>> (z/2)**(v-1)/2/gamma(v) * \ + ... nprod(lambda k: 1-(z/besseljzero(v,k,1))**2, [1,inf]) + ... + 0.2102436158811325550203884 + >>> besselj(v,z,1) + 0.2102436158811325550203884 + + """ + return +bessel_zero(ctx, 1, derivative, v, m) + +@defun +def besselyzero(ctx, v, m, derivative=0): + r""" + For a real order `\nu \ge 0` and a positive integer `m`, returns + `y_{\nu,m}`, the `m`-th positive zero of the Bessel function of the + second kind `Y_{\nu}(z)` (see :func:`~mpmath.bessely`). Alternatively, + with *derivative=1*, gives the first positive zero `y'_{\nu,m}` of + `Y'_{\nu}(z)`. + + The zeros are interlaced according to the inequalities + + .. math :: + + y_{\nu,k} < y'_{\nu,k} < y_{\nu,k+1} + + y_{\nu,1} < y_{\nu+1,2} < y_{\nu,2} < y_{\nu+1,2} < y_{\nu,3} < \cdots + + **Examples** + + Initial zeros of the Bessel functions `Y_0(z), Y_1(z), Y_2(z)`:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> besselyzero(0,1); besselyzero(0,2); besselyzero(0,3) + 0.8935769662791675215848871 + 3.957678419314857868375677 + 7.086051060301772697623625 + >>> besselyzero(1,1); besselyzero(1,2); besselyzero(1,3) + 2.197141326031017035149034 + 5.429681040794135132772005 + 8.596005868331168926429606 + >>> besselyzero(2,1); besselyzero(2,2); besselyzero(2,3) + 3.384241767149593472701426 + 6.793807513268267538291167 + 10.02347797936003797850539 + + Initial zeros of `Y'_0(z), Y'_1(z), Y'_2(z)`:: + + >>> besselyzero(0,1,1); besselyzero(0,2,1); besselyzero(0,3,1) + 2.197141326031017035149034 + 5.429681040794135132772005 + 8.596005868331168926429606 + >>> besselyzero(1,1,1); besselyzero(1,2,1); besselyzero(1,3,1) + 3.683022856585177699898967 + 6.941499953654175655751944 + 10.12340465543661307978775 + >>> besselyzero(2,1,1); besselyzero(2,2,1); besselyzero(2,3,1) + 5.002582931446063945200176 + 8.350724701413079526349714 + 11.57419546521764654624265 + + Zeros with large index:: + + >>> besselyzero(0,100); besselyzero(0,1000); besselyzero(0,10000) + 311.8034717601871549333419 + 3139.236498918198006794026 + 31413.57034538691205229188 + >>> besselyzero(5,100); besselyzero(5,1000); besselyzero(5,10000) + 319.6183338562782156235062 + 3147.086508524556404473186 + 31421.42392920214673402828 + >>> besselyzero(0,100,1); besselyzero(0,1000,1); besselyzero(0,10000,1) + 313.3726705426359345050449 + 3140.807136030340213610065 + 31415.14112579761578220175 + + Zeros of functions with large order:: + + >>> besselyzero(50,1) + 53.50285882040036394680237 + >>> besselyzero(50,2) + 60.11244442774058114686022 + >>> besselyzero(50,100) + 387.1096509824943957706835 + >>> besselyzero(50,1,1) + 56.96290427516751320063605 + >>> besselyzero(50,2,1) + 62.74888166945933944036623 + >>> besselyzero(50,100,1) + 388.6923300548309258355475 + + Zeros of functions with fractional order:: + + >>> besselyzero(0.5,1); besselyzero(1.5,1); besselyzero(2.25,4) + 1.570796326794896619231322 + 2.798386045783887136720249 + 13.56721208770735123376018 + + """ + return +bessel_zero(ctx, 2, derivative, v, m) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/elliptic.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/elliptic.py new file mode 100644 index 0000000000000000000000000000000000000000..1e198697fa042b7cc8bcba9e9e770f5c8106dad6 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/elliptic.py @@ -0,0 +1,1431 @@ +r""" +Elliptic functions historically comprise the elliptic integrals +and their inverses, and originate from the problem of computing the +arc length of an ellipse. From a more modern point of view, +an elliptic function is defined as a doubly periodic function, i.e. +a function which satisfies + +.. math :: + + f(z + 2 \omega_1) = f(z + 2 \omega_2) = f(z) + +for some half-periods `\omega_1, \omega_2` with +`\mathrm{Im}[\omega_1 / \omega_2] > 0`. The canonical elliptic +functions are the Jacobi elliptic functions. More broadly, this section +includes quasi-doubly periodic functions (such as the Jacobi theta +functions) and other functions useful in the study of elliptic functions. + +Many different conventions for the arguments of +elliptic functions are in use. It is even standard to use +different parameterizations for different functions in the same +text or software (and mpmath is no exception). +The usual parameters are the elliptic nome `q`, which usually +must satisfy `|q| < 1`; the elliptic parameter `m` (an arbitrary +complex number); the elliptic modulus `k` (an arbitrary complex +number); and the half-period ratio `\tau`, which usually must +satisfy `\mathrm{Im}[\tau] > 0`. +These quantities can be expressed in terms of each other +using the following relations: + +.. math :: + + m = k^2 + +.. math :: + + \tau = i \frac{K(1-m)}{K(m)} + +.. math :: + + q = e^{i \pi \tau} + +.. math :: + + k = \frac{\vartheta_2^2(q)}{\vartheta_3^2(q)} + +In addition, an alternative definition is used for the nome in +number theory, which we here denote by q-bar: + +.. math :: + + \bar{q} = q^2 = e^{2 i \pi \tau} + +For convenience, mpmath provides functions to convert +between the various parameters (:func:`~mpmath.qfrom`, :func:`~mpmath.mfrom`, +:func:`~mpmath.kfrom`, :func:`~mpmath.taufrom`, :func:`~mpmath.qbarfrom`). + +**References** + +1. [AbramowitzStegun]_ + +2. [WhittakerWatson]_ + +""" + +from .functions import defun, defun_wrapped + +@defun_wrapped +def eta(ctx, tau): + r""" + Returns the Dedekind eta function of tau in the upper half-plane. + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> eta(1j); gamma(0.25) / (2*pi**0.75) + (0.7682254223260566590025942 + 0.0j) + 0.7682254223260566590025942 + >>> tau = sqrt(2) + sqrt(5)*1j + >>> eta(-1/tau); sqrt(-1j*tau) * eta(tau) + (0.9022859908439376463573294 + 0.07985093673948098408048575j) + (0.9022859908439376463573295 + 0.07985093673948098408048575j) + >>> eta(tau+1); exp(pi*1j/12) * eta(tau) + (0.4493066139717553786223114 + 0.3290014793877986663915939j) + (0.4493066139717553786223114 + 0.3290014793877986663915939j) + >>> f = lambda z: diff(eta, z) / eta(z) + >>> chop(36*diff(f,tau)**2 - 24*diff(f,tau,2)*f(tau) + diff(f,tau,3)) + 0.0 + + """ + if ctx.im(tau) <= 0.0: + raise ValueError("eta is only defined in the upper half-plane") + q = ctx.expjpi(tau/12) + return q * ctx.qp(q**24) + +def nome(ctx, m): + m = ctx.convert(m) + if not m: + return m + if m == ctx.one: + return m + if ctx.isnan(m): + return m + if ctx.isinf(m): + if m == ctx.ninf: + return type(m)(-1) + else: + return ctx.mpc(-1) + a = ctx.ellipk(ctx.one-m) + b = ctx.ellipk(m) + v = ctx.exp(-ctx.pi*a/b) + if not ctx._im(m) and ctx._re(m) < 1: + if ctx._is_real_type(m): + return v.real + else: + return v.real + 0j + elif m == 2: + v = ctx.mpc(0, v.imag) + return v + +@defun_wrapped +def qfrom(ctx, q=None, m=None, k=None, tau=None, qbar=None): + r""" + Returns the elliptic nome `q`, given any of `q, m, k, \tau, \bar{q}`:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> qfrom(q=0.25) + 0.25 + >>> qfrom(m=mfrom(q=0.25)) + 0.25 + >>> qfrom(k=kfrom(q=0.25)) + 0.25 + >>> qfrom(tau=taufrom(q=0.25)) + (0.25 + 0.0j) + >>> qfrom(qbar=qbarfrom(q=0.25)) + 0.25 + + """ + if q is not None: + return ctx.convert(q) + if m is not None: + return nome(ctx, m) + if k is not None: + return nome(ctx, ctx.convert(k)**2) + if tau is not None: + return ctx.expjpi(tau) + if qbar is not None: + return ctx.sqrt(qbar) + +@defun_wrapped +def qbarfrom(ctx, q=None, m=None, k=None, tau=None, qbar=None): + r""" + Returns the number-theoretic nome `\bar q`, given any of + `q, m, k, \tau, \bar{q}`:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> qbarfrom(qbar=0.25) + 0.25 + >>> qbarfrom(q=qfrom(qbar=0.25)) + 0.25 + >>> qbarfrom(m=extraprec(20)(mfrom)(qbar=0.25)) # ill-conditioned + 0.25 + >>> qbarfrom(k=extraprec(20)(kfrom)(qbar=0.25)) # ill-conditioned + 0.25 + >>> qbarfrom(tau=taufrom(qbar=0.25)) + (0.25 + 0.0j) + + """ + if qbar is not None: + return ctx.convert(qbar) + if q is not None: + return ctx.convert(q) ** 2 + if m is not None: + return nome(ctx, m) ** 2 + if k is not None: + return nome(ctx, ctx.convert(k)**2) ** 2 + if tau is not None: + return ctx.expjpi(2*tau) + +@defun_wrapped +def taufrom(ctx, q=None, m=None, k=None, tau=None, qbar=None): + r""" + Returns the elliptic half-period ratio `\tau`, given any of + `q, m, k, \tau, \bar{q}`:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> taufrom(tau=0.5j) + (0.0 + 0.5j) + >>> taufrom(q=qfrom(tau=0.5j)) + (0.0 + 0.5j) + >>> taufrom(m=mfrom(tau=0.5j)) + (0.0 + 0.5j) + >>> taufrom(k=kfrom(tau=0.5j)) + (0.0 + 0.5j) + >>> taufrom(qbar=qbarfrom(tau=0.5j)) + (0.0 + 0.5j) + + """ + if tau is not None: + return ctx.convert(tau) + if m is not None: + m = ctx.convert(m) + return ctx.j*ctx.ellipk(1-m)/ctx.ellipk(m) + if k is not None: + k = ctx.convert(k) + return ctx.j*ctx.ellipk(1-k**2)/ctx.ellipk(k**2) + if q is not None: + return ctx.log(q) / (ctx.pi*ctx.j) + if qbar is not None: + qbar = ctx.convert(qbar) + return ctx.log(qbar) / (2*ctx.pi*ctx.j) + +@defun_wrapped +def kfrom(ctx, q=None, m=None, k=None, tau=None, qbar=None): + r""" + Returns the elliptic modulus `k`, given any of + `q, m, k, \tau, \bar{q}`:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> kfrom(k=0.25) + 0.25 + >>> kfrom(m=mfrom(k=0.25)) + 0.25 + >>> kfrom(q=qfrom(k=0.25)) + 0.25 + >>> kfrom(tau=taufrom(k=0.25)) + (0.25 + 0.0j) + >>> kfrom(qbar=qbarfrom(k=0.25)) + 0.25 + + As `q \to 1` and `q \to -1`, `k` rapidly approaches + `1` and `i \infty` respectively:: + + >>> kfrom(q=0.75) + 0.9999999999999899166471767 + >>> kfrom(q=-0.75) + (0.0 + 7041781.096692038332790615j) + >>> kfrom(q=1) + 1 + >>> kfrom(q=-1) + (0.0 + +infj) + """ + if k is not None: + return ctx.convert(k) + if m is not None: + return ctx.sqrt(m) + if tau is not None: + q = ctx.expjpi(tau) + if qbar is not None: + q = ctx.sqrt(qbar) + if q == 1: + return q + if q == -1: + return ctx.mpc(0,'inf') + return (ctx.jtheta(2,0,q)/ctx.jtheta(3,0,q))**2 + +@defun_wrapped +def mfrom(ctx, q=None, m=None, k=None, tau=None, qbar=None): + r""" + Returns the elliptic parameter `m`, given any of + `q, m, k, \tau, \bar{q}`:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> mfrom(m=0.25) + 0.25 + >>> mfrom(q=qfrom(m=0.25)) + 0.25 + >>> mfrom(k=kfrom(m=0.25)) + 0.25 + >>> mfrom(tau=taufrom(m=0.25)) + (0.25 + 0.0j) + >>> mfrom(qbar=qbarfrom(m=0.25)) + 0.25 + + As `q \to 1` and `q \to -1`, `m` rapidly approaches + `1` and `-\infty` respectively:: + + >>> mfrom(q=0.75) + 0.9999999999999798332943533 + >>> mfrom(q=-0.75) + -49586681013729.32611558353 + >>> mfrom(q=1) + 1.0 + >>> mfrom(q=-1) + -inf + + The inverse nome as a function of `q` has an integer + Taylor series expansion:: + + >>> taylor(lambda q: mfrom(q), 0, 7) + [0.0, 16.0, -128.0, 704.0, -3072.0, 11488.0, -38400.0, 117632.0] + + """ + if m is not None: + return m + if k is not None: + return k**2 + if tau is not None: + q = ctx.expjpi(tau) + if qbar is not None: + q = ctx.sqrt(qbar) + if q == 1: + return ctx.convert(q) + if q == -1: + return q*ctx.inf + v = (ctx.jtheta(2,0,q)/ctx.jtheta(3,0,q))**4 + if ctx._is_real_type(q) and q < 0: + v = v.real + return v + +jacobi_spec = { + 'sn' : ([3],[2],[1],[4], 'sin', 'tanh'), + 'cn' : ([4],[2],[2],[4], 'cos', 'sech'), + 'dn' : ([4],[3],[3],[4], '1', 'sech'), + 'ns' : ([2],[3],[4],[1], 'csc', 'coth'), + 'nc' : ([2],[4],[4],[2], 'sec', 'cosh'), + 'nd' : ([3],[4],[4],[3], '1', 'cosh'), + 'sc' : ([3],[4],[1],[2], 'tan', 'sinh'), + 'sd' : ([3,3],[2,4],[1],[3], 'sin', 'sinh'), + 'cd' : ([3],[2],[2],[3], 'cos', '1'), + 'cs' : ([4],[3],[2],[1], 'cot', 'csch'), + 'dc' : ([2],[3],[3],[2], 'sec', '1'), + 'ds' : ([2,4],[3,3],[3],[1], 'csc', 'csch'), + 'cc' : None, + 'ss' : None, + 'nn' : None, + 'dd' : None +} + +@defun +def ellipfun(ctx, kind, u=None, m=None, q=None, k=None, tau=None): + try: + S = jacobi_spec[kind] + except KeyError: + raise ValueError("First argument must be a two-character string " + "containing 's', 'c', 'd' or 'n', e.g.: 'sn'") + if u is None: + def f(*args, **kwargs): + return ctx.ellipfun(kind, *args, **kwargs) + f.__name__ = kind + return f + prec = ctx.prec + try: + ctx.prec += 10 + u = ctx.convert(u) + q = ctx.qfrom(m=m, q=q, k=k, tau=tau) + if S is None: + v = ctx.one + 0*q*u + elif q == ctx.zero: + if S[4] == '1': v = ctx.one + else: v = getattr(ctx, S[4])(u) + v += 0*q*u + elif q == ctx.one: + if S[5] == '1': v = ctx.one + else: v = getattr(ctx, S[5])(u) + v += 0*q*u + else: + t = u / ctx.jtheta(3, 0, q)**2 + v = ctx.one + for a in S[0]: v *= ctx.jtheta(a, 0, q) + for b in S[1]: v /= ctx.jtheta(b, 0, q) + for c in S[2]: v *= ctx.jtheta(c, t, q) + for d in S[3]: v /= ctx.jtheta(d, t, q) + finally: + ctx.prec = prec + return +v + +@defun_wrapped +def kleinj(ctx, tau=None, **kwargs): + r""" + Evaluates the Klein j-invariant, which is a modular function defined for + `\tau` in the upper half-plane as + + .. math :: + + J(\tau) = \frac{g_2^3(\tau)}{g_2^3(\tau) - 27 g_3^2(\tau)} + + where `g_2` and `g_3` are the modular invariants of the Weierstrass + elliptic function, + + .. math :: + + g_2(\tau) = 60 \sum_{(m,n) \in \mathbb{Z}^2 \setminus (0,0)} (m \tau+n)^{-4} + + g_3(\tau) = 140 \sum_{(m,n) \in \mathbb{Z}^2 \setminus (0,0)} (m \tau+n)^{-6}. + + An alternative, common notation is that of the j-function + `j(\tau) = 1728 J(\tau)`. + + **Plots** + + .. literalinclude :: /plots/kleinj.py + .. image :: /plots/kleinj.png + .. literalinclude :: /plots/kleinj2.py + .. image :: /plots/kleinj2.png + + **Examples** + + Verifying the functional equation `J(\tau) = J(\tau+1) = J(-\tau^{-1})`:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> tau = 0.625+0.75*j + >>> tau = 0.625+0.75*j + >>> kleinj(tau) + (-0.1507492166511182267125242 + 0.07595948379084571927228948j) + >>> kleinj(tau+1) + (-0.1507492166511182267125242 + 0.07595948379084571927228948j) + >>> kleinj(-1/tau) + (-0.1507492166511182267125242 + 0.07595948379084571927228946j) + + The j-function has a famous Laurent series expansion in terms of the nome + `\bar{q}`, `j(\tau) = \bar{q}^{-1} + 744 + 196884\bar{q} + \ldots`:: + + >>> mp.dps = 15 + >>> taylor(lambda q: 1728*q*kleinj(qbar=q), 0, 5, singular=True) + [1.0, 744.0, 196884.0, 21493760.0, 864299970.0, 20245856256.0] + + The j-function admits exact evaluation at special algebraic points + related to the Heegner numbers 1, 2, 3, 7, 11, 19, 43, 67, 163:: + + >>> @extraprec(10) + ... def h(n): + ... v = (1+sqrt(n)*j) + ... if n > 2: + ... v *= 0.5 + ... return v + ... + >>> mp.dps = 25 + >>> for n in [1,2,3,7,11,19,43,67,163]: + ... n, chop(1728*kleinj(h(n))) + ... + (1, 1728.0) + (2, 8000.0) + (3, 0.0) + (7, -3375.0) + (11, -32768.0) + (19, -884736.0) + (43, -884736000.0) + (67, -147197952000.0) + (163, -262537412640768000.0) + + Also at other special points, the j-function assumes explicit + algebraic values, e.g.:: + + >>> chop(1728*kleinj(j*sqrt(5))) + 1264538.909475140509320227 + >>> identify(cbrt(_)) # note: not simplified + '((100+sqrt(13520))/2)' + >>> (50+26*sqrt(5))**3 + 1264538.909475140509320227 + + """ + q = ctx.qfrom(tau=tau, **kwargs) + t2 = ctx.jtheta(2,0,q) + t3 = ctx.jtheta(3,0,q) + t4 = ctx.jtheta(4,0,q) + P = (t2**8 + t3**8 + t4**8)**3 + Q = 54*(t2*t3*t4)**8 + return P/Q + + +def RF_calc(ctx, x, y, z, r): + if y == z: return RC_calc(ctx, x, y, r) + if x == z: return RC_calc(ctx, y, x, r) + if x == y: return RC_calc(ctx, z, x, r) + if not (ctx.isnormal(x) and ctx.isnormal(y) and ctx.isnormal(z)): + if ctx.isnan(x) or ctx.isnan(y) or ctx.isnan(z): + return x*y*z + if ctx.isinf(x) or ctx.isinf(y) or ctx.isinf(z): + return ctx.zero + xm,ym,zm = x,y,z + A0 = Am = (x+y+z)/3 + Q = ctx.root(3*r, -6) * max(abs(A0-x),abs(A0-y),abs(A0-z)) + g = ctx.mpf(0.25) + pow4 = ctx.one + while 1: + xs = ctx.sqrt(xm) + ys = ctx.sqrt(ym) + zs = ctx.sqrt(zm) + lm = xs*ys + xs*zs + ys*zs + Am1 = (Am+lm)*g + xm, ym, zm = (xm+lm)*g, (ym+lm)*g, (zm+lm)*g + if pow4 * Q < abs(Am): + break + Am = Am1 + pow4 *= g + t = pow4/Am + X = (A0-x)*t + Y = (A0-y)*t + Z = -X-Y + E2 = X*Y-Z**2 + E3 = X*Y*Z + return ctx.power(Am,-0.5) * (9240-924*E2+385*E2**2+660*E3-630*E2*E3)/9240 + +def RC_calc(ctx, x, y, r, pv=True): + if not (ctx.isnormal(x) and ctx.isnormal(y)): + if ctx.isinf(x) or ctx.isinf(y): + return 1/(x*y) + if y == 0: + return ctx.inf + if x == 0: + return ctx.pi / ctx.sqrt(y) / 2 + raise ValueError + # Cauchy principal value + if pv and ctx._im(y) == 0 and ctx._re(y) < 0: + return ctx.sqrt(x/(x-y)) * RC_calc(ctx, x-y, -y, r) + if x == y: + return 1/ctx.sqrt(x) + extraprec = 2*max(0,-ctx.mag(x-y)+ctx.mag(x)) + ctx.prec += extraprec + if ctx._is_real_type(x) and ctx._is_real_type(y): + x = ctx._re(x) + y = ctx._re(y) + a = ctx.sqrt(x/y) + if x < y: + b = ctx.sqrt(y-x) + v = ctx.acos(a)/b + else: + b = ctx.sqrt(x-y) + v = ctx.acosh(a)/b + else: + sx = ctx.sqrt(x) + sy = ctx.sqrt(y) + v = ctx.acos(sx/sy)/(ctx.sqrt((1-x/y))*sy) + ctx.prec -= extraprec + return v + +def RJ_calc(ctx, x, y, z, p, r, integration): + """ + With integration == 0, computes RJ only using Carlson's algorithm + (may be wrong for some values). + With integration == 1, uses an initial integration to make sure + Carlson's algorithm is correct. + With integration == 2, uses only integration. + """ + if not (ctx.isnormal(x) and ctx.isnormal(y) and \ + ctx.isnormal(z) and ctx.isnormal(p)): + if ctx.isnan(x) or ctx.isnan(y) or ctx.isnan(z) or ctx.isnan(p): + return x*y*z + if ctx.isinf(x) or ctx.isinf(y) or ctx.isinf(z) or ctx.isinf(p): + return ctx.zero + if not p: + return ctx.inf + if (not x) + (not y) + (not z) > 1: + return ctx.inf + # Check conditions and fall back on integration for argument + # reduction if needed. The following conditions might be needlessly + # restrictive. + initial_integral = ctx.zero + if integration >= 1: + ok = (x.real >= 0 and y.real >= 0 and z.real >= 0 and p.real > 0) + if not ok: + if x == p or y == p or z == p: + ok = True + if not ok: + if p.imag != 0 or p.real >= 0: + if (x.imag == 0 and x.real >= 0 and ctx.conj(y) == z): + ok = True + if (y.imag == 0 and y.real >= 0 and ctx.conj(x) == z): + ok = True + if (z.imag == 0 and z.real >= 0 and ctx.conj(x) == y): + ok = True + if not ok or (integration == 2): + N = ctx.ceil(-min(x.real, y.real, z.real, p.real)) + 1 + # Integrate around any singularities + if all((t.imag >= 0 or t.real > 0) for t in [x, y, z, p]): + margin = ctx.j + elif all((t.imag < 0 or t.real > 0) for t in [x, y, z, p]): + margin = -ctx.j + else: + margin = 1 + # Go through the upper half-plane, but low enough that any + # parameter starting in the lower plane doesn't cross the + # branch cut + for t in [x, y, z, p]: + if t.imag >= 0 or t.real > 0: + continue + margin = min(margin, abs(t.imag) * 0.5) + margin *= ctx.j + N += margin + F = lambda t: 1/(ctx.sqrt(t+x)*ctx.sqrt(t+y)*ctx.sqrt(t+z)*(t+p)) + if integration == 2: + return 1.5 * ctx.quadsubdiv(F, [0, N, ctx.inf]) + initial_integral = 1.5 * ctx.quadsubdiv(F, [0, N]) + x += N; y += N; z += N; p += N + xm,ym,zm,pm = x,y,z,p + A0 = Am = (x + y + z + 2*p)/5 + delta = (p-x)*(p-y)*(p-z) + Q = ctx.root(0.25*r, -6) * max(abs(A0-x),abs(A0-y),abs(A0-z),abs(A0-p)) + g = ctx.mpf(0.25) + pow4 = ctx.one + S = 0 + while 1: + sx = ctx.sqrt(xm) + sy = ctx.sqrt(ym) + sz = ctx.sqrt(zm) + sp = ctx.sqrt(pm) + lm = sx*sy + sx*sz + sy*sz + Am1 = (Am+lm)*g + xm = (xm+lm)*g; ym = (ym+lm)*g; zm = (zm+lm)*g; pm = (pm+lm)*g + dm = (sp+sx) * (sp+sy) * (sp+sz) + em = delta * pow4**3 / dm**2 + if pow4 * Q < abs(Am): + break + T = RC_calc(ctx, ctx.one, ctx.one+em, r) * pow4 / dm + S += T + pow4 *= g + Am = Am1 + t = pow4 / Am + X = (A0-x)*t + Y = (A0-y)*t + Z = (A0-z)*t + P = (-X-Y-Z)/2 + E2 = X*Y + X*Z + Y*Z - 3*P**2 + E3 = X*Y*Z + 2*E2*P + 4*P**3 + E4 = (2*X*Y*Z + E2*P + 3*P**3)*P + E5 = X*Y*Z*P**2 + P = 24024 - 5148*E2 + 2457*E2**2 + 4004*E3 - 4158*E2*E3 - 3276*E4 + 2772*E5 + Q = 24024 + v1 = pow4 * ctx.power(Am, -1.5) * P/Q + v2 = 6*S + return initial_integral + v1 + v2 + +@defun +def elliprf(ctx, x, y, z): + r""" + Evaluates the Carlson symmetric elliptic integral of the first kind + + .. math :: + + R_F(x,y,z) = \frac{1}{2} + \int_0^{\infty} \frac{dt}{\sqrt{(t+x)(t+y)(t+z)}} + + which is defined for `x,y,z \notin (-\infty,0)`, and with + at most one of `x,y,z` being zero. + + For real `x,y,z \ge 0`, the principal square root is taken in the integrand. + For complex `x,y,z`, the principal square root is taken as `t \to \infty` + and as `t \to 0` non-principal branches are chosen as necessary so as to + make the integrand continuous. + + **Examples** + + Some basic values and limits:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> elliprf(0,1,1); pi/2 + 1.570796326794896619231322 + 1.570796326794896619231322 + >>> elliprf(0,1,inf) + 0.0 + >>> elliprf(1,1,1) + 1.0 + >>> elliprf(2,2,2)**2 + 0.5 + >>> elliprf(1,0,0); elliprf(0,0,1); elliprf(0,1,0); elliprf(0,0,0) + +inf + +inf + +inf + +inf + + Representing complete elliptic integrals in terms of `R_F`:: + + >>> m = mpf(0.75) + >>> ellipk(m); elliprf(0,1-m,1) + 2.156515647499643235438675 + 2.156515647499643235438675 + >>> ellipe(m); elliprf(0,1-m,1)-m*elliprd(0,1-m,1)/3 + 1.211056027568459524803563 + 1.211056027568459524803563 + + Some symmetries and argument transformations:: + + >>> x,y,z = 2,3,4 + >>> elliprf(x,y,z); elliprf(y,x,z); elliprf(z,y,x) + 0.5840828416771517066928492 + 0.5840828416771517066928492 + 0.5840828416771517066928492 + >>> k = mpf(100000) + >>> elliprf(k*x,k*y,k*z); k**(-0.5) * elliprf(x,y,z) + 0.001847032121923321253219284 + 0.001847032121923321253219284 + >>> l = sqrt(x*y) + sqrt(y*z) + sqrt(z*x) + >>> elliprf(x,y,z); 2*elliprf(x+l,y+l,z+l) + 0.5840828416771517066928492 + 0.5840828416771517066928492 + >>> elliprf((x+l)/4,(y+l)/4,(z+l)/4) + 0.5840828416771517066928492 + + Comparing with numerical integration:: + + >>> x,y,z = 2,3,4 + >>> elliprf(x,y,z) + 0.5840828416771517066928492 + >>> f = lambda t: 0.5*((t+x)*(t+y)*(t+z))**(-0.5) + >>> q = extradps(25)(quad) + >>> q(f, [0,inf]) + 0.5840828416771517066928492 + + With the following arguments, the square root in the integrand becomes + discontinuous at `t = 1/2` if the principal branch is used. To obtain + the right value, `-\sqrt{r}` must be taken instead of `\sqrt{r}` + on `t \in (0, 1/2)`:: + + >>> x,y,z = j-1,j,0 + >>> elliprf(x,y,z) + (0.7961258658423391329305694 - 1.213856669836495986430094j) + >>> -q(f, [0,0.5]) + q(f, [0.5,inf]) + (0.7961258658423391329305694 - 1.213856669836495986430094j) + + The so-called *first lemniscate constant*, a transcendental number:: + + >>> elliprf(0,1,2) + 1.31102877714605990523242 + >>> extradps(25)(quad)(lambda t: 1/sqrt(1-t**4), [0,1]) + 1.31102877714605990523242 + >>> gamma('1/4')**2/(4*sqrt(2*pi)) + 1.31102877714605990523242 + + **References** + + 1. [Carlson]_ + 2. [DLMF]_ Chapter 19. Elliptic Integrals + + """ + x = ctx.convert(x) + y = ctx.convert(y) + z = ctx.convert(z) + prec = ctx.prec + try: + ctx.prec += 20 + tol = ctx.eps * 2**10 + v = RF_calc(ctx, x, y, z, tol) + finally: + ctx.prec = prec + return +v + +@defun +def elliprc(ctx, x, y, pv=True): + r""" + Evaluates the degenerate Carlson symmetric elliptic integral + of the first kind + + .. math :: + + R_C(x,y) = R_F(x,y,y) = + \frac{1}{2} \int_0^{\infty} \frac{dt}{(t+y) \sqrt{(t+x)}}. + + If `y \in (-\infty,0)`, either a value defined by continuity, + or with *pv=True* the Cauchy principal value, can be computed. + + If `x \ge 0, y > 0`, the value can be expressed in terms of + elementary functions as + + .. math :: + + R_C(x,y) = + \begin{cases} + \dfrac{1}{\sqrt{y-x}} + \cos^{-1}\left(\sqrt{\dfrac{x}{y}}\right), & x < y \\ + \dfrac{1}{\sqrt{y}}, & x = y \\ + \dfrac{1}{\sqrt{x-y}} + \cosh^{-1}\left(\sqrt{\dfrac{x}{y}}\right), & x > y \\ + \end{cases}. + + **Examples** + + Some special values and limits:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> elliprc(1,2)*4; elliprc(0,1)*2; +pi + 3.141592653589793238462643 + 3.141592653589793238462643 + 3.141592653589793238462643 + >>> elliprc(1,0) + +inf + >>> elliprc(5,5)**2 + 0.2 + >>> elliprc(1,inf); elliprc(inf,1); elliprc(inf,inf) + 0.0 + 0.0 + 0.0 + + Comparing with the elementary closed-form solution:: + + >>> elliprc('1/3', '1/5'); sqrt(7.5)*acosh(sqrt('5/3')) + 2.041630778983498390751238 + 2.041630778983498390751238 + >>> elliprc('1/5', '1/3'); sqrt(7.5)*acos(sqrt('3/5')) + 1.875180765206547065111085 + 1.875180765206547065111085 + + Comparing with numerical integration:: + + >>> q = extradps(25)(quad) + >>> elliprc(2, -3, pv=True) + 0.3333969101113672670749334 + >>> elliprc(2, -3, pv=False) + (0.3333969101113672670749334 + 0.7024814731040726393156375j) + >>> 0.5*q(lambda t: 1/(sqrt(t+2)*(t-3)), [0,3-j,6,inf]) + (0.3333969101113672670749334 + 0.7024814731040726393156375j) + + """ + x = ctx.convert(x) + y = ctx.convert(y) + prec = ctx.prec + try: + ctx.prec += 20 + tol = ctx.eps * 2**10 + v = RC_calc(ctx, x, y, tol, pv) + finally: + ctx.prec = prec + return +v + +@defun +def elliprj(ctx, x, y, z, p, integration=1): + r""" + Evaluates the Carlson symmetric elliptic integral of the third kind + + .. math :: + + R_J(x,y,z,p) = \frac{3}{2} + \int_0^{\infty} \frac{dt}{(t+p)\sqrt{(t+x)(t+y)(t+z)}}. + + Like :func:`~mpmath.elliprf`, the branch of the square root in the integrand + is defined so as to be continuous along the path of integration for + complex values of the arguments. + + **Examples** + + Some values and limits:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> elliprj(1,1,1,1) + 1.0 + >>> elliprj(2,2,2,2); 1/(2*sqrt(2)) + 0.3535533905932737622004222 + 0.3535533905932737622004222 + >>> elliprj(0,1,2,2) + 1.067937989667395702268688 + >>> 3*(2*gamma('5/4')**2-pi**2/gamma('1/4')**2)/(sqrt(2*pi)) + 1.067937989667395702268688 + >>> elliprj(0,1,1,2); 3*pi*(2-sqrt(2))/4 + 1.380226776765915172432054 + 1.380226776765915172432054 + >>> elliprj(1,3,2,0); elliprj(0,1,1,0); elliprj(0,0,0,0) + +inf + +inf + +inf + >>> elliprj(1,inf,1,0); elliprj(1,1,1,inf) + 0.0 + 0.0 + >>> chop(elliprj(1+j, 1-j, 1, 1)) + 0.8505007163686739432927844 + + Scale transformation:: + + >>> x,y,z,p = 2,3,4,5 + >>> k = mpf(100000) + >>> elliprj(k*x,k*y,k*z,k*p); k**(-1.5)*elliprj(x,y,z,p) + 4.521291677592745527851168e-9 + 4.521291677592745527851168e-9 + + Comparing with numerical integration:: + + >>> elliprj(1,2,3,4) + 0.2398480997495677621758617 + >>> f = lambda t: 1/((t+4)*sqrt((t+1)*(t+2)*(t+3))) + >>> 1.5*quad(f, [0,inf]) + 0.2398480997495677621758617 + >>> elliprj(1,2+1j,3,4-2j) + (0.216888906014633498739952 + 0.04081912627366673332369512j) + >>> f = lambda t: 1/((t+4-2j)*sqrt((t+1)*(t+2+1j)*(t+3))) + >>> 1.5*quad(f, [0,inf]) + (0.216888906014633498739952 + 0.04081912627366673332369511j) + + """ + x = ctx.convert(x) + y = ctx.convert(y) + z = ctx.convert(z) + p = ctx.convert(p) + prec = ctx.prec + try: + ctx.prec += 20 + tol = ctx.eps * 2**10 + v = RJ_calc(ctx, x, y, z, p, tol, integration) + finally: + ctx.prec = prec + return +v + +@defun +def elliprd(ctx, x, y, z): + r""" + Evaluates the degenerate Carlson symmetric elliptic integral + of the third kind or Carlson elliptic integral of the + second kind `R_D(x,y,z) = R_J(x,y,z,z)`. + + See :func:`~mpmath.elliprj` for additional information. + + **Examples** + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> elliprd(1,2,3) + 0.2904602810289906442326534 + >>> elliprj(1,2,3,3) + 0.2904602810289906442326534 + + The so-called *second lemniscate constant*, a transcendental number:: + + >>> elliprd(0,2,1)/3 + 0.5990701173677961037199612 + >>> extradps(25)(quad)(lambda t: t**2/sqrt(1-t**4), [0,1]) + 0.5990701173677961037199612 + >>> gamma('3/4')**2/sqrt(2*pi) + 0.5990701173677961037199612 + + """ + return ctx.elliprj(x,y,z,z) + +@defun +def elliprg(ctx, x, y, z): + r""" + Evaluates the Carlson completely symmetric elliptic integral + of the second kind + + .. math :: + + R_G(x,y,z) = \frac{1}{4} \int_0^{\infty} + \frac{t}{\sqrt{(t+x)(t+y)(t+z)}} + \left( \frac{x}{t+x} + \frac{y}{t+y} + \frac{z}{t+z}\right) dt. + + **Examples** + + Evaluation for real and complex arguments:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> elliprg(0,1,1)*4; +pi + 3.141592653589793238462643 + 3.141592653589793238462643 + >>> elliprg(0,0.5,1) + 0.6753219405238377512600874 + >>> chop(elliprg(1+j, 1-j, 2)) + 1.172431327676416604532822 + + A double integral that can be evaluated in terms of `R_G`:: + + >>> x,y,z = 2,3,4 + >>> def f(t,u): + ... st = fp.sin(t); ct = fp.cos(t) + ... su = fp.sin(u); cu = fp.cos(u) + ... return (x*(st*cu)**2 + y*(st*su)**2 + z*ct**2)**0.5 * st + ... + >>> nprint(mpf(fp.quad(f, [0,fp.pi], [0,2*fp.pi])/(4*fp.pi)), 13) + 1.725503028069 + >>> nprint(elliprg(x,y,z), 13) + 1.725503028069 + + """ + x = ctx.convert(x) + y = ctx.convert(y) + z = ctx.convert(z) + zeros = (not x) + (not y) + (not z) + if zeros == 3: + return (x+y+z)*0 + if zeros == 2: + if x: return 0.5*ctx.sqrt(x) + if y: return 0.5*ctx.sqrt(y) + return 0.5*ctx.sqrt(z) + if zeros == 1: + if not z: + x, z = z, x + def terms(): + T1 = 0.5*z*ctx.elliprf(x,y,z) + T2 = -0.5*(x-z)*(y-z)*ctx.elliprd(x,y,z)/3 + T3 = 0.5*ctx.sqrt(x)*ctx.sqrt(y)/ctx.sqrt(z) + return T1,T2,T3 + return ctx.sum_accurately(terms) + + +@defun_wrapped +def ellipf(ctx, phi, m): + r""" + Evaluates the Legendre incomplete elliptic integral of the first kind + + .. math :: + + F(\phi,m) = \int_0^{\phi} \frac{dt}{\sqrt{1-m \sin^2 t}} + + or equivalently + + .. math :: + + F(\phi,m) = \int_0^{\sin \phi} + \frac{dt}{\left(\sqrt{1-t^2}\right)\left(\sqrt{1-mt^2}\right)}. + + The function reduces to a complete elliptic integral of the first kind + (see :func:`~mpmath.ellipk`) when `\phi = \frac{\pi}{2}`; that is, + + .. math :: + + F\left(\frac{\pi}{2}, m\right) = K(m). + + In the defining integral, it is assumed that the principal branch + of the square root is taken and that the path of integration avoids + crossing any branch cuts. Outside `-\pi/2 \le \Re(\phi) \le \pi/2`, + the function extends quasi-periodically as + + .. math :: + + F(\phi + n \pi, m) = 2 n K(m) + F(\phi,m), n \in \mathbb{Z}. + + **Plots** + + .. literalinclude :: /plots/ellipf.py + .. image :: /plots/ellipf.png + + **Examples** + + Basic values and limits:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> ellipf(0,1) + 0.0 + >>> ellipf(0,0) + 0.0 + >>> ellipf(1,0); ellipf(2+3j,0) + 1.0 + (2.0 + 3.0j) + >>> ellipf(1,1); log(sec(1)+tan(1)) + 1.226191170883517070813061 + 1.226191170883517070813061 + >>> ellipf(pi/2, -0.5); ellipk(-0.5) + 1.415737208425956198892166 + 1.415737208425956198892166 + >>> ellipf(pi/2+eps, 1); ellipf(-pi/2-eps, 1) + +inf + +inf + >>> ellipf(1.5, 1) + 3.340677542798311003320813 + + Comparing with numerical integration:: + + >>> z,m = 0.5, 1.25 + >>> ellipf(z,m) + 0.5287219202206327872978255 + >>> quad(lambda t: (1-m*sin(t)**2)**(-0.5), [0,z]) + 0.5287219202206327872978255 + + The arguments may be complex numbers:: + + >>> ellipf(3j, 0.5) + (0.0 + 1.713602407841590234804143j) + >>> ellipf(3+4j, 5-6j) + (1.269131241950351323305741 - 0.3561052815014558335412538j) + >>> z,m = 2+3j, 1.25 + >>> k = 1011 + >>> ellipf(z+pi*k,m); ellipf(z,m) + 2*k*ellipk(m) + (4086.184383622179764082821 - 3003.003538923749396546871j) + (4086.184383622179764082821 - 3003.003538923749396546871j) + + For `|\Re(z)| < \pi/2`, the function can be expressed as a + hypergeometric series of two variables + (see :func:`~mpmath.appellf1`):: + + >>> z,m = 0.5, 0.25 + >>> ellipf(z,m) + 0.5050887275786480788831083 + >>> sin(z)*appellf1(0.5,0.5,0.5,1.5,sin(z)**2,m*sin(z)**2) + 0.5050887275786480788831083 + + """ + z = phi + if not (ctx.isnormal(z) and ctx.isnormal(m)): + if m == 0: + return z + m + if z == 0: + return z * m + if m == ctx.inf or m == ctx.ninf: return z/m + raise ValueError + x = z.real + ctx.prec += max(0, ctx.mag(x)) + pi = +ctx.pi + away = abs(x) > pi/2 + if m == 1: + if away: + return ctx.inf + if away: + d = ctx.nint(x/pi) + z = z-pi*d + P = 2*d*ctx.ellipk(m) + else: + P = 0 + c, s = ctx.cos_sin(z) + return s * ctx.elliprf(c**2, 1-m*s**2, 1) + P + +@defun_wrapped +def ellipe(ctx, *args): + r""" + Called with a single argument `m`, evaluates the Legendre complete + elliptic integral of the second kind, `E(m)`, defined by + + .. math :: E(m) = \int_0^{\pi/2} \sqrt{1-m \sin^2 t} \, dt \,=\, + \frac{\pi}{2} + \,_2F_1\left(\frac{1}{2}, -\frac{1}{2}, 1, m\right). + + Called with two arguments `\phi, m`, evaluates the incomplete elliptic + integral of the second kind + + .. math :: + + E(\phi,m) = \int_0^{\phi} \sqrt{1-m \sin^2 t} \, dt = + \int_0^{\sin z} + \frac{\sqrt{1-mt^2}}{\sqrt{1-t^2}} \, dt. + + The incomplete integral reduces to a complete integral when + `\phi = \frac{\pi}{2}`; that is, + + .. math :: + + E\left(\frac{\pi}{2}, m\right) = E(m). + + In the defining integral, it is assumed that the principal branch + of the square root is taken and that the path of integration avoids + crossing any branch cuts. Outside `-\pi/2 \le \Re(z) \le \pi/2`, + the function extends quasi-periodically as + + .. math :: + + E(\phi + n \pi, m) = 2 n E(m) + E(\phi,m), n \in \mathbb{Z}. + + **Plots** + + .. literalinclude :: /plots/ellipe.py + .. image :: /plots/ellipe.png + + **Examples for the complete integral** + + Basic values and limits:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> ellipe(0) + 1.570796326794896619231322 + >>> ellipe(1) + 1.0 + >>> ellipe(-1) + 1.910098894513856008952381 + >>> ellipe(2) + (0.5990701173677961037199612 + 0.5990701173677961037199612j) + >>> ellipe(inf) + (0.0 + +infj) + >>> ellipe(-inf) + +inf + + Verifying the defining integral and hypergeometric + representation:: + + >>> ellipe(0.5) + 1.350643881047675502520175 + >>> quad(lambda t: sqrt(1-0.5*sin(t)**2), [0, pi/2]) + 1.350643881047675502520175 + >>> pi/2*hyp2f1(0.5,-0.5,1,0.5) + 1.350643881047675502520175 + + Evaluation is supported for arbitrary complex `m`:: + + >>> ellipe(0.5+0.25j) + (1.360868682163129682716687 - 0.1238733442561786843557315j) + >>> ellipe(3+4j) + (1.499553520933346954333612 - 1.577879007912758274533309j) + + A definite integral:: + + >>> quad(ellipe, [0,1]) + 1.333333333333333333333333 + + **Examples for the incomplete integral** + + Basic values and limits:: + + >>> ellipe(0,1) + 0.0 + >>> ellipe(0,0) + 0.0 + >>> ellipe(1,0) + 1.0 + >>> ellipe(2+3j,0) + (2.0 + 3.0j) + >>> ellipe(1,1); sin(1) + 0.8414709848078965066525023 + 0.8414709848078965066525023 + >>> ellipe(pi/2, -0.5); ellipe(-0.5) + 1.751771275694817862026502 + 1.751771275694817862026502 + >>> ellipe(pi/2, 1); ellipe(-pi/2, 1) + 1.0 + -1.0 + >>> ellipe(1.5, 1) + 0.9974949866040544309417234 + + Comparing with numerical integration:: + + >>> z,m = 0.5, 1.25 + >>> ellipe(z,m) + 0.4740152182652628394264449 + >>> quad(lambda t: sqrt(1-m*sin(t)**2), [0,z]) + 0.4740152182652628394264449 + + The arguments may be complex numbers:: + + >>> ellipe(3j, 0.5) + (0.0 + 7.551991234890371873502105j) + >>> ellipe(3+4j, 5-6j) + (24.15299022574220502424466 + 75.2503670480325997418156j) + >>> k = 35 + >>> z,m = 2+3j, 1.25 + >>> ellipe(z+pi*k,m); ellipe(z,m) + 2*k*ellipe(m) + (48.30138799412005235090766 + 17.47255216721987688224357j) + (48.30138799412005235090766 + 17.47255216721987688224357j) + + For `|\Re(z)| < \pi/2`, the function can be expressed as a + hypergeometric series of two variables + (see :func:`~mpmath.appellf1`):: + + >>> z,m = 0.5, 0.25 + >>> ellipe(z,m) + 0.4950017030164151928870375 + >>> sin(z)*appellf1(0.5,0.5,-0.5,1.5,sin(z)**2,m*sin(z)**2) + 0.4950017030164151928870376 + + """ + if len(args) == 1: + return ctx._ellipe(args[0]) + else: + phi, m = args + z = phi + if not (ctx.isnormal(z) and ctx.isnormal(m)): + if m == 0: + return z + m + if z == 0: + return z * m + if m == ctx.inf or m == ctx.ninf: + return ctx.inf + raise ValueError + x = z.real + ctx.prec += max(0, ctx.mag(x)) + pi = +ctx.pi + away = abs(x) > pi/2 + if away: + d = ctx.nint(x/pi) + z = z-pi*d + P = 2*d*ctx.ellipe(m) + else: + P = 0 + def terms(): + c, s = ctx.cos_sin(z) + x = c**2 + y = 1-m*s**2 + RF = ctx.elliprf(x, y, 1) + RD = ctx.elliprd(x, y, 1) + return s*RF, -m*s**3*RD/3 + return ctx.sum_accurately(terms) + P + +@defun_wrapped +def ellippi(ctx, *args): + r""" + Called with three arguments `n, \phi, m`, evaluates the Legendre + incomplete elliptic integral of the third kind + + .. math :: + + \Pi(n; \phi, m) = \int_0^{\phi} + \frac{dt}{(1-n \sin^2 t) \sqrt{1-m \sin^2 t}} = + \int_0^{\sin \phi} + \frac{dt}{(1-nt^2) \sqrt{1-t^2} \sqrt{1-mt^2}}. + + Called with two arguments `n, m`, evaluates the complete + elliptic integral of the third kind + `\Pi(n,m) = \Pi(n; \frac{\pi}{2},m)`. + + In the defining integral, it is assumed that the principal branch + of the square root is taken and that the path of integration avoids + crossing any branch cuts. Outside `-\pi/2 \le \Re(\phi) \le \pi/2`, + the function extends quasi-periodically as + + .. math :: + + \Pi(n,\phi+k\pi,m) = 2k\Pi(n,m) + \Pi(n,\phi,m), k \in \mathbb{Z}. + + **Plots** + + .. literalinclude :: /plots/ellippi.py + .. image :: /plots/ellippi.png + + **Examples for the complete integral** + + Some basic values and limits:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> ellippi(0,-5); ellipk(-5) + 0.9555039270640439337379334 + 0.9555039270640439337379334 + >>> ellippi(inf,2) + 0.0 + >>> ellippi(2,inf) + 0.0 + >>> abs(ellippi(1,5)) + +inf + >>> abs(ellippi(0.25,1)) + +inf + + Evaluation in terms of simpler functions:: + + >>> ellippi(0.25,0.25); ellipe(0.25)/(1-0.25) + 1.956616279119236207279727 + 1.956616279119236207279727 + >>> ellippi(3,0); pi/(2*sqrt(-2)) + (0.0 - 1.11072073453959156175397j) + (0.0 - 1.11072073453959156175397j) + >>> ellippi(-3,0); pi/(2*sqrt(4)) + 0.7853981633974483096156609 + 0.7853981633974483096156609 + + **Examples for the incomplete integral** + + Basic values and limits:: + + >>> ellippi(0.25,-0.5); ellippi(0.25,pi/2,-0.5) + 1.622944760954741603710555 + 1.622944760954741603710555 + >>> ellippi(1,0,1) + 0.0 + >>> ellippi(inf,0,1) + 0.0 + >>> ellippi(0,0.25,0.5); ellipf(0.25,0.5) + 0.2513040086544925794134591 + 0.2513040086544925794134591 + >>> ellippi(1,1,1); (log(sec(1)+tan(1))+sec(1)*tan(1))/2 + 2.054332933256248668692452 + 2.054332933256248668692452 + >>> ellippi(0.25, 53*pi/2, 0.75); 53*ellippi(0.25,0.75) + 135.240868757890840755058 + 135.240868757890840755058 + >>> ellippi(0.5,pi/4,0.5); 2*ellipe(pi/4,0.5)-1/sqrt(3) + 0.9190227391656969903987269 + 0.9190227391656969903987269 + + Complex arguments are supported:: + + >>> ellippi(0.5, 5+6j-2*pi, -7-8j) + (-0.3612856620076747660410167 + 0.5217735339984807829755815j) + + Some degenerate cases:: + + >>> ellippi(1,1) + +inf + >>> ellippi(1,0) + +inf + >>> ellippi(1,2,0) + +inf + >>> ellippi(1,2,1) + +inf + >>> ellippi(1,0,1) + 0.0 + + """ + if len(args) == 2: + n, m = args + complete = True + z = phi = ctx.pi/2 + else: + n, phi, m = args + complete = False + z = phi + if not (ctx.isnormal(n) and ctx.isnormal(z) and ctx.isnormal(m)): + if ctx.isnan(n) or ctx.isnan(z) or ctx.isnan(m): + raise ValueError + if complete: + if m == 0: + if n == 1: + return ctx.inf + return ctx.pi/(2*ctx.sqrt(1-n)) + if n == 0: return ctx.ellipk(m) + if ctx.isinf(n) or ctx.isinf(m): return ctx.zero + else: + if z == 0: return z + if ctx.isinf(n): return ctx.zero + if ctx.isinf(m): return ctx.zero + if ctx.isinf(n) or ctx.isinf(z) or ctx.isinf(m): + raise ValueError + if complete: + if m == 1: + if n == 1: + return ctx.inf + return -ctx.inf/ctx.sign(n-1) + away = False + else: + x = z.real + ctx.prec += max(0, ctx.mag(x)) + pi = +ctx.pi + away = abs(x) > pi/2 + if away: + d = ctx.nint(x/pi) + z = z-pi*d + P = 2*d*ctx.ellippi(n,m) + if ctx.isinf(P): + return ctx.inf + else: + P = 0 + def terms(): + if complete: + c, s = ctx.zero, ctx.one + else: + c, s = ctx.cos_sin(z) + x = c**2 + y = 1-m*s**2 + RF = ctx.elliprf(x, y, 1) + RJ = ctx.elliprj(x, y, 1, 1-n*s**2) + return s*RF, n*s**3*RJ/3 + return ctx.sum_accurately(terms) + P diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/expintegrals.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/expintegrals.py new file mode 100644 index 0000000000000000000000000000000000000000..0dee8356c0386819d8f0421fded476ee77229359 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/expintegrals.py @@ -0,0 +1,425 @@ +from .functions import defun, defun_wrapped + +@defun_wrapped +def _erf_complex(ctx, z): + z2 = ctx.square_exp_arg(z, -1) + #z2 = -z**2 + v = (2/ctx.sqrt(ctx.pi))*z * ctx.hyp1f1((1,2),(3,2), z2) + if not ctx._re(z): + v = ctx._im(v)*ctx.j + return v + +@defun_wrapped +def _erfc_complex(ctx, z): + if ctx.re(z) > 2: + z2 = ctx.square_exp_arg(z) + nz2 = ctx.fneg(z2, exact=True) + v = ctx.exp(nz2)/ctx.sqrt(ctx.pi) * ctx.hyperu((1,2),(1,2), z2) + else: + v = 1 - ctx._erf_complex(z) + if not ctx._re(z): + v = 1+ctx._im(v)*ctx.j + return v + +@defun +def erf(ctx, z): + z = ctx.convert(z) + if ctx._is_real_type(z): + try: + return ctx._erf(z) + except NotImplementedError: + pass + if ctx._is_complex_type(z) and not z.imag: + try: + return type(z)(ctx._erf(z.real)) + except NotImplementedError: + pass + return ctx._erf_complex(z) + +@defun +def erfc(ctx, z): + z = ctx.convert(z) + if ctx._is_real_type(z): + try: + return ctx._erfc(z) + except NotImplementedError: + pass + if ctx._is_complex_type(z) and not z.imag: + try: + return type(z)(ctx._erfc(z.real)) + except NotImplementedError: + pass + return ctx._erfc_complex(z) + +@defun +def square_exp_arg(ctx, z, mult=1, reciprocal=False): + prec = ctx.prec*4+20 + if reciprocal: + z2 = ctx.fmul(z, z, prec=prec) + z2 = ctx.fdiv(ctx.one, z2, prec=prec) + else: + z2 = ctx.fmul(z, z, prec=prec) + if mult != 1: + z2 = ctx.fmul(z2, mult, exact=True) + return z2 + +@defun_wrapped +def erfi(ctx, z): + if not z: + return z + z2 = ctx.square_exp_arg(z) + v = (2/ctx.sqrt(ctx.pi)*z) * ctx.hyp1f1((1,2), (3,2), z2) + if not ctx._re(z): + v = ctx._im(v)*ctx.j + return v + +@defun_wrapped +def erfinv(ctx, x): + xre = ctx._re(x) + if (xre != x) or (xre < -1) or (xre > 1): + return ctx.bad_domain("erfinv(x) is defined only for -1 <= x <= 1") + x = xre + #if ctx.isnan(x): return x + if not x: return x + if x == 1: return ctx.inf + if x == -1: return ctx.ninf + if abs(x) < 0.9: + a = 0.53728*x**3 + 0.813198*x + else: + # An asymptotic formula + u = ctx.ln(2/ctx.pi/(abs(x)-1)**2) + a = ctx.sign(x) * ctx.sqrt(u - ctx.ln(u))/ctx.sqrt(2) + ctx.prec += 10 + return ctx.findroot(lambda t: ctx.erf(t)-x, a) + +@defun_wrapped +def npdf(ctx, x, mu=0, sigma=1): + sigma = ctx.convert(sigma) + return ctx.exp(-(x-mu)**2/(2*sigma**2)) / (sigma*ctx.sqrt(2*ctx.pi)) + +@defun_wrapped +def ncdf(ctx, x, mu=0, sigma=1): + a = (x-mu)/(sigma*ctx.sqrt(2)) + if a < 0: + return ctx.erfc(-a)/2 + else: + return (1+ctx.erf(a))/2 + +@defun_wrapped +def betainc(ctx, a, b, x1=0, x2=1, regularized=False): + if x1 == x2: + v = 0 + elif not x1: + if x1 == 0 and x2 == 1: + v = ctx.beta(a, b) + else: + v = x2**a * ctx.hyp2f1(a, 1-b, a+1, x2) / a + else: + m, d = ctx.nint_distance(a) + if m <= 0: + if d < -ctx.prec: + h = +ctx.eps + ctx.prec *= 2 + a += h + elif d < -4: + ctx.prec -= d + s1 = x2**a * ctx.hyp2f1(a,1-b,a+1,x2) + s2 = x1**a * ctx.hyp2f1(a,1-b,a+1,x1) + v = (s1 - s2) / a + if regularized: + v /= ctx.beta(a,b) + return v + +@defun +def gammainc(ctx, z, a=0, b=None, regularized=False): + regularized = bool(regularized) + z = ctx.convert(z) + if a is None: + a = ctx.zero + lower_modified = False + else: + a = ctx.convert(a) + lower_modified = a != ctx.zero + if b is None: + b = ctx.inf + upper_modified = False + else: + b = ctx.convert(b) + upper_modified = b != ctx.inf + # Complete gamma function + if not (upper_modified or lower_modified): + if regularized: + if ctx.re(z) < 0: + return ctx.inf + elif ctx.re(z) > 0: + return ctx.one + else: + return ctx.nan + return ctx.gamma(z) + if a == b: + return ctx.zero + # Standardize + if ctx.re(a) > ctx.re(b): + return -ctx.gammainc(z, b, a, regularized) + # Generalized gamma + if upper_modified and lower_modified: + return +ctx._gamma3(z, a, b, regularized) + # Upper gamma + elif lower_modified: + return ctx._upper_gamma(z, a, regularized) + # Lower gamma + elif upper_modified: + return ctx._lower_gamma(z, b, regularized) + +@defun +def _lower_gamma(ctx, z, b, regularized=False): + # Pole + if ctx.isnpint(z): + return type(z)(ctx.inf) + G = [z] * regularized + negb = ctx.fneg(b, exact=True) + def h(z): + T1 = [ctx.exp(negb), b, z], [1, z, -1], [], G, [1], [1+z], b + return (T1,) + return ctx.hypercomb(h, [z]) + +@defun +def _upper_gamma(ctx, z, a, regularized=False): + # Fast integer case, when available + if ctx.isint(z): + try: + if regularized: + # Gamma pole + if ctx.isnpint(z): + return type(z)(ctx.zero) + orig = ctx.prec + try: + ctx.prec += 10 + return ctx._gamma_upper_int(z, a) / ctx.gamma(z) + finally: + ctx.prec = orig + else: + return ctx._gamma_upper_int(z, a) + except NotImplementedError: + pass + # hypercomb is unable to detect the exact zeros, so handle them here + if z == 2 and a == -1: + return (z+a)*0 + if z == 3 and (a == -1-1j or a == -1+1j): + return (z+a)*0 + nega = ctx.fneg(a, exact=True) + G = [z] * regularized + # Use 2F0 series when possible; fall back to lower gamma representation + try: + def h(z): + r = z-1 + return [([ctx.exp(nega), a], [1, r], [], G, [1, -r], [], 1/nega)] + return ctx.hypercomb(h, [z], force_series=True) + except ctx.NoConvergence: + def h(z): + T1 = [], [1, z-1], [z], G, [], [], 0 + T2 = [-ctx.exp(nega), a, z], [1, z, -1], [], G, [1], [1+z], a + return T1, T2 + return ctx.hypercomb(h, [z]) + +@defun +def _gamma3(ctx, z, a, b, regularized=False): + pole = ctx.isnpint(z) + if regularized and pole: + return ctx.zero + try: + ctx.prec += 15 + # We don't know in advance whether it's better to write as a difference + # of lower or upper gamma functions, so try both + T1 = ctx.gammainc(z, a, regularized=regularized) + T2 = ctx.gammainc(z, b, regularized=regularized) + R = T1 - T2 + if ctx.mag(R) - max(ctx.mag(T1), ctx.mag(T2)) > -10: + return R + if not pole: + T1 = ctx.gammainc(z, 0, b, regularized=regularized) + T2 = ctx.gammainc(z, 0, a, regularized=regularized) + R = T1 - T2 + # May be ok, but should probably at least print a warning + # about possible cancellation + if 1: #ctx.mag(R) - max(ctx.mag(T1), ctx.mag(T2)) > -10: + return R + finally: + ctx.prec -= 15 + raise NotImplementedError + +@defun_wrapped +def expint(ctx, n, z): + if ctx.isint(n) and ctx._is_real_type(z): + try: + return ctx._expint_int(n, z) + except NotImplementedError: + pass + if ctx.isnan(n) or ctx.isnan(z): + return z*n + if z == ctx.inf: + return 1/z + if z == 0: + # integral from 1 to infinity of t^n + if ctx.re(n) <= 1: + # TODO: reasonable sign of infinity + return type(z)(ctx.inf) + else: + return ctx.one/(n-1) + if n == 0: + return ctx.exp(-z)/z + if n == -1: + return ctx.exp(-z)*(z+1)/z**2 + return z**(n-1) * ctx.gammainc(1-n, z) + +@defun_wrapped +def li(ctx, z, offset=False): + if offset: + if z == 2: + return ctx.zero + return ctx.ei(ctx.ln(z)) - ctx.ei(ctx.ln2) + if not z: + return z + if z == 1: + return ctx.ninf + return ctx.ei(ctx.ln(z)) + +@defun +def ei(ctx, z): + try: + return ctx._ei(z) + except NotImplementedError: + return ctx._ei_generic(z) + +@defun_wrapped +def _ei_generic(ctx, z): + # Note: the following is currently untested because mp and fp + # both use special-case ei code + if z == ctx.inf: + return z + if z == ctx.ninf: + return ctx.zero + if ctx.mag(z) > 1: + try: + r = ctx.one/z + v = ctx.exp(z)*ctx.hyper([1,1],[],r, + maxterms=ctx.prec, force_series=True)/z + im = ctx._im(z) + if im > 0: + v += ctx.pi*ctx.j + if im < 0: + v -= ctx.pi*ctx.j + return v + except ctx.NoConvergence: + pass + v = z*ctx.hyp2f2(1,1,2,2,z) + ctx.euler + if ctx._im(z): + v += 0.5*(ctx.log(z) - ctx.log(ctx.one/z)) + else: + v += ctx.log(abs(z)) + return v + +@defun +def e1(ctx, z): + try: + return ctx._e1(z) + except NotImplementedError: + return ctx.expint(1, z) + +@defun +def ci(ctx, z): + try: + return ctx._ci(z) + except NotImplementedError: + return ctx._ci_generic(z) + +@defun_wrapped +def _ci_generic(ctx, z): + if ctx.isinf(z): + if z == ctx.inf: return ctx.zero + if z == ctx.ninf: return ctx.pi*1j + jz = ctx.fmul(ctx.j,z,exact=True) + njz = ctx.fneg(jz,exact=True) + v = 0.5*(ctx.ei(jz) + ctx.ei(njz)) + zreal = ctx._re(z) + zimag = ctx._im(z) + if zreal == 0: + if zimag > 0: v += ctx.pi*0.5j + if zimag < 0: v -= ctx.pi*0.5j + if zreal < 0: + if zimag >= 0: v += ctx.pi*1j + if zimag < 0: v -= ctx.pi*1j + if ctx._is_real_type(z) and zreal > 0: + v = ctx._re(v) + return v + +@defun +def si(ctx, z): + try: + return ctx._si(z) + except NotImplementedError: + return ctx._si_generic(z) + +@defun_wrapped +def _si_generic(ctx, z): + if ctx.isinf(z): + if z == ctx.inf: return 0.5*ctx.pi + if z == ctx.ninf: return -0.5*ctx.pi + # Suffers from cancellation near 0 + if ctx.mag(z) >= -1: + jz = ctx.fmul(ctx.j,z,exact=True) + njz = ctx.fneg(jz,exact=True) + v = (-0.5j)*(ctx.ei(jz) - ctx.ei(njz)) + zreal = ctx._re(z) + if zreal > 0: + v -= 0.5*ctx.pi + if zreal < 0: + v += 0.5*ctx.pi + if ctx._is_real_type(z): + v = ctx._re(v) + return v + else: + return z*ctx.hyp1f2((1,2),(3,2),(3,2),-0.25*z*z) + +@defun_wrapped +def chi(ctx, z): + nz = ctx.fneg(z, exact=True) + v = 0.5*(ctx.ei(z) + ctx.ei(nz)) + zreal = ctx._re(z) + zimag = ctx._im(z) + if zimag > 0: + v += ctx.pi*0.5j + elif zimag < 0: + v -= ctx.pi*0.5j + elif zreal < 0: + v += ctx.pi*1j + return v + +@defun_wrapped +def shi(ctx, z): + # Suffers from cancellation near 0 + if ctx.mag(z) >= -1: + nz = ctx.fneg(z, exact=True) + v = 0.5*(ctx.ei(z) - ctx.ei(nz)) + zimag = ctx._im(z) + if zimag > 0: v -= 0.5j*ctx.pi + if zimag < 0: v += 0.5j*ctx.pi + return v + else: + return z * ctx.hyp1f2((1,2),(3,2),(3,2),0.25*z*z) + +@defun_wrapped +def fresnels(ctx, z): + if z == ctx.inf: + return ctx.mpf(0.5) + if z == ctx.ninf: + return ctx.mpf(-0.5) + return ctx.pi*z**3/6*ctx.hyp1f2((3,4),(3,2),(7,4),-ctx.pi**2*z**4/16) + +@defun_wrapped +def fresnelc(ctx, z): + if z == ctx.inf: + return ctx.mpf(0.5) + if z == ctx.ninf: + return ctx.mpf(-0.5) + return z*ctx.hyp1f2((1,4),(1,2),(5,4),-ctx.pi**2*z**4/16) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/factorials.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/factorials.py new file mode 100644 index 0000000000000000000000000000000000000000..9259e40b95bf1c908a7ad98b59bbb33528606b07 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/factorials.py @@ -0,0 +1,187 @@ +from ..libmp.backend import xrange +from .functions import defun, defun_wrapped + +@defun +def gammaprod(ctx, a, b, _infsign=False): + a = [ctx.convert(x) for x in a] + b = [ctx.convert(x) for x in b] + poles_num = [] + poles_den = [] + regular_num = [] + regular_den = [] + for x in a: [regular_num, poles_num][ctx.isnpint(x)].append(x) + for x in b: [regular_den, poles_den][ctx.isnpint(x)].append(x) + # One more pole in numerator or denominator gives 0 or inf + if len(poles_num) < len(poles_den): return ctx.zero + if len(poles_num) > len(poles_den): + # Get correct sign of infinity for x+h, h -> 0 from above + # XXX: hack, this should be done properly + if _infsign: + a = [x and x*(1+ctx.eps) or x+ctx.eps for x in poles_num] + b = [x and x*(1+ctx.eps) or x+ctx.eps for x in poles_den] + return ctx.sign(ctx.gammaprod(a+regular_num,b+regular_den)) * ctx.inf + else: + return ctx.inf + # All poles cancel + # lim G(i)/G(j) = (-1)**(i+j) * gamma(1-j) / gamma(1-i) + p = ctx.one + orig = ctx.prec + try: + ctx.prec = orig + 15 + while poles_num: + i = poles_num.pop() + j = poles_den.pop() + p *= (-1)**(i+j) * ctx.gamma(1-j) / ctx.gamma(1-i) + for x in regular_num: p *= ctx.gamma(x) + for x in regular_den: p /= ctx.gamma(x) + finally: + ctx.prec = orig + return +p + +@defun +def beta(ctx, x, y): + x = ctx.convert(x) + y = ctx.convert(y) + if ctx.isinf(y): + x, y = y, x + if ctx.isinf(x): + if x == ctx.inf and not ctx._im(y): + if y == ctx.ninf: + return ctx.nan + if y > 0: + return ctx.zero + if ctx.isint(y): + return ctx.nan + if y < 0: + return ctx.sign(ctx.gamma(y)) * ctx.inf + return ctx.nan + xy = ctx.fadd(x, y, prec=2*ctx.prec) + return ctx.gammaprod([x, y], [xy]) + +@defun +def binomial(ctx, n, k): + n1 = ctx.fadd(n, 1, prec=2*ctx.prec) + k1 = ctx.fadd(k, 1, prec=2*ctx.prec) + nk1 = ctx.fsub(n1, k, prec=2*ctx.prec) + return ctx.gammaprod([n1], [k1, nk1]) + +@defun +def rf(ctx, x, n): + xn = ctx.fadd(x, n, prec=2*ctx.prec) + return ctx.gammaprod([xn], [x]) + +@defun +def ff(ctx, x, n): + x1 = ctx.fadd(x, 1, prec=2*ctx.prec) + xn1 = ctx.fadd(ctx.fsub(x, n, prec=2*ctx.prec), 1, prec=2*ctx.prec) + return ctx.gammaprod([x1], [xn1]) + +@defun_wrapped +def fac2(ctx, x): + if ctx.isinf(x): + if x == ctx.inf: + return x + return ctx.nan + return 2**(x/2)*(ctx.pi/2)**((ctx.cospi(x)-1)/4)*ctx.gamma(x/2+1) + +@defun_wrapped +def barnesg(ctx, z): + if ctx.isinf(z): + if z == ctx.inf: + return z + return ctx.nan + if ctx.isnan(z): + return z + if (not ctx._im(z)) and ctx._re(z) <= 0 and ctx.isint(ctx._re(z)): + return z*0 + # Account for size (would not be needed if computing log(G)) + if abs(z) > 5: + ctx.dps += 2*ctx.log(abs(z),2) + # Reflection formula + if ctx.re(z) < -ctx.dps: + w = 1-z + pi2 = 2*ctx.pi + u = ctx.expjpi(2*w) + v = ctx.j*ctx.pi/12 - ctx.j*ctx.pi*w**2/2 + w*ctx.ln(1-u) - \ + ctx.j*ctx.polylog(2, u)/pi2 + v = ctx.barnesg(2-z)*ctx.exp(v)/pi2**w + if ctx._is_real_type(z): + v = ctx._re(v) + return v + # Estimate terms for asymptotic expansion + # TODO: fixme, obviously + N = ctx.dps // 2 + 5 + G = 1 + while abs(z) < N or ctx.re(z) < 1: + G /= ctx.gamma(z) + z += 1 + z -= 1 + s = ctx.mpf(1)/12 + s -= ctx.log(ctx.glaisher) + s += z*ctx.log(2*ctx.pi)/2 + s += (z**2/2-ctx.mpf(1)/12)*ctx.log(z) + s -= 3*z**2/4 + z2k = z2 = z**2 + for k in xrange(1, N+1): + t = ctx.bernoulli(2*k+2) / (4*k*(k+1)*z2k) + if abs(t) < ctx.eps: + #print k, N # check how many terms were needed + break + z2k *= z2 + s += t + #if k == N: + # print "warning: series for barnesg failed to converge", ctx.dps + return G*ctx.exp(s) + +@defun +def superfac(ctx, z): + return ctx.barnesg(z+2) + +@defun_wrapped +def hyperfac(ctx, z): + # XXX: estimate needed extra bits accurately + if z == ctx.inf: + return z + if abs(z) > 5: + extra = 4*int(ctx.log(abs(z),2)) + else: + extra = 0 + ctx.prec += extra + if not ctx._im(z) and ctx._re(z) < 0 and ctx.isint(ctx._re(z)): + n = int(ctx.re(z)) + h = ctx.hyperfac(-n-1) + if ((n+1)//2) & 1: + h = -h + if ctx._is_complex_type(z): + return h + 0j + return h + zp1 = z+1 + # Wrong branch cut + #v = ctx.gamma(zp1)**z + #ctx.prec -= extra + #return v / ctx.barnesg(zp1) + v = ctx.exp(z*ctx.loggamma(zp1)) + ctx.prec -= extra + return v / ctx.barnesg(zp1) + +''' +@defun +def psi0(ctx, z): + """Shortcut for psi(0,z) (the digamma function)""" + return ctx.psi(0, z) + +@defun +def psi1(ctx, z): + """Shortcut for psi(1,z) (the trigamma function)""" + return ctx.psi(1, z) + +@defun +def psi2(ctx, z): + """Shortcut for psi(2,z) (the tetragamma function)""" + return ctx.psi(2, z) + +@defun +def psi3(ctx, z): + """Shortcut for psi(3,z) (the pentagamma function)""" + return ctx.psi(3, z) +''' diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/functions.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/functions.py new file mode 100644 index 0000000000000000000000000000000000000000..4cdf5dd921418db10847ea75b32f8e6dfacdba64 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/functions.py @@ -0,0 +1,645 @@ +from ..libmp.backend import xrange + +class SpecialFunctions(object): + """ + This class implements special functions using high-level code. + + Elementary and some other functions (e.g. gamma function, basecase + hypergeometric series) are assumed to be predefined by the context as + "builtins" or "low-level" functions. + """ + defined_functions = {} + + # The series for the Jacobi theta functions converge for |q| < 1; + # in the current implementation they throw a ValueError for + # abs(q) > THETA_Q_LIM + THETA_Q_LIM = 1 - 10**-7 + + def __init__(self): + cls = self.__class__ + for name in cls.defined_functions: + f, wrap = cls.defined_functions[name] + cls._wrap_specfun(name, f, wrap) + + self.mpq_1 = self._mpq((1,1)) + self.mpq_0 = self._mpq((0,1)) + self.mpq_1_2 = self._mpq((1,2)) + self.mpq_3_2 = self._mpq((3,2)) + self.mpq_1_4 = self._mpq((1,4)) + self.mpq_1_16 = self._mpq((1,16)) + self.mpq_3_16 = self._mpq((3,16)) + self.mpq_5_2 = self._mpq((5,2)) + self.mpq_3_4 = self._mpq((3,4)) + self.mpq_7_4 = self._mpq((7,4)) + self.mpq_5_4 = self._mpq((5,4)) + self.mpq_1_3 = self._mpq((1,3)) + self.mpq_2_3 = self._mpq((2,3)) + self.mpq_4_3 = self._mpq((4,3)) + self.mpq_1_6 = self._mpq((1,6)) + self.mpq_5_6 = self._mpq((5,6)) + self.mpq_5_3 = self._mpq((5,3)) + + self._misc_const_cache = {} + + self._aliases.update({ + 'phase' : 'arg', + 'conjugate' : 'conj', + 'nthroot' : 'root', + 'polygamma' : 'psi', + 'hurwitz' : 'zeta', + #'digamma' : 'psi0', + #'trigamma' : 'psi1', + #'tetragamma' : 'psi2', + #'pentagamma' : 'psi3', + 'fibonacci' : 'fib', + 'factorial' : 'fac', + }) + + self.zetazero_memoized = self.memoize(self.zetazero) + + # Default -- do nothing + @classmethod + def _wrap_specfun(cls, name, f, wrap): + setattr(cls, name, f) + + # Optional fast versions of common functions in common cases. + # If not overridden, default (generic hypergeometric series) + # implementations will be used + def _besselj(ctx, n, z): raise NotImplementedError + def _erf(ctx, z): raise NotImplementedError + def _erfc(ctx, z): raise NotImplementedError + def _gamma_upper_int(ctx, z, a): raise NotImplementedError + def _expint_int(ctx, n, z): raise NotImplementedError + def _zeta(ctx, s): raise NotImplementedError + def _zetasum_fast(ctx, s, a, n, derivatives, reflect): raise NotImplementedError + def _ei(ctx, z): raise NotImplementedError + def _e1(ctx, z): raise NotImplementedError + def _ci(ctx, z): raise NotImplementedError + def _si(ctx, z): raise NotImplementedError + def _altzeta(ctx, s): raise NotImplementedError + +def defun_wrapped(f): + SpecialFunctions.defined_functions[f.__name__] = f, True + return f + +def defun(f): + SpecialFunctions.defined_functions[f.__name__] = f, False + return f + +def defun_static(f): + setattr(SpecialFunctions, f.__name__, f) + return f + +@defun_wrapped +def cot(ctx, z): return ctx.one / ctx.tan(z) + +@defun_wrapped +def sec(ctx, z): return ctx.one / ctx.cos(z) + +@defun_wrapped +def csc(ctx, z): return ctx.one / ctx.sin(z) + +@defun_wrapped +def coth(ctx, z): return ctx.one / ctx.tanh(z) + +@defun_wrapped +def sech(ctx, z): return ctx.one / ctx.cosh(z) + +@defun_wrapped +def csch(ctx, z): return ctx.one / ctx.sinh(z) + +@defun_wrapped +def acot(ctx, z): + if not z: + return ctx.pi * 0.5 + else: + return ctx.atan(ctx.one / z) + +@defun_wrapped +def asec(ctx, z): return ctx.acos(ctx.one / z) + +@defun_wrapped +def acsc(ctx, z): return ctx.asin(ctx.one / z) + +@defun_wrapped +def acoth(ctx, z): + if not z: + return ctx.pi * 0.5j + else: + return ctx.atanh(ctx.one / z) + + +@defun_wrapped +def asech(ctx, z): return ctx.acosh(ctx.one / z) + +@defun_wrapped +def acsch(ctx, z): return ctx.asinh(ctx.one / z) + +@defun +def sign(ctx, x): + x = ctx.convert(x) + if not x or ctx.isnan(x): + return x + if ctx._is_real_type(x): + if x > 0: + return ctx.one + else: + return -ctx.one + return x / abs(x) + +@defun +def agm(ctx, a, b=1): + if b == 1: + return ctx.agm1(a) + a = ctx.convert(a) + b = ctx.convert(b) + return ctx._agm(a, b) + +@defun_wrapped +def sinc(ctx, x): + if ctx.isinf(x): + return 1/x + if not x: + return x+1 + return ctx.sin(x)/x + +@defun_wrapped +def sincpi(ctx, x): + if ctx.isinf(x): + return 1/x + if not x: + return x+1 + return ctx.sinpi(x)/(ctx.pi*x) + +# TODO: tests; improve implementation +@defun_wrapped +def expm1(ctx, x): + if not x: + return ctx.zero + # exp(x) - 1 ~ x + if ctx.mag(x) < -ctx.prec: + return x + 0.5*x**2 + # TODO: accurately eval the smaller of the real/imag parts + return ctx.sum_accurately(lambda: iter([ctx.exp(x),-1]),1) + +@defun_wrapped +def log1p(ctx, x): + if not x: + return ctx.zero + if ctx.mag(x) < -ctx.prec: + return x - 0.5*x**2 + return ctx.log(ctx.fadd(1, x, prec=2*ctx.prec)) + +@defun_wrapped +def powm1(ctx, x, y): + mag = ctx.mag + one = ctx.one + w = x**y - one + M = mag(w) + # Only moderate cancellation + if M > -8: + return w + # Check for the only possible exact cases + if not w: + if (not y) or (x in (1, -1, 1j, -1j) and ctx.isint(y)): + return w + x1 = x - one + magy = mag(y) + lnx = ctx.ln(x) + # Small y: x^y - 1 ~ log(x)*y + O(log(x)^2 * y^2) + if magy + mag(lnx) < -ctx.prec: + return lnx*y + (lnx*y)**2/2 + # TODO: accurately eval the smaller of the real/imag part + return ctx.sum_accurately(lambda: iter([x**y, -1]), 1) + +@defun +def _rootof1(ctx, k, n): + k = int(k) + n = int(n) + k %= n + if not k: + return ctx.one + elif 2*k == n: + return -ctx.one + elif 4*k == n: + return ctx.j + elif 4*k == 3*n: + return -ctx.j + return ctx.expjpi(2*ctx.mpf(k)/n) + +@defun +def root(ctx, x, n, k=0): + n = int(n) + x = ctx.convert(x) + if k: + # Special case: there is an exact real root + if (n & 1 and 2*k == n-1) and (not ctx.im(x)) and (ctx.re(x) < 0): + return -ctx.root(-x, n) + # Multiply by root of unity + prec = ctx.prec + try: + ctx.prec += 10 + v = ctx.root(x, n, 0) * ctx._rootof1(k, n) + finally: + ctx.prec = prec + return +v + return ctx._nthroot(x, n) + +@defun +def unitroots(ctx, n, primitive=False): + gcd = ctx._gcd + prec = ctx.prec + try: + ctx.prec += 10 + if primitive: + v = [ctx._rootof1(k,n) for k in range(n) if gcd(k,n) == 1] + else: + # TODO: this can be done *much* faster + v = [ctx._rootof1(k,n) for k in range(n)] + finally: + ctx.prec = prec + return [+x for x in v] + +@defun +def arg(ctx, x): + x = ctx.convert(x) + re = ctx._re(x) + im = ctx._im(x) + return ctx.atan2(im, re) + +@defun +def fabs(ctx, x): + return abs(ctx.convert(x)) + +@defun +def re(ctx, x): + x = ctx.convert(x) + if hasattr(x, "real"): # py2.5 doesn't have .real/.imag for all numbers + return x.real + return x + +@defun +def im(ctx, x): + x = ctx.convert(x) + if hasattr(x, "imag"): # py2.5 doesn't have .real/.imag for all numbers + return x.imag + return ctx.zero + +@defun +def conj(ctx, x): + x = ctx.convert(x) + try: + return x.conjugate() + except AttributeError: + return x + +@defun +def polar(ctx, z): + return (ctx.fabs(z), ctx.arg(z)) + +@defun_wrapped +def rect(ctx, r, phi): + return r * ctx.mpc(*ctx.cos_sin(phi)) + +@defun +def log(ctx, x, b=None): + if b is None: + return ctx.ln(x) + wp = ctx.prec + 20 + return ctx.ln(x, prec=wp) / ctx.ln(b, prec=wp) + +@defun +def log10(ctx, x): + return ctx.log(x, 10) + +@defun +def fmod(ctx, x, y): + return ctx.convert(x) % ctx.convert(y) + +@defun +def degrees(ctx, x): + return x / ctx.degree + +@defun +def radians(ctx, x): + return x * ctx.degree + +def _lambertw_special(ctx, z, k): + # W(0,0) = 0; all other branches are singular + if not z: + if not k: + return z + return ctx.ninf + z + if z == ctx.inf: + if k == 0: + return z + else: + return z + 2*k*ctx.pi*ctx.j + if z == ctx.ninf: + return (-z) + (2*k+1)*ctx.pi*ctx.j + # Some kind of nan or complex inf/nan? + return ctx.ln(z) + +import math +import cmath + +def _lambertw_approx_hybrid(z, k): + imag_sign = 0 + if hasattr(z, "imag"): + x = float(z.real) + y = z.imag + if y: + imag_sign = (-1) ** (y < 0) + y = float(y) + else: + x = float(z) + y = 0.0 + imag_sign = 0 + # hack to work regardless of whether Python supports -0.0 + if not y: + y = 0.0 + z = complex(x,y) + if k == 0: + if -4.0 < y < 4.0 and -1.0 < x < 2.5: + if imag_sign: + # Taylor series in upper/lower half-plane + if y > 1.00: return (0.876+0.645j) + (0.118-0.174j)*(z-(0.75+2.5j)) + if y > 0.25: return (0.505+0.204j) + (0.375-0.132j)*(z-(0.75+0.5j)) + if y < -1.00: return (0.876-0.645j) + (0.118+0.174j)*(z-(0.75-2.5j)) + if y < -0.25: return (0.505-0.204j) + (0.375+0.132j)*(z-(0.75-0.5j)) + # Taylor series near -1 + if x < -0.5: + if imag_sign >= 0: + return (-0.318+1.34j) + (-0.697-0.593j)*(z+1) + else: + return (-0.318-1.34j) + (-0.697+0.593j)*(z+1) + # return real type + r = -0.367879441171442 + if (not imag_sign) and x > r: + z = x + # Singularity near -1/e + if x < -0.2: + return -1 + 2.33164398159712*(z-r)**0.5 - 1.81218788563936*(z-r) + # Taylor series near 0 + if x < 0.5: return z + # Simple linear approximation + return 0.2 + 0.3*z + if (not imag_sign) and x > 0.0: + L1 = math.log(x); L2 = math.log(L1) + else: + L1 = cmath.log(z); L2 = cmath.log(L1) + elif k == -1: + # return real type + r = -0.367879441171442 + if (not imag_sign) and r < x < 0.0: + z = x + if (imag_sign >= 0) and y < 0.1 and -0.6 < x < -0.2: + return -1 - 2.33164398159712*(z-r)**0.5 - 1.81218788563936*(z-r) + if (not imag_sign) and -0.2 <= x < 0.0: + L1 = math.log(-x) + return L1 - math.log(-L1) + else: + if imag_sign == -1 and (not y) and x < 0.0: + L1 = cmath.log(z) - 3.1415926535897932j + else: + L1 = cmath.log(z) - 6.2831853071795865j + L2 = cmath.log(L1) + return L1 - L2 + L2/L1 + L2*(L2-2)/(2*L1**2) + +def _lambertw_series(ctx, z, k, tol): + """ + Return rough approximation for W_k(z) from an asymptotic series, + sufficiently accurate for the Halley iteration to converge to + the correct value. + """ + magz = ctx.mag(z) + if (-10 < magz < 900) and (-1000 < k < 1000): + # Near the branch point at -1/e + if magz < 1 and abs(z+0.36787944117144) < 0.05: + if k == 0 or (k == -1 and ctx._im(z) >= 0) or \ + (k == 1 and ctx._im(z) < 0): + delta = ctx.sum_accurately(lambda: [z, ctx.exp(-1)]) + cancellation = -ctx.mag(delta) + ctx.prec += cancellation + # Use series given in Corless et al. + p = ctx.sqrt(2*(ctx.e*z+1)) + ctx.prec -= cancellation + u = {0:ctx.mpf(-1), 1:ctx.mpf(1)} + a = {0:ctx.mpf(2), 1:ctx.mpf(-1)} + if k != 0: + p = -p + s = ctx.zero + # The series converges, so we could use it directly, but unless + # *extremely* close, it is better to just use the first few + # terms to get a good approximation for the iteration + for l in xrange(max(2,cancellation)): + if l not in u: + a[l] = ctx.fsum(u[j]*u[l+1-j] for j in xrange(2,l)) + u[l] = (l-1)*(u[l-2]/2+a[l-2]/4)/(l+1)-a[l]/2-u[l-1]/(l+1) + term = u[l] * p**l + s += term + if ctx.mag(term) < -tol: + return s, True + l += 1 + ctx.prec += cancellation//2 + return s, False + if k == 0 or k == -1: + return _lambertw_approx_hybrid(z, k), False + if k == 0: + if magz < -1: + return z*(1-z), False + L1 = ctx.ln(z) + L2 = ctx.ln(L1) + elif k == -1 and (not ctx._im(z)) and (-0.36787944117144 < ctx._re(z) < 0): + L1 = ctx.ln(-z) + return L1 - ctx.ln(-L1), False + else: + # This holds both as z -> 0 and z -> inf. + # Relative error is O(1/log(z)). + L1 = ctx.ln(z) + 2j*ctx.pi*k + L2 = ctx.ln(L1) + return L1 - L2 + L2/L1 + L2*(L2-2)/(2*L1**2), False + +@defun +def lambertw(ctx, z, k=0): + z = ctx.convert(z) + k = int(k) + if not ctx.isnormal(z): + return _lambertw_special(ctx, z, k) + prec = ctx.prec + ctx.prec += 20 + ctx.mag(k or 1) + wp = ctx.prec + tol = wp - 5 + w, done = _lambertw_series(ctx, z, k, tol) + if not done: + # Use Halley iteration to solve w*exp(w) = z + two = ctx.mpf(2) + for i in xrange(100): + ew = ctx.exp(w) + wew = w*ew + wewz = wew-z + wn = w - wewz/(wew+ew-(w+two)*wewz/(two*w+two)) + if ctx.mag(wn-w) <= ctx.mag(wn) - tol: + w = wn + break + else: + w = wn + if i == 100: + ctx.warn("Lambert W iteration failed to converge for z = %s" % z) + ctx.prec = prec + return +w + +@defun_wrapped +def bell(ctx, n, x=1): + x = ctx.convert(x) + if not n: + if ctx.isnan(x): + return x + return type(x)(1) + if ctx.isinf(x) or ctx.isinf(n) or ctx.isnan(x) or ctx.isnan(n): + return x**n + if n == 1: return x + if n == 2: return x*(x+1) + if x == 0: return ctx.sincpi(n) + return _polyexp(ctx, n, x, True) / ctx.exp(x) + +def _polyexp(ctx, n, x, extra=False): + def _terms(): + if extra: + yield ctx.sincpi(n) + t = x + k = 1 + while 1: + yield k**n * t + k += 1 + t = t*x/k + return ctx.sum_accurately(_terms, check_step=4) + +@defun_wrapped +def polyexp(ctx, s, z): + if ctx.isinf(z) or ctx.isinf(s) or ctx.isnan(z) or ctx.isnan(s): + return z**s + if z == 0: return z*s + if s == 0: return ctx.expm1(z) + if s == 1: return ctx.exp(z)*z + if s == 2: return ctx.exp(z)*z*(z+1) + return _polyexp(ctx, s, z) + +@defun_wrapped +def cyclotomic(ctx, n, z): + n = int(n) + if n < 0: + raise ValueError("n cannot be negative") + p = ctx.one + if n == 0: + return p + if n == 1: + return z - p + if n == 2: + return z + p + # Use divisor product representation. Unfortunately, this sometimes + # includes singularities for roots of unity, which we have to cancel out. + # Matching zeros/poles pairwise, we have (1-z^a)/(1-z^b) ~ a/b + O(z-1). + a_prod = 1 + b_prod = 1 + num_zeros = 0 + num_poles = 0 + for d in range(1,n+1): + if not n % d: + w = ctx.moebius(n//d) + # Use powm1 because it is important that we get 0 only + # if it really is exactly 0 + b = -ctx.powm1(z, d) + if b: + p *= b**w + else: + if w == 1: + a_prod *= d + num_zeros += 1 + elif w == -1: + b_prod *= d + num_poles += 1 + #print n, num_zeros, num_poles + if num_zeros: + if num_zeros > num_poles: + p *= 0 + else: + p *= a_prod + p /= b_prod + return p + +@defun +def mangoldt(ctx, n): + r""" + Evaluates the von Mangoldt function `\Lambda(n) = \log p` + if `n = p^k` a power of a prime, and `\Lambda(n) = 0` otherwise. + + **Examples** + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> [mangoldt(n) for n in range(-2,3)] + [0.0, 0.0, 0.0, 0.0, 0.6931471805599453094172321] + >>> mangoldt(6) + 0.0 + >>> mangoldt(7) + 1.945910149055313305105353 + >>> mangoldt(8) + 0.6931471805599453094172321 + >>> fsum(mangoldt(n) for n in range(101)) + 94.04531122935739224600493 + >>> fsum(mangoldt(n) for n in range(10001)) + 10013.39669326311478372032 + + """ + n = int(n) + if n < 2: + return ctx.zero + if n % 2 == 0: + # Must be a power of two + if n & (n-1) == 0: + return +ctx.ln2 + else: + return ctx.zero + # TODO: the following could be generalized into a perfect + # power testing function + # --- + # Look for a small factor + for p in (3,5,7,11,13,17,19,23,29,31): + if not n % p: + q, r = n // p, 0 + while q > 1: + q, r = divmod(q, p) + if r: + return ctx.zero + return ctx.ln(p) + if ctx.isprime(n): + return ctx.ln(n) + # Obviously, we could use arbitrary-precision arithmetic for this... + if n > 10**30: + raise NotImplementedError + k = 2 + while 1: + p = int(n**(1./k) + 0.5) + if p < 2: + return ctx.zero + if p ** k == n: + if ctx.isprime(p): + return ctx.ln(p) + k += 1 + +@defun +def stirling1(ctx, n, k, exact=False): + v = ctx._stirling1(int(n), int(k)) + if exact: + return int(v) + else: + return ctx.mpf(v) + +@defun +def stirling2(ctx, n, k, exact=False): + v = ctx._stirling2(int(n), int(k)) + if exact: + return int(v) + else: + return ctx.mpf(v) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/hypergeometric.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/hypergeometric.py new file mode 100644 index 0000000000000000000000000000000000000000..ddb50cbf3ea6daa5982678d3c26157a67a7d7945 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/hypergeometric.py @@ -0,0 +1,1413 @@ +from ..libmp.backend import xrange +from .functions import defun, defun_wrapped + +def _check_need_perturb(ctx, terms, prec, discard_known_zeros): + perturb = recompute = False + extraprec = 0 + discard = [] + for term_index, term in enumerate(terms): + w_s, c_s, alpha_s, beta_s, a_s, b_s, z = term + have_singular_nongamma_weight = False + # Avoid division by zero in leading factors (TODO: + # also check for near division by zero?) + for k, w in enumerate(w_s): + if not w: + if ctx.re(c_s[k]) <= 0 and c_s[k]: + perturb = recompute = True + have_singular_nongamma_weight = True + pole_count = [0, 0, 0] + # Check for gamma and series poles and near-poles + for data_index, data in enumerate([alpha_s, beta_s, b_s]): + for i, x in enumerate(data): + n, d = ctx.nint_distance(x) + # Poles + if n > 0: + continue + if d == ctx.ninf: + # OK if we have a polynomial + # ------------------------------ + ok = False + if data_index == 2: + for u in a_s: + if ctx.isnpint(u) and u >= int(n): + ok = True + break + if ok: + continue + pole_count[data_index] += 1 + # ------------------------------ + #perturb = recompute = True + #return perturb, recompute, extraprec + elif d < -4: + extraprec += -d + recompute = True + if discard_known_zeros and pole_count[1] > pole_count[0] + pole_count[2] \ + and not have_singular_nongamma_weight: + discard.append(term_index) + elif sum(pole_count): + perturb = recompute = True + return perturb, recompute, extraprec, discard + +_hypercomb_msg = """ +hypercomb() failed to converge to the requested %i bits of accuracy +using a working precision of %i bits. The function value may be zero or +infinite; try passing zeroprec=N or infprec=M to bound finite values between +2^(-N) and 2^M. Otherwise try a higher maxprec or maxterms. +""" + +@defun +def hypercomb(ctx, function, params=[], discard_known_zeros=True, **kwargs): + orig = ctx.prec + sumvalue = ctx.zero + dist = ctx.nint_distance + ninf = ctx.ninf + orig_params = params[:] + verbose = kwargs.get('verbose', False) + maxprec = kwargs.get('maxprec', ctx._default_hyper_maxprec(orig)) + kwargs['maxprec'] = maxprec # For calls to hypsum + zeroprec = kwargs.get('zeroprec') + infprec = kwargs.get('infprec') + perturbed_reference_value = None + hextra = 0 + try: + while 1: + ctx.prec += 10 + if ctx.prec > maxprec: + raise ValueError(_hypercomb_msg % (orig, ctx.prec)) + orig2 = ctx.prec + params = orig_params[:] + terms = function(*params) + if verbose: + print() + print("ENTERING hypercomb main loop") + print("prec =", ctx.prec) + print("hextra", hextra) + perturb, recompute, extraprec, discard = \ + _check_need_perturb(ctx, terms, orig, discard_known_zeros) + ctx.prec += extraprec + if perturb: + if "hmag" in kwargs: + hmag = kwargs["hmag"] + elif ctx._fixed_precision: + hmag = int(ctx.prec*0.3) + else: + hmag = orig + 10 + hextra + h = ctx.ldexp(ctx.one, -hmag) + ctx.prec = orig2 + 10 + hmag + 10 + for k in range(len(params)): + params[k] += h + # Heuristically ensure that the perturbations + # are "independent" so that two perturbations + # don't accidentally cancel each other out + # in a subtraction. + h += h/(k+1) + if recompute: + terms = function(*params) + if discard_known_zeros: + terms = [term for (i, term) in enumerate(terms) if i not in discard] + if not terms: + return ctx.zero + evaluated_terms = [] + for term_index, term_data in enumerate(terms): + w_s, c_s, alpha_s, beta_s, a_s, b_s, z = term_data + if verbose: + print() + print(" Evaluating term %i/%i : %iF%i" % \ + (term_index+1, len(terms), len(a_s), len(b_s))) + print(" powers", ctx.nstr(w_s), ctx.nstr(c_s)) + print(" gamma", ctx.nstr(alpha_s), ctx.nstr(beta_s)) + print(" hyper", ctx.nstr(a_s), ctx.nstr(b_s)) + print(" z", ctx.nstr(z)) + #v = ctx.hyper(a_s, b_s, z, **kwargs) + #for a in alpha_s: v *= ctx.gamma(a) + #for b in beta_s: v *= ctx.rgamma(b) + #for w, c in zip(w_s, c_s): v *= ctx.power(w, c) + v = ctx.fprod([ctx.hyper(a_s, b_s, z, **kwargs)] + \ + [ctx.gamma(a) for a in alpha_s] + \ + [ctx.rgamma(b) for b in beta_s] + \ + [ctx.power(w,c) for (w,c) in zip(w_s,c_s)]) + if verbose: + print(" Value:", v) + evaluated_terms.append(v) + + if len(terms) == 1 and (not perturb): + sumvalue = evaluated_terms[0] + break + + if ctx._fixed_precision: + sumvalue = ctx.fsum(evaluated_terms) + break + + sumvalue = ctx.fsum(evaluated_terms) + term_magnitudes = [ctx.mag(x) for x in evaluated_terms] + max_magnitude = max(term_magnitudes) + sum_magnitude = ctx.mag(sumvalue) + cancellation = max_magnitude - sum_magnitude + if verbose: + print() + print(" Cancellation:", cancellation, "bits") + print(" Increased precision:", ctx.prec - orig, "bits") + + precision_ok = cancellation < ctx.prec - orig + + if zeroprec is None: + zero_ok = False + else: + zero_ok = max_magnitude - ctx.prec < -zeroprec + if infprec is None: + inf_ok = False + else: + inf_ok = max_magnitude > infprec + + if precision_ok and (not perturb) or ctx.isnan(cancellation): + break + elif precision_ok: + if perturbed_reference_value is None: + hextra += 20 + perturbed_reference_value = sumvalue + continue + elif ctx.mag(sumvalue - perturbed_reference_value) <= \ + ctx.mag(sumvalue) - orig: + break + elif zero_ok: + sumvalue = ctx.zero + break + elif inf_ok: + sumvalue = ctx.inf + break + elif 'hmag' in kwargs: + break + else: + hextra *= 2 + perturbed_reference_value = sumvalue + # Increase precision + else: + increment = min(max(cancellation, orig//2), max(extraprec,orig)) + ctx.prec += increment + if verbose: + print(" Must start over with increased precision") + continue + finally: + ctx.prec = orig + return +sumvalue + +@defun +def hyper(ctx, a_s, b_s, z, **kwargs): + """ + Hypergeometric function, general case. + """ + z = ctx.convert(z) + p = len(a_s) + q = len(b_s) + a_s = [ctx._convert_param(a) for a in a_s] + b_s = [ctx._convert_param(b) for b in b_s] + # Reduce degree by eliminating common parameters + if kwargs.get('eliminate', True): + elim_nonpositive = kwargs.get('eliminate_all', False) + i = 0 + while i < q and a_s: + b = b_s[i] + if b in a_s and (elim_nonpositive or not ctx.isnpint(b[0])): + a_s.remove(b) + b_s.remove(b) + p -= 1 + q -= 1 + else: + i += 1 + # Handle special cases + if p == 0: + if q == 1: return ctx._hyp0f1(b_s, z, **kwargs) + elif q == 0: return ctx.exp(z) + elif p == 1: + if q == 1: return ctx._hyp1f1(a_s, b_s, z, **kwargs) + elif q == 2: return ctx._hyp1f2(a_s, b_s, z, **kwargs) + elif q == 0: return ctx._hyp1f0(a_s[0][0], z) + elif p == 2: + if q == 1: return ctx._hyp2f1(a_s, b_s, z, **kwargs) + elif q == 2: return ctx._hyp2f2(a_s, b_s, z, **kwargs) + elif q == 3: return ctx._hyp2f3(a_s, b_s, z, **kwargs) + elif q == 0: return ctx._hyp2f0(a_s, b_s, z, **kwargs) + elif p == q+1: + return ctx._hypq1fq(p, q, a_s, b_s, z, **kwargs) + elif p > q+1 and not kwargs.get('force_series'): + return ctx._hyp_borel(p, q, a_s, b_s, z, **kwargs) + coeffs, types = zip(*(a_s+b_s)) + return ctx.hypsum(p, q, types, coeffs, z, **kwargs) + +@defun +def hyp0f1(ctx,b,z,**kwargs): + return ctx.hyper([],[b],z,**kwargs) + +@defun +def hyp1f1(ctx,a,b,z,**kwargs): + return ctx.hyper([a],[b],z,**kwargs) + +@defun +def hyp1f2(ctx,a1,b1,b2,z,**kwargs): + return ctx.hyper([a1],[b1,b2],z,**kwargs) + +@defun +def hyp2f1(ctx,a,b,c,z,**kwargs): + return ctx.hyper([a,b],[c],z,**kwargs) + +@defun +def hyp2f2(ctx,a1,a2,b1,b2,z,**kwargs): + return ctx.hyper([a1,a2],[b1,b2],z,**kwargs) + +@defun +def hyp2f3(ctx,a1,a2,b1,b2,b3,z,**kwargs): + return ctx.hyper([a1,a2],[b1,b2,b3],z,**kwargs) + +@defun +def hyp2f0(ctx,a,b,z,**kwargs): + return ctx.hyper([a,b],[],z,**kwargs) + +@defun +def hyp3f2(ctx,a1,a2,a3,b1,b2,z,**kwargs): + return ctx.hyper([a1,a2,a3],[b1,b2],z,**kwargs) + +@defun_wrapped +def _hyp1f0(ctx, a, z): + return (1-z) ** (-a) + +@defun +def _hyp0f1(ctx, b_s, z, **kwargs): + (b, btype), = b_s + if z: + magz = ctx.mag(z) + else: + magz = 0 + if magz >= 8 and not kwargs.get('force_series'): + try: + # http://functions.wolfram.com/HypergeometricFunctions/ + # Hypergeometric0F1/06/02/03/0004/ + # TODO: handle the all-real case more efficiently! + # TODO: figure out how much precision is needed (exponential growth) + orig = ctx.prec + try: + ctx.prec += 12 + magz//2 + def h(): + w = ctx.sqrt(-z) + jw = ctx.j*w + u = 1/(4*jw) + c = ctx.mpq_1_2 - b + E = ctx.exp(2*jw) + T1 = ([-jw,E], [c,-1], [], [], [b-ctx.mpq_1_2, ctx.mpq_3_2-b], [], -u) + T2 = ([jw,E], [c,1], [], [], [b-ctx.mpq_1_2, ctx.mpq_3_2-b], [], u) + return T1, T2 + v = ctx.hypercomb(h, [], force_series=True) + v = ctx.gamma(b)/(2*ctx.sqrt(ctx.pi))*v + finally: + ctx.prec = orig + if ctx._is_real_type(b) and ctx._is_real_type(z): + v = ctx._re(v) + return +v + except ctx.NoConvergence: + pass + return ctx.hypsum(0, 1, (btype,), [b], z, **kwargs) + +@defun +def _hyp1f1(ctx, a_s, b_s, z, **kwargs): + (a, atype), = a_s + (b, btype), = b_s + if not z: + return ctx.one+z + magz = ctx.mag(z) + if magz >= 7 and not (ctx.isint(a) and ctx.re(a) <= 0): + if ctx.isinf(z): + if ctx.sign(a) == ctx.sign(b) == ctx.sign(z) == 1: + return ctx.inf + return ctx.nan * z + try: + try: + ctx.prec += magz + sector = ctx._im(z) < 0 + def h(a,b): + if sector: + E = ctx.expjpi(ctx.fneg(a, exact=True)) + else: + E = ctx.expjpi(a) + rz = 1/z + T1 = ([E,z], [1,-a], [b], [b-a], [a, 1+a-b], [], -rz) + T2 = ([ctx.exp(z),z], [1,a-b], [b], [a], [b-a, 1-a], [], rz) + return T1, T2 + v = ctx.hypercomb(h, [a,b], force_series=True) + if ctx._is_real_type(a) and ctx._is_real_type(b) and ctx._is_real_type(z): + v = ctx._re(v) + return +v + except ctx.NoConvergence: + pass + finally: + ctx.prec -= magz + v = ctx.hypsum(1, 1, (atype, btype), [a, b], z, **kwargs) + return v + +def _hyp2f1_gosper(ctx,a,b,c,z,**kwargs): + # Use Gosper's recurrence + # See http://www.math.utexas.edu/pipermail/maxima/2006/000126.html + _a,_b,_c,_z = a, b, c, z + orig = ctx.prec + maxprec = kwargs.get('maxprec', 100*orig) + extra = 10 + while 1: + ctx.prec = orig + extra + #a = ctx.convert(_a) + #b = ctx.convert(_b) + #c = ctx.convert(_c) + z = ctx.convert(_z) + d = ctx.mpf(0) + e = ctx.mpf(1) + f = ctx.mpf(0) + k = 0 + # Common subexpression elimination, unfortunately making + # things a bit unreadable. The formula is quite messy to begin + # with, though... + abz = a*b*z + ch = c * ctx.mpq_1_2 + c1h = (c+1) * ctx.mpq_1_2 + nz = 1-z + g = z/nz + abg = a*b*g + cba = c-b-a + z2 = z-2 + tol = -ctx.prec - 10 + nstr = ctx.nstr + nprint = ctx.nprint + mag = ctx.mag + maxmag = ctx.ninf + while 1: + kch = k+ch + kakbz = (k+a)*(k+b)*z / (4*(k+1)*kch*(k+c1h)) + d1 = kakbz*(e-(k+cba)*d*g) + e1 = kakbz*(d*abg+(k+c)*e) + ft = d*(k*(cba*z+k*z2-c)-abz)/(2*kch*nz) + f1 = f + e - ft + maxmag = max(maxmag, mag(f1)) + if mag(f1-f) < tol: + break + d, e, f = d1, e1, f1 + k += 1 + cancellation = maxmag - mag(f1) + if cancellation < extra: + break + else: + extra += cancellation + if extra > maxprec: + raise ctx.NoConvergence + return f1 + +@defun +def _hyp2f1(ctx, a_s, b_s, z, **kwargs): + (a, atype), (b, btype) = a_s + (c, ctype), = b_s + if z == 1: + # TODO: the following logic can be simplified + convergent = ctx.re(c-a-b) > 0 + finite = (ctx.isint(a) and a <= 0) or (ctx.isint(b) and b <= 0) + zerodiv = ctx.isint(c) and c <= 0 and not \ + ((ctx.isint(a) and c <= a <= 0) or (ctx.isint(b) and c <= b <= 0)) + #print "bz", a, b, c, z, convergent, finite, zerodiv + # Gauss's theorem gives the value if convergent + if (convergent or finite) and not zerodiv: + return ctx.gammaprod([c, c-a-b], [c-a, c-b], _infsign=True) + # Otherwise, there is a pole and we take the + # sign to be that when approaching from below + # XXX: this evaluation is not necessarily correct in all cases + return ctx.hyp2f1(a,b,c,1-ctx.eps*2) * ctx.inf + + # Equal to 1 (first term), unless there is a subsequent + # division by zero + if not z: + # Division by zero but power of z is higher than + # first order so cancels + if c or a == 0 or b == 0: + return 1+z + # Indeterminate + return ctx.nan + + # Hit zero denominator unless numerator goes to 0 first + if ctx.isint(c) and c <= 0: + if (ctx.isint(a) and c <= a <= 0) or \ + (ctx.isint(b) and c <= b <= 0): + pass + else: + # Pole in series + return ctx.inf + + absz = abs(z) + + # Fast case: standard series converges rapidly, + # possibly in finitely many terms + if absz <= 0.8 or (ctx.isint(a) and a <= 0 and a >= -1000) or \ + (ctx.isint(b) and b <= 0 and b >= -1000): + return ctx.hypsum(2, 1, (atype, btype, ctype), [a, b, c], z, **kwargs) + + orig = ctx.prec + try: + ctx.prec += 10 + + # Use 1/z transformation + if absz >= 1.3: + def h(a,b): + t = ctx.mpq_1-c; ab = a-b; rz = 1/z + T1 = ([-z],[-a], [c,-ab],[b,c-a], [a,t+a],[ctx.mpq_1+ab], rz) + T2 = ([-z],[-b], [c,ab],[a,c-b], [b,t+b],[ctx.mpq_1-ab], rz) + return T1, T2 + v = ctx.hypercomb(h, [a,b], **kwargs) + + # Use 1-z transformation + elif abs(1-z) <= 0.75: + def h(a,b): + t = c-a-b; ca = c-a; cb = c-b; rz = 1-z + T1 = [], [], [c,t], [ca,cb], [a,b], [1-t], rz + T2 = [rz], [t], [c,a+b-c], [a,b], [ca,cb], [1+t], rz + return T1, T2 + v = ctx.hypercomb(h, [a,b], **kwargs) + + # Use z/(z-1) transformation + elif abs(z/(z-1)) <= 0.75: + v = ctx.hyp2f1(a, c-b, c, z/(z-1)) / (1-z)**a + + # Remaining part of unit circle + else: + v = _hyp2f1_gosper(ctx,a,b,c,z,**kwargs) + + finally: + ctx.prec = orig + return +v + +@defun +def _hypq1fq(ctx, p, q, a_s, b_s, z, **kwargs): + r""" + Evaluates 3F2, 4F3, 5F4, ... + """ + a_s, a_types = zip(*a_s) + b_s, b_types = zip(*b_s) + a_s = list(a_s) + b_s = list(b_s) + absz = abs(z) + ispoly = False + for a in a_s: + if ctx.isint(a) and a <= 0: + ispoly = True + break + # Direct summation + if absz < 1 or ispoly: + try: + return ctx.hypsum(p, q, a_types+b_types, a_s+b_s, z, **kwargs) + except ctx.NoConvergence: + if absz > 1.1 or ispoly: + raise + # Use expansion at |z-1| -> 0. + # Reference: Wolfgang Buhring, "Generalized Hypergeometric Functions at + # Unit Argument", Proc. Amer. Math. Soc., Vol. 114, No. 1 (Jan. 1992), + # pp.145-153 + # The current implementation has several problems: + # 1. We only implement it for 3F2. The expansion coefficients are + # given by extremely messy nested sums in the higher degree cases + # (see reference). Is efficient sequential generation of the coefficients + # possible in the > 3F2 case? + # 2. Although the series converges, it may do so slowly, so we need + # convergence acceleration. The acceleration implemented by + # nsum does not always help, so results returned are sometimes + # inaccurate! Can we do better? + # 3. We should check conditions for convergence, and possibly + # do a better job of cancelling out gamma poles if possible. + if z == 1: + # XXX: should also check for division by zero in the + # denominator of the series (cf. hyp2f1) + S = ctx.re(sum(b_s)-sum(a_s)) + if S <= 0: + #return ctx.hyper(a_s, b_s, 1-ctx.eps*2, **kwargs) * ctx.inf + return ctx.hyper(a_s, b_s, 0.9, **kwargs) * ctx.inf + if (p,q) == (3,2) and abs(z-1) < 0.05: # and kwargs.get('sum1') + #print "Using alternate summation (experimental)" + a1,a2,a3 = a_s + b1,b2 = b_s + u = b1+b2-a3 + initial = ctx.gammaprod([b2-a3,b1-a3,a1,a2],[b2-a3,b1-a3,1,u]) + def term(k, _cache={0:initial}): + u = b1+b2-a3+k + if k in _cache: + t = _cache[k] + else: + t = _cache[k-1] + t *= (b1+k-a3-1)*(b2+k-a3-1) + t /= k*(u-1) + _cache[k] = t + return t * ctx.hyp2f1(a1,a2,u,z) + try: + S = ctx.nsum(term, [0,ctx.inf], verbose=kwargs.get('verbose'), + strict=kwargs.get('strict', True)) + return S * ctx.gammaprod([b1,b2],[a1,a2,a3]) + except ctx.NoConvergence: + pass + # Try to use convergence acceleration on and close to the unit circle. + # Problem: the convergence acceleration degenerates as |z-1| -> 0, + # except for special cases. Everywhere else, the Shanks transformation + # is very efficient. + if absz < 1.1 and ctx._re(z) <= 1: + + def term(kk, _cache={0:ctx.one}): + k = int(kk) + if k != kk: + t = z ** ctx.mpf(kk) / ctx.fac(kk) + for a in a_s: t *= ctx.rf(a,kk) + for b in b_s: t /= ctx.rf(b,kk) + return t + if k in _cache: + return _cache[k] + t = term(k-1) + m = k-1 + for j in xrange(p): t *= (a_s[j]+m) + for j in xrange(q): t /= (b_s[j]+m) + t *= z + t /= k + _cache[k] = t + return t + + sum_method = kwargs.get('sum_method', 'r+s+e') + + try: + return ctx.nsum(term, [0,ctx.inf], verbose=kwargs.get('verbose'), + strict=kwargs.get('strict', True), + method=sum_method.replace('e','')) + except ctx.NoConvergence: + if 'e' not in sum_method: + raise + pass + + if kwargs.get('verbose'): + print("Attempting Euler-Maclaurin summation") + + + """ + Somewhat slower version (one diffs_exp for each factor). + However, this would be faster with fast direct derivatives + of the gamma function. + + def power_diffs(k0): + r = 0 + l = ctx.log(z) + while 1: + yield z**ctx.mpf(k0) * l**r + r += 1 + + def loggamma_diffs(x, reciprocal=False): + sign = (-1) ** reciprocal + yield sign * ctx.loggamma(x) + i = 0 + while 1: + yield sign * ctx.psi(i,x) + i += 1 + + def hyper_diffs(k0): + b2 = b_s + [1] + A = [ctx.diffs_exp(loggamma_diffs(a+k0)) for a in a_s] + B = [ctx.diffs_exp(loggamma_diffs(b+k0,True)) for b in b2] + Z = [power_diffs(k0)] + C = ctx.gammaprod([b for b in b2], [a for a in a_s]) + for d in ctx.diffs_prod(A + B + Z): + v = C * d + yield v + """ + + def log_diffs(k0): + b2 = b_s + [1] + yield sum(ctx.loggamma(a+k0) for a in a_s) - \ + sum(ctx.loggamma(b+k0) for b in b2) + k0*ctx.log(z) + i = 0 + while 1: + v = sum(ctx.psi(i,a+k0) for a in a_s) - \ + sum(ctx.psi(i,b+k0) for b in b2) + if i == 0: + v += ctx.log(z) + yield v + i += 1 + + def hyper_diffs(k0): + C = ctx.gammaprod([b for b in b_s], [a for a in a_s]) + for d in ctx.diffs_exp(log_diffs(k0)): + v = C * d + yield v + + tol = ctx.eps / 1024 + prec = ctx.prec + try: + trunc = 50 * ctx.dps + ctx.prec += 20 + for i in xrange(5): + head = ctx.fsum(term(k) for k in xrange(trunc)) + tail, err = ctx.sumem(term, [trunc, ctx.inf], tol=tol, + adiffs=hyper_diffs(trunc), + verbose=kwargs.get('verbose'), + error=True, + _fast_abort=True) + if err < tol: + v = head + tail + break + trunc *= 2 + # Need to increase precision because calculation of + # derivatives may be inaccurate + ctx.prec += ctx.prec//2 + if i == 4: + raise ctx.NoConvergence(\ + "Euler-Maclaurin summation did not converge") + finally: + ctx.prec = prec + return +v + + # Use 1/z transformation + # http://functions.wolfram.com/HypergeometricFunctions/ + # HypergeometricPFQ/06/01/05/02/0004/ + def h(*args): + a_s = list(args[:p]) + b_s = list(args[p:]) + Ts = [] + recz = ctx.one/z + negz = ctx.fneg(z, exact=True) + for k in range(q+1): + ak = a_s[k] + C = [negz] + Cp = [-ak] + Gn = b_s + [ak] + [a_s[j]-ak for j in range(q+1) if j != k] + Gd = a_s + [b_s[j]-ak for j in range(q)] + Fn = [ak] + [ak-b_s[j]+1 for j in range(q)] + Fd = [1-a_s[j]+ak for j in range(q+1) if j != k] + Ts.append((C, Cp, Gn, Gd, Fn, Fd, recz)) + return Ts + return ctx.hypercomb(h, a_s+b_s, **kwargs) + +@defun +def _hyp_borel(ctx, p, q, a_s, b_s, z, **kwargs): + if a_s: + a_s, a_types = zip(*a_s) + a_s = list(a_s) + else: + a_s, a_types = [], () + if b_s: + b_s, b_types = zip(*b_s) + b_s = list(b_s) + else: + b_s, b_types = [], () + kwargs['maxterms'] = kwargs.get('maxterms', ctx.prec) + try: + return ctx.hypsum(p, q, a_types+b_types, a_s+b_s, z, **kwargs) + except ctx.NoConvergence: + pass + prec = ctx.prec + try: + tol = kwargs.get('asymp_tol', ctx.eps/4) + ctx.prec += 10 + # hypsum is has a conservative tolerance. So we try again: + def term(k, cache={0:ctx.one}): + if k in cache: + return cache[k] + t = term(k-1) + for a in a_s: t *= (a+(k-1)) + for b in b_s: t /= (b+(k-1)) + t *= z + t /= k + cache[k] = t + return t + s = ctx.one + for k in xrange(1, ctx.prec): + t = term(k) + s += t + if abs(t) <= tol: + return s + finally: + ctx.prec = prec + if p <= q+3: + contour = kwargs.get('contour') + if not contour: + if ctx.arg(z) < 0.25: + u = z / max(1, abs(z)) + if ctx.arg(z) >= 0: + contour = [0, 2j, (2j+2)/u, 2/u, ctx.inf] + else: + contour = [0, -2j, (-2j+2)/u, 2/u, ctx.inf] + #contour = [0, 2j/z, 2/z, ctx.inf] + #contour = [0, 2j, 2/z, ctx.inf] + #contour = [0, 2j, ctx.inf] + else: + contour = [0, ctx.inf] + quad_kwargs = kwargs.get('quad_kwargs', {}) + def g(t): + return ctx.exp(-t)*ctx.hyper(a_s, b_s+[1], t*z) + I, err = ctx.quad(g, contour, error=True, **quad_kwargs) + if err <= abs(I)*ctx.eps*8: + return I + raise ctx.NoConvergence + + +@defun +def _hyp2f2(ctx, a_s, b_s, z, **kwargs): + (a1, a1type), (a2, a2type) = a_s + (b1, b1type), (b2, b2type) = b_s + + absz = abs(z) + magz = ctx.mag(z) + orig = ctx.prec + + # Asymptotic expansion is ~ exp(z) + asymp_extraprec = magz + + # Asymptotic series is in terms of 3F1 + can_use_asymptotic = (not kwargs.get('force_series')) and \ + (ctx.mag(absz) > 3) + + # TODO: much of the following could be shared with 2F3 instead of + # copypasted + if can_use_asymptotic: + #print "using asymp" + try: + try: + ctx.prec += asymp_extraprec + # http://functions.wolfram.com/HypergeometricFunctions/ + # Hypergeometric2F2/06/02/02/0002/ + def h(a1,a2,b1,b2): + X = a1+a2-b1-b2 + A2 = a1+a2 + B2 = b1+b2 + c = {} + c[0] = ctx.one + c[1] = (A2-1)*X+b1*b2-a1*a2 + s1 = 0 + k = 0 + tprev = 0 + while 1: + if k not in c: + uu1 = 1-B2+2*a1+a1**2+2*a2+a2**2-A2*B2+a1*a2+b1*b2+(2*B2-3*(A2+1))*k+2*k**2 + uu2 = (k-A2+b1-1)*(k-A2+b2-1)*(k-X-2) + c[k] = ctx.one/k * (uu1*c[k-1]-uu2*c[k-2]) + t1 = c[k] * z**(-k) + if abs(t1) < 0.1*ctx.eps: + #print "Convergence :)" + break + # Quit if the series doesn't converge quickly enough + if k > 5 and abs(tprev) / abs(t1) < 1.5: + #print "No convergence :(" + raise ctx.NoConvergence + s1 += t1 + tprev = t1 + k += 1 + S = ctx.exp(z)*s1 + T1 = [z,S], [X,1], [b1,b2],[a1,a2],[],[],0 + T2 = [-z],[-a1],[b1,b2,a2-a1],[a2,b1-a1,b2-a1],[a1,a1-b1+1,a1-b2+1],[a1-a2+1],-1/z + T3 = [-z],[-a2],[b1,b2,a1-a2],[a1,b1-a2,b2-a2],[a2,a2-b1+1,a2-b2+1],[-a1+a2+1],-1/z + return T1, T2, T3 + v = ctx.hypercomb(h, [a1,a2,b1,b2], force_series=True, maxterms=4*ctx.prec) + if sum(ctx._is_real_type(u) for u in [a1,a2,b1,b2,z]) == 5: + v = ctx.re(v) + return v + except ctx.NoConvergence: + pass + finally: + ctx.prec = orig + + return ctx.hypsum(2, 2, (a1type, a2type, b1type, b2type), [a1, a2, b1, b2], z, **kwargs) + + + +@defun +def _hyp1f2(ctx, a_s, b_s, z, **kwargs): + (a1, a1type), = a_s + (b1, b1type), (b2, b2type) = b_s + + absz = abs(z) + magz = ctx.mag(z) + orig = ctx.prec + + # Asymptotic expansion is ~ exp(sqrt(z)) + asymp_extraprec = z and magz//2 + + # Asymptotic series is in terms of 3F0 + can_use_asymptotic = (not kwargs.get('force_series')) and \ + (ctx.mag(absz) > 19) and \ + (ctx.sqrt(absz) > 1.5*orig) # and \ + # ctx._hyp_check_convergence([a1, a1-b1+1, a1-b2+1], [], + # 1/absz, orig+40+asymp_extraprec) + + # TODO: much of the following could be shared with 2F3 instead of + # copypasted + if can_use_asymptotic: + #print "using asymp" + try: + try: + ctx.prec += asymp_extraprec + # http://functions.wolfram.com/HypergeometricFunctions/ + # Hypergeometric1F2/06/02/03/ + def h(a1,b1,b2): + X = ctx.mpq_1_2*(a1-b1-b2+ctx.mpq_1_2) + c = {} + c[0] = ctx.one + c[1] = 2*(ctx.mpq_1_4*(3*a1+b1+b2-2)*(a1-b1-b2)+b1*b2-ctx.mpq_3_16) + c[2] = 2*(b1*b2+ctx.mpq_1_4*(a1-b1-b2)*(3*a1+b1+b2-2)-ctx.mpq_3_16)**2+\ + ctx.mpq_1_16*(-16*(2*a1-3)*b1*b2 + \ + 4*(a1-b1-b2)*(-8*a1**2+11*a1+b1+b2-2)-3) + s1 = 0 + s2 = 0 + k = 0 + tprev = 0 + while 1: + if k not in c: + uu1 = (3*k**2+(-6*a1+2*b1+2*b2-4)*k + 3*a1**2 - \ + (b1-b2)**2 - 2*a1*(b1+b2-2) + ctx.mpq_1_4) + uu2 = (k-a1+b1-b2-ctx.mpq_1_2)*(k-a1-b1+b2-ctx.mpq_1_2)*\ + (k-a1+b1+b2-ctx.mpq_5_2) + c[k] = ctx.one/(2*k)*(uu1*c[k-1]-uu2*c[k-2]) + w = c[k] * (-z)**(-0.5*k) + t1 = (-ctx.j)**k * ctx.mpf(2)**(-k) * w + t2 = ctx.j**k * ctx.mpf(2)**(-k) * w + if abs(t1) < 0.1*ctx.eps: + #print "Convergence :)" + break + # Quit if the series doesn't converge quickly enough + if k > 5 and abs(tprev) / abs(t1) < 1.5: + #print "No convergence :(" + raise ctx.NoConvergence + s1 += t1 + s2 += t2 + tprev = t1 + k += 1 + S = ctx.expj(ctx.pi*X+2*ctx.sqrt(-z))*s1 + \ + ctx.expj(-(ctx.pi*X+2*ctx.sqrt(-z)))*s2 + T1 = [0.5*S, ctx.pi, -z], [1, -0.5, X], [b1, b2], [a1],\ + [], [], 0 + T2 = [-z], [-a1], [b1,b2],[b1-a1,b2-a1], \ + [a1,a1-b1+1,a1-b2+1], [], 1/z + return T1, T2 + v = ctx.hypercomb(h, [a1,b1,b2], force_series=True, maxterms=4*ctx.prec) + if sum(ctx._is_real_type(u) for u in [a1,b1,b2,z]) == 4: + v = ctx.re(v) + return v + except ctx.NoConvergence: + pass + finally: + ctx.prec = orig + + #print "not using asymp" + return ctx.hypsum(1, 2, (a1type, b1type, b2type), [a1, b1, b2], z, **kwargs) + + + +@defun +def _hyp2f3(ctx, a_s, b_s, z, **kwargs): + (a1, a1type), (a2, a2type) = a_s + (b1, b1type), (b2, b2type), (b3, b3type) = b_s + + absz = abs(z) + magz = ctx.mag(z) + + # Asymptotic expansion is ~ exp(sqrt(z)) + asymp_extraprec = z and magz//2 + orig = ctx.prec + + # Asymptotic series is in terms of 4F1 + # The square root below empirically provides a plausible criterion + # for the leading series to converge + can_use_asymptotic = (not kwargs.get('force_series')) and \ + (ctx.mag(absz) > 19) and (ctx.sqrt(absz) > 1.5*orig) + + if can_use_asymptotic: + #print "using asymp" + try: + try: + ctx.prec += asymp_extraprec + # http://functions.wolfram.com/HypergeometricFunctions/ + # Hypergeometric2F3/06/02/03/01/0002/ + def h(a1,a2,b1,b2,b3): + X = ctx.mpq_1_2*(a1+a2-b1-b2-b3+ctx.mpq_1_2) + A2 = a1+a2 + B3 = b1+b2+b3 + A = a1*a2 + B = b1*b2+b3*b2+b1*b3 + R = b1*b2*b3 + c = {} + c[0] = ctx.one + c[1] = 2*(B - A + ctx.mpq_1_4*(3*A2+B3-2)*(A2-B3) - ctx.mpq_3_16) + c[2] = ctx.mpq_1_2*c[1]**2 + ctx.mpq_1_16*(-16*(2*A2-3)*(B-A) + 32*R +\ + 4*(-8*A2**2 + 11*A2 + 8*A + B3 - 2)*(A2-B3)-3) + s1 = 0 + s2 = 0 + k = 0 + tprev = 0 + while 1: + if k not in c: + uu1 = (k-2*X-3)*(k-2*X-2*b1-1)*(k-2*X-2*b2-1)*\ + (k-2*X-2*b3-1) + uu2 = (4*(k-1)**3 - 6*(4*X+B3)*(k-1)**2 + \ + 2*(24*X**2+12*B3*X+4*B+B3-1)*(k-1) - 32*X**3 - \ + 24*B3*X**2 - 4*B - 8*R - 4*(4*B+B3-1)*X + 2*B3-1) + uu3 = (5*(k-1)**2+2*(-10*X+A2-3*B3+3)*(k-1)+2*c[1]) + c[k] = ctx.one/(2*k)*(uu1*c[k-3]-uu2*c[k-2]+uu3*c[k-1]) + w = c[k] * ctx.power(-z, -0.5*k) + t1 = (-ctx.j)**k * ctx.mpf(2)**(-k) * w + t2 = ctx.j**k * ctx.mpf(2)**(-k) * w + if abs(t1) < 0.1*ctx.eps: + break + # Quit if the series doesn't converge quickly enough + if k > 5 and abs(tprev) / abs(t1) < 1.5: + raise ctx.NoConvergence + s1 += t1 + s2 += t2 + tprev = t1 + k += 1 + S = ctx.expj(ctx.pi*X+2*ctx.sqrt(-z))*s1 + \ + ctx.expj(-(ctx.pi*X+2*ctx.sqrt(-z)))*s2 + T1 = [0.5*S, ctx.pi, -z], [1, -0.5, X], [b1, b2, b3], [a1, a2],\ + [], [], 0 + T2 = [-z], [-a1], [b1,b2,b3,a2-a1],[a2,b1-a1,b2-a1,b3-a1], \ + [a1,a1-b1+1,a1-b2+1,a1-b3+1], [a1-a2+1], 1/z + T3 = [-z], [-a2], [b1,b2,b3,a1-a2],[a1,b1-a2,b2-a2,b3-a2], \ + [a2,a2-b1+1,a2-b2+1,a2-b3+1],[-a1+a2+1], 1/z + return T1, T2, T3 + v = ctx.hypercomb(h, [a1,a2,b1,b2,b3], force_series=True, maxterms=4*ctx.prec) + if sum(ctx._is_real_type(u) for u in [a1,a2,b1,b2,b3,z]) == 6: + v = ctx.re(v) + return v + except ctx.NoConvergence: + pass + finally: + ctx.prec = orig + + return ctx.hypsum(2, 3, (a1type, a2type, b1type, b2type, b3type), [a1, a2, b1, b2, b3], z, **kwargs) + +@defun +def _hyp2f0(ctx, a_s, b_s, z, **kwargs): + (a, atype), (b, btype) = a_s + # We want to try aggressively to use the asymptotic expansion, + # and fall back only when absolutely necessary + try: + kwargsb = kwargs.copy() + kwargsb['maxterms'] = kwargsb.get('maxterms', ctx.prec) + return ctx.hypsum(2, 0, (atype,btype), [a,b], z, **kwargsb) + except ctx.NoConvergence: + if kwargs.get('force_series'): + raise + pass + def h(a, b): + w = ctx.sinpi(b) + rz = -1/z + T1 = ([ctx.pi,w,rz],[1,-1,a],[],[a-b+1,b],[a],[b],rz) + T2 = ([-ctx.pi,w,rz],[1,-1,1+a-b],[],[a,2-b],[a-b+1],[2-b],rz) + return T1, T2 + return ctx.hypercomb(h, [a, 1+a-b], **kwargs) + +@defun +def meijerg(ctx, a_s, b_s, z, r=1, series=None, **kwargs): + an, ap = a_s + bm, bq = b_s + n = len(an) + p = n + len(ap) + m = len(bm) + q = m + len(bq) + a = an+ap + b = bm+bq + a = [ctx.convert(_) for _ in a] + b = [ctx.convert(_) for _ in b] + z = ctx.convert(z) + if series is None: + if p < q: series = 1 + if p > q: series = 2 + if p == q: + if m+n == p and abs(z) > 1: + series = 2 + else: + series = 1 + if kwargs.get('verbose'): + print("Meijer G m,n,p,q,series =", m,n,p,q,series) + if series == 1: + def h(*args): + a = args[:p] + b = args[p:] + terms = [] + for k in range(m): + bases = [z] + expts = [b[k]/r] + gn = [b[j]-b[k] for j in range(m) if j != k] + gn += [1-a[j]+b[k] for j in range(n)] + gd = [a[j]-b[k] for j in range(n,p)] + gd += [1-b[j]+b[k] for j in range(m,q)] + hn = [1-a[j]+b[k] for j in range(p)] + hd = [1-b[j]+b[k] for j in range(q) if j != k] + hz = (-ctx.one)**(p-m-n) * z**(ctx.one/r) + terms.append((bases, expts, gn, gd, hn, hd, hz)) + return terms + else: + def h(*args): + a = args[:p] + b = args[p:] + terms = [] + for k in range(n): + bases = [z] + if r == 1: + expts = [a[k]-1] + else: + expts = [(a[k]-1)/ctx.convert(r)] + gn = [a[k]-a[j] for j in range(n) if j != k] + gn += [1-a[k]+b[j] for j in range(m)] + gd = [a[k]-b[j] for j in range(m,q)] + gd += [1-a[k]+a[j] for j in range(n,p)] + hn = [1-a[k]+b[j] for j in range(q)] + hd = [1+a[j]-a[k] for j in range(p) if j != k] + hz = (-ctx.one)**(q-m-n) / z**(ctx.one/r) + terms.append((bases, expts, gn, gd, hn, hd, hz)) + return terms + return ctx.hypercomb(h, a+b, **kwargs) + +@defun_wrapped +def appellf1(ctx,a,b1,b2,c,x,y,**kwargs): + # Assume x smaller + # We will use x for the outer loop + if abs(x) > abs(y): + x, y = y, x + b1, b2 = b2, b1 + def ok(x): + return abs(x) < 0.99 + # Finite cases + if ctx.isnpint(a): + pass + elif ctx.isnpint(b1): + pass + elif ctx.isnpint(b2): + x, y, b1, b2 = y, x, b2, b1 + else: + #print x, y + # Note: ok if |y| > 1, because + # 2F1 implements analytic continuation + if not ok(x): + u1 = (x-y)/(x-1) + if not ok(u1): + raise ValueError("Analytic continuation not implemented") + #print "Using analytic continuation" + return (1-x)**(-b1)*(1-y)**(c-a-b2)*\ + ctx.appellf1(c-a,b1,c-b1-b2,c,u1,y,**kwargs) + return ctx.hyper2d({'m+n':[a],'m':[b1],'n':[b2]}, {'m+n':[c]}, x,y, **kwargs) + +@defun +def appellf2(ctx,a,b1,b2,c1,c2,x,y,**kwargs): + # TODO: continuation + return ctx.hyper2d({'m+n':[a],'m':[b1],'n':[b2]}, + {'m':[c1],'n':[c2]}, x,y, **kwargs) + +@defun +def appellf3(ctx,a1,a2,b1,b2,c,x,y,**kwargs): + outer_polynomial = ctx.isnpint(a1) or ctx.isnpint(b1) + inner_polynomial = ctx.isnpint(a2) or ctx.isnpint(b2) + if not outer_polynomial: + if inner_polynomial or abs(x) > abs(y): + x, y = y, x + a1,a2,b1,b2 = a2,a1,b2,b1 + return ctx.hyper2d({'m':[a1,b1],'n':[a2,b2]}, {'m+n':[c]},x,y,**kwargs) + +@defun +def appellf4(ctx,a,b,c1,c2,x,y,**kwargs): + # TODO: continuation + return ctx.hyper2d({'m+n':[a,b]}, {'m':[c1],'n':[c2]},x,y,**kwargs) + +@defun +def hyper2d(ctx, a, b, x, y, **kwargs): + r""" + Sums the generalized 2D hypergeometric series + + .. math :: + + \sum_{m=0}^{\infty} \sum_{n=0}^{\infty} + \frac{P((a),m,n)}{Q((b),m,n)} + \frac{x^m y^n} {m! n!} + + where `(a) = (a_1,\ldots,a_r)`, `(b) = (b_1,\ldots,b_s)` and where + `P` and `Q` are products of rising factorials such as `(a_j)_n` or + `(a_j)_{m+n}`. `P` and `Q` are specified in the form of dicts, with + the `m` and `n` dependence as keys and parameter lists as values. + The supported rising factorials are given in the following table + (note that only a few are supported in `Q`): + + +------------+-------------------+--------+ + | Key | Rising factorial | `Q` | + +============+===================+========+ + | ``'m'`` | `(a_j)_m` | Yes | + +------------+-------------------+--------+ + | ``'n'`` | `(a_j)_n` | Yes | + +------------+-------------------+--------+ + | ``'m+n'`` | `(a_j)_{m+n}` | Yes | + +------------+-------------------+--------+ + | ``'m-n'`` | `(a_j)_{m-n}` | No | + +------------+-------------------+--------+ + | ``'n-m'`` | `(a_j)_{n-m}` | No | + +------------+-------------------+--------+ + | ``'2m+n'`` | `(a_j)_{2m+n}` | No | + +------------+-------------------+--------+ + | ``'2m-n'`` | `(a_j)_{2m-n}` | No | + +------------+-------------------+--------+ + | ``'2n-m'`` | `(a_j)_{2n-m}` | No | + +------------+-------------------+--------+ + + For example, the Appell F1 and F4 functions + + .. math :: + + F_1 = \sum_{m=0}^{\infty} \sum_{n=0}^{\infty} + \frac{(a)_{m+n} (b)_m (c)_n}{(d)_{m+n}} + \frac{x^m y^n}{m! n!} + + F_4 = \sum_{m=0}^{\infty} \sum_{n=0}^{\infty} + \frac{(a)_{m+n} (b)_{m+n}}{(c)_m (d)_{n}} + \frac{x^m y^n}{m! n!} + + can be represented respectively as + + ``hyper2d({'m+n':[a], 'm':[b], 'n':[c]}, {'m+n':[d]}, x, y)`` + + ``hyper2d({'m+n':[a,b]}, {'m':[c], 'n':[d]}, x, y)`` + + More generally, :func:`~mpmath.hyper2d` can evaluate any of the 34 distinct + convergent second-order (generalized Gaussian) hypergeometric + series enumerated by Horn, as well as the Kampe de Feriet + function. + + The series is computed by rewriting it so that the inner + series (i.e. the series containing `n` and `y`) has the form of an + ordinary generalized hypergeometric series and thereby can be + evaluated efficiently using :func:`~mpmath.hyper`. If possible, + manually swapping `x` and `y` and the corresponding parameters + can sometimes give better results. + + **Examples** + + Two separable cases: a product of two geometric series, and a + product of two Gaussian hypergeometric functions:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> x, y = mpf(0.25), mpf(0.5) + >>> hyper2d({'m':1,'n':1}, {}, x,y) + 2.666666666666666666666667 + >>> 1/(1-x)/(1-y) + 2.666666666666666666666667 + >>> hyper2d({'m':[1,2],'n':[3,4]}, {'m':[5],'n':[6]}, x,y) + 4.164358531238938319669856 + >>> hyp2f1(1,2,5,x)*hyp2f1(3,4,6,y) + 4.164358531238938319669856 + + Some more series that can be done in closed form:: + + >>> hyper2d({'m':1,'n':1},{'m+n':1},x,y) + 2.013417124712514809623881 + >>> (exp(x)*x-exp(y)*y)/(x-y) + 2.013417124712514809623881 + + Six of the 34 Horn functions, G1-G3 and H1-H3:: + + >>> from mpmath import * + >>> mp.dps = 10; mp.pretty = True + >>> x, y = 0.0625, 0.125 + >>> a1,a2,b1,b2,c1,c2,d = 1.1,-1.2,-1.3,-1.4,1.5,-1.6,1.7 + >>> hyper2d({'m+n':a1,'n-m':b1,'m-n':b2},{},x,y) # G1 + 1.139090746 + >>> nsum(lambda m,n: rf(a1,m+n)*rf(b1,n-m)*rf(b2,m-n)*\ + ... x**m*y**n/fac(m)/fac(n), [0,inf], [0,inf]) + 1.139090746 + >>> hyper2d({'m':a1,'n':a2,'n-m':b1,'m-n':b2},{},x,y) # G2 + 0.9503682696 + >>> nsum(lambda m,n: rf(a1,m)*rf(a2,n)*rf(b1,n-m)*rf(b2,m-n)*\ + ... x**m*y**n/fac(m)/fac(n), [0,inf], [0,inf]) + 0.9503682696 + >>> hyper2d({'2n-m':a1,'2m-n':a2},{},x,y) # G3 + 1.029372029 + >>> nsum(lambda m,n: rf(a1,2*n-m)*rf(a2,2*m-n)*\ + ... x**m*y**n/fac(m)/fac(n), [0,inf], [0,inf]) + 1.029372029 + >>> hyper2d({'m-n':a1,'m+n':b1,'n':c1},{'m':d},x,y) # H1 + -1.605331256 + >>> nsum(lambda m,n: rf(a1,m-n)*rf(b1,m+n)*rf(c1,n)/rf(d,m)*\ + ... x**m*y**n/fac(m)/fac(n), [0,inf], [0,inf]) + -1.605331256 + >>> hyper2d({'m-n':a1,'m':b1,'n':[c1,c2]},{'m':d},x,y) # H2 + -2.35405404 + >>> nsum(lambda m,n: rf(a1,m-n)*rf(b1,m)*rf(c1,n)*rf(c2,n)/rf(d,m)*\ + ... x**m*y**n/fac(m)/fac(n), [0,inf], [0,inf]) + -2.35405404 + >>> hyper2d({'2m+n':a1,'n':b1},{'m+n':c1},x,y) # H3 + 0.974479074 + >>> nsum(lambda m,n: rf(a1,2*m+n)*rf(b1,n)/rf(c1,m+n)*\ + ... x**m*y**n/fac(m)/fac(n), [0,inf], [0,inf]) + 0.974479074 + + **References** + + 1. [SrivastavaKarlsson]_ + 2. [Weisstein]_ http://mathworld.wolfram.com/HornFunction.html + 3. [Weisstein]_ http://mathworld.wolfram.com/AppellHypergeometricFunction.html + + """ + x = ctx.convert(x) + y = ctx.convert(y) + def parse(dct, key): + args = dct.pop(key, []) + try: + args = list(args) + except TypeError: + args = [args] + return [ctx.convert(arg) for arg in args] + a_s = dict(a) + b_s = dict(b) + a_m = parse(a, 'm') + a_n = parse(a, 'n') + a_m_add_n = parse(a, 'm+n') + a_m_sub_n = parse(a, 'm-n') + a_n_sub_m = parse(a, 'n-m') + a_2m_add_n = parse(a, '2m+n') + a_2m_sub_n = parse(a, '2m-n') + a_2n_sub_m = parse(a, '2n-m') + b_m = parse(b, 'm') + b_n = parse(b, 'n') + b_m_add_n = parse(b, 'm+n') + if a: raise ValueError("unsupported key: %r" % a.keys()[0]) + if b: raise ValueError("unsupported key: %r" % b.keys()[0]) + s = 0 + outer = ctx.one + m = ctx.mpf(0) + ok_count = 0 + prec = ctx.prec + maxterms = kwargs.get('maxterms', 20*prec) + try: + ctx.prec += 10 + tol = +ctx.eps + while 1: + inner_sign = 1 + outer_sign = 1 + inner_a = list(a_n) + inner_b = list(b_n) + outer_a = [a+m for a in a_m] + outer_b = [b+m for b in b_m] + # (a)_{m+n} = (a)_m (a+m)_n + for a in a_m_add_n: + a = a+m + inner_a.append(a) + outer_a.append(a) + # (b)_{m+n} = (b)_m (b+m)_n + for b in b_m_add_n: + b = b+m + inner_b.append(b) + outer_b.append(b) + # (a)_{n-m} = (a-m)_n / (a-m)_m + for a in a_n_sub_m: + inner_a.append(a-m) + outer_b.append(a-m-1) + # (a)_{m-n} = (-1)^(m+n) (1-a-m)_m / (1-a-m)_n + for a in a_m_sub_n: + inner_sign *= (-1) + outer_sign *= (-1)**(m) + inner_b.append(1-a-m) + outer_a.append(-a-m) + # (a)_{2m+n} = (a)_{2m} (a+2m)_n + for a in a_2m_add_n: + inner_a.append(a+2*m) + outer_a.append((a+2*m)*(1+a+2*m)) + # (a)_{2m-n} = (-1)^(2m+n) (1-a-2m)_{2m} / (1-a-2m)_n + for a in a_2m_sub_n: + inner_sign *= (-1) + inner_b.append(1-a-2*m) + outer_a.append((a+2*m)*(1+a+2*m)) + # (a)_{2n-m} = 4^n ((a-m)/2)_n ((a-m+1)/2)_n / (a-m)_m + for a in a_2n_sub_m: + inner_sign *= 4 + inner_a.append(0.5*(a-m)) + inner_a.append(0.5*(a-m+1)) + outer_b.append(a-m-1) + inner = ctx.hyper(inner_a, inner_b, inner_sign*y, + zeroprec=ctx.prec, **kwargs) + term = outer * inner * outer_sign + if abs(term) < tol: + ok_count += 1 + else: + ok_count = 0 + if ok_count >= 3 or not outer: + break + s += term + for a in outer_a: outer *= a + for b in outer_b: outer /= b + m += 1 + outer = outer * x / m + if m > maxterms: + raise ctx.NoConvergence("maxterms exceeded in hyper2d") + finally: + ctx.prec = prec + return +s + +""" +@defun +def kampe_de_feriet(ctx,a,b,c,d,e,f,x,y,**kwargs): + return ctx.hyper2d({'m+n':a,'m':b,'n':c}, + {'m+n':d,'m':e,'n':f}, x,y, **kwargs) +""" + +@defun +def bihyper(ctx, a_s, b_s, z, **kwargs): + r""" + Evaluates the bilateral hypergeometric series + + .. math :: + + \,_AH_B(a_1, \ldots, a_k; b_1, \ldots, b_B; z) = + \sum_{n=-\infty}^{\infty} + \frac{(a_1)_n \ldots (a_A)_n} + {(b_1)_n \ldots (b_B)_n} \, z^n + + where, for direct convergence, `A = B` and `|z| = 1`, although a + regularized sum exists more generally by considering the + bilateral series as a sum of two ordinary hypergeometric + functions. In order for the series to make sense, none of the + parameters may be integers. + + **Examples** + + The value of `\,_2H_2` at `z = 1` is given by Dougall's formula:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> a,b,c,d = 0.5, 1.5, 2.25, 3.25 + >>> bihyper([a,b],[c,d],1) + -14.49118026212345786148847 + >>> gammaprod([c,d,1-a,1-b,c+d-a-b-1],[c-a,d-a,c-b,d-b]) + -14.49118026212345786148847 + + The regularized function `\,_1H_0` can be expressed as the + sum of one `\,_2F_0` function and one `\,_1F_1` function:: + + >>> a = mpf(0.25) + >>> z = mpf(0.75) + >>> bihyper([a], [], z) + (0.2454393389657273841385582 + 0.2454393389657273841385582j) + >>> hyper([a,1],[],z) + (hyper([1],[1-a],-1/z)-1) + (0.2454393389657273841385582 + 0.2454393389657273841385582j) + >>> hyper([a,1],[],z) + hyper([1],[2-a],-1/z)/z/(a-1) + (0.2454393389657273841385582 + 0.2454393389657273841385582j) + + **References** + + 1. [Slater]_ (chapter 6: "Bilateral Series", pp. 180-189) + 2. [Wikipedia]_ http://en.wikipedia.org/wiki/Bilateral_hypergeometric_series + + """ + z = ctx.convert(z) + c_s = a_s + b_s + p = len(a_s) + q = len(b_s) + if (p, q) == (0,0) or (p, q) == (1,1): + return ctx.zero * z + neg = (p-q) % 2 + def h(*c_s): + a_s = list(c_s[:p]) + b_s = list(c_s[p:]) + aa_s = [2-b for b in b_s] + bb_s = [2-a for a in a_s] + rp = [(-1)**neg * z] + [1-b for b in b_s] + [1-a for a in a_s] + rc = [-1] + [1]*len(b_s) + [-1]*len(a_s) + T1 = [], [], [], [], a_s + [1], b_s, z + T2 = rp, rc, [], [], aa_s + [1], bb_s, (-1)**neg / z + return T1, T2 + return ctx.hypercomb(h, c_s, **kwargs) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/orthogonal.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/orthogonal.py new file mode 100644 index 0000000000000000000000000000000000000000..aa33d8bd78290f55a970e78dab7a317d5f652dee --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/orthogonal.py @@ -0,0 +1,493 @@ +from .functions import defun, defun_wrapped + +def _hermite_param(ctx, n, z, parabolic_cylinder): + """ + Combined calculation of the Hermite polynomial H_n(z) (and its + generalization to complex n) and the parabolic cylinder + function D. + """ + n, ntyp = ctx._convert_param(n) + z = ctx.convert(z) + q = -ctx.mpq_1_2 + # For re(z) > 0, 2F0 -- http://functions.wolfram.com/ + # HypergeometricFunctions/HermiteHGeneral/06/02/0009/ + # Otherwise, there is a reflection formula + # 2F0 + http://functions.wolfram.com/HypergeometricFunctions/ + # HermiteHGeneral/16/01/01/0006/ + # + # TODO: + # An alternative would be to use + # http://functions.wolfram.com/HypergeometricFunctions/ + # HermiteHGeneral/06/02/0006/ + # + # Also, the 1F1 expansion + # http://functions.wolfram.com/HypergeometricFunctions/ + # HermiteHGeneral/26/01/02/0001/ + # should probably be used for tiny z + if not z: + T1 = [2, ctx.pi], [n, 0.5], [], [q*(n-1)], [], [], 0 + if parabolic_cylinder: + T1[1][0] += q*n + return T1, + can_use_2f0 = ctx.isnpint(-n) or ctx.re(z) > 0 or \ + (ctx.re(z) == 0 and ctx.im(z) > 0) + expprec = ctx.prec*4 + 20 + if parabolic_cylinder: + u = ctx.fmul(ctx.fmul(z,z,prec=expprec), -0.25, exact=True) + w = ctx.fmul(z, ctx.sqrt(0.5,prec=expprec), prec=expprec) + else: + w = z + w2 = ctx.fmul(w, w, prec=expprec) + rw2 = ctx.fdiv(1, w2, prec=expprec) + nrw2 = ctx.fneg(rw2, exact=True) + nw = ctx.fneg(w, exact=True) + if can_use_2f0: + T1 = [2, w], [n, n], [], [], [q*n, q*(n-1)], [], nrw2 + terms = [T1] + else: + T1 = [2, nw], [n, n], [], [], [q*n, q*(n-1)], [], nrw2 + T2 = [2, ctx.pi, nw], [n+2, 0.5, 1], [], [q*n], [q*(n-1)], [1-q], w2 + terms = [T1,T2] + # Multiply by prefactor for D_n + if parabolic_cylinder: + expu = ctx.exp(u) + for i in range(len(terms)): + terms[i][1][0] += q*n + terms[i][0].append(expu) + terms[i][1].append(1) + return tuple(terms) + +@defun +def hermite(ctx, n, z, **kwargs): + return ctx.hypercomb(lambda: _hermite_param(ctx, n, z, 0), [], **kwargs) + +@defun +def pcfd(ctx, n, z, **kwargs): + r""" + Gives the parabolic cylinder function in Whittaker's notation + `D_n(z) = U(-n-1/2, z)` (see :func:`~mpmath.pcfu`). + It solves the differential equation + + .. math :: + + y'' + \left(n + \frac{1}{2} - \frac{1}{4} z^2\right) y = 0. + + and can be represented in terms of Hermite polynomials + (see :func:`~mpmath.hermite`) as + + .. math :: + + D_n(z) = 2^{-n/2} e^{-z^2/4} H_n\left(\frac{z}{\sqrt{2}}\right). + + **Plots** + + .. literalinclude :: /plots/pcfd.py + .. image :: /plots/pcfd.png + + **Examples** + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> pcfd(0,0); pcfd(1,0); pcfd(2,0); pcfd(3,0) + 1.0 + 0.0 + -1.0 + 0.0 + >>> pcfd(4,0); pcfd(-3,0) + 3.0 + 0.6266570686577501256039413 + >>> pcfd('1/2', 2+3j) + (-5.363331161232920734849056 - 3.858877821790010714163487j) + >>> pcfd(2, -10) + 1.374906442631438038871515e-9 + + Verifying the differential equation:: + + >>> n = mpf(2.5) + >>> y = lambda z: pcfd(n,z) + >>> z = 1.75 + >>> chop(diff(y,z,2) + (n+0.5-0.25*z**2)*y(z)) + 0.0 + + Rational Taylor series expansion when `n` is an integer:: + + >>> taylor(lambda z: pcfd(5,z), 0, 7) + [0.0, 15.0, 0.0, -13.75, 0.0, 3.96875, 0.0, -0.6015625] + + """ + return ctx.hypercomb(lambda: _hermite_param(ctx, n, z, 1), [], **kwargs) + +@defun +def pcfu(ctx, a, z, **kwargs): + r""" + Gives the parabolic cylinder function `U(a,z)`, which may be + defined for `\Re(z) > 0` in terms of the confluent + U-function (see :func:`~mpmath.hyperu`) by + + .. math :: + + U(a,z) = 2^{-\frac{1}{4}-\frac{a}{2}} e^{-\frac{1}{4} z^2} + U\left(\frac{a}{2}+\frac{1}{4}, + \frac{1}{2}, \frac{1}{2}z^2\right) + + or, for arbitrary `z`, + + .. math :: + + e^{-\frac{1}{4}z^2} U(a,z) = + U(a,0) \,_1F_1\left(-\tfrac{a}{2}+\tfrac{1}{4}; + \tfrac{1}{2}; -\tfrac{1}{2}z^2\right) + + U'(a,0) z \,_1F_1\left(-\tfrac{a}{2}+\tfrac{3}{4}; + \tfrac{3}{2}; -\tfrac{1}{2}z^2\right). + + **Examples** + + Connection to other functions:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> z = mpf(3) + >>> pcfu(0.5,z) + 0.03210358129311151450551963 + >>> sqrt(pi/2)*exp(z**2/4)*erfc(z/sqrt(2)) + 0.03210358129311151450551963 + >>> pcfu(0.5,-z) + 23.75012332835297233711255 + >>> sqrt(pi/2)*exp(z**2/4)*erfc(-z/sqrt(2)) + 23.75012332835297233711255 + >>> pcfu(0.5,-z) + 23.75012332835297233711255 + >>> sqrt(pi/2)*exp(z**2/4)*erfc(-z/sqrt(2)) + 23.75012332835297233711255 + + """ + n, _ = ctx._convert_param(a) + return ctx.pcfd(-n-ctx.mpq_1_2, z) + +@defun +def pcfv(ctx, a, z, **kwargs): + r""" + Gives the parabolic cylinder function `V(a,z)`, which can be + represented in terms of :func:`~mpmath.pcfu` as + + .. math :: + + V(a,z) = \frac{\Gamma(a+\tfrac{1}{2}) (U(a,-z)-\sin(\pi a) U(a,z)}{\pi}. + + **Examples** + + Wronskian relation between `U` and `V`:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> a, z = 2, 3 + >>> pcfu(a,z)*diff(pcfv,(a,z),(0,1))-diff(pcfu,(a,z),(0,1))*pcfv(a,z) + 0.7978845608028653558798921 + >>> sqrt(2/pi) + 0.7978845608028653558798921 + >>> a, z = 2.5, 3 + >>> pcfu(a,z)*diff(pcfv,(a,z),(0,1))-diff(pcfu,(a,z),(0,1))*pcfv(a,z) + 0.7978845608028653558798921 + >>> a, z = 0.25, -1 + >>> pcfu(a,z)*diff(pcfv,(a,z),(0,1))-diff(pcfu,(a,z),(0,1))*pcfv(a,z) + 0.7978845608028653558798921 + >>> a, z = 2+1j, 2+3j + >>> chop(pcfu(a,z)*diff(pcfv,(a,z),(0,1))-diff(pcfu,(a,z),(0,1))*pcfv(a,z)) + 0.7978845608028653558798921 + + """ + n, ntype = ctx._convert_param(a) + z = ctx.convert(z) + q = ctx.mpq_1_2 + r = ctx.mpq_1_4 + if ntype == 'Q' and ctx.isint(n*2): + # Faster for half-integers + def h(): + jz = ctx.fmul(z, -1j, exact=True) + T1terms = _hermite_param(ctx, -n-q, z, 1) + T2terms = _hermite_param(ctx, n-q, jz, 1) + for T in T1terms: + T[0].append(1j) + T[1].append(1) + T[3].append(q-n) + u = ctx.expjpi((q*n-r)) * ctx.sqrt(2/ctx.pi) + for T in T2terms: + T[0].append(u) + T[1].append(1) + return T1terms + T2terms + v = ctx.hypercomb(h, [], **kwargs) + if ctx._is_real_type(n) and ctx._is_real_type(z): + v = ctx._re(v) + return v + else: + def h(n): + w = ctx.square_exp_arg(z, -0.25) + u = ctx.square_exp_arg(z, 0.5) + e = ctx.exp(w) + l = [ctx.pi, q, ctx.exp(w)] + Y1 = l, [-q, n*q+r, 1], [r-q*n], [], [q*n+r], [q], u + Y2 = l + [z], [-q, n*q-r, 1, 1], [1-r-q*n], [], [q*n+1-r], [1+q], u + c, s = ctx.cospi_sinpi(r+q*n) + Y1[0].append(s) + Y2[0].append(c) + for Y in (Y1, Y2): + Y[1].append(1) + Y[3].append(q-n) + return Y1, Y2 + return ctx.hypercomb(h, [n], **kwargs) + + +@defun +def pcfw(ctx, a, z, **kwargs): + r""" + Gives the parabolic cylinder function `W(a,z)` defined in (DLMF 12.14). + + **Examples** + + Value at the origin:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> a = mpf(0.25) + >>> pcfw(a,0) + 0.9722833245718180765617104 + >>> power(2,-0.75)*sqrt(abs(gamma(0.25+0.5j*a)/gamma(0.75+0.5j*a))) + 0.9722833245718180765617104 + >>> diff(pcfw,(a,0),(0,1)) + -0.5142533944210078966003624 + >>> -power(2,-0.25)*sqrt(abs(gamma(0.75+0.5j*a)/gamma(0.25+0.5j*a))) + -0.5142533944210078966003624 + + """ + n, _ = ctx._convert_param(a) + z = ctx.convert(z) + def terms(): + phi2 = ctx.arg(ctx.gamma(0.5 + ctx.j*n)) + phi2 = (ctx.loggamma(0.5+ctx.j*n) - ctx.loggamma(0.5-ctx.j*n))/2j + rho = ctx.pi/8 + 0.5*phi2 + # XXX: cancellation computing k + k = ctx.sqrt(1 + ctx.exp(2*ctx.pi*n)) - ctx.exp(ctx.pi*n) + C = ctx.sqrt(k/2) * ctx.exp(0.25*ctx.pi*n) + yield C * ctx.expj(rho) * ctx.pcfu(ctx.j*n, z*ctx.expjpi(-0.25)) + yield C * ctx.expj(-rho) * ctx.pcfu(-ctx.j*n, z*ctx.expjpi(0.25)) + v = ctx.sum_accurately(terms) + if ctx._is_real_type(n) and ctx._is_real_type(z): + v = ctx._re(v) + return v + +""" +Even/odd PCFs. Useful? + +@defun +def pcfy1(ctx, a, z, **kwargs): + a, _ = ctx._convert_param(n) + z = ctx.convert(z) + def h(): + w = ctx.square_exp_arg(z) + w1 = ctx.fmul(w, -0.25, exact=True) + w2 = ctx.fmul(w, 0.5, exact=True) + e = ctx.exp(w1) + return [e], [1], [], [], [ctx.mpq_1_2*a+ctx.mpq_1_4], [ctx.mpq_1_2], w2 + return ctx.hypercomb(h, [], **kwargs) + +@defun +def pcfy2(ctx, a, z, **kwargs): + a, _ = ctx._convert_param(n) + z = ctx.convert(z) + def h(): + w = ctx.square_exp_arg(z) + w1 = ctx.fmul(w, -0.25, exact=True) + w2 = ctx.fmul(w, 0.5, exact=True) + e = ctx.exp(w1) + return [e, z], [1, 1], [], [], [ctx.mpq_1_2*a+ctx.mpq_3_4], \ + [ctx.mpq_3_2], w2 + return ctx.hypercomb(h, [], **kwargs) +""" + +@defun_wrapped +def gegenbauer(ctx, n, a, z, **kwargs): + # Special cases: a+0.5, a*2 poles + if ctx.isnpint(a): + return 0*(z+n) + if ctx.isnpint(a+0.5): + # TODO: something else is required here + # E.g.: gegenbauer(-2, -0.5, 3) == -12 + if ctx.isnpint(n+1): + raise NotImplementedError("Gegenbauer function with two limits") + def h(a): + a2 = 2*a + T = [], [], [n+a2], [n+1, a2], [-n, n+a2], [a+0.5], 0.5*(1-z) + return [T] + return ctx.hypercomb(h, [a], **kwargs) + def h(n): + a2 = 2*a + T = [], [], [n+a2], [n+1, a2], [-n, n+a2], [a+0.5], 0.5*(1-z) + return [T] + return ctx.hypercomb(h, [n], **kwargs) + +@defun_wrapped +def jacobi(ctx, n, a, b, x, **kwargs): + if not ctx.isnpint(a): + def h(n): + return (([], [], [a+n+1], [n+1, a+1], [-n, a+b+n+1], [a+1], (1-x)*0.5),) + return ctx.hypercomb(h, [n], **kwargs) + if not ctx.isint(b): + def h(n, a): + return (([], [], [-b], [n+1, -b-n], [-n, a+b+n+1], [b+1], (x+1)*0.5),) + return ctx.hypercomb(h, [n, a], **kwargs) + # XXX: determine appropriate limit + return ctx.binomial(n+a,n) * ctx.hyp2f1(-n,1+n+a+b,a+1,(1-x)/2, **kwargs) + +@defun_wrapped +def laguerre(ctx, n, a, z, **kwargs): + # XXX: limits, poles + #if ctx.isnpint(n): + # return 0*(a+z) + def h(a): + return (([], [], [a+n+1], [a+1, n+1], [-n], [a+1], z),) + return ctx.hypercomb(h, [a], **kwargs) + +@defun_wrapped +def legendre(ctx, n, x, **kwargs): + if ctx.isint(n): + n = int(n) + # Accuracy near zeros + if (n + (n < 0)) & 1: + if not x: + return x + mag = ctx.mag(x) + if mag < -2*ctx.prec-10: + return x + if mag < -5: + ctx.prec += -mag + return ctx.hyp2f1(-n,n+1,1,(1-x)/2, **kwargs) + +@defun +def legenp(ctx, n, m, z, type=2, **kwargs): + # Legendre function, 1st kind + n = ctx.convert(n) + m = ctx.convert(m) + # Faster + if not m: + return ctx.legendre(n, z, **kwargs) + # TODO: correct evaluation at singularities + if type == 2: + def h(n,m): + g = m*0.5 + T = [1+z, 1-z], [g, -g], [], [1-m], [-n, n+1], [1-m], 0.5*(1-z) + return (T,) + return ctx.hypercomb(h, [n,m], **kwargs) + if type == 3: + def h(n,m): + g = m*0.5 + T = [z+1, z-1], [g, -g], [], [1-m], [-n, n+1], [1-m], 0.5*(1-z) + return (T,) + return ctx.hypercomb(h, [n,m], **kwargs) + raise ValueError("requires type=2 or type=3") + +@defun +def legenq(ctx, n, m, z, type=2, **kwargs): + # Legendre function, 2nd kind + n = ctx.convert(n) + m = ctx.convert(m) + z = ctx.convert(z) + if z in (1, -1): + #if ctx.isint(m): + # return ctx.nan + #return ctx.inf # unsigned + return ctx.nan + if type == 2: + def h(n, m): + cos, sin = ctx.cospi_sinpi(m) + s = 2 * sin / ctx.pi + c = cos + a = 1+z + b = 1-z + u = m/2 + w = (1-z)/2 + T1 = [s, c, a, b], [-1, 1, u, -u], [], [1-m], \ + [-n, n+1], [1-m], w + T2 = [-s, a, b], [-1, -u, u], [n+m+1], [n-m+1, m+1], \ + [-n, n+1], [m+1], w + return T1, T2 + return ctx.hypercomb(h, [n, m], **kwargs) + if type == 3: + # The following is faster when there only is a single series + # Note: not valid for -1 < z < 0 (?) + if abs(z) > 1: + def h(n, m): + T1 = [ctx.expjpi(m), 2, ctx.pi, z, z-1, z+1], \ + [1, -n-1, 0.5, -n-m-1, 0.5*m, 0.5*m], \ + [n+m+1], [n+1.5], \ + [0.5*(2+n+m), 0.5*(1+n+m)], [n+1.5], z**(-2) + return [T1] + return ctx.hypercomb(h, [n, m], **kwargs) + else: + # not valid for 1 < z < inf ? + def h(n, m): + s = 2 * ctx.sinpi(m) / ctx.pi + c = ctx.expjpi(m) + a = 1+z + b = z-1 + u = m/2 + w = (1-z)/2 + T1 = [s, c, a, b], [-1, 1, u, -u], [], [1-m], \ + [-n, n+1], [1-m], w + T2 = [-s, c, a, b], [-1, 1, -u, u], [n+m+1], [n-m+1, m+1], \ + [-n, n+1], [m+1], w + return T1, T2 + return ctx.hypercomb(h, [n, m], **kwargs) + raise ValueError("requires type=2 or type=3") + +@defun_wrapped +def chebyt(ctx, n, x, **kwargs): + if (not x) and ctx.isint(n) and int(ctx._re(n)) % 2 == 1: + return x * 0 + return ctx.hyp2f1(-n,n,(1,2),(1-x)/2, **kwargs) + +@defun_wrapped +def chebyu(ctx, n, x, **kwargs): + if (not x) and ctx.isint(n) and int(ctx._re(n)) % 2 == 1: + return x * 0 + return (n+1) * ctx.hyp2f1(-n, n+2, (3,2), (1-x)/2, **kwargs) + +@defun +def spherharm(ctx, l, m, theta, phi, **kwargs): + l = ctx.convert(l) + m = ctx.convert(m) + theta = ctx.convert(theta) + phi = ctx.convert(phi) + l_isint = ctx.isint(l) + l_natural = l_isint and l >= 0 + m_isint = ctx.isint(m) + if l_isint and l < 0 and m_isint: + return ctx.spherharm(-(l+1), m, theta, phi, **kwargs) + if theta == 0 and m_isint and m < 0: + return ctx.zero * 1j + if l_natural and m_isint: + if abs(m) > l: + return ctx.zero * 1j + # http://functions.wolfram.com/Polynomials/ + # SphericalHarmonicY/26/01/02/0004/ + def h(l,m): + absm = abs(m) + C = [-1, ctx.expj(m*phi), + (2*l+1)*ctx.fac(l+absm)/ctx.pi/ctx.fac(l-absm), + ctx.sin(theta)**2, + ctx.fac(absm), 2] + P = [0.5*m*(ctx.sign(m)+1), 1, 0.5, 0.5*absm, -1, -absm-1] + return ((C, P, [], [], [absm-l, l+absm+1], [absm+1], + ctx.sin(0.5*theta)**2),) + else: + # http://functions.wolfram.com/HypergeometricFunctions/ + # SphericalHarmonicYGeneral/26/01/02/0001/ + def h(l,m): + if ctx.isnpint(l-m+1) or ctx.isnpint(l+m+1) or ctx.isnpint(1-m): + return (([0], [-1], [], [], [], [], 0),) + cos, sin = ctx.cos_sin(0.5*theta) + C = [0.5*ctx.expj(m*phi), (2*l+1)/ctx.pi, + ctx.gamma(l-m+1), ctx.gamma(l+m+1), + cos**2, sin**2] + P = [1, 0.5, 0.5, -0.5, 0.5*m, -0.5*m] + return ((C, P, [], [1-m], [-l,l+1], [1-m], sin**2),) + return ctx.hypercomb(h, [l,m], **kwargs) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/qfunctions.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/qfunctions.py new file mode 100644 index 0000000000000000000000000000000000000000..5a20e53a8b6fa0d8fbc9ad098614d2694998f49a --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/qfunctions.py @@ -0,0 +1,280 @@ +from .functions import defun, defun_wrapped + +@defun +def qp(ctx, a, q=None, n=None, **kwargs): + r""" + Evaluates the q-Pochhammer symbol (or q-rising factorial) + + .. math :: + + (a; q)_n = \prod_{k=0}^{n-1} (1-a q^k) + + where `n = \infty` is permitted if `|q| < 1`. Called with two arguments, + ``qp(a,q)`` computes `(a;q)_{\infty}`; with a single argument, ``qp(q)`` + computes `(q;q)_{\infty}`. The special case + + .. math :: + + \phi(q) = (q; q)_{\infty} = \prod_{k=1}^{\infty} (1-q^k) = + \sum_{k=-\infty}^{\infty} (-1)^k q^{(3k^2-k)/2} + + is also known as the Euler function, or (up to a factor `q^{-1/24}`) + the Dedekind eta function. + + **Examples** + + If `n` is a positive integer, the function amounts to a finite product:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> qp(2,3,5) + -725305.0 + >>> fprod(1-2*3**k for k in range(5)) + -725305.0 + >>> qp(2,3,0) + 1.0 + + Complex arguments are allowed:: + + >>> qp(2-1j, 0.75j) + (0.4628842231660149089976379 + 4.481821753552703090628793j) + + The regular Pochhammer symbol `(a)_n` is obtained in the + following limit as `q \to 1`:: + + >>> a, n = 4, 7 + >>> limit(lambda q: qp(q**a,q,n) / (1-q)**n, 1) + 604800.0 + >>> rf(a,n) + 604800.0 + + The Taylor series of the reciprocal Euler function gives + the partition function `P(n)`, i.e. the number of ways of writing + `n` as a sum of positive integers:: + + >>> taylor(lambda q: 1/qp(q), 0, 10) + [1.0, 1.0, 2.0, 3.0, 5.0, 7.0, 11.0, 15.0, 22.0, 30.0, 42.0] + + Special values include:: + + >>> qp(0) + 1.0 + >>> findroot(diffun(qp), -0.4) # location of maximum + -0.4112484791779547734440257 + >>> qp(_) + 1.228348867038575112586878 + + The q-Pochhammer symbol is related to the Jacobi theta functions. + For example, the following identity holds:: + + >>> q = mpf(0.5) # arbitrary + >>> qp(q) + 0.2887880950866024212788997 + >>> root(3,-2)*root(q,-24)*jtheta(2,pi/6,root(q,6)) + 0.2887880950866024212788997 + + """ + a = ctx.convert(a) + if n is None: + n = ctx.inf + else: + n = ctx.convert(n) + if n < 0: + raise ValueError("n cannot be negative") + if q is None: + q = a + else: + q = ctx.convert(q) + if n == 0: + return ctx.one + 0*(a+q) + infinite = (n == ctx.inf) + same = (a == q) + if infinite: + if abs(q) >= 1: + if same and (q == -1 or q == 1): + return ctx.zero * q + raise ValueError("q-function only defined for |q| < 1") + elif q == 0: + return ctx.one - a + maxterms = kwargs.get('maxterms', 50*ctx.prec) + if infinite and same: + # Euler's pentagonal theorem + def terms(): + t = 1 + yield t + k = 1 + x1 = q + x2 = q**2 + while 1: + yield (-1)**k * x1 + yield (-1)**k * x2 + x1 *= q**(3*k+1) + x2 *= q**(3*k+2) + k += 1 + if k > maxterms: + raise ctx.NoConvergence + return ctx.sum_accurately(terms) + # return ctx.nprod(lambda k: 1-a*q**k, [0,n-1]) + def factors(): + k = 0 + r = ctx.one + while 1: + yield 1 - a*r + r *= q + k += 1 + if k >= n: + return + if k > maxterms: + raise ctx.NoConvergence + return ctx.mul_accurately(factors) + +@defun_wrapped +def qgamma(ctx, z, q, **kwargs): + r""" + Evaluates the q-gamma function + + .. math :: + + \Gamma_q(z) = \frac{(q; q)_{\infty}}{(q^z; q)_{\infty}} (1-q)^{1-z}. + + + **Examples** + + Evaluation for real and complex arguments:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> qgamma(4,0.75) + 4.046875 + >>> qgamma(6,6) + 121226245.0 + >>> qgamma(3+4j, 0.5j) + (0.1663082382255199834630088 + 0.01952474576025952984418217j) + + The q-gamma function satisfies a functional equation similar + to that of the ordinary gamma function:: + + >>> q = mpf(0.25) + >>> z = mpf(2.5) + >>> qgamma(z+1,q) + 1.428277424823760954685912 + >>> (1-q**z)/(1-q)*qgamma(z,q) + 1.428277424823760954685912 + + """ + if abs(q) > 1: + return ctx.qgamma(z,1/q)*q**((z-2)*(z-1)*0.5) + return ctx.qp(q, q, None, **kwargs) / \ + ctx.qp(q**z, q, None, **kwargs) * (1-q)**(1-z) + +@defun_wrapped +def qfac(ctx, z, q, **kwargs): + r""" + Evaluates the q-factorial, + + .. math :: + + [n]_q! = (1+q)(1+q+q^2)\cdots(1+q+\cdots+q^{n-1}) + + or more generally + + .. math :: + + [z]_q! = \frac{(q;q)_z}{(1-q)^z}. + + **Examples** + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> qfac(0,0) + 1.0 + >>> qfac(4,3) + 2080.0 + >>> qfac(5,6) + 121226245.0 + >>> qfac(1+1j, 2+1j) + (0.4370556551322672478613695 + 0.2609739839216039203708921j) + + """ + if ctx.isint(z) and ctx._re(z) > 0: + n = int(ctx._re(z)) + return ctx.qp(q, q, n, **kwargs) / (1-q)**n + return ctx.qgamma(z+1, q, **kwargs) + +@defun +def qhyper(ctx, a_s, b_s, q, z, **kwargs): + r""" + Evaluates the basic hypergeometric series or hypergeometric q-series + + .. math :: + + \,_r\phi_s \left[\begin{matrix} + a_1 & a_2 & \ldots & a_r \\ + b_1 & b_2 & \ldots & b_s + \end{matrix} ; q,z \right] = + \sum_{n=0}^\infty + \frac{(a_1;q)_n, \ldots, (a_r;q)_n} + {(b_1;q)_n, \ldots, (b_s;q)_n} + \left((-1)^n q^{n\choose 2}\right)^{1+s-r} + \frac{z^n}{(q;q)_n} + + where `(a;q)_n` denotes the q-Pochhammer symbol (see :func:`~mpmath.qp`). + + **Examples** + + Evaluation works for real and complex arguments:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> qhyper([0.5], [2.25], 0.25, 4) + -0.1975849091263356009534385 + >>> qhyper([0.5], [2.25], 0.25-0.25j, 4) + (2.806330244925716649839237 + 3.568997623337943121769938j) + >>> qhyper([1+j], [2,3+0.5j], 0.25, 3+4j) + (9.112885171773400017270226 - 1.272756997166375050700388j) + + Comparing with a summation of the defining series, using + :func:`~mpmath.nsum`:: + + >>> b, q, z = 3, 0.25, 0.5 + >>> qhyper([], [b], q, z) + 0.6221136748254495583228324 + >>> nsum(lambda n: z**n / qp(q,q,n)/qp(b,q,n) * q**(n*(n-1)), [0,inf]) + 0.6221136748254495583228324 + + """ + #a_s = [ctx._convert_param(a)[0] for a in a_s] + #b_s = [ctx._convert_param(b)[0] for b in b_s] + #q = ctx._convert_param(q)[0] + a_s = [ctx.convert(a) for a in a_s] + b_s = [ctx.convert(b) for b in b_s] + q = ctx.convert(q) + z = ctx.convert(z) + r = len(a_s) + s = len(b_s) + d = 1+s-r + maxterms = kwargs.get('maxterms', 50*ctx.prec) + def terms(): + t = ctx.one + yield t + qk = 1 + k = 0 + x = 1 + while 1: + for a in a_s: + p = 1 - a*qk + t *= p + for b in b_s: + p = 1 - b*qk + if not p: + raise ValueError + t /= p + t *= z + x *= (-1)**d * qk ** d + qk *= q + t /= (1 - qk) + k += 1 + yield t * x + if k > maxterms: + raise ctx.NoConvergence + return ctx.sum_accurately(terms) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/rszeta.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/rszeta.py new file mode 100644 index 0000000000000000000000000000000000000000..19e2c9a251b81bafe8cf77a2b0180636b1078ee4 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/rszeta.py @@ -0,0 +1,1403 @@ +""" +--------------------------------------------------------------------- +.. sectionauthor:: Juan Arias de Reyna + +This module implements zeta-related functions using the Riemann-Siegel +expansion: zeta_offline(s,k=0) + +* coef(J, eps): Need in the computation of Rzeta(s,k) + +* Rzeta_simul(s, der=0) computes Rzeta^(k)(s) and Rzeta^(k)(1-s) simultaneously + for 0 <= k <= der. Used by zeta_offline and z_offline + +* Rzeta_set(s, derivatives) computes Rzeta^(k)(s) for given derivatives, used by + z_half(t,k) and zeta_half + +* z_offline(w,k): Z(w) and its derivatives of order k <= 4 +* z_half(t,k): Z(t) (Riemann Siegel function) and its derivatives of order k <= 4 +* zeta_offline(s): zeta(s) and its derivatives of order k<= 4 +* zeta_half(1/2+it,k): zeta(s) and its derivatives of order k<= 4 + +* rs_zeta(s,k=0) Computes zeta^(k)(s) Unifies zeta_half and zeta_offline +* rs_z(w,k=0) Computes Z^(k)(w) Unifies z_offline and z_half +---------------------------------------------------------------------- + +This program uses Riemann-Siegel expansion even to compute +zeta(s) on points s = sigma + i t with sigma arbitrary not +necessarily equal to 1/2. + +It is founded on a new deduction of the formula, with rigorous +and sharp bounds for the terms and rest of this expansion. + +More information on the papers: + + J. Arias de Reyna, High Precision Computation of Riemann's + Zeta Function by the Riemann-Siegel Formula I, II + + We refer to them as I, II. + + In them we shall find detailed explanation of all the + procedure. + +The program uses Riemann-Siegel expansion. +This is useful when t is big, ( say t > 10000 ). +The precision is limited, roughly it can compute zeta(sigma+it) +with an error less than exp(-c t) for some constant c depending +on sigma. The program gives an error when the Riemann-Siegel +formula can not compute to the wanted precision. + +""" + +import math + +class RSCache(object): + def __init__(ctx): + ctx._rs_cache = [0, 10, {}, {}] + +from .functions import defun + +#-------------------------------------------------------------------------------# +# # +# coef(ctx, J, eps, _cache=[0, 10, {} ] ) # +# # +#-------------------------------------------------------------------------------# + +# This function computes the coefficients c[n] defined on (I, equation (47)) +# but see also (II, section 3.14). +# +# Since these coefficients are very difficult to compute we save the values +# in a cache. So if we compute several values of the functions Rzeta(s) for +# near values of s, we do not recompute these coefficients. +# +# c[n] are the Taylor coefficients of the function: +# +# F(z):= (exp(pi*j*(z*z/2+3/8))-j* sqrt(2) cos(pi*z/2))/(2*cos(pi *z)) +# +# + +def _coef(ctx, J, eps): + r""" + Computes the coefficients `c_n` for `0\le n\le 2J` with error less than eps + + **Definition** + + The coefficients c_n are defined by + + .. math :: + + \begin{equation} + F(z)=\frac{e^{\pi i + \bigl(\frac{z^2}{2}+\frac38\bigr)}-i\sqrt{2}\cos\frac{\pi}{2}z}{2\cos\pi + z}=\sum_{n=0}^\infty c_{2n} z^{2n} + \end{equation} + + they are computed applying the relation + + .. math :: + + \begin{multline} + c_{2n}=-\frac{i}{\sqrt{2}}\Bigl(\frac{\pi}{2}\Bigr)^{2n} + \sum_{k=0}^n\frac{(-1)^k}{(2k)!} + 2^{2n-2k}\frac{(-1)^{n-k}E_{2n-2k}}{(2n-2k)!}+\\ + +e^{3\pi i/8}\sum_{j=0}^n(-1)^j\frac{ + E_{2j}}{(2j)!}\frac{i^{n-j}\pi^{n+j}}{(n-j)!2^{n-j+1}}. + \end{multline} + """ + + newJ = J+2 # compute more coefficients that are needed + neweps6 = eps/2. # compute with a slight more precision that are needed + + # PREPARATION FOR THE COMPUTATION OF V(N) AND W(N) + # See II Section 3.16 + # + # Computing the exponent wpvw of the error II equation (81) + wpvw = max(ctx.mag(10*(newJ+3)), 4*newJ+5-ctx.mag(neweps6)) + + # Preparation of Euler numbers (we need until the 2*RS_NEWJ) + E = ctx._eulernum(2*newJ) + + # Now we have in the cache all the needed Euler numbers. + # + # Computing the powers of pi + # + # We need to compute the powers pi**n for 1<= n <= 2*J + # with relative error less than 2**(-wpvw) + # it is easy to show that this is obtained + # taking wppi as the least d with + # 2**d>40*J and 2**d> 4.24 *newJ + 2**wpvw + # In II Section 3.9 we need also that + # wppi > wptcoef[0], and that the powers + # here computed 0<= k <= 2*newJ are more + # than those needed there that are 2*L-2. + # so we need J >= L this will be checked + # before computing tcoef[] + wppi = max(ctx.mag(40*newJ), ctx.mag(newJ)+3 +wpvw) + ctx.prec = wppi + pipower = {} + pipower[0] = ctx.one + pipower[1] = ctx.pi + for n in range(2,2*newJ+1): + pipower[n] = pipower[n-1]*ctx.pi + + # COMPUTING THE COEFFICIENTS v(n) AND w(n) + # see II equation (61) and equations (81) and (82) + ctx.prec = wpvw+2 + v={} + w={} + for n in range(0,newJ+1): + va = (-1)**n * ctx._eulernum(2*n) + va = ctx.mpf(va)/ctx.fac(2*n) + v[n]=va*pipower[2*n] + for n in range(0,2*newJ+1): + wa = ctx.one/ctx.fac(n) + wa=wa/(2**n) + w[n]=wa*pipower[n] + + # COMPUTATION OF THE CONVOLUTIONS RS_P1 AND RS_P2 + # See II Section 3.16 + ctx.prec = 15 + wpp1a = 9 - ctx.mag(neweps6) + P1 = {} + for n in range(0,newJ+1): + ctx.prec = 15 + wpp1 = max(ctx.mag(10*(n+4)),4*n+wpp1a) + ctx.prec = wpp1 + sump = 0 + for k in range(0,n+1): + sump += ((-1)**k) * v[k]*w[2*n-2*k] + P1[n]=((-1)**(n+1))*ctx.j*sump + P2={} + for n in range(0,newJ+1): + ctx.prec = 15 + wpp2 = max(ctx.mag(10*(n+4)),4*n+wpp1a) + ctx.prec = wpp2 + sump = 0 + for k in range(0,n+1): + sump += (ctx.j**(n-k)) * v[k]*w[n-k] + P2[n]=sump + # COMPUTING THE COEFFICIENTS c[2n] + # See II Section 3.14 + ctx.prec = 15 + wpc0 = 5 - ctx.mag(neweps6) + wpc = max(6,4*newJ+wpc0) + ctx.prec = wpc + mu = ctx.sqrt(ctx.mpf('2'))/2 + nu = ctx.expjpi(3./8)/2 + c={} + for n in range(0,newJ): + ctx.prec = 15 + wpc = max(6,4*n+wpc0) + ctx.prec = wpc + c[2*n] = mu*P1[n]+nu*P2[n] + for n in range(1,2*newJ,2): + c[n] = 0 + return [newJ, neweps6, c, pipower] + +def coef(ctx, J, eps): + _cache = ctx._rs_cache + if J <= _cache[0] and eps >= _cache[1]: + return _cache[2], _cache[3] + orig = ctx._mp.prec + try: + data = _coef(ctx._mp, J, eps) + finally: + ctx._mp.prec = orig + if ctx is not ctx._mp: + data[2] = dict((k,ctx.convert(v)) for (k,v) in data[2].items()) + data[3] = dict((k,ctx.convert(v)) for (k,v) in data[3].items()) + ctx._rs_cache[:] = data + return ctx._rs_cache[2], ctx._rs_cache[3] + +#-------------------------------------------------------------------------------# +# # +# Rzeta_simul(s,k=0) # +# # +#-------------------------------------------------------------------------------# +# This function return a list with the values: +# Rzeta(sigma+it), conj(Rzeta(1-sigma+it)),Rzeta'(sigma+it), conj(Rzeta'(1-sigma+it)), +# .... , Rzeta^{(k)}(sigma+it), conj(Rzeta^{(k)}(1-sigma+it)) +# +# Useful to compute the function zeta(s) and Z(w) or its derivatives. +# + +def aux_M_Fp(ctx, xA, xeps4, a, xB1, xL): + # COMPUTING M NUMBER OF DERIVATIVES Fp[m] TO COMPUTE + # See II Section 3.11 equations (47) and (48) + aux1 = 126.0657606*xA/xeps4 # 126.06.. = 316/sqrt(2*pi) + aux1 = ctx.ln(aux1) + aux2 = (2*ctx.ln(ctx.pi)+ctx.ln(xB1)+ctx.ln(a))/3 -ctx.ln(2*ctx.pi)/2 + m = 3*xL-3 + aux3= (ctx.loggamma(m+1)-ctx.loggamma(m/3.0+2))/2 -ctx.loggamma((m+1)/2.) + while((aux1 < m*aux2+ aux3)and (m>1)): + m = m - 1 + aux3 = (ctx.loggamma(m+1)-ctx.loggamma(m/3.0+2))/2 -ctx.loggamma((m+1)/2.) + xM = m + return xM + +def aux_J_needed(ctx, xA, xeps4, a, xB1, xM): + # DETERMINATION OF J THE NUMBER OF TERMS NEEDED + # IN THE TAYLOR SERIES OF F. + # See II Section 3.11 equation (49)) + # Only determine one + h1 = xeps4/(632*xA) + h2 = xB1*a * 126.31337419529260248 # = pi^2*e^2*sqrt(3) + h2 = h1 * ctx.power((h2/xM**2),(xM-1)/3) / xM + h3 = min(h1,h2) + return h3 + +def Rzeta_simul(ctx, s, der=0): + # First we take the value of ctx.prec + wpinitial = ctx.prec + + # INITIALIZATION + # Take the real and imaginary part of s + t = ctx._im(s) + xsigma = ctx._re(s) + ysigma = 1 - xsigma + + # Now compute several parameter that appear on the program + ctx.prec = 15 + a = ctx.sqrt(t/(2*ctx.pi)) + xasigma = a ** xsigma + yasigma = a ** ysigma + + # We need a simple bound A1 < asigma (see II Section 3.1 and 3.3) + xA1=ctx.power(2, ctx.mag(xasigma)-1) + yA1=ctx.power(2, ctx.mag(yasigma)-1) + + # We compute various epsilon's (see II end of Section 3.1) + eps = ctx.power(2, -wpinitial) + eps1 = eps/6. + xeps2 = eps * xA1/3. + yeps2 = eps * yA1/3. + + # COMPUTING SOME COEFFICIENTS THAT DEPENDS + # ON sigma + # constant b and c (see I Theorem 2 formula (26) ) + # coefficients A and B1 (see I Section 6.1 equation (50)) + # + # here we not need high precision + ctx.prec = 15 + if xsigma > 0: + xb = 2. + xc = math.pow(9,xsigma)/4.44288 + # 4.44288 =(math.sqrt(2)*math.pi) + xA = math.pow(9,xsigma) + xB1 = 1 + else: + xb = 2.25158 # math.sqrt( (3-2* math.log(2))*math.pi ) + xc = math.pow(2,-xsigma)/4.44288 + xA = math.pow(2,-xsigma) + xB1 = 1.10789 # = 2*sqrt(1-log(2)) + + if(ysigma > 0): + yb = 2. + yc = math.pow(9,ysigma)/4.44288 + # 4.44288 =(math.sqrt(2)*math.pi) + yA = math.pow(9,ysigma) + yB1 = 1 + else: + yb = 2.25158 # math.sqrt( (3-2* math.log(2))*math.pi ) + yc = math.pow(2,-ysigma)/4.44288 + yA = math.pow(2,-ysigma) + yB1 = 1.10789 # = 2*sqrt(1-log(2)) + + # COMPUTING L THE NUMBER OF TERMS NEEDED IN THE RIEMANN-SIEGEL + # CORRECTION + # See II Section 3.2 + ctx.prec = 15 + xL = 1 + while 3*xc*ctx.gamma(xL*0.5) * ctx.power(xb*a,-xL) >= xeps2: + xL = xL+1 + xL = max(2,xL) + yL = 1 + while 3*yc*ctx.gamma(yL*0.5) * ctx.power(yb*a,-yL) >= yeps2: + yL = yL+1 + yL = max(2,yL) + + # The number L has to satify some conditions. + # If not RS can not compute Rzeta(s) with the prescribed precision + # (see II, Section 3.2 condition (20) ) and + # (II, Section 3.3 condition (22) ). Also we have added + # an additional technical condition in Section 3.17 Proposition 17 + if ((3*xL >= 2*a*a/25.) or (3*xL+2+xsigma<0) or (abs(xsigma) > a/2.) or \ + (3*yL >= 2*a*a/25.) or (3*yL+2+ysigma<0) or (abs(ysigma) > a/2.)): + ctx.prec = wpinitial + raise NotImplementedError("Riemann-Siegel can not compute with such precision") + + # We take the maximum of the two values + L = max(xL, yL) + + # INITIALIZATION (CONTINUATION) + # + # eps3 is the constant defined on (II, Section 3.5 equation (27) ) + # each term of the RS correction must be computed with error <= eps3 + xeps3 = xeps2/(4*xL) + yeps3 = yeps2/(4*yL) + + # eps4 is defined on (II Section 3.6 equation (30) ) + # each component of the formula (II Section 3.6 equation (29) ) + # must be computed with error <= eps4 + xeps4 = xeps3/(3*xL) + yeps4 = yeps3/(3*yL) + + # COMPUTING M NUMBER OF DERIVATIVES Fp[m] TO COMPUTE + xM = aux_M_Fp(ctx, xA, xeps4, a, xB1, xL) + yM = aux_M_Fp(ctx, yA, yeps4, a, yB1, yL) + M = max(xM, yM) + + # COMPUTING NUMBER OF TERMS J NEEDED + h3 = aux_J_needed(ctx, xA, xeps4, a, xB1, xM) + h4 = aux_J_needed(ctx, yA, yeps4, a, yB1, yM) + h3 = min(h3,h4) + J = 12 + jvalue = (2*ctx.pi)**J / ctx.gamma(J+1) + while jvalue > h3: + J = J+1 + jvalue = (2*ctx.pi)*jvalue/J + + # COMPUTING eps5[m] for 1 <= m <= 21 + # See II Section 10 equation (43) + # We choose the minimum of the two possibilities + eps5={} + xforeps5 = math.pi*math.pi*xB1*a + yforeps5 = math.pi*math.pi*yB1*a + for m in range(0,22): + xaux1 = math.pow(xforeps5, m/3)/(316.*xA) + yaux1 = math.pow(yforeps5, m/3)/(316.*yA) + aux1 = min(xaux1, yaux1) + aux2 = ctx.gamma(m+1)/ctx.gamma(m/3.0+0.5) + aux2 = math.sqrt(aux2) + eps5[m] = (aux1*aux2*min(xeps4,yeps4)) + + # COMPUTING wpfp + # See II Section 3.13 equation (59) + twenty = min(3*L-3, 21)+1 + aux = 6812*J + wpfp = ctx.mag(44*J) + for m in range(0,twenty): + wpfp = max(wpfp, ctx.mag(aux*ctx.gamma(m+1)/eps5[m])) + + # COMPUTING N AND p + # See II Section + ctx.prec = wpfp + ctx.mag(t)+20 + a = ctx.sqrt(t/(2*ctx.pi)) + N = ctx.floor(a) + p = 1-2*(a-N) + + # now we get a rounded version of p + # to the precision wpfp + # this possibly is not necessary + num=ctx.floor(p*(ctx.mpf('2')**wpfp)) + difference = p * (ctx.mpf('2')**wpfp)-num + if (difference < 0.5): + num = num + else: + num = num+1 + p = ctx.convert(num * (ctx.mpf('2')**(-wpfp))) + + # COMPUTING THE COEFFICIENTS c[n] = cc[n] + # We shall use the notation cc[n], since there is + # a constant that is called c + # See II Section 3.14 + # We compute the coefficients and also save then in a + # cache. The bulk of the computation is passed to + # the function coef() + # + # eps6 is defined in II Section 3.13 equation (58) + eps6 = ctx.power(ctx.convert(2*ctx.pi), J)/(ctx.gamma(J+1)*3*J) + + # Now we compute the coefficients + cc = {} + cont = {} + cont, pipowers = coef(ctx, J, eps6) + cc=cont.copy() # we need a copy since we have to change his values. + Fp={} # this is the adequate locus of this + for n in range(M, 3*L-2): + Fp[n] = 0 + Fp={} + ctx.prec = wpfp + for m in range(0,M+1): + sumP = 0 + for k in range(2*J-m-1,-1,-1): + sumP = (sumP * p)+ cc[k] + Fp[m] = sumP + # preparation of the new coefficients + for k in range(0,2*J-m-1): + cc[k] = (k+1)* cc[k+1] + + # COMPUTING THE NUMBERS xd[u,n,k], yd[u,n,k] + # See II Section 3.17 + # + # First we compute the working precisions xwpd[k] + # Se II equation (92) + xwpd={} + d1 = max(6,ctx.mag(40*L*L)) + xd2 = 13+ctx.mag((1+abs(xsigma))*xA)-ctx.mag(xeps4)-1 + xconst = ctx.ln(8/(ctx.pi*ctx.pi*a*a*xB1*xB1)) /2 + for n in range(0,L): + xd3 = ctx.mag(ctx.sqrt(ctx.gamma(n-0.5)))-ctx.floor(n*xconst)+xd2 + xwpd[n]=max(xd3,d1) + + # procedure of II Section 3.17 + ctx.prec = xwpd[1]+10 + xpsigma = 1-(2*xsigma) + xd = {} + xd[0,0,-2]=0; xd[0,0,-1]=0; xd[0,0,0]=1; xd[0,0,1]=0 + xd[0,-1,-2]=0; xd[0,-1,-1]=0; xd[0,-1,0]=1; xd[0,-1,1]=0 + for n in range(1,L): + ctx.prec = xwpd[n]+10 + for k in range(0,3*n//2+1): + m = 3*n-2*k + if(m!=0): + m1 = ctx.one/m + c1= m1/4 + c2=(xpsigma*m1)/2 + c3=-(m+1) + xd[0,n,k]=c3*xd[0,n-1,k-2]+c1*xd[0,n-1,k]+c2*xd[0,n-1,k-1] + else: + xd[0,n,k]=0 + for r in range(0,k): + add=xd[0,n,r]*(ctx.mpf('1.0')*ctx.fac(2*k-2*r)/ctx.fac(k-r)) + xd[0,n,k] -= ((-1)**(k-r))*add + xd[0,n,-2]=0; xd[0,n,-1]=0; xd[0,n,3*n//2+1]=0 + for mu in range(-2,der+1): + for n in range(-2,L): + for k in range(-3,max(1,3*n//2+2)): + if( (mu<0)or (n<0) or(k<0)or (k>3*n//2)): + xd[mu,n,k] = 0 + for mu in range(1,der+1): + for n in range(0,L): + ctx.prec = xwpd[n]+10 + for k in range(0,3*n//2+1): + aux=(2*mu-2)*xd[mu-2,n-2,k-3]+2*(xsigma+n-2)*xd[mu-1,n-2,k-3] + xd[mu,n,k] = aux - xd[mu-1,n-1,k-1] + + # Now we compute the working precisions ywpd[k] + # Se II equation (92) + ywpd={} + d1 = max(6,ctx.mag(40*L*L)) + yd2 = 13+ctx.mag((1+abs(ysigma))*yA)-ctx.mag(yeps4)-1 + yconst = ctx.ln(8/(ctx.pi*ctx.pi*a*a*yB1*yB1)) /2 + for n in range(0,L): + yd3 = ctx.mag(ctx.sqrt(ctx.gamma(n-0.5)))-ctx.floor(n*yconst)+yd2 + ywpd[n]=max(yd3,d1) + + # procedure of II Section 3.17 + ctx.prec = ywpd[1]+10 + ypsigma = 1-(2*ysigma) + yd = {} + yd[0,0,-2]=0; yd[0,0,-1]=0; yd[0,0,0]=1; yd[0,0,1]=0 + yd[0,-1,-2]=0; yd[0,-1,-1]=0; yd[0,-1,0]=1; yd[0,-1,1]=0 + for n in range(1,L): + ctx.prec = ywpd[n]+10 + for k in range(0,3*n//2+1): + m = 3*n-2*k + if(m!=0): + m1 = ctx.one/m + c1= m1/4 + c2=(ypsigma*m1)/2 + c3=-(m+1) + yd[0,n,k]=c3*yd[0,n-1,k-2]+c1*yd[0,n-1,k]+c2*yd[0,n-1,k-1] + else: + yd[0,n,k]=0 + for r in range(0,k): + add=yd[0,n,r]*(ctx.mpf('1.0')*ctx.fac(2*k-2*r)/ctx.fac(k-r)) + yd[0,n,k] -= ((-1)**(k-r))*add + yd[0,n,-2]=0; yd[0,n,-1]=0; yd[0,n,3*n//2+1]=0 + + for mu in range(-2,der+1): + for n in range(-2,L): + for k in range(-3,max(1,3*n//2+2)): + if( (mu<0)or (n<0) or(k<0)or (k>3*n//2)): + yd[mu,n,k] = 0 + for mu in range(1,der+1): + for n in range(0,L): + ctx.prec = ywpd[n]+10 + for k in range(0,3*n//2+1): + aux=(2*mu-2)*yd[mu-2,n-2,k-3]+2*(ysigma+n-2)*yd[mu-1,n-2,k-3] + yd[mu,n,k] = aux - yd[mu-1,n-1,k-1] + + # COMPUTING THE COEFFICIENTS xtcoef[k,l] + # See II Section 3.9 + # + # computing the needed wp + xwptcoef={} + xwpterm={} + ctx.prec = 15 + c1 = ctx.mag(40*(L+2)) + xc2 = ctx.mag(68*(L+2)*xA) + xc4 = ctx.mag(xB1*a*math.sqrt(ctx.pi))-1 + for k in range(0,L): + xc3 = xc2 - k*xc4+ctx.mag(ctx.fac(k+0.5))/2. + xwptcoef[k] = (max(c1,xc3-ctx.mag(xeps4)+1)+1 +20)*1.5 + xwpterm[k] = (max(c1,ctx.mag(L+2)+xc3-ctx.mag(xeps3)+1)+1 +20) + ywptcoef={} + ywpterm={} + ctx.prec = 15 + c1 = ctx.mag(40*(L+2)) + yc2 = ctx.mag(68*(L+2)*yA) + yc4 = ctx.mag(yB1*a*math.sqrt(ctx.pi))-1 + for k in range(0,L): + yc3 = yc2 - k*yc4+ctx.mag(ctx.fac(k+0.5))/2. + ywptcoef[k] = ((max(c1,yc3-ctx.mag(yeps4)+1))+10)*1.5 + ywpterm[k] = (max(c1,ctx.mag(L+2)+yc3-ctx.mag(yeps3)+1)+1)+10 + + # check of power of pi + # computing the fortcoef[mu,k,ell] + xfortcoef={} + for mu in range(0,der+1): + for k in range(0,L): + for ell in range(-2,3*k//2+1): + xfortcoef[mu,k,ell]=0 + for mu in range(0,der+1): + for k in range(0,L): + ctx.prec = xwptcoef[k] + for ell in range(0,3*k//2+1): + xfortcoef[mu,k,ell]=xd[mu,k,ell]*Fp[3*k-2*ell]/pipowers[2*k-ell] + xfortcoef[mu,k,ell]=xfortcoef[mu,k,ell]/((2*ctx.j)**ell) + + def trunc_a(t): + wp = ctx.prec + ctx.prec = wp + 2 + aa = ctx.sqrt(t/(2*ctx.pi)) + ctx.prec = wp + return aa + + # computing the tcoef[k,ell] + xtcoef={} + for mu in range(0,der+1): + for k in range(0,L): + for ell in range(-2,3*k//2+1): + xtcoef[mu,k,ell]=0 + ctx.prec = max(xwptcoef[0],ywptcoef[0])+3 + aa= trunc_a(t) + la = -ctx.ln(aa) + + for chi in range(0,der+1): + for k in range(0,L): + ctx.prec = xwptcoef[k] + for ell in range(0,3*k//2+1): + xtcoef[chi,k,ell] =0 + for mu in range(0, chi+1): + tcoefter=ctx.binomial(chi,mu)*ctx.power(la,mu)*xfortcoef[chi-mu,k,ell] + xtcoef[chi,k,ell] += tcoefter + + # COMPUTING THE COEFFICIENTS ytcoef[k,l] + # See II Section 3.9 + # + # computing the needed wp + # check of power of pi + # computing the fortcoef[mu,k,ell] + yfortcoef={} + for mu in range(0,der+1): + for k in range(0,L): + for ell in range(-2,3*k//2+1): + yfortcoef[mu,k,ell]=0 + for mu in range(0,der+1): + for k in range(0,L): + ctx.prec = ywptcoef[k] + for ell in range(0,3*k//2+1): + yfortcoef[mu,k,ell]=yd[mu,k,ell]*Fp[3*k-2*ell]/pipowers[2*k-ell] + yfortcoef[mu,k,ell]=yfortcoef[mu,k,ell]/((2*ctx.j)**ell) + # computing the tcoef[k,ell] + ytcoef={} + for chi in range(0,der+1): + for k in range(0,L): + for ell in range(-2,3*k//2+1): + ytcoef[chi,k,ell]=0 + for chi in range(0,der+1): + for k in range(0,L): + ctx.prec = ywptcoef[k] + for ell in range(0,3*k//2+1): + ytcoef[chi,k,ell] =0 + for mu in range(0, chi+1): + tcoefter=ctx.binomial(chi,mu)*ctx.power(la,mu)*yfortcoef[chi-mu,k,ell] + ytcoef[chi,k,ell] += tcoefter + + # COMPUTING tv[k,ell] + # See II Section 3.8 + # + # a has a good value + ctx.prec = max(xwptcoef[0], ywptcoef[0])+2 + av = {} + av[0] = 1 + av[1] = av[0]/a + + ctx.prec = max(xwptcoef[0],ywptcoef[0]) + for k in range(2,L): + av[k] = av[k-1] * av[1] + + # Computing the quotients + xtv = {} + for chi in range(0,der+1): + for k in range(0,L): + ctx.prec = xwptcoef[k] + for ell in range(0,3*k//2+1): + xtv[chi,k,ell] = xtcoef[chi,k,ell]* av[k] + # Computing the quotients + ytv = {} + for chi in range(0,der+1): + for k in range(0,L): + ctx.prec = ywptcoef[k] + for ell in range(0,3*k//2+1): + ytv[chi,k,ell] = ytcoef[chi,k,ell]* av[k] + + # COMPUTING THE TERMS xterm[k] + # See II Section 3.6 + xterm = {} + for chi in range(0,der+1): + for n in range(0,L): + ctx.prec = xwpterm[n] + te = 0 + for k in range(0, 3*n//2+1): + te += xtv[chi,n,k] + xterm[chi,n] = te + + # COMPUTING THE TERMS yterm[k] + # See II Section 3.6 + yterm = {} + for chi in range(0,der+1): + for n in range(0,L): + ctx.prec = ywpterm[n] + te = 0 + for k in range(0, 3*n//2+1): + te += ytv[chi,n,k] + yterm[chi,n] = te + + # COMPUTING rssum + # See II Section 3.5 + xrssum={} + ctx.prec=15 + xrsbound = math.sqrt(ctx.pi) * xc /(xb*a) + ctx.prec=15 + xwprssum = ctx.mag(4.4*((L+3)**2)*xrsbound / xeps2) + xwprssum = max(xwprssum, ctx.mag(10*(L+1))) + ctx.prec = xwprssum + for chi in range(0,der+1): + xrssum[chi] = 0 + for k in range(1,L+1): + xrssum[chi] += xterm[chi,L-k] + yrssum={} + ctx.prec=15 + yrsbound = math.sqrt(ctx.pi) * yc /(yb*a) + ctx.prec=15 + ywprssum = ctx.mag(4.4*((L+3)**2)*yrsbound / yeps2) + ywprssum = max(ywprssum, ctx.mag(10*(L+1))) + ctx.prec = ywprssum + for chi in range(0,der+1): + yrssum[chi] = 0 + for k in range(1,L+1): + yrssum[chi] += yterm[chi,L-k] + + # COMPUTING S3 + # See II Section 3.19 + ctx.prec = 15 + A2 = 2**(max(ctx.mag(abs(xrssum[0])), ctx.mag(abs(yrssum[0])))) + eps8 = eps/(3*A2) + T = t *ctx.ln(t/(2*ctx.pi)) + xwps3 = 5 + ctx.mag((1+(2/eps8)*ctx.power(a,-xsigma))*T) + ywps3 = 5 + ctx.mag((1+(2/eps8)*ctx.power(a,-ysigma))*T) + + ctx.prec = max(xwps3, ywps3) + + tpi = t/(2*ctx.pi) + arg = (t/2)*ctx.ln(tpi)-(t/2)-ctx.pi/8 + U = ctx.expj(-arg) + a = trunc_a(t) + xasigma = ctx.power(a, -xsigma) + yasigma = ctx.power(a, -ysigma) + xS3 = ((-1)**(N-1)) * xasigma * U + yS3 = ((-1)**(N-1)) * yasigma * U + + # COMPUTING S1 the zetasum + # See II Section 3.18 + ctx.prec = 15 + xwpsum = 4+ ctx.mag((N+ctx.power(N,1-xsigma))*ctx.ln(N) /eps1) + ywpsum = 4+ ctx.mag((N+ctx.power(N,1-ysigma))*ctx.ln(N) /eps1) + wpsum = max(xwpsum, ywpsum) + + ctx.prec = wpsum +10 + ''' + # This can be improved + xS1={} + yS1={} + for chi in range(0,der+1): + xS1[chi] = 0 + yS1[chi] = 0 + for n in range(1,int(N)+1): + ln = ctx.ln(n) + xexpn = ctx.exp(-ln*(xsigma+ctx.j*t)) + yexpn = ctx.conj(1/(n*xexpn)) + for chi in range(0,der+1): + pown = ctx.power(-ln, chi) + xterm = pown*xexpn + yterm = pown*yexpn + xS1[chi] += xterm + yS1[chi] += yterm + ''' + xS1, yS1 = ctx._zetasum(s, 1, int(N)-1, range(0,der+1), True) + + # END OF COMPUTATION of xrz, yrz + # See II Section 3.1 + ctx.prec = 15 + xabsS1 = abs(xS1[der]) + xabsS2 = abs(xrssum[der] * xS3) + xwpend = max(6, wpinitial+ctx.mag(6*(3*xabsS1+7*xabsS2) ) ) + + ctx.prec = xwpend + xrz={} + for chi in range(0,der+1): + xrz[chi] = xS1[chi]+xrssum[chi]*xS3 + + ctx.prec = 15 + yabsS1 = abs(yS1[der]) + yabsS2 = abs(yrssum[der] * yS3) + ywpend = max(6, wpinitial+ctx.mag(6*(3*yabsS1+7*yabsS2) ) ) + + ctx.prec = ywpend + yrz={} + for chi in range(0,der+1): + yrz[chi] = yS1[chi]+yrssum[chi]*yS3 + yrz[chi] = ctx.conj(yrz[chi]) + ctx.prec = wpinitial + return xrz, yrz + +def Rzeta_set(ctx, s, derivatives=[0]): + r""" + Computes several derivatives of the auxiliary function of Riemann `R(s)`. + + **Definition** + + The function is defined by + + .. math :: + + \begin{equation} + {\mathop{\mathcal R }\nolimits}(s)= + \int_{0\swarrow1}\frac{x^{-s} e^{\pi i x^2}}{e^{\pi i x}- + e^{-\pi i x}}\,dx + \end{equation} + + To this function we apply the Riemann-Siegel expansion. + """ + der = max(derivatives) + # First we take the value of ctx.prec + # During the computation we will change ctx.prec, and finally we will + # restaurate the initial value + wpinitial = ctx.prec + # Take the real and imaginary part of s + t = ctx._im(s) + sigma = ctx._re(s) + # Now compute several parameter that appear on the program + ctx.prec = 15 + a = ctx.sqrt(t/(2*ctx.pi)) # Careful + asigma = ctx.power(a, sigma) # Careful + # We need a simple bound A1 < asigma (see II Section 3.1 and 3.3) + A1 = ctx.power(2, ctx.mag(asigma)-1) + # We compute various epsilon's (see II end of Section 3.1) + eps = ctx.power(2, -wpinitial) + eps1 = eps/6. + eps2 = eps * A1/3. + # COMPUTING SOME COEFFICIENTS THAT DEPENDS + # ON sigma + # constant b and c (see I Theorem 2 formula (26) ) + # coefficients A and B1 (see I Section 6.1 equation (50)) + # here we not need high precision + ctx.prec = 15 + if sigma > 0: + b = 2. + c = math.pow(9,sigma)/4.44288 + # 4.44288 =(math.sqrt(2)*math.pi) + A = math.pow(9,sigma) + B1 = 1 + else: + b = 2.25158 # math.sqrt( (3-2* math.log(2))*math.pi ) + c = math.pow(2,-sigma)/4.44288 + A = math.pow(2,-sigma) + B1 = 1.10789 # = 2*sqrt(1-log(2)) + # COMPUTING L THE NUMBER OF TERMS NEEDED IN THE RIEMANN-SIEGEL + # CORRECTION + # See II Section 3.2 + ctx.prec = 15 + L = 1 + while 3*c*ctx.gamma(L*0.5) * ctx.power(b*a,-L) >= eps2: + L = L+1 + L = max(2,L) + # The number L has to satify some conditions. + # If not RS can not compute Rzeta(s) with the prescribed precision + # (see II, Section 3.2 condition (20) ) and + # (II, Section 3.3 condition (22) ). Also we have added + # an additional technical condition in Section 3.17 Proposition 17 + if ((3*L >= 2*a*a/25.) or (3*L+2+sigma<0) or (abs(sigma)> a/2.)): + #print 'Error Riemann-Siegel can not compute with such precision' + ctx.prec = wpinitial + raise NotImplementedError("Riemann-Siegel can not compute with such precision") + + # INITIALIZATION (CONTINUATION) + # + # eps3 is the constant defined on (II, Section 3.5 equation (27) ) + # each term of the RS correction must be computed with error <= eps3 + eps3 = eps2/(4*L) + + # eps4 is defined on (II Section 3.6 equation (30) ) + # each component of the formula (II Section 3.6 equation (29) ) + # must be computed with error <= eps4 + eps4 = eps3/(3*L) + + # COMPUTING M. NUMBER OF DERIVATIVES Fp[m] TO COMPUTE + M = aux_M_Fp(ctx, A, eps4, a, B1, L) + Fp = {} + for n in range(M, 3*L-2): + Fp[n] = 0 + + # But I have not seen an instance of M != 3*L-3 + # + # DETERMINATION OF J THE NUMBER OF TERMS NEEDED + # IN THE TAYLOR SERIES OF F. + # See II Section 3.11 equation (49)) + h1 = eps4/(632*A) + h2 = ctx.pi*ctx.pi*B1*a *ctx.sqrt(3)*math.e*math.e + h2 = h1 * ctx.power((h2/M**2),(M-1)/3) / M + h3 = min(h1,h2) + J=12 + jvalue = (2*ctx.pi)**J / ctx.gamma(J+1) + while jvalue > h3: + J = J+1 + jvalue = (2*ctx.pi)*jvalue/J + + # COMPUTING eps5[m] for 1 <= m <= 21 + # See II Section 10 equation (43) + eps5={} + foreps5 = math.pi*math.pi*B1*a + for m in range(0,22): + aux1 = math.pow(foreps5, m/3)/(316.*A) + aux2 = ctx.gamma(m+1)/ctx.gamma(m/3.0+0.5) + aux2 = math.sqrt(aux2) + eps5[m] = aux1*aux2*eps4 + + # COMPUTING wpfp + # See II Section 3.13 equation (59) + twenty = min(3*L-3, 21)+1 + aux = 6812*J + wpfp = ctx.mag(44*J) + for m in range(0, twenty): + wpfp = max(wpfp, ctx.mag(aux*ctx.gamma(m+1)/eps5[m])) + # COMPUTING N AND p + # See II Section + ctx.prec = wpfp + ctx.mag(t) + 20 + a = ctx.sqrt(t/(2*ctx.pi)) + N = ctx.floor(a) + p = 1-2*(a-N) + + # now we get a rounded version of p to the precision wpfp + # this possibly is not necessary + num = ctx.floor(p*(ctx.mpf(2)**wpfp)) + difference = p * (ctx.mpf(2)**wpfp)-num + if difference < 0.5: + num = num + else: + num = num+1 + p = ctx.convert(num * (ctx.mpf(2)**(-wpfp))) + + # COMPUTING THE COEFFICIENTS c[n] = cc[n] + # We shall use the notation cc[n], since there is + # a constant that is called c + # See II Section 3.14 + # We compute the coefficients and also save then in a + # cache. The bulk of the computation is passed to + # the function coef() + # + # eps6 is defined in II Section 3.13 equation (58) + eps6 = ctx.power(2*ctx.pi, J)/(ctx.gamma(J+1)*3*J) + + # Now we compute the coefficients + cc={} + cont={} + cont, pipowers = coef(ctx, J, eps6) + cc = cont.copy() # we need a copy since we have + Fp={} + for n in range(M, 3*L-2): + Fp[n] = 0 + ctx.prec = wpfp + for m in range(0,M+1): + sumP = 0 + for k in range(2*J-m-1,-1,-1): + sumP = (sumP * p) + cc[k] + Fp[m] = sumP + # preparation of the new coefficients + for k in range(0, 2*J-m-1): + cc[k] = (k+1) * cc[k+1] + + # COMPUTING THE NUMBERS d[n,k] + # See II Section 3.17 + + # First we compute the working precisions wpd[k] + # Se II equation (92) + wpd = {} + d1 = max(6, ctx.mag(40*L*L)) + d2 = 13+ctx.mag((1+abs(sigma))*A)-ctx.mag(eps4)-1 + const = ctx.ln(8/(ctx.pi*ctx.pi*a*a*B1*B1)) /2 + for n in range(0,L): + d3 = ctx.mag(ctx.sqrt(ctx.gamma(n-0.5)))-ctx.floor(n*const)+d2 + wpd[n] = max(d3,d1) + + # procedure of II Section 3.17 + ctx.prec = wpd[1]+10 + psigma = 1-(2*sigma) + d = {} + d[0,0,-2]=0; d[0,0,-1]=0; d[0,0,0]=1; d[0,0,1]=0 + d[0,-1,-2]=0; d[0,-1,-1]=0; d[0,-1,0]=1; d[0,-1,1]=0 + for n in range(1,L): + ctx.prec = wpd[n]+10 + for k in range(0,3*n//2+1): + m = 3*n-2*k + if (m!=0): + m1 = ctx.one/m + c1 = m1/4 + c2 = (psigma*m1)/2 + c3 = -(m+1) + d[0,n,k] = c3*d[0,n-1,k-2]+c1*d[0,n-1,k]+c2*d[0,n-1,k-1] + else: + d[0,n,k]=0 + for r in range(0,k): + add = d[0,n,r]*(ctx.one*ctx.fac(2*k-2*r)/ctx.fac(k-r)) + d[0,n,k] -= ((-1)**(k-r))*add + d[0,n,-2]=0; d[0,n,-1]=0; d[0,n,3*n//2+1]=0 + + for mu in range(-2,der+1): + for n in range(-2,L): + for k in range(-3,max(1,3*n//2+2)): + if ((mu<0)or (n<0) or(k<0)or (k>3*n//2)): + d[mu,n,k] = 0 + + for mu in range(1,der+1): + for n in range(0,L): + ctx.prec = wpd[n]+10 + for k in range(0,3*n//2+1): + aux=(2*mu-2)*d[mu-2,n-2,k-3]+2*(sigma+n-2)*d[mu-1,n-2,k-3] + d[mu,n,k] = aux - d[mu-1,n-1,k-1] + + # COMPUTING THE COEFFICIENTS t[k,l] + # See II Section 3.9 + # + # computing the needed wp + wptcoef = {} + wpterm = {} + ctx.prec = 15 + c1 = ctx.mag(40*(L+2)) + c2 = ctx.mag(68*(L+2)*A) + c4 = ctx.mag(B1*a*math.sqrt(ctx.pi))-1 + for k in range(0,L): + c3 = c2 - k*c4+ctx.mag(ctx.fac(k+0.5))/2. + wptcoef[k] = max(c1,c3-ctx.mag(eps4)+1)+1 +10 + wpterm[k] = max(c1,ctx.mag(L+2)+c3-ctx.mag(eps3)+1)+1 +10 + + # check of power of pi + + # computing the fortcoef[mu,k,ell] + fortcoef={} + for mu in derivatives: + for k in range(0,L): + for ell in range(-2,3*k//2+1): + fortcoef[mu,k,ell]=0 + + for mu in derivatives: + for k in range(0,L): + ctx.prec = wptcoef[k] + for ell in range(0,3*k//2+1): + fortcoef[mu,k,ell]=d[mu,k,ell]*Fp[3*k-2*ell]/pipowers[2*k-ell] + fortcoef[mu,k,ell]=fortcoef[mu,k,ell]/((2*ctx.j)**ell) + + def trunc_a(t): + wp = ctx.prec + ctx.prec = wp + 2 + aa = ctx.sqrt(t/(2*ctx.pi)) + ctx.prec = wp + return aa + + # computing the tcoef[chi,k,ell] + tcoef={} + for chi in derivatives: + for k in range(0,L): + for ell in range(-2,3*k//2+1): + tcoef[chi,k,ell]=0 + ctx.prec = wptcoef[0]+3 + aa = trunc_a(t) + la = -ctx.ln(aa) + + for chi in derivatives: + for k in range(0,L): + ctx.prec = wptcoef[k] + for ell in range(0,3*k//2+1): + tcoef[chi,k,ell] = 0 + for mu in range(0, chi+1): + tcoefter = ctx.binomial(chi,mu) * la**mu * \ + fortcoef[chi-mu,k,ell] + tcoef[chi,k,ell] += tcoefter + + # COMPUTING tv[k,ell] + # See II Section 3.8 + + # Computing the powers av[k] = a**(-k) + ctx.prec = wptcoef[0] + 2 + + # a has a good value of a. + # See II Section 3.6 + av = {} + av[0] = 1 + av[1] = av[0]/a + + ctx.prec = wptcoef[0] + for k in range(2,L): + av[k] = av[k-1] * av[1] + + # Computing the quotients + tv = {} + for chi in derivatives: + for k in range(0,L): + ctx.prec = wptcoef[k] + for ell in range(0,3*k//2+1): + tv[chi,k,ell] = tcoef[chi,k,ell]* av[k] + + # COMPUTING THE TERMS term[k] + # See II Section 3.6 + term = {} + for chi in derivatives: + for n in range(0,L): + ctx.prec = wpterm[n] + te = 0 + for k in range(0, 3*n//2+1): + te += tv[chi,n,k] + term[chi,n] = te + + # COMPUTING rssum + # See II Section 3.5 + rssum={} + ctx.prec=15 + rsbound = math.sqrt(ctx.pi) * c /(b*a) + ctx.prec=15 + wprssum = ctx.mag(4.4*((L+3)**2)*rsbound / eps2) + wprssum = max(wprssum, ctx.mag(10*(L+1))) + ctx.prec = wprssum + for chi in derivatives: + rssum[chi] = 0 + for k in range(1,L+1): + rssum[chi] += term[chi,L-k] + + # COMPUTING S3 + # See II Section 3.19 + ctx.prec = 15 + A2 = 2**(ctx.mag(rssum[0])) + eps8 = eps/(3* A2) + T = t * ctx.ln(t/(2*ctx.pi)) + wps3 = 5 + ctx.mag((1+(2/eps8)*ctx.power(a,-sigma))*T) + + ctx.prec = wps3 + tpi = t/(2*ctx.pi) + arg = (t/2)*ctx.ln(tpi)-(t/2)-ctx.pi/8 + U = ctx.expj(-arg) + a = trunc_a(t) + asigma = ctx.power(a, -sigma) + S3 = ((-1)**(N-1)) * asigma * U + + # COMPUTING S1 the zetasum + # See II Section 3.18 + ctx.prec = 15 + wpsum = 4 + ctx.mag((N+ctx.power(N,1-sigma))*ctx.ln(N)/eps1) + + ctx.prec = wpsum + 10 + ''' + # This can be improved + S1 = {} + for chi in derivatives: + S1[chi] = 0 + for n in range(1,int(N)+1): + ln = ctx.ln(n) + expn = ctx.exp(-ln*(sigma+ctx.j*t)) + for chi in derivatives: + term = ctx.power(-ln, chi)*expn + S1[chi] += term + ''' + S1 = ctx._zetasum(s, 1, int(N)-1, derivatives)[0] + + # END OF COMPUTATION + # See II Section 3.1 + ctx.prec = 15 + absS1 = abs(S1[der]) + absS2 = abs(rssum[der] * S3) + wpend = max(6, wpinitial + ctx.mag(6*(3*absS1+7*absS2))) + ctx.prec = wpend + rz = {} + for chi in derivatives: + rz[chi] = S1[chi]+rssum[chi]*S3 + ctx.prec = wpinitial + return rz + + +def z_half(ctx,t,der=0): + r""" + z_half(t,der=0) Computes Z^(der)(t) + """ + s=ctx.mpf('0.5')+ctx.j*t + wpinitial = ctx.prec + ctx.prec = 15 + tt = t/(2*ctx.pi) + wptheta = wpinitial +1 + ctx.mag(3*(tt**1.5)*ctx.ln(tt)) + wpz = wpinitial + 1 + ctx.mag(12*tt*ctx.ln(tt)) + ctx.prec = wptheta + theta = ctx.siegeltheta(t) + ctx.prec = wpz + rz = Rzeta_set(ctx,s, range(der+1)) + if der > 0: ps1 = ctx._re(ctx.psi(0,s/2)/2 - ctx.ln(ctx.pi)/2) + if der > 1: ps2 = ctx._re(ctx.j*ctx.psi(1,s/2)/4) + if der > 2: ps3 = ctx._re(-ctx.psi(2,s/2)/8) + if der > 3: ps4 = ctx._re(-ctx.j*ctx.psi(3,s/2)/16) + exptheta = ctx.expj(theta) + if der == 0: + z = 2*exptheta*rz[0] + if der == 1: + zf = 2j*exptheta + z = zf*(ps1*rz[0]+rz[1]) + if der == 2: + zf = 2 * exptheta + z = -zf*(2*rz[1]*ps1+rz[0]*ps1**2+rz[2]-ctx.j*rz[0]*ps2) + if der == 3: + zf = -2j*exptheta + z = 3*rz[1]*ps1**2+rz[0]*ps1**3+3*ps1*rz[2] + z = zf*(z-3j*rz[1]*ps2-3j*rz[0]*ps1*ps2+rz[3]-rz[0]*ps3) + if der == 4: + zf = 2*exptheta + z = 4*rz[1]*ps1**3+rz[0]*ps1**4+6*ps1**2*rz[2] + z = z-12j*rz[1]*ps1*ps2-6j*rz[0]*ps1**2*ps2-6j*rz[2]*ps2-3*rz[0]*ps2*ps2 + z = z + 4*ps1*rz[3]-4*rz[1]*ps3-4*rz[0]*ps1*ps3+rz[4]+ctx.j*rz[0]*ps4 + z = zf*z + ctx.prec = wpinitial + return ctx._re(z) + +def zeta_half(ctx, s, k=0): + """ + zeta_half(s,k=0) Computes zeta^(k)(s) when Re s = 0.5 + """ + wpinitial = ctx.prec + sigma = ctx._re(s) + t = ctx._im(s) + #--- compute wptheta, wpR, wpbasic --- + ctx.prec = 53 + # X see II Section 3.21 (109) and (110) + if sigma > 0: + X = ctx.sqrt(abs(s)) + else: + X = (2*ctx.pi)**(sigma-1) * abs(1-s)**(0.5-sigma) + # M1 see II Section 3.21 (111) and (112) + if sigma > 0: + M1 = 2*ctx.sqrt(t/(2*ctx.pi)) + else: + M1 = 4 * t * X + # T see II Section 3.21 (113) + abst = abs(0.5-s) + T = 2* abst*math.log(abst) + # computing wpbasic, wptheta, wpR see II Section 3.21 + wpbasic = max(6,3+ctx.mag(t)) + wpbasic2 = 2+ctx.mag(2.12*M1+21.2*M1*X+1.3*M1*X*T)+wpinitial+1 + wpbasic = max(wpbasic, wpbasic2) + wptheta = max(4, 3+ctx.mag(2.7*M1*X)+wpinitial+1) + wpR = 3+ctx.mag(1.1+2*X)+wpinitial+1 + ctx.prec = wptheta + theta = ctx.siegeltheta(t-ctx.j*(sigma-ctx.mpf('0.5'))) + if k > 0: ps1 = (ctx._re(ctx.psi(0,s/2)))/2 - ctx.ln(ctx.pi)/2 + if k > 1: ps2 = -(ctx._im(ctx.psi(1,s/2)))/4 + if k > 2: ps3 = -(ctx._re(ctx.psi(2,s/2)))/8 + if k > 3: ps4 = (ctx._im(ctx.psi(3,s/2)))/16 + ctx.prec = wpR + xrz = Rzeta_set(ctx,s,range(k+1)) + yrz={} + for chi in range(0,k+1): + yrz[chi] = ctx.conj(xrz[chi]) + ctx.prec = wpbasic + exptheta = ctx.expj(-2*theta) + if k==0: + zv = xrz[0]+exptheta*yrz[0] + if k==1: + zv1 = -yrz[1] - 2*yrz[0]*ps1 + zv = xrz[1] + exptheta*zv1 + if k==2: + zv1 = 4*yrz[1]*ps1+4*yrz[0]*(ps1**2)+yrz[2]+2j*yrz[0]*ps2 + zv = xrz[2]+exptheta*zv1 + if k==3: + zv1 = -12*yrz[1]*ps1**2-8*yrz[0]*ps1**3-6*yrz[2]*ps1-6j*yrz[1]*ps2 + zv1 = zv1 - 12j*yrz[0]*ps1*ps2-yrz[3]+2*yrz[0]*ps3 + zv = xrz[3]+exptheta*zv1 + if k == 4: + zv1 = 32*yrz[1]*ps1**3 +16*yrz[0]*ps1**4+24*yrz[2]*ps1**2 + zv1 = zv1 +48j*yrz[1]*ps1*ps2+48j*yrz[0]*(ps1**2)*ps2 + zv1 = zv1+12j*yrz[2]*ps2-12*yrz[0]*ps2**2+8*yrz[3]*ps1-8*yrz[1]*ps3 + zv1 = zv1-16*yrz[0]*ps1*ps3+yrz[4]-2j*yrz[0]*ps4 + zv = xrz[4]+exptheta*zv1 + ctx.prec = wpinitial + return zv + +def zeta_offline(ctx, s, k=0): + """ + Computes zeta^(k)(s) off the line + """ + wpinitial = ctx.prec + sigma = ctx._re(s) + t = ctx._im(s) + #--- compute wptheta, wpR, wpbasic --- + ctx.prec = 53 + # X see II Section 3.21 (109) and (110) + if sigma > 0: + X = ctx.power(abs(s), 0.5) + else: + X = ctx.power(2*ctx.pi, sigma-1)*ctx.power(abs(1-s),0.5-sigma) + # M1 see II Section 3.21 (111) and (112) + if (sigma > 0): + M1 = 2*ctx.sqrt(t/(2*ctx.pi)) + else: + M1 = 4 * t * X + # M2 see II Section 3.21 (111) and (112) + if (1-sigma > 0): + M2 = 2*ctx.sqrt(t/(2*ctx.pi)) + else: + M2 = 4*t*ctx.power(2*ctx.pi, -sigma)*ctx.power(abs(s),sigma-0.5) + # T see II Section 3.21 (113) + abst = abs(0.5-s) + T = 2* abst*math.log(abst) + # computing wpbasic, wptheta, wpR see II Section 3.21 + wpbasic = max(6,3+ctx.mag(t)) + wpbasic2 = 2+ctx.mag(2.12*M1+21.2*M2*X+1.3*M2*X*T)+wpinitial+1 + wpbasic = max(wpbasic, wpbasic2) + wptheta = max(4, 3+ctx.mag(2.7*M2*X)+wpinitial+1) + wpR = 3+ctx.mag(1.1+2*X)+wpinitial+1 + ctx.prec = wptheta + theta = ctx.siegeltheta(t-ctx.j*(sigma-ctx.mpf('0.5'))) + s1 = s + s2 = ctx.conj(1-s1) + ctx.prec = wpR + xrz, yrz = Rzeta_simul(ctx, s, k) + if k > 0: ps1 = (ctx.psi(0,s1/2)+ctx.psi(0,(1-s1)/2))/4 - ctx.ln(ctx.pi)/2 + if k > 1: ps2 = ctx.j*(ctx.psi(1,s1/2)-ctx.psi(1,(1-s1)/2))/8 + if k > 2: ps3 = -(ctx.psi(2,s1/2)+ctx.psi(2,(1-s1)/2))/16 + if k > 3: ps4 = -ctx.j*(ctx.psi(3,s1/2)-ctx.psi(3,(1-s1)/2))/32 + ctx.prec = wpbasic + exptheta = ctx.expj(-2*theta) + if k == 0: + zv = xrz[0]+exptheta*yrz[0] + if k == 1: + zv1 = -yrz[1]-2*yrz[0]*ps1 + zv = xrz[1]+exptheta*zv1 + if k == 2: + zv1 = 4*yrz[1]*ps1+4*yrz[0]*(ps1**2) +yrz[2]+2j*yrz[0]*ps2 + zv = xrz[2]+exptheta*zv1 + if k == 3: + zv1 = -12*yrz[1]*ps1**2 -8*yrz[0]*ps1**3-6*yrz[2]*ps1-6j*yrz[1]*ps2 + zv1 = zv1 - 12j*yrz[0]*ps1*ps2-yrz[3]+2*yrz[0]*ps3 + zv = xrz[3]+exptheta*zv1 + if k == 4: + zv1 = 32*yrz[1]*ps1**3 +16*yrz[0]*ps1**4+24*yrz[2]*ps1**2 + zv1 = zv1 +48j*yrz[1]*ps1*ps2+48j*yrz[0]*(ps1**2)*ps2 + zv1 = zv1+12j*yrz[2]*ps2-12*yrz[0]*ps2**2+8*yrz[3]*ps1-8*yrz[1]*ps3 + zv1 = zv1-16*yrz[0]*ps1*ps3+yrz[4]-2j*yrz[0]*ps4 + zv = xrz[4]+exptheta*zv1 + ctx.prec = wpinitial + return zv + +def z_offline(ctx, w, k=0): + r""" + Computes Z(w) and its derivatives off the line + """ + s = ctx.mpf('0.5')+ctx.j*w + s1 = s + s2 = ctx.conj(1-s1) + wpinitial = ctx.prec + ctx.prec = 35 + # X see II Section 3.21 (109) and (110) + # M1 see II Section 3.21 (111) and (112) + if (ctx._re(s1) >= 0): + M1 = 2*ctx.sqrt(ctx._im(s1)/(2 * ctx.pi)) + X = ctx.sqrt(abs(s1)) + else: + X = (2*ctx.pi)**(ctx._re(s1)-1) * abs(1-s1)**(0.5-ctx._re(s1)) + M1 = 4 * ctx._im(s1)*X + # M2 see II Section 3.21 (111) and (112) + if (ctx._re(s2) >= 0): + M2 = 2*ctx.sqrt(ctx._im(s2)/(2 * ctx.pi)) + else: + M2 = 4 * ctx._im(s2)*(2*ctx.pi)**(ctx._re(s2)-1)*abs(1-s2)**(0.5-ctx._re(s2)) + # T see II Section 3.21 Prop. 27 + T = 2*abs(ctx.siegeltheta(w)) + # defining some precisions + # see II Section 3.22 (115), (116), (117) + aux1 = ctx.sqrt(X) + aux2 = aux1*(M1+M2) + aux3 = 3 +wpinitial + wpbasic = max(6, 3+ctx.mag(T), ctx.mag(aux2*(26+2*T))+aux3) + wptheta = max(4,ctx.mag(2.04*aux2)+aux3) + wpR = ctx.mag(4*aux1)+aux3 + # now the computations + ctx.prec = wptheta + theta = ctx.siegeltheta(w) + ctx.prec = wpR + xrz, yrz = Rzeta_simul(ctx,s,k) + pta = 0.25 + 0.5j*w + ptb = 0.25 - 0.5j*w + if k > 0: ps1 = 0.25*(ctx.psi(0,pta)+ctx.psi(0,ptb)) - ctx.ln(ctx.pi)/2 + if k > 1: ps2 = (1j/8)*(ctx.psi(1,pta)-ctx.psi(1,ptb)) + if k > 2: ps3 = (-1./16)*(ctx.psi(2,pta)+ctx.psi(2,ptb)) + if k > 3: ps4 = (-1j/32)*(ctx.psi(3,pta)-ctx.psi(3,ptb)) + ctx.prec = wpbasic + exptheta = ctx.expj(theta) + if k == 0: + zv = exptheta*xrz[0]+yrz[0]/exptheta + j = ctx.j + if k == 1: + zv = j*exptheta*(xrz[1]+xrz[0]*ps1)-j*(yrz[1]+yrz[0]*ps1)/exptheta + if k == 2: + zv = exptheta*(-2*xrz[1]*ps1-xrz[0]*ps1**2-xrz[2]+j*xrz[0]*ps2) + zv =zv + (-2*yrz[1]*ps1-yrz[0]*ps1**2-yrz[2]-j*yrz[0]*ps2)/exptheta + if k == 3: + zv1 = -3*xrz[1]*ps1**2-xrz[0]*ps1**3-3*xrz[2]*ps1+j*3*xrz[1]*ps2 + zv1 = (zv1+ 3j*xrz[0]*ps1*ps2-xrz[3]+xrz[0]*ps3)*j*exptheta + zv2 = 3*yrz[1]*ps1**2+yrz[0]*ps1**3+3*yrz[2]*ps1+j*3*yrz[1]*ps2 + zv2 = j*(zv2 + 3j*yrz[0]*ps1*ps2+ yrz[3]-yrz[0]*ps3)/exptheta + zv = zv1+zv2 + if k == 4: + zv1 = 4*xrz[1]*ps1**3+xrz[0]*ps1**4 + 6*xrz[2]*ps1**2 + zv1 = zv1-12j*xrz[1]*ps1*ps2-6j*xrz[0]*ps1**2*ps2-6j*xrz[2]*ps2 + zv1 = zv1-3*xrz[0]*ps2*ps2+4*xrz[3]*ps1-4*xrz[1]*ps3-4*xrz[0]*ps1*ps3 + zv1 = zv1+xrz[4]+j*xrz[0]*ps4 + zv2 = 4*yrz[1]*ps1**3+yrz[0]*ps1**4 + 6*yrz[2]*ps1**2 + zv2 = zv2+12j*yrz[1]*ps1*ps2+6j*yrz[0]*ps1**2*ps2+6j*yrz[2]*ps2 + zv2 = zv2-3*yrz[0]*ps2*ps2+4*yrz[3]*ps1-4*yrz[1]*ps3-4*yrz[0]*ps1*ps3 + zv2 = zv2+yrz[4]-j*yrz[0]*ps4 + zv = exptheta*zv1+zv2/exptheta + ctx.prec = wpinitial + return zv + +@defun +def rs_zeta(ctx, s, derivative=0, **kwargs): + if derivative > 4: + raise NotImplementedError + s = ctx.convert(s) + re = ctx._re(s); im = ctx._im(s) + if im < 0: + z = ctx.conj(ctx.rs_zeta(ctx.conj(s), derivative)) + return z + critical_line = (re == 0.5) + if critical_line: + return zeta_half(ctx, s, derivative) + else: + return zeta_offline(ctx, s, derivative) + +@defun +def rs_z(ctx, w, derivative=0): + w = ctx.convert(w) + re = ctx._re(w); im = ctx._im(w) + if re < 0: + return rs_z(ctx, -w, derivative) + critical_line = (im == 0) + if critical_line : + return z_half(ctx, w, derivative) + else: + return z_offline(ctx, w, derivative) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/signals.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/signals.py new file mode 100644 index 0000000000000000000000000000000000000000..6fadafb2dbb44fe19a2defa8d807d81d7c8e2789 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/signals.py @@ -0,0 +1,32 @@ +from .functions import defun_wrapped + +@defun_wrapped +def squarew(ctx, t, amplitude=1, period=1): + P = period + A = amplitude + return A*((-1)**ctx.floor(2*t/P)) + +@defun_wrapped +def trianglew(ctx, t, amplitude=1, period=1): + A = amplitude + P = period + + return 2*A*(0.5 - ctx.fabs(1 - 2*ctx.frac(t/P + 0.25))) + +@defun_wrapped +def sawtoothw(ctx, t, amplitude=1, period=1): + A = amplitude + P = period + return A*ctx.frac(t/P) + +@defun_wrapped +def unit_triangle(ctx, t, amplitude=1): + A = amplitude + if t <= -1 or t >= 1: + return ctx.zero + return A*(-ctx.fabs(t) + 1) + +@defun_wrapped +def sigmoid(ctx, t, amplitude=1): + A = amplitude + return A / (1 + ctx.exp(-t)) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/theta.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/theta.py new file mode 100644 index 0000000000000000000000000000000000000000..2b3d8323a163a43186b85417a1b40f3b656c30d0 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/theta.py @@ -0,0 +1,1049 @@ +from .functions import defun, defun_wrapped + +@defun +def _jacobi_theta2(ctx, z, q): + extra1 = 10 + extra2 = 20 + # the loops below break when the fixed precision quantities + # a and b go to zero; + # right shifting small negative numbers by wp one obtains -1, not zero, + # so the condition a**2 + b**2 > MIN is used to break the loops. + MIN = 2 + if z == ctx.zero: + if (not ctx._im(q)): + wp = ctx.prec + extra1 + x = ctx.to_fixed(ctx._re(q), wp) + x2 = (x*x) >> wp + a = b = x2 + s = x2 + while abs(a) > MIN: + b = (b*x2) >> wp + a = (a*b) >> wp + s += a + s = (1 << (wp+1)) + (s << 1) + s = ctx.ldexp(s, -wp) + else: + wp = ctx.prec + extra1 + xre = ctx.to_fixed(ctx._re(q), wp) + xim = ctx.to_fixed(ctx._im(q), wp) + x2re = (xre*xre - xim*xim) >> wp + x2im = (xre*xim) >> (wp-1) + are = bre = x2re + aim = bim = x2im + sre = (1< MIN: + bre, bim = (bre * x2re - bim * x2im) >> wp, \ + (bre * x2im + bim * x2re) >> wp + are, aim = (are * bre - aim * bim) >> wp, \ + (are * bim + aim * bre) >> wp + sre += are + sim += aim + sre = (sre << 1) + sim = (sim << 1) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + else: + if (not ctx._im(q)) and (not ctx._im(z)): + wp = ctx.prec + extra1 + x = ctx.to_fixed(ctx._re(q), wp) + x2 = (x*x) >> wp + a = b = x2 + c1, s1 = ctx.cos_sin(ctx._re(z), prec=wp) + cn = c1 = ctx.to_fixed(c1, wp) + sn = s1 = ctx.to_fixed(s1, wp) + c2 = (c1*c1 - s1*s1) >> wp + s2 = (c1 * s1) >> (wp - 1) + cn, sn = (cn*c2 - sn*s2) >> wp, (sn*c2 + cn*s2) >> wp + s = c1 + ((a * cn) >> wp) + while abs(a) > MIN: + b = (b*x2) >> wp + a = (a*b) >> wp + cn, sn = (cn*c2 - sn*s2) >> wp, (sn*c2 + cn*s2) >> wp + s += (a * cn) >> wp + s = (s << 1) + s = ctx.ldexp(s, -wp) + s *= ctx.nthroot(q, 4) + return s + # case z real, q complex + elif not ctx._im(z): + wp = ctx.prec + extra2 + xre = ctx.to_fixed(ctx._re(q), wp) + xim = ctx.to_fixed(ctx._im(q), wp) + x2re = (xre*xre - xim*xim) >> wp + x2im = (xre*xim) >> (wp - 1) + are = bre = x2re + aim = bim = x2im + c1, s1 = ctx.cos_sin(ctx._re(z), prec=wp) + cn = c1 = ctx.to_fixed(c1, wp) + sn = s1 = ctx.to_fixed(s1, wp) + c2 = (c1*c1 - s1*s1) >> wp + s2 = (c1 * s1) >> (wp - 1) + cn, sn = (cn*c2 - sn*s2) >> wp, (sn*c2 + cn*s2) >> wp + sre = c1 + ((are * cn) >> wp) + sim = ((aim * cn) >> wp) + while are**2 + aim**2 > MIN: + bre, bim = (bre * x2re - bim * x2im) >> wp, \ + (bre * x2im + bim * x2re) >> wp + are, aim = (are * bre - aim * bim) >> wp, \ + (are * bim + aim * bre) >> wp + cn, sn = (cn*c2 - sn*s2) >> wp, (sn*c2 + cn*s2) >> wp + sre += ((are * cn) >> wp) + sim += ((aim * cn) >> wp) + sre = (sre << 1) + sim = (sim << 1) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + #case z complex, q real + elif not ctx._im(q): + wp = ctx.prec + extra2 + x = ctx.to_fixed(ctx._re(q), wp) + x2 = (x*x) >> wp + a = b = x2 + prec0 = ctx.prec + ctx.prec = wp + c1, s1 = ctx.cos_sin(z) + ctx.prec = prec0 + cnre = c1re = ctx.to_fixed(ctx._re(c1), wp) + cnim = c1im = ctx.to_fixed(ctx._im(c1), wp) + snre = s1re = ctx.to_fixed(ctx._re(s1), wp) + snim = s1im = ctx.to_fixed(ctx._im(s1), wp) + #c2 = (c1*c1 - s1*s1) >> wp + c2re = (c1re*c1re - c1im*c1im - s1re*s1re + s1im*s1im) >> wp + c2im = (c1re*c1im - s1re*s1im) >> (wp - 1) + #s2 = (c1 * s1) >> (wp - 1) + s2re = (c1re*s1re - c1im*s1im) >> (wp - 1) + s2im = (c1re*s1im + c1im*s1re) >> (wp - 1) + #cn, sn = (cn*c2 - sn*s2) >> wp, (sn*c2 + cn*s2) >> wp + t1 = (cnre*c2re - cnim*c2im - snre*s2re + snim*s2im) >> wp + t2 = (cnre*c2im + cnim*c2re - snre*s2im - snim*s2re) >> wp + t3 = (snre*c2re - snim*c2im + cnre*s2re - cnim*s2im) >> wp + t4 = (snre*c2im + snim*c2re + cnre*s2im + cnim*s2re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + sre = c1re + ((a * cnre) >> wp) + sim = c1im + ((a * cnim) >> wp) + while abs(a) > MIN: + b = (b*x2) >> wp + a = (a*b) >> wp + t1 = (cnre*c2re - cnim*c2im - snre*s2re + snim*s2im) >> wp + t2 = (cnre*c2im + cnim*c2re - snre*s2im - snim*s2re) >> wp + t3 = (snre*c2re - snim*c2im + cnre*s2re - cnim*s2im) >> wp + t4 = (snre*c2im + snim*c2re + cnre*s2im + cnim*s2re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + sre += ((a * cnre) >> wp) + sim += ((a * cnim) >> wp) + sre = (sre << 1) + sim = (sim << 1) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + # case z and q complex + else: + wp = ctx.prec + extra2 + xre = ctx.to_fixed(ctx._re(q), wp) + xim = ctx.to_fixed(ctx._im(q), wp) + x2re = (xre*xre - xim*xim) >> wp + x2im = (xre*xim) >> (wp - 1) + are = bre = x2re + aim = bim = x2im + prec0 = ctx.prec + ctx.prec = wp + # cos(z), sin(z) with z complex + c1, s1 = ctx.cos_sin(z) + ctx.prec = prec0 + cnre = c1re = ctx.to_fixed(ctx._re(c1), wp) + cnim = c1im = ctx.to_fixed(ctx._im(c1), wp) + snre = s1re = ctx.to_fixed(ctx._re(s1), wp) + snim = s1im = ctx.to_fixed(ctx._im(s1), wp) + c2re = (c1re*c1re - c1im*c1im - s1re*s1re + s1im*s1im) >> wp + c2im = (c1re*c1im - s1re*s1im) >> (wp - 1) + s2re = (c1re*s1re - c1im*s1im) >> (wp - 1) + s2im = (c1re*s1im + c1im*s1re) >> (wp - 1) + t1 = (cnre*c2re - cnim*c2im - snre*s2re + snim*s2im) >> wp + t2 = (cnre*c2im + cnim*c2re - snre*s2im - snim*s2re) >> wp + t3 = (snre*c2re - snim*c2im + cnre*s2re - cnim*s2im) >> wp + t4 = (snre*c2im + snim*c2re + cnre*s2im + cnim*s2re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + n = 1 + termre = c1re + termim = c1im + sre = c1re + ((are * cnre - aim * cnim) >> wp) + sim = c1im + ((are * cnim + aim * cnre) >> wp) + n = 3 + termre = ((are * cnre - aim * cnim) >> wp) + termim = ((are * cnim + aim * cnre) >> wp) + sre = c1re + ((are * cnre - aim * cnim) >> wp) + sim = c1im + ((are * cnim + aim * cnre) >> wp) + n = 5 + while are**2 + aim**2 > MIN: + bre, bim = (bre * x2re - bim * x2im) >> wp, \ + (bre * x2im + bim * x2re) >> wp + are, aim = (are * bre - aim * bim) >> wp, \ + (are * bim + aim * bre) >> wp + #cn, sn = (cn*c1 - sn*s1) >> wp, (sn*c1 + cn*s1) >> wp + t1 = (cnre*c2re - cnim*c2im - snre*s2re + snim*s2im) >> wp + t2 = (cnre*c2im + cnim*c2re - snre*s2im - snim*s2re) >> wp + t3 = (snre*c2re - snim*c2im + cnre*s2re - cnim*s2im) >> wp + t4 = (snre*c2im + snim*c2re + cnre*s2im + cnim*s2re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + termre = ((are * cnre - aim * cnim) >> wp) + termim = ((aim * cnre + are * cnim) >> wp) + sre += ((are * cnre - aim * cnim) >> wp) + sim += ((aim * cnre + are * cnim) >> wp) + n += 2 + sre = (sre << 1) + sim = (sim << 1) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + s *= ctx.nthroot(q, 4) + return s + +@defun +def _djacobi_theta2(ctx, z, q, nd): + MIN = 2 + extra1 = 10 + extra2 = 20 + if (not ctx._im(q)) and (not ctx._im(z)): + wp = ctx.prec + extra1 + x = ctx.to_fixed(ctx._re(q), wp) + x2 = (x*x) >> wp + a = b = x2 + c1, s1 = ctx.cos_sin(ctx._re(z), prec=wp) + cn = c1 = ctx.to_fixed(c1, wp) + sn = s1 = ctx.to_fixed(s1, wp) + c2 = (c1*c1 - s1*s1) >> wp + s2 = (c1 * s1) >> (wp - 1) + cn, sn = (cn*c2 - sn*s2) >> wp, (sn*c2 + cn*s2) >> wp + if (nd&1): + s = s1 + ((a * sn * 3**nd) >> wp) + else: + s = c1 + ((a * cn * 3**nd) >> wp) + n = 2 + while abs(a) > MIN: + b = (b*x2) >> wp + a = (a*b) >> wp + cn, sn = (cn*c2 - sn*s2) >> wp, (sn*c2 + cn*s2) >> wp + if nd&1: + s += (a * sn * (2*n+1)**nd) >> wp + else: + s += (a * cn * (2*n+1)**nd) >> wp + n += 1 + s = -(s << 1) + s = ctx.ldexp(s, -wp) + # case z real, q complex + elif not ctx._im(z): + wp = ctx.prec + extra2 + xre = ctx.to_fixed(ctx._re(q), wp) + xim = ctx.to_fixed(ctx._im(q), wp) + x2re = (xre*xre - xim*xim) >> wp + x2im = (xre*xim) >> (wp - 1) + are = bre = x2re + aim = bim = x2im + c1, s1 = ctx.cos_sin(ctx._re(z), prec=wp) + cn = c1 = ctx.to_fixed(c1, wp) + sn = s1 = ctx.to_fixed(s1, wp) + c2 = (c1*c1 - s1*s1) >> wp + s2 = (c1 * s1) >> (wp - 1) + cn, sn = (cn*c2 - sn*s2) >> wp, (sn*c2 + cn*s2) >> wp + if (nd&1): + sre = s1 + ((are * sn * 3**nd) >> wp) + sim = ((aim * sn * 3**nd) >> wp) + else: + sre = c1 + ((are * cn * 3**nd) >> wp) + sim = ((aim * cn * 3**nd) >> wp) + n = 5 + while are**2 + aim**2 > MIN: + bre, bim = (bre * x2re - bim * x2im) >> wp, \ + (bre * x2im + bim * x2re) >> wp + are, aim = (are * bre - aim * bim) >> wp, \ + (are * bim + aim * bre) >> wp + cn, sn = (cn*c2 - sn*s2) >> wp, (sn*c2 + cn*s2) >> wp + + if (nd&1): + sre += ((are * sn * n**nd) >> wp) + sim += ((aim * sn * n**nd) >> wp) + else: + sre += ((are * cn * n**nd) >> wp) + sim += ((aim * cn * n**nd) >> wp) + n += 2 + sre = -(sre << 1) + sim = -(sim << 1) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + #case z complex, q real + elif not ctx._im(q): + wp = ctx.prec + extra2 + x = ctx.to_fixed(ctx._re(q), wp) + x2 = (x*x) >> wp + a = b = x2 + prec0 = ctx.prec + ctx.prec = wp + c1, s1 = ctx.cos_sin(z) + ctx.prec = prec0 + cnre = c1re = ctx.to_fixed(ctx._re(c1), wp) + cnim = c1im = ctx.to_fixed(ctx._im(c1), wp) + snre = s1re = ctx.to_fixed(ctx._re(s1), wp) + snim = s1im = ctx.to_fixed(ctx._im(s1), wp) + #c2 = (c1*c1 - s1*s1) >> wp + c2re = (c1re*c1re - c1im*c1im - s1re*s1re + s1im*s1im) >> wp + c2im = (c1re*c1im - s1re*s1im) >> (wp - 1) + #s2 = (c1 * s1) >> (wp - 1) + s2re = (c1re*s1re - c1im*s1im) >> (wp - 1) + s2im = (c1re*s1im + c1im*s1re) >> (wp - 1) + #cn, sn = (cn*c2 - sn*s2) >> wp, (sn*c2 + cn*s2) >> wp + t1 = (cnre*c2re - cnim*c2im - snre*s2re + snim*s2im) >> wp + t2 = (cnre*c2im + cnim*c2re - snre*s2im - snim*s2re) >> wp + t3 = (snre*c2re - snim*c2im + cnre*s2re - cnim*s2im) >> wp + t4 = (snre*c2im + snim*c2re + cnre*s2im + cnim*s2re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + if (nd&1): + sre = s1re + ((a * snre * 3**nd) >> wp) + sim = s1im + ((a * snim * 3**nd) >> wp) + else: + sre = c1re + ((a * cnre * 3**nd) >> wp) + sim = c1im + ((a * cnim * 3**nd) >> wp) + n = 5 + while abs(a) > MIN: + b = (b*x2) >> wp + a = (a*b) >> wp + t1 = (cnre*c2re - cnim*c2im - snre*s2re + snim*s2im) >> wp + t2 = (cnre*c2im + cnim*c2re - snre*s2im - snim*s2re) >> wp + t3 = (snre*c2re - snim*c2im + cnre*s2re - cnim*s2im) >> wp + t4 = (snre*c2im + snim*c2re + cnre*s2im + cnim*s2re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + if (nd&1): + sre += ((a * snre * n**nd) >> wp) + sim += ((a * snim * n**nd) >> wp) + else: + sre += ((a * cnre * n**nd) >> wp) + sim += ((a * cnim * n**nd) >> wp) + n += 2 + sre = -(sre << 1) + sim = -(sim << 1) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + # case z and q complex + else: + wp = ctx.prec + extra2 + xre = ctx.to_fixed(ctx._re(q), wp) + xim = ctx.to_fixed(ctx._im(q), wp) + x2re = (xre*xre - xim*xim) >> wp + x2im = (xre*xim) >> (wp - 1) + are = bre = x2re + aim = bim = x2im + prec0 = ctx.prec + ctx.prec = wp + # cos(2*z), sin(2*z) with z complex + c1, s1 = ctx.cos_sin(z) + ctx.prec = prec0 + cnre = c1re = ctx.to_fixed(ctx._re(c1), wp) + cnim = c1im = ctx.to_fixed(ctx._im(c1), wp) + snre = s1re = ctx.to_fixed(ctx._re(s1), wp) + snim = s1im = ctx.to_fixed(ctx._im(s1), wp) + c2re = (c1re*c1re - c1im*c1im - s1re*s1re + s1im*s1im) >> wp + c2im = (c1re*c1im - s1re*s1im) >> (wp - 1) + s2re = (c1re*s1re - c1im*s1im) >> (wp - 1) + s2im = (c1re*s1im + c1im*s1re) >> (wp - 1) + t1 = (cnre*c2re - cnim*c2im - snre*s2re + snim*s2im) >> wp + t2 = (cnre*c2im + cnim*c2re - snre*s2im - snim*s2re) >> wp + t3 = (snre*c2re - snim*c2im + cnre*s2re - cnim*s2im) >> wp + t4 = (snre*c2im + snim*c2re + cnre*s2im + cnim*s2re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + if (nd&1): + sre = s1re + (((are * snre - aim * snim) * 3**nd) >> wp) + sim = s1im + (((are * snim + aim * snre)* 3**nd) >> wp) + else: + sre = c1re + (((are * cnre - aim * cnim) * 3**nd) >> wp) + sim = c1im + (((are * cnim + aim * cnre)* 3**nd) >> wp) + n = 5 + while are**2 + aim**2 > MIN: + bre, bim = (bre * x2re - bim * x2im) >> wp, \ + (bre * x2im + bim * x2re) >> wp + are, aim = (are * bre - aim * bim) >> wp, \ + (are * bim + aim * bre) >> wp + #cn, sn = (cn*c1 - sn*s1) >> wp, (sn*c1 + cn*s1) >> wp + t1 = (cnre*c2re - cnim*c2im - snre*s2re + snim*s2im) >> wp + t2 = (cnre*c2im + cnim*c2re - snre*s2im - snim*s2re) >> wp + t3 = (snre*c2re - snim*c2im + cnre*s2re - cnim*s2im) >> wp + t4 = (snre*c2im + snim*c2re + cnre*s2im + cnim*s2re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + if (nd&1): + sre += (((are * snre - aim * snim) * n**nd) >> wp) + sim += (((aim * snre + are * snim) * n**nd) >> wp) + else: + sre += (((are * cnre - aim * cnim) * n**nd) >> wp) + sim += (((aim * cnre + are * cnim) * n**nd) >> wp) + n += 2 + sre = -(sre << 1) + sim = -(sim << 1) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + s *= ctx.nthroot(q, 4) + if (nd&1): + return (-1)**(nd//2) * s + else: + return (-1)**(1 + nd//2) * s + +@defun +def _jacobi_theta3(ctx, z, q): + extra1 = 10 + extra2 = 20 + MIN = 2 + if z == ctx.zero: + if not ctx._im(q): + wp = ctx.prec + extra1 + x = ctx.to_fixed(ctx._re(q), wp) + s = x + a = b = x + x2 = (x*x) >> wp + while abs(a) > MIN: + b = (b*x2) >> wp + a = (a*b) >> wp + s += a + s = (1 << wp) + (s << 1) + s = ctx.ldexp(s, -wp) + return s + else: + wp = ctx.prec + extra1 + xre = ctx.to_fixed(ctx._re(q), wp) + xim = ctx.to_fixed(ctx._im(q), wp) + x2re = (xre*xre - xim*xim) >> wp + x2im = (xre*xim) >> (wp - 1) + sre = are = bre = xre + sim = aim = bim = xim + while are**2 + aim**2 > MIN: + bre, bim = (bre * x2re - bim * x2im) >> wp, \ + (bre * x2im + bim * x2re) >> wp + are, aim = (are * bre - aim * bim) >> wp, \ + (are * bim + aim * bre) >> wp + sre += are + sim += aim + sre = (1 << wp) + (sre << 1) + sim = (sim << 1) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + return s + else: + if (not ctx._im(q)) and (not ctx._im(z)): + s = 0 + wp = ctx.prec + extra1 + x = ctx.to_fixed(ctx._re(q), wp) + a = b = x + x2 = (x*x) >> wp + c1, s1 = ctx.cos_sin(ctx._re(z)*2, prec=wp) + c1 = ctx.to_fixed(c1, wp) + s1 = ctx.to_fixed(s1, wp) + cn = c1 + sn = s1 + s += (a * cn) >> wp + while abs(a) > MIN: + b = (b*x2) >> wp + a = (a*b) >> wp + cn, sn = (cn*c1 - sn*s1) >> wp, (sn*c1 + cn*s1) >> wp + s += (a * cn) >> wp + s = (1 << wp) + (s << 1) + s = ctx.ldexp(s, -wp) + return s + # case z real, q complex + elif not ctx._im(z): + wp = ctx.prec + extra2 + xre = ctx.to_fixed(ctx._re(q), wp) + xim = ctx.to_fixed(ctx._im(q), wp) + x2re = (xre*xre - xim*xim) >> wp + x2im = (xre*xim) >> (wp - 1) + are = bre = xre + aim = bim = xim + c1, s1 = ctx.cos_sin(ctx._re(z)*2, prec=wp) + c1 = ctx.to_fixed(c1, wp) + s1 = ctx.to_fixed(s1, wp) + cn = c1 + sn = s1 + sre = (are * cn) >> wp + sim = (aim * cn) >> wp + while are**2 + aim**2 > MIN: + bre, bim = (bre * x2re - bim * x2im) >> wp, \ + (bre * x2im + bim * x2re) >> wp + are, aim = (are * bre - aim * bim) >> wp, \ + (are * bim + aim * bre) >> wp + cn, sn = (cn*c1 - sn*s1) >> wp, (sn*c1 + cn*s1) >> wp + sre += (are * cn) >> wp + sim += (aim * cn) >> wp + sre = (1 << wp) + (sre << 1) + sim = (sim << 1) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + return s + #case z complex, q real + elif not ctx._im(q): + wp = ctx.prec + extra2 + x = ctx.to_fixed(ctx._re(q), wp) + a = b = x + x2 = (x*x) >> wp + prec0 = ctx.prec + ctx.prec = wp + c1, s1 = ctx.cos_sin(2*z) + ctx.prec = prec0 + cnre = c1re = ctx.to_fixed(ctx._re(c1), wp) + cnim = c1im = ctx.to_fixed(ctx._im(c1), wp) + snre = s1re = ctx.to_fixed(ctx._re(s1), wp) + snim = s1im = ctx.to_fixed(ctx._im(s1), wp) + sre = (a * cnre) >> wp + sim = (a * cnim) >> wp + while abs(a) > MIN: + b = (b*x2) >> wp + a = (a*b) >> wp + t1 = (cnre*c1re - cnim*c1im - snre*s1re + snim*s1im) >> wp + t2 = (cnre*c1im + cnim*c1re - snre*s1im - snim*s1re) >> wp + t3 = (snre*c1re - snim*c1im + cnre*s1re - cnim*s1im) >> wp + t4 = (snre*c1im + snim*c1re + cnre*s1im + cnim*s1re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + sre += (a * cnre) >> wp + sim += (a * cnim) >> wp + sre = (1 << wp) + (sre << 1) + sim = (sim << 1) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + return s + # case z and q complex + else: + wp = ctx.prec + extra2 + xre = ctx.to_fixed(ctx._re(q), wp) + xim = ctx.to_fixed(ctx._im(q), wp) + x2re = (xre*xre - xim*xim) >> wp + x2im = (xre*xim) >> (wp - 1) + are = bre = xre + aim = bim = xim + prec0 = ctx.prec + ctx.prec = wp + # cos(2*z), sin(2*z) with z complex + c1, s1 = ctx.cos_sin(2*z) + ctx.prec = prec0 + cnre = c1re = ctx.to_fixed(ctx._re(c1), wp) + cnim = c1im = ctx.to_fixed(ctx._im(c1), wp) + snre = s1re = ctx.to_fixed(ctx._re(s1), wp) + snim = s1im = ctx.to_fixed(ctx._im(s1), wp) + sre = (are * cnre - aim * cnim) >> wp + sim = (aim * cnre + are * cnim) >> wp + while are**2 + aim**2 > MIN: + bre, bim = (bre * x2re - bim * x2im) >> wp, \ + (bre * x2im + bim * x2re) >> wp + are, aim = (are * bre - aim * bim) >> wp, \ + (are * bim + aim * bre) >> wp + t1 = (cnre*c1re - cnim*c1im - snre*s1re + snim*s1im) >> wp + t2 = (cnre*c1im + cnim*c1re - snre*s1im - snim*s1re) >> wp + t3 = (snre*c1re - snim*c1im + cnre*s1re - cnim*s1im) >> wp + t4 = (snre*c1im + snim*c1re + cnre*s1im + cnim*s1re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + sre += (are * cnre - aim * cnim) >> wp + sim += (aim * cnre + are * cnim) >> wp + sre = (1 << wp) + (sre << 1) + sim = (sim << 1) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + return s + +@defun +def _djacobi_theta3(ctx, z, q, nd): + """nd=1,2,3 order of the derivative with respect to z""" + MIN = 2 + extra1 = 10 + extra2 = 20 + if (not ctx._im(q)) and (not ctx._im(z)): + s = 0 + wp = ctx.prec + extra1 + x = ctx.to_fixed(ctx._re(q), wp) + a = b = x + x2 = (x*x) >> wp + c1, s1 = ctx.cos_sin(ctx._re(z)*2, prec=wp) + c1 = ctx.to_fixed(c1, wp) + s1 = ctx.to_fixed(s1, wp) + cn = c1 + sn = s1 + if (nd&1): + s += (a * sn) >> wp + else: + s += (a * cn) >> wp + n = 2 + while abs(a) > MIN: + b = (b*x2) >> wp + a = (a*b) >> wp + cn, sn = (cn*c1 - sn*s1) >> wp, (sn*c1 + cn*s1) >> wp + if nd&1: + s += (a * sn * n**nd) >> wp + else: + s += (a * cn * n**nd) >> wp + n += 1 + s = -(s << (nd+1)) + s = ctx.ldexp(s, -wp) + # case z real, q complex + elif not ctx._im(z): + wp = ctx.prec + extra2 + xre = ctx.to_fixed(ctx._re(q), wp) + xim = ctx.to_fixed(ctx._im(q), wp) + x2re = (xre*xre - xim*xim) >> wp + x2im = (xre*xim) >> (wp - 1) + are = bre = xre + aim = bim = xim + c1, s1 = ctx.cos_sin(ctx._re(z)*2, prec=wp) + c1 = ctx.to_fixed(c1, wp) + s1 = ctx.to_fixed(s1, wp) + cn = c1 + sn = s1 + if (nd&1): + sre = (are * sn) >> wp + sim = (aim * sn) >> wp + else: + sre = (are * cn) >> wp + sim = (aim * cn) >> wp + n = 2 + while are**2 + aim**2 > MIN: + bre, bim = (bre * x2re - bim * x2im) >> wp, \ + (bre * x2im + bim * x2re) >> wp + are, aim = (are * bre - aim * bim) >> wp, \ + (are * bim + aim * bre) >> wp + cn, sn = (cn*c1 - sn*s1) >> wp, (sn*c1 + cn*s1) >> wp + if nd&1: + sre += (are * sn * n**nd) >> wp + sim += (aim * sn * n**nd) >> wp + else: + sre += (are * cn * n**nd) >> wp + sim += (aim * cn * n**nd) >> wp + n += 1 + sre = -(sre << (nd+1)) + sim = -(sim << (nd+1)) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + #case z complex, q real + elif not ctx._im(q): + wp = ctx.prec + extra2 + x = ctx.to_fixed(ctx._re(q), wp) + a = b = x + x2 = (x*x) >> wp + prec0 = ctx.prec + ctx.prec = wp + c1, s1 = ctx.cos_sin(2*z) + ctx.prec = prec0 + cnre = c1re = ctx.to_fixed(ctx._re(c1), wp) + cnim = c1im = ctx.to_fixed(ctx._im(c1), wp) + snre = s1re = ctx.to_fixed(ctx._re(s1), wp) + snim = s1im = ctx.to_fixed(ctx._im(s1), wp) + if (nd&1): + sre = (a * snre) >> wp + sim = (a * snim) >> wp + else: + sre = (a * cnre) >> wp + sim = (a * cnim) >> wp + n = 2 + while abs(a) > MIN: + b = (b*x2) >> wp + a = (a*b) >> wp + t1 = (cnre*c1re - cnim*c1im - snre*s1re + snim*s1im) >> wp + t2 = (cnre*c1im + cnim*c1re - snre*s1im - snim*s1re) >> wp + t3 = (snre*c1re - snim*c1im + cnre*s1re - cnim*s1im) >> wp + t4 = (snre*c1im + snim*c1re + cnre*s1im + cnim*s1re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + if (nd&1): + sre += (a * snre * n**nd) >> wp + sim += (a * snim * n**nd) >> wp + else: + sre += (a * cnre * n**nd) >> wp + sim += (a * cnim * n**nd) >> wp + n += 1 + sre = -(sre << (nd+1)) + sim = -(sim << (nd+1)) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + # case z and q complex + else: + wp = ctx.prec + extra2 + xre = ctx.to_fixed(ctx._re(q), wp) + xim = ctx.to_fixed(ctx._im(q), wp) + x2re = (xre*xre - xim*xim) >> wp + x2im = (xre*xim) >> (wp - 1) + are = bre = xre + aim = bim = xim + prec0 = ctx.prec + ctx.prec = wp + # cos(2*z), sin(2*z) with z complex + c1, s1 = ctx.cos_sin(2*z) + ctx.prec = prec0 + cnre = c1re = ctx.to_fixed(ctx._re(c1), wp) + cnim = c1im = ctx.to_fixed(ctx._im(c1), wp) + snre = s1re = ctx.to_fixed(ctx._re(s1), wp) + snim = s1im = ctx.to_fixed(ctx._im(s1), wp) + if (nd&1): + sre = (are * snre - aim * snim) >> wp + sim = (aim * snre + are * snim) >> wp + else: + sre = (are * cnre - aim * cnim) >> wp + sim = (aim * cnre + are * cnim) >> wp + n = 2 + while are**2 + aim**2 > MIN: + bre, bim = (bre * x2re - bim * x2im) >> wp, \ + (bre * x2im + bim * x2re) >> wp + are, aim = (are * bre - aim * bim) >> wp, \ + (are * bim + aim * bre) >> wp + t1 = (cnre*c1re - cnim*c1im - snre*s1re + snim*s1im) >> wp + t2 = (cnre*c1im + cnim*c1re - snre*s1im - snim*s1re) >> wp + t3 = (snre*c1re - snim*c1im + cnre*s1re - cnim*s1im) >> wp + t4 = (snre*c1im + snim*c1re + cnre*s1im + cnim*s1re) >> wp + cnre = t1 + cnim = t2 + snre = t3 + snim = t4 + if(nd&1): + sre += ((are * snre - aim * snim) * n**nd) >> wp + sim += ((aim * snre + are * snim) * n**nd) >> wp + else: + sre += ((are * cnre - aim * cnim) * n**nd) >> wp + sim += ((aim * cnre + are * cnim) * n**nd) >> wp + n += 1 + sre = -(sre << (nd+1)) + sim = -(sim << (nd+1)) + sre = ctx.ldexp(sre, -wp) + sim = ctx.ldexp(sim, -wp) + s = ctx.mpc(sre, sim) + if (nd&1): + return (-1)**(nd//2) * s + else: + return (-1)**(1 + nd//2) * s + +@defun +def _jacobi_theta2a(ctx, z, q): + """ + case ctx._im(z) != 0 + theta(2, z, q) = + q**1/4 * Sum(q**(n*n + n) * exp(j*(2*n + 1)*z), n=-inf, inf) + max term for minimum (2*n+1)*log(q).real - 2* ctx._im(z) + n0 = int(ctx._im(z)/log(q).real - 1/2) + theta(2, z, q) = + q**1/4 * Sum(q**(n*n + n) * exp(j*(2*n + 1)*z), n=n0, inf) + + q**1/4 * Sum(q**(n*n + n) * exp(j*(2*n + 1)*z), n, n0-1, -inf) + """ + n = n0 = int(ctx._im(z)/ctx._re(ctx.log(q)) - 1/2) + e2 = ctx.expj(2*z) + e = e0 = ctx.expj((2*n+1)*z) + a = q**(n*n + n) + # leading term + term = a * e + s = term + eps1 = ctx.eps*abs(term) + while 1: + n += 1 + e = e * e2 + term = q**(n*n + n) * e + if abs(term) < eps1: + break + s += term + e = e0 + e2 = ctx.expj(-2*z) + n = n0 + while 1: + n -= 1 + e = e * e2 + term = q**(n*n + n) * e + if abs(term) < eps1: + break + s += term + s = s * ctx.nthroot(q, 4) + return s + +@defun +def _jacobi_theta3a(ctx, z, q): + """ + case ctx._im(z) != 0 + theta3(z, q) = Sum(q**(n*n) * exp(j*2*n*z), n, -inf, inf) + max term for n*abs(log(q).real) + ctx._im(z) ~= 0 + n0 = int(- ctx._im(z)/abs(log(q).real)) + """ + n = n0 = int(-ctx._im(z)/abs(ctx._re(ctx.log(q)))) + e2 = ctx.expj(2*z) + e = e0 = ctx.expj(2*n*z) + s = term = q**(n*n) * e + eps1 = ctx.eps*abs(term) + while 1: + n += 1 + e = e * e2 + term = q**(n*n) * e + if abs(term) < eps1: + break + s += term + e = e0 + e2 = ctx.expj(-2*z) + n = n0 + while 1: + n -= 1 + e = e * e2 + term = q**(n*n) * e + if abs(term) < eps1: + break + s += term + return s + +@defun +def _djacobi_theta2a(ctx, z, q, nd): + """ + case ctx._im(z) != 0 + dtheta(2, z, q, nd) = + j* q**1/4 * Sum(q**(n*n + n) * (2*n+1)*exp(j*(2*n + 1)*z), n=-inf, inf) + max term for (2*n0+1)*log(q).real - 2* ctx._im(z) ~= 0 + n0 = int(ctx._im(z)/log(q).real - 1/2) + """ + n = n0 = int(ctx._im(z)/ctx._re(ctx.log(q)) - 1/2) + e2 = ctx.expj(2*z) + e = e0 = ctx.expj((2*n + 1)*z) + a = q**(n*n + n) + # leading term + term = (2*n+1)**nd * a * e + s = term + eps1 = ctx.eps*abs(term) + while 1: + n += 1 + e = e * e2 + term = (2*n+1)**nd * q**(n*n + n) * e + if abs(term) < eps1: + break + s += term + e = e0 + e2 = ctx.expj(-2*z) + n = n0 + while 1: + n -= 1 + e = e * e2 + term = (2*n+1)**nd * q**(n*n + n) * e + if abs(term) < eps1: + break + s += term + return ctx.j**nd * s * ctx.nthroot(q, 4) + +@defun +def _djacobi_theta3a(ctx, z, q, nd): + """ + case ctx._im(z) != 0 + djtheta3(z, q, nd) = (2*j)**nd * + Sum(q**(n*n) * n**nd * exp(j*2*n*z), n, -inf, inf) + max term for minimum n*abs(log(q).real) + ctx._im(z) + """ + n = n0 = int(-ctx._im(z)/abs(ctx._re(ctx.log(q)))) + e2 = ctx.expj(2*z) + e = e0 = ctx.expj(2*n*z) + a = q**(n*n) * e + s = term = n**nd * a + if n != 0: + eps1 = ctx.eps*abs(term) + else: + eps1 = ctx.eps*abs(a) + while 1: + n += 1 + e = e * e2 + a = q**(n*n) * e + term = n**nd * a + if n != 0: + aterm = abs(term) + else: + aterm = abs(a) + if aterm < eps1: + break + s += term + e = e0 + e2 = ctx.expj(-2*z) + n = n0 + while 1: + n -= 1 + e = e * e2 + a = q**(n*n) * e + term = n**nd * a + if n != 0: + aterm = abs(term) + else: + aterm = abs(a) + if aterm < eps1: + break + s += term + return (2*ctx.j)**nd * s + +@defun +def jtheta(ctx, n, z, q, derivative=0): + if derivative: + return ctx._djtheta(n, z, q, derivative) + + z = ctx.convert(z) + q = ctx.convert(q) + + # Implementation note + # If ctx._im(z) is close to zero, _jacobi_theta2 and _jacobi_theta3 + # are used, + # which compute the series starting from n=0 using fixed precision + # numbers; + # otherwise _jacobi_theta2a and _jacobi_theta3a are used, which compute + # the series starting from n=n0, which is the largest term. + + # TODO: write _jacobi_theta2a and _jacobi_theta3a using fixed-point + + if abs(q) > ctx.THETA_Q_LIM: + raise ValueError('abs(q) > THETA_Q_LIM = %f' % ctx.THETA_Q_LIM) + + extra = 10 + if z: + M = ctx.mag(z) + if M > 5 or (n == 1 and M < -5): + extra += 2*abs(M) + cz = 0.5 + extra2 = 50 + prec0 = ctx.prec + try: + ctx.prec += extra + if n == 1: + if ctx._im(z): + if abs(ctx._im(z)) < cz * abs(ctx._re(ctx.log(q))): + ctx.dps += extra2 + res = ctx._jacobi_theta2(z - ctx.pi/2, q) + else: + ctx.dps += 10 + res = ctx._jacobi_theta2a(z - ctx.pi/2, q) + else: + res = ctx._jacobi_theta2(z - ctx.pi/2, q) + elif n == 2: + if ctx._im(z): + if abs(ctx._im(z)) < cz * abs(ctx._re(ctx.log(q))): + ctx.dps += extra2 + res = ctx._jacobi_theta2(z, q) + else: + ctx.dps += 10 + res = ctx._jacobi_theta2a(z, q) + else: + res = ctx._jacobi_theta2(z, q) + elif n == 3: + if ctx._im(z): + if abs(ctx._im(z)) < cz * abs(ctx._re(ctx.log(q))): + ctx.dps += extra2 + res = ctx._jacobi_theta3(z, q) + else: + ctx.dps += 10 + res = ctx._jacobi_theta3a(z, q) + else: + res = ctx._jacobi_theta3(z, q) + elif n == 4: + if ctx._im(z): + if abs(ctx._im(z)) < cz * abs(ctx._re(ctx.log(q))): + ctx.dps += extra2 + res = ctx._jacobi_theta3(z, -q) + else: + ctx.dps += 10 + res = ctx._jacobi_theta3a(z, -q) + else: + res = ctx._jacobi_theta3(z, -q) + else: + raise ValueError + finally: + ctx.prec = prec0 + return res + +@defun +def _djtheta(ctx, n, z, q, derivative=1): + z = ctx.convert(z) + q = ctx.convert(q) + nd = int(derivative) + + if abs(q) > ctx.THETA_Q_LIM: + raise ValueError('abs(q) > THETA_Q_LIM = %f' % ctx.THETA_Q_LIM) + extra = 10 + ctx.prec * nd // 10 + if z: + M = ctx.mag(z) + if M > 5 or (n != 1 and M < -5): + extra += 2*abs(M) + cz = 0.5 + extra2 = 50 + prec0 = ctx.prec + try: + ctx.prec += extra + if n == 1: + if ctx._im(z): + if abs(ctx._im(z)) < cz * abs(ctx._re(ctx.log(q))): + ctx.dps += extra2 + res = ctx._djacobi_theta2(z - ctx.pi/2, q, nd) + else: + ctx.dps += 10 + res = ctx._djacobi_theta2a(z - ctx.pi/2, q, nd) + else: + res = ctx._djacobi_theta2(z - ctx.pi/2, q, nd) + elif n == 2: + if ctx._im(z): + if abs(ctx._im(z)) < cz * abs(ctx._re(ctx.log(q))): + ctx.dps += extra2 + res = ctx._djacobi_theta2(z, q, nd) + else: + ctx.dps += 10 + res = ctx._djacobi_theta2a(z, q, nd) + else: + res = ctx._djacobi_theta2(z, q, nd) + elif n == 3: + if ctx._im(z): + if abs(ctx._im(z)) < cz * abs(ctx._re(ctx.log(q))): + ctx.dps += extra2 + res = ctx._djacobi_theta3(z, q, nd) + else: + ctx.dps += 10 + res = ctx._djacobi_theta3a(z, q, nd) + else: + res = ctx._djacobi_theta3(z, q, nd) + elif n == 4: + if ctx._im(z): + if abs(ctx._im(z)) < cz * abs(ctx._re(ctx.log(q))): + ctx.dps += extra2 + res = ctx._djacobi_theta3(z, -q, nd) + else: + ctx.dps += 10 + res = ctx._djacobi_theta3a(z, -q, nd) + else: + res = ctx._djacobi_theta3(z, -q, nd) + else: + raise ValueError + finally: + ctx.prec = prec0 + return +res diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/zeta.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/zeta.py new file mode 100644 index 0000000000000000000000000000000000000000..d7ede50d95e5b6eff511619620c934529942cbdd --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/zeta.py @@ -0,0 +1,1154 @@ +from __future__ import print_function + +from ..libmp.backend import xrange +from .functions import defun, defun_wrapped, defun_static + +@defun +def stieltjes(ctx, n, a=1): + n = ctx.convert(n) + a = ctx.convert(a) + if n < 0: + return ctx.bad_domain("Stieltjes constants defined for n >= 0") + if hasattr(ctx, "stieltjes_cache"): + stieltjes_cache = ctx.stieltjes_cache + else: + stieltjes_cache = ctx.stieltjes_cache = {} + if a == 1: + if n == 0: + return +ctx.euler + if n in stieltjes_cache: + prec, s = stieltjes_cache[n] + if prec >= ctx.prec: + return +s + mag = 1 + def f(x): + xa = x/a + v = (xa-ctx.j)*ctx.ln(a-ctx.j*x)**n/(1+xa**2)/(ctx.exp(2*ctx.pi*x)-1) + return ctx._re(v) / mag + orig = ctx.prec + try: + # Normalize integrand by approx. magnitude to + # speed up quadrature (which uses absolute error) + if n > 50: + ctx.prec = 20 + mag = ctx.quad(f, [0,ctx.inf], maxdegree=3) + ctx.prec = orig + 10 + int(n**0.5) + s = ctx.quad(f, [0,ctx.inf], maxdegree=20) + v = ctx.ln(a)**n/(2*a) - ctx.ln(a)**(n+1)/(n+1) + 2*s/a*mag + finally: + ctx.prec = orig + if a == 1 and ctx.isint(n): + stieltjes_cache[n] = (ctx.prec, v) + return +v + +@defun_wrapped +def siegeltheta(ctx, t, derivative=0): + d = int(derivative) + if (t == ctx.inf or t == ctx.ninf): + if d < 2: + if t == ctx.ninf and d == 0: + return ctx.ninf + return ctx.inf + else: + return ctx.zero + if d == 0: + if ctx._im(t): + # XXX: cancellation occurs + a = ctx.loggamma(0.25+0.5j*t) + b = ctx.loggamma(0.25-0.5j*t) + return -ctx.ln(ctx.pi)/2*t - 0.5j*(a-b) + else: + if ctx.isinf(t): + return t + return ctx._im(ctx.loggamma(0.25+0.5j*t)) - ctx.ln(ctx.pi)/2*t + if d > 0: + a = (-0.5j)**(d-1)*ctx.polygamma(d-1, 0.25-0.5j*t) + b = (0.5j)**(d-1)*ctx.polygamma(d-1, 0.25+0.5j*t) + if ctx._im(t): + if d == 1: + return -0.5*ctx.log(ctx.pi)+0.25*(a+b) + else: + return 0.25*(a+b) + else: + if d == 1: + return ctx._re(-0.5*ctx.log(ctx.pi)+0.25*(a+b)) + else: + return ctx._re(0.25*(a+b)) + +@defun_wrapped +def grampoint(ctx, n): + # asymptotic expansion, from + # http://mathworld.wolfram.com/GramPoint.html + g = 2*ctx.pi*ctx.exp(1+ctx.lambertw((8*n+1)/(8*ctx.e))) + return ctx.findroot(lambda t: ctx.siegeltheta(t)-ctx.pi*n, g) + + +@defun_wrapped +def siegelz(ctx, t, **kwargs): + d = int(kwargs.get("derivative", 0)) + t = ctx.convert(t) + t1 = ctx._re(t) + t2 = ctx._im(t) + prec = ctx.prec + try: + if abs(t1) > 500*prec and t2**2 < t1: + v = ctx.rs_z(t, d) + if ctx._is_real_type(t): + return ctx._re(v) + return v + except NotImplementedError: + pass + ctx.prec += 21 + e1 = ctx.expj(ctx.siegeltheta(t)) + z = ctx.zeta(0.5+ctx.j*t) + if d == 0: + v = e1*z + ctx.prec=prec + if ctx._is_real_type(t): + return ctx._re(v) + return +v + z1 = ctx.zeta(0.5+ctx.j*t, derivative=1) + theta1 = ctx.siegeltheta(t, derivative=1) + if d == 1: + v = ctx.j*e1*(z1+z*theta1) + ctx.prec=prec + if ctx._is_real_type(t): + return ctx._re(v) + return +v + z2 = ctx.zeta(0.5+ctx.j*t, derivative=2) + theta2 = ctx.siegeltheta(t, derivative=2) + comb1 = theta1**2-ctx.j*theta2 + if d == 2: + def terms(): + return [2*z1*theta1, z2, z*comb1] + v = ctx.sum_accurately(terms, 1) + v = -e1*v + ctx.prec = prec + if ctx._is_real_type(t): + return ctx._re(v) + return +v + ctx.prec += 10 + z3 = ctx.zeta(0.5+ctx.j*t, derivative=3) + theta3 = ctx.siegeltheta(t, derivative=3) + comb2 = theta1**3-3*ctx.j*theta1*theta2-theta3 + if d == 3: + def terms(): + return [3*theta1*z2, 3*z1*comb1, z3+z*comb2] + v = ctx.sum_accurately(terms, 1) + v = -ctx.j*e1*v + ctx.prec = prec + if ctx._is_real_type(t): + return ctx._re(v) + return +v + z4 = ctx.zeta(0.5+ctx.j*t, derivative=4) + theta4 = ctx.siegeltheta(t, derivative=4) + def terms(): + return [theta1**4, -6*ctx.j*theta1**2*theta2, -3*theta2**2, + -4*theta1*theta3, ctx.j*theta4] + comb3 = ctx.sum_accurately(terms, 1) + if d == 4: + def terms(): + return [6*theta1**2*z2, -6*ctx.j*z2*theta2, 4*theta1*z3, + 4*z1*comb2, z4, z*comb3] + v = ctx.sum_accurately(terms, 1) + v = e1*v + ctx.prec = prec + if ctx._is_real_type(t): + return ctx._re(v) + return +v + if d > 4: + h = lambda x: ctx.siegelz(x, derivative=4) + return ctx.diff(h, t, n=d-4) + + +_zeta_zeros = [ +14.134725142,21.022039639,25.010857580,30.424876126,32.935061588, +37.586178159,40.918719012,43.327073281,48.005150881,49.773832478, +52.970321478,56.446247697,59.347044003,60.831778525,65.112544048, +67.079810529,69.546401711,72.067157674,75.704690699,77.144840069, +79.337375020,82.910380854,84.735492981,87.425274613,88.809111208, +92.491899271,94.651344041,95.870634228,98.831194218,101.317851006, +103.725538040,105.446623052,107.168611184,111.029535543,111.874659177, +114.320220915,116.226680321,118.790782866,121.370125002,122.946829294, +124.256818554,127.516683880,129.578704200,131.087688531,133.497737203, +134.756509753,138.116042055,139.736208952,141.123707404,143.111845808, +146.000982487,147.422765343,150.053520421,150.925257612,153.024693811, +156.112909294,157.597591818,158.849988171,161.188964138,163.030709687, +165.537069188,167.184439978,169.094515416,169.911976479,173.411536520, +174.754191523,176.441434298,178.377407776,179.916484020,182.207078484, +184.874467848,185.598783678,187.228922584,189.416158656,192.026656361, +193.079726604,195.265396680,196.876481841,198.015309676,201.264751944, +202.493594514,204.189671803,205.394697202,207.906258888,209.576509717, +211.690862595,213.347919360,214.547044783,216.169538508,219.067596349, +220.714918839,221.430705555,224.007000255,224.983324670,227.421444280, +229.337413306,231.250188700,231.987235253,233.693404179,236.524229666, +] + +def _load_zeta_zeros(url): + import urllib + d = urllib.urlopen(url) + L = [float(x) for x in d.readlines()] + # Sanity check + assert round(L[0]) == 14 + _zeta_zeros[:] = L + +@defun +def oldzetazero(ctx, n, url='http://www.dtc.umn.edu/~odlyzko/zeta_tables/zeros1'): + n = int(n) + if n < 0: + return ctx.zetazero(-n).conjugate() + if n == 0: + raise ValueError("n must be nonzero") + if n > len(_zeta_zeros) and n <= 100000: + _load_zeta_zeros(url) + if n > len(_zeta_zeros): + raise NotImplementedError("n too large for zetazeros") + return ctx.mpc(0.5, ctx.findroot(ctx.siegelz, _zeta_zeros[n-1])) + +@defun_wrapped +def riemannr(ctx, x): + if x == 0: + return ctx.zero + # Check if a simple asymptotic estimate is accurate enough + if abs(x) > 1000: + a = ctx.li(x) + b = 0.5*ctx.li(ctx.sqrt(x)) + if abs(b) < abs(a)*ctx.eps: + return a + if abs(x) < 0.01: + # XXX + ctx.prec += int(-ctx.log(abs(x),2)) + # Sum Gram's series + s = t = ctx.one + u = ctx.ln(x) + k = 1 + while abs(t) > abs(s)*ctx.eps: + t = t * u / k + s += t / (k * ctx._zeta_int(k+1)) + k += 1 + return s + +@defun_static +def primepi(ctx, x): + x = int(x) + if x < 2: + return 0 + return len(ctx.list_primes(x)) + +# TODO: fix the interface wrt contexts +@defun_wrapped +def primepi2(ctx, x): + x = int(x) + if x < 2: + return ctx._iv.zero + if x < 2657: + return ctx._iv.mpf(ctx.primepi(x)) + mid = ctx.li(x) + # Schoenfeld's estimate for x >= 2657, assuming RH + err = ctx.sqrt(x,rounding='u')*ctx.ln(x,rounding='u')/8/ctx.pi(rounding='d') + a = ctx.floor((ctx._iv.mpf(mid)-err).a, rounding='d') + b = ctx.ceil((ctx._iv.mpf(mid)+err).b, rounding='u') + return ctx._iv.mpf([a,b]) + +@defun_wrapped +def primezeta(ctx, s): + if ctx.isnan(s): + return s + if ctx.re(s) <= 0: + raise ValueError("prime zeta function defined only for re(s) > 0") + if s == 1: + return ctx.inf + if s == 0.5: + return ctx.mpc(ctx.ninf, ctx.pi) + r = ctx.re(s) + if r > ctx.prec: + return 0.5**s + else: + wp = ctx.prec + int(r) + def terms(): + orig = ctx.prec + # zeta ~ 1+eps; need to set precision + # to get logarithm accurately + k = 0 + while 1: + k += 1 + u = ctx.moebius(k) + if not u: + continue + ctx.prec = wp + t = u*ctx.ln(ctx.zeta(k*s))/k + if not t: + return + #print ctx.prec, ctx.nstr(t) + ctx.prec = orig + yield t + return ctx.sum_accurately(terms) + +# TODO: for bernpoly and eulerpoly, ensure that all exact zeros are covered + +@defun_wrapped +def bernpoly(ctx, n, z): + # Slow implementation: + #return sum(ctx.binomial(n,k)*ctx.bernoulli(k)*z**(n-k) for k in xrange(0,n+1)) + n = int(n) + if n < 0: + raise ValueError("Bernoulli polynomials only defined for n >= 0") + if z == 0 or (z == 1 and n > 1): + return ctx.bernoulli(n) + if z == 0.5: + return (ctx.ldexp(1,1-n)-1)*ctx.bernoulli(n) + if n <= 3: + if n == 0: return z ** 0 + if n == 1: return z - 0.5 + if n == 2: return (6*z*(z-1)+1)/6 + if n == 3: return z*(z*(z-1.5)+0.5) + if ctx.isinf(z): + return z ** n + if ctx.isnan(z): + return z + if abs(z) > 2: + def terms(): + t = ctx.one + yield t + r = ctx.one/z + k = 1 + while k <= n: + t = t*(n+1-k)/k*r + if not (k > 2 and k & 1): + yield t*ctx.bernoulli(k) + k += 1 + return ctx.sum_accurately(terms) * z**n + else: + def terms(): + yield ctx.bernoulli(n) + t = ctx.one + k = 1 + while k <= n: + t = t*(n+1-k)/k * z + m = n-k + if not (m > 2 and m & 1): + yield t*ctx.bernoulli(m) + k += 1 + return ctx.sum_accurately(terms) + +@defun_wrapped +def eulerpoly(ctx, n, z): + n = int(n) + if n < 0: + raise ValueError("Euler polynomials only defined for n >= 0") + if n <= 2: + if n == 0: return z ** 0 + if n == 1: return z - 0.5 + if n == 2: return z*(z-1) + if ctx.isinf(z): + return z**n + if ctx.isnan(z): + return z + m = n+1 + if z == 0: + return -2*(ctx.ldexp(1,m)-1)*ctx.bernoulli(m)/m * z**0 + if z == 1: + return 2*(ctx.ldexp(1,m)-1)*ctx.bernoulli(m)/m * z**0 + if z == 0.5: + if n % 2: + return ctx.zero + # Use exact code for Euler numbers + if n < 100 or n*ctx.mag(0.46839865*n) < ctx.prec*0.25: + return ctx.ldexp(ctx._eulernum(n), -n) + # http://functions.wolfram.com/Polynomials/EulerE2/06/01/02/01/0002/ + def terms(): + t = ctx.one + k = 0 + w = ctx.ldexp(1,n+2) + while 1: + v = n-k+1 + if not (v > 2 and v & 1): + yield (2-w)*ctx.bernoulli(v)*t + k += 1 + if k > n: + break + t = t*z*(n-k+2)/k + w *= 0.5 + return ctx.sum_accurately(terms) / m + +@defun +def eulernum(ctx, n, exact=False): + n = int(n) + if exact: + return int(ctx._eulernum(n)) + if n < 100: + return ctx.mpf(ctx._eulernum(n)) + if n % 2: + return ctx.zero + return ctx.ldexp(ctx.eulerpoly(n,0.5), n) + +# TODO: this should be implemented low-level +def polylog_series(ctx, s, z): + tol = +ctx.eps + l = ctx.zero + k = 1 + zk = z + while 1: + term = zk / k**s + l += term + if abs(term) < tol: + break + zk *= z + k += 1 + return l + +def polylog_continuation(ctx, n, z): + if n < 0: + return z*0 + twopij = 2j * ctx.pi + a = -twopij**n/ctx.fac(n) * ctx.bernpoly(n, ctx.ln(z)/twopij) + if ctx._is_real_type(z) and z < 0: + a = ctx._re(a) + if ctx._im(z) < 0 or (ctx._im(z) == 0 and ctx._re(z) >= 1): + a -= twopij*ctx.ln(z)**(n-1)/ctx.fac(n-1) + return a + +def polylog_unitcircle(ctx, n, z): + tol = +ctx.eps + if n > 1: + l = ctx.zero + logz = ctx.ln(z) + logmz = ctx.one + m = 0 + while 1: + if (n-m) != 1: + term = ctx.zeta(n-m) * logmz / ctx.fac(m) + if term and abs(term) < tol: + break + l += term + logmz *= logz + m += 1 + l += ctx.ln(z)**(n-1)/ctx.fac(n-1)*(ctx.harmonic(n-1)-ctx.ln(-ctx.ln(z))) + elif n < 1: # else + l = ctx.fac(-n)*(-ctx.ln(z))**(n-1) + logz = ctx.ln(z) + logkz = ctx.one + k = 0 + while 1: + b = ctx.bernoulli(k-n+1) + if b: + term = b*logkz/(ctx.fac(k)*(k-n+1)) + if abs(term) < tol: + break + l -= term + logkz *= logz + k += 1 + else: + raise ValueError + if ctx._is_real_type(z) and z < 0: + l = ctx._re(l) + return l + +def polylog_general(ctx, s, z): + v = ctx.zero + u = ctx.ln(z) + if not abs(u) < 5: # theoretically |u| < 2*pi + j = ctx.j + v = 1-s + y = ctx.ln(-z)/(2*ctx.pi*j) + return ctx.gamma(v)*(j**v*ctx.zeta(v,0.5+y) + j**-v*ctx.zeta(v,0.5-y))/(2*ctx.pi)**v + t = 1 + k = 0 + while 1: + term = ctx.zeta(s-k) * t + if abs(term) < ctx.eps: + break + v += term + k += 1 + t *= u + t /= k + return ctx.gamma(1-s)*(-u)**(s-1) + v + +@defun_wrapped +def polylog(ctx, s, z): + s = ctx.convert(s) + z = ctx.convert(z) + if z == 1: + return ctx.zeta(s) + if z == -1: + return -ctx.altzeta(s) + if s == 0: + return z/(1-z) + if s == 1: + return -ctx.ln(1-z) + if s == -1: + return z/(1-z)**2 + if abs(z) <= 0.75 or (not ctx.isint(s) and abs(z) < 0.9): + return polylog_series(ctx, s, z) + if abs(z) >= 1.4 and ctx.isint(s): + return (-1)**(s+1)*polylog_series(ctx, s, 1/z) + polylog_continuation(ctx, int(ctx.re(s)), z) + if ctx.isint(s): + return polylog_unitcircle(ctx, int(ctx.re(s)), z) + return polylog_general(ctx, s, z) + +@defun_wrapped +def clsin(ctx, s, z, pi=False): + if ctx.isint(s) and s < 0 and int(s) % 2 == 1: + return z*0 + if pi: + a = ctx.expjpi(z) + else: + a = ctx.expj(z) + if ctx._is_real_type(z) and ctx._is_real_type(s): + return ctx.im(ctx.polylog(s,a)) + b = 1/a + return (-0.5j)*(ctx.polylog(s,a) - ctx.polylog(s,b)) + +@defun_wrapped +def clcos(ctx, s, z, pi=False): + if ctx.isint(s) and s < 0 and int(s) % 2 == 0: + return z*0 + if pi: + a = ctx.expjpi(z) + else: + a = ctx.expj(z) + if ctx._is_real_type(z) and ctx._is_real_type(s): + return ctx.re(ctx.polylog(s,a)) + b = 1/a + return 0.5*(ctx.polylog(s,a) + ctx.polylog(s,b)) + +@defun +def altzeta(ctx, s, **kwargs): + try: + return ctx._altzeta(s, **kwargs) + except NotImplementedError: + return ctx._altzeta_generic(s) + +@defun_wrapped +def _altzeta_generic(ctx, s): + if s == 1: + return ctx.ln2 + 0*s + return -ctx.powm1(2, 1-s) * ctx.zeta(s) + +@defun +def zeta(ctx, s, a=1, derivative=0, method=None, **kwargs): + d = int(derivative) + if a == 1 and not (d or method): + try: + return ctx._zeta(s, **kwargs) + except NotImplementedError: + pass + s = ctx.convert(s) + prec = ctx.prec + method = kwargs.get('method') + verbose = kwargs.get('verbose') + if (not s) and (not derivative): + return ctx.mpf(0.5) - ctx._convert_param(a)[0] + if a == 1 and method != 'euler-maclaurin': + im = abs(ctx._im(s)) + re = abs(ctx._re(s)) + #if (im < prec or method == 'borwein') and not derivative: + # try: + # if verbose: + # print "zeta: Attempting to use the Borwein algorithm" + # return ctx._zeta(s, **kwargs) + # except NotImplementedError: + # if verbose: + # print "zeta: Could not use the Borwein algorithm" + # pass + if abs(im) > 500*prec and 10*re < prec and derivative <= 4 or \ + method == 'riemann-siegel': + try: # py2.4 compatible try block + try: + if verbose: + print("zeta: Attempting to use the Riemann-Siegel algorithm") + return ctx.rs_zeta(s, derivative, **kwargs) + except NotImplementedError: + if verbose: + print("zeta: Could not use the Riemann-Siegel algorithm") + pass + finally: + ctx.prec = prec + if s == 1: + return ctx.inf + abss = abs(s) + if abss == ctx.inf: + if ctx.re(s) == ctx.inf: + if d == 0: + return ctx.one + return ctx.zero + return s*0 + elif ctx.isnan(abss): + return 1/s + if ctx.re(s) > 2*ctx.prec and a == 1 and not derivative: + return ctx.one + ctx.power(2, -s) + return +ctx._hurwitz(s, a, d, **kwargs) + +@defun +def _hurwitz(ctx, s, a=1, d=0, **kwargs): + prec = ctx.prec + verbose = kwargs.get('verbose') + try: + extraprec = 10 + ctx.prec += extraprec + # We strongly want to special-case rational a + a, atype = ctx._convert_param(a) + if ctx.re(s) < 0: + if verbose: + print("zeta: Attempting reflection formula") + try: + return _hurwitz_reflection(ctx, s, a, d, atype) + except NotImplementedError: + pass + if verbose: + print("zeta: Reflection formula failed") + if verbose: + print("zeta: Using the Euler-Maclaurin algorithm") + while 1: + ctx.prec = prec + extraprec + T1, T2 = _hurwitz_em(ctx, s, a, d, prec+10, verbose) + cancellation = ctx.mag(T1) - ctx.mag(T1+T2) + if verbose: + print("Term 1:", T1) + print("Term 2:", T2) + print("Cancellation:", cancellation, "bits") + if cancellation < extraprec: + return T1 + T2 + else: + extraprec = max(2*extraprec, min(cancellation + 5, 100*prec)) + if extraprec > kwargs.get('maxprec', 100*prec): + raise ctx.NoConvergence("zeta: too much cancellation") + finally: + ctx.prec = prec + +def _hurwitz_reflection(ctx, s, a, d, atype): + # TODO: implement for derivatives + if d != 0: + raise NotImplementedError + res = ctx.re(s) + negs = -s + # Integer reflection formula + if ctx.isnpint(s): + n = int(res) + if n <= 0: + return ctx.bernpoly(1-n, a) / (n-1) + if not (atype == 'Q' or atype == 'Z'): + raise NotImplementedError + t = 1-s + # We now require a to be standardized + v = 0 + shift = 0 + b = a + while ctx.re(b) > 1: + b -= 1 + v -= b**negs + shift -= 1 + while ctx.re(b) <= 0: + v += b**negs + b += 1 + shift += 1 + # Rational reflection formula + try: + p, q = a._mpq_ + except: + assert a == int(a) + p = int(a) + q = 1 + p += shift*q + assert 1 <= p <= q + g = ctx.fsum(ctx.cospi(t/2-2*k*b)*ctx._hurwitz(t,(k,q)) \ + for k in range(1,q+1)) + g *= 2*ctx.gamma(t)/(2*ctx.pi*q)**t + v += g + return v + +def _hurwitz_em(ctx, s, a, d, prec, verbose): + # May not be converted at this point + a = ctx.convert(a) + tol = -prec + # Estimate number of terms for Euler-Maclaurin summation; could be improved + M1 = 0 + M2 = prec // 3 + N = M2 + lsum = 0 + # This speeds up the recurrence for derivatives + if ctx.isint(s): + s = int(ctx._re(s)) + s1 = s-1 + while 1: + # Truncated L-series + l = ctx._zetasum(s, M1+a, M2-M1-1, [d])[0][0] + #if d: + # l = ctx.fsum((-ctx.ln(n+a))**d * (n+a)**negs for n in range(M1,M2)) + #else: + # l = ctx.fsum((n+a)**negs for n in range(M1,M2)) + lsum += l + M2a = M2+a + logM2a = ctx.ln(M2a) + logM2ad = logM2a**d + logs = [logM2ad] + logr = 1/logM2a + rM2a = 1/M2a + M2as = M2a**(-s) + if d: + tailsum = ctx.gammainc(d+1, s1*logM2a) / s1**(d+1) + else: + tailsum = 1/((s1)*(M2a)**s1) + tailsum += 0.5 * logM2ad * M2as + U = [1] + r = M2as + fact = 2 + for j in range(1, N+1): + # TODO: the following could perhaps be tidied a bit + j2 = 2*j + if j == 1: + upds = [1] + else: + upds = [j2-2, j2-1] + for m in upds: + D = min(m,d+1) + if m <= d: + logs.append(logs[-1] * logr) + Un = [0]*(D+1) + for i in xrange(D): Un[i] = (1-m-s)*U[i] + for i in xrange(1,D+1): Un[i] += (d-(i-1))*U[i-1] + U = Un + r *= rM2a + t = ctx.fdot(U, logs) * r * ctx.bernoulli(j2)/(-fact) + tailsum += t + if ctx.mag(t) < tol: + return lsum, (-1)**d * tailsum + fact *= (j2+1)*(j2+2) + if verbose: + print("Sum range:", M1, M2, "term magnitude", ctx.mag(t), "tolerance", tol) + M1, M2 = M2, M2*2 + if ctx.re(s) < 0: + N += N//2 + + + +@defun +def _zetasum(ctx, s, a, n, derivatives=[0], reflect=False): + """ + Returns [xd0,xd1,...,xdr], [yd0,yd1,...ydr] where + + xdk = D^k ( 1/a^s + 1/(a+1)^s + ... + 1/(a+n)^s ) + ydk = D^k conj( 1/a^(1-s) + 1/(a+1)^(1-s) + ... + 1/(a+n)^(1-s) ) + + D^k = kth derivative with respect to s, k ranges over the given list of + derivatives (which should consist of either a single element + or a range 0,1,...r). If reflect=False, the ydks are not computed. + """ + #print "zetasum", s, a, n + # don't use the fixed-point code if there are large exponentials + if abs(ctx.re(s)) < 0.5 * ctx.prec: + try: + return ctx._zetasum_fast(s, a, n, derivatives, reflect) + except NotImplementedError: + pass + negs = ctx.fneg(s, exact=True) + have_derivatives = derivatives != [0] + have_one_derivative = len(derivatives) == 1 + if not reflect: + if not have_derivatives: + return [ctx.fsum((a+k)**negs for k in xrange(n+1))], [] + if have_one_derivative: + d = derivatives[0] + x = ctx.fsum(ctx.ln(a+k)**d * (a+k)**negs for k in xrange(n+1)) + return [(-1)**d * x], [] + maxd = max(derivatives) + if not have_one_derivative: + derivatives = range(maxd+1) + xs = [ctx.zero for d in derivatives] + if reflect: + ys = [ctx.zero for d in derivatives] + else: + ys = [] + for k in xrange(n+1): + w = a + k + xterm = w ** negs + if reflect: + yterm = ctx.conj(ctx.one / (w * xterm)) + if have_derivatives: + logw = -ctx.ln(w) + if have_one_derivative: + logw = logw ** maxd + xs[0] += xterm * logw + if reflect: + ys[0] += yterm * logw + else: + t = ctx.one + for d in derivatives: + xs[d] += xterm * t + if reflect: + ys[d] += yterm * t + t *= logw + else: + xs[0] += xterm + if reflect: + ys[0] += yterm + return xs, ys + +@defun +def dirichlet(ctx, s, chi=[1], derivative=0): + s = ctx.convert(s) + q = len(chi) + d = int(derivative) + if d > 2: + raise NotImplementedError("arbitrary order derivatives") + prec = ctx.prec + try: + ctx.prec += 10 + if s == 1: + have_pole = True + for x in chi: + if x and x != 1: + have_pole = False + h = +ctx.eps + ctx.prec *= 2*(d+1) + s += h + if have_pole: + return +ctx.inf + z = ctx.zero + for p in range(1,q+1): + if chi[p%q]: + if d == 1: + z += chi[p%q] * (ctx.zeta(s, (p,q), 1) - \ + ctx.zeta(s, (p,q))*ctx.log(q)) + else: + z += chi[p%q] * ctx.zeta(s, (p,q)) + z /= q**s + finally: + ctx.prec = prec + return +z + + +def secondzeta_main_term(ctx, s, a, **kwargs): + tol = ctx.eps + f = lambda n: ctx.gammainc(0.5*s, a*gamm**2, regularized=True)*gamm**(-s) + totsum = term = ctx.zero + mg = ctx.inf + n = 0 + while mg > tol: + totsum += term + n += 1 + gamm = ctx.im(ctx.zetazero_memoized(n)) + term = f(n) + mg = abs(term) + err = 0 + if kwargs.get("error"): + sg = ctx.re(s) + err = 0.5*ctx.pi**(-1)*max(1,sg)*a**(sg-0.5)*ctx.log(gamm/(2*ctx.pi))*\ + ctx.gammainc(-0.5, a*gamm**2)/abs(ctx.gamma(s/2)) + err = abs(err) + return +totsum, err, n + +def secondzeta_prime_term(ctx, s, a, **kwargs): + tol = ctx.eps + f = lambda n: ctx.gammainc(0.5*(1-s),0.25*ctx.log(n)**2 * a**(-1))*\ + ((0.5*ctx.log(n))**(s-1))*ctx.mangoldt(n)/ctx.sqrt(n)/\ + (2*ctx.gamma(0.5*s)*ctx.sqrt(ctx.pi)) + totsum = term = ctx.zero + mg = ctx.inf + n = 1 + while mg > tol or n < 9: + totsum += term + n += 1 + term = f(n) + if term == 0: + mg = ctx.inf + else: + mg = abs(term) + if kwargs.get("error"): + err = mg + return +totsum, err, n + +def secondzeta_exp_term(ctx, s, a): + if ctx.isint(s) and ctx.re(s) <= 0: + m = int(round(ctx.re(s))) + if not m & 1: + return ctx.mpf('-0.25')**(-m//2) + tol = ctx.eps + f = lambda n: (0.25*a)**n/((n+0.5*s)*ctx.fac(n)) + totsum = ctx.zero + term = f(0) + mg = ctx.inf + n = 0 + while mg > tol: + totsum += term + n += 1 + term = f(n) + mg = abs(term) + v = a**(0.5*s)*totsum/ctx.gamma(0.5*s) + return v + +def secondzeta_singular_term(ctx, s, a, **kwargs): + factor = a**(0.5*(s-1))/(4*ctx.sqrt(ctx.pi)*ctx.gamma(0.5*s)) + extraprec = ctx.mag(factor) + ctx.prec += extraprec + factor = a**(0.5*(s-1))/(4*ctx.sqrt(ctx.pi)*ctx.gamma(0.5*s)) + tol = ctx.eps + f = lambda n: ctx.bernpoly(n,0.75)*(4*ctx.sqrt(a))**n*\ + ctx.gamma(0.5*n)/((s+n-1)*ctx.fac(n)) + totsum = ctx.zero + mg1 = ctx.inf + n = 1 + term = f(n) + mg2 = abs(term) + while mg2 > tol and mg2 <= mg1: + totsum += term + n += 1 + term = f(n) + totsum += term + n +=1 + term = f(n) + mg1 = mg2 + mg2 = abs(term) + totsum += term + pole = -2*(s-1)**(-2)+(ctx.euler+ctx.log(16*ctx.pi**2*a))*(s-1)**(-1) + st = factor*(pole+totsum) + err = 0 + if kwargs.get("error"): + if not ((mg2 > tol) and (mg2 <= mg1)): + if mg2 <= tol: + err = ctx.mpf(10)**int(ctx.log(abs(factor*tol),10)) + if mg2 > mg1: + err = ctx.mpf(10)**int(ctx.log(abs(factor*mg1),10)) + err = max(err, ctx.eps*1.) + ctx.prec -= extraprec + return +st, err + +@defun +def secondzeta(ctx, s, a = 0.015, **kwargs): + r""" + Evaluates the secondary zeta function `Z(s)`, defined for + `\mathrm{Re}(s)>1` by + + .. math :: + + Z(s) = \sum_{n=1}^{\infty} \frac{1}{\tau_n^s} + + where `\frac12+i\tau_n` runs through the zeros of `\zeta(s)` with + imaginary part positive. + + `Z(s)` extends to a meromorphic function on `\mathbb{C}` with a + double pole at `s=1` and simple poles at the points `-2n` for + `n=0`, 1, 2, ... + + **Examples** + + >>> from mpmath import * + >>> mp.pretty = True; mp.dps = 15 + >>> secondzeta(2) + 0.023104993115419 + >>> xi = lambda s: 0.5*s*(s-1)*pi**(-0.5*s)*gamma(0.5*s)*zeta(s) + >>> Xi = lambda t: xi(0.5+t*j) + >>> chop(-0.5*diff(Xi,0,n=2)/Xi(0)) + 0.023104993115419 + + We may ask for an approximate error value:: + + >>> secondzeta(0.5+100j, error=True) + ((-0.216272011276718 - 0.844952708937228j), 2.22044604925031e-16) + + The function has poles at the negative odd integers, + and dyadic rational values at the negative even integers:: + + >>> mp.dps = 30 + >>> secondzeta(-8) + -0.67236328125 + >>> secondzeta(-7) + +inf + + **Implementation notes** + + The function is computed as sum of four terms `Z(s)=A(s)-P(s)+E(s)-S(s)` + respectively main, prime, exponential and singular terms. + The main term `A(s)` is computed from the zeros of zeta. + The prime term depends on the von Mangoldt function. + The singular term is responsible for the poles of the function. + + The four terms depends on a small parameter `a`. We may change the + value of `a`. Theoretically this has no effect on the sum of the four + terms, but in practice may be important. + + A smaller value of the parameter `a` makes `A(s)` depend on + a smaller number of zeros of zeta, but `P(s)` uses more values of + von Mangoldt function. + + We may also add a verbose option to obtain data about the + values of the four terms. + + >>> mp.dps = 10 + >>> secondzeta(0.5 + 40j, error=True, verbose=True) + main term = (-30190318549.138656312556 - 13964804384.624622876523j) + computed using 19 zeros of zeta + prime term = (132717176.89212754625045 + 188980555.17563978290601j) + computed using 9 values of the von Mangoldt function + exponential term = (542447428666.07179812536 + 362434922978.80192435203j) + singular term = (512124392939.98154322355 + 348281138038.65531023921j) + ((0.059471043 + 0.3463514534j), 1.455191523e-11) + + >>> secondzeta(0.5 + 40j, a=0.04, error=True, verbose=True) + main term = (-151962888.19606243907725 - 217930683.90210294051982j) + computed using 9 zeros of zeta + prime term = (2476659342.3038722372461 + 28711581821.921627163136j) + computed using 37 values of the von Mangoldt function + exponential term = (178506047114.7838188264 + 819674143244.45677330576j) + singular term = (175877424884.22441310708 + 790744630738.28669174871j) + ((0.059471043 + 0.3463514534j), 1.455191523e-11) + + Notice the great cancellation between the four terms. Changing `a`, the + four terms are very different numbers but the cancellation gives + the good value of Z(s). + + **References** + + A. Voros, Zeta functions for the Riemann zeros, Ann. Institute Fourier, + 53, (2003) 665--699. + + A. Voros, Zeta functions over Zeros of Zeta Functions, Lecture Notes + of the Unione Matematica Italiana, Springer, 2009. + """ + s = ctx.convert(s) + a = ctx.convert(a) + tol = ctx.eps + if ctx.isint(s) and ctx.re(s) <= 1: + if abs(s-1) < tol*1000: + return ctx.inf + m = int(round(ctx.re(s))) + if m & 1: + return ctx.inf + else: + return ((-1)**(-m//2)*\ + ctx.fraction(8-ctx.eulernum(-m,exact=True),2**(-m+3))) + prec = ctx.prec + try: + t3 = secondzeta_exp_term(ctx, s, a) + extraprec = max(ctx.mag(t3),0) + ctx.prec += extraprec + 3 + t1, r1, gt = secondzeta_main_term(ctx,s,a,error='True', verbose='True') + t2, r2, pt = secondzeta_prime_term(ctx,s,a,error='True', verbose='True') + t4, r4 = secondzeta_singular_term(ctx,s,a,error='True') + t3 = secondzeta_exp_term(ctx, s, a) + err = r1+r2+r4 + t = t1-t2+t3-t4 + if kwargs.get("verbose"): + print('main term =', t1) + print(' computed using', gt, 'zeros of zeta') + print('prime term =', t2) + print(' computed using', pt, 'values of the von Mangoldt function') + print('exponential term =', t3) + print('singular term =', t4) + finally: + ctx.prec = prec + if kwargs.get("error"): + w = max(ctx.mag(abs(t)),0) + err = max(err*2**w, ctx.eps*1.*2**w) + return +t, err + return +t + + +@defun_wrapped +def lerchphi(ctx, z, s, a): + r""" + Gives the Lerch transcendent, defined for `|z| < 1` and + `\Re{a} > 0` by + + .. math :: + + \Phi(z,s,a) = \sum_{k=0}^{\infty} \frac{z^k}{(a+k)^s} + + and generally by the recurrence `\Phi(z,s,a) = z \Phi(z,s,a+1) + a^{-s}` + along with the integral representation valid for `\Re{a} > 0` + + .. math :: + + \Phi(z,s,a) = \frac{1}{2 a^s} + + \int_0^{\infty} \frac{z^t}{(a+t)^s} dt - + 2 \int_0^{\infty} \frac{\sin(t \log z - s + \operatorname{arctan}(t/a)}{(a^2 + t^2)^{s/2} + (e^{2 \pi t}-1)} dt. + + The Lerch transcendent generalizes the Hurwitz zeta function :func:`zeta` + (`z = 1`) and the polylogarithm :func:`polylog` (`a = 1`). + + **Examples** + + Several evaluations in terms of simpler functions:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> lerchphi(-1,2,0.5); 4*catalan + 3.663862376708876060218414 + 3.663862376708876060218414 + >>> diff(lerchphi, (-1,-2,1), (0,1,0)); 7*zeta(3)/(4*pi**2) + 0.2131391994087528954617607 + 0.2131391994087528954617607 + >>> lerchphi(-4,1,1); log(5)/4 + 0.4023594781085250936501898 + 0.4023594781085250936501898 + >>> lerchphi(-3+2j,1,0.5); 2*atanh(sqrt(-3+2j))/sqrt(-3+2j) + (1.142423447120257137774002 + 0.2118232380980201350495795j) + (1.142423447120257137774002 + 0.2118232380980201350495795j) + + Evaluation works for complex arguments and `|z| \ge 1`:: + + >>> lerchphi(1+2j, 3-j, 4+2j) + (0.002025009957009908600539469 + 0.003327897536813558807438089j) + >>> lerchphi(-2,2,-2.5) + -12.28676272353094275265944 + >>> lerchphi(10,10,10) + (-4.462130727102185701817349e-11 - 1.575172198981096218823481e-12j) + >>> lerchphi(10,10,-10.5) + (112658784011940.5605789002 - 498113185.5756221777743631j) + + Some degenerate cases:: + + >>> lerchphi(0,1,2) + 0.5 + >>> lerchphi(0,1,-2) + -0.5 + + Reduction to simpler functions:: + + >>> lerchphi(1, 4.25+1j, 1) + (1.044674457556746668033975 - 0.04674508654012658932271226j) + >>> zeta(4.25+1j) + (1.044674457556746668033975 - 0.04674508654012658932271226j) + >>> lerchphi(1 - 0.5**10, 4.25+1j, 1) + (1.044629338021507546737197 - 0.04667768813963388181708101j) + >>> lerchphi(3, 4, 1) + (1.249503297023366545192592 - 0.2314252413375664776474462j) + >>> polylog(4, 3) / 3 + (1.249503297023366545192592 - 0.2314252413375664776474462j) + >>> lerchphi(3, 4, 1 - 0.5**10) + (1.253978063946663945672674 - 0.2316736622836535468765376j) + + **References** + + 1. [DLMF]_ section 25.14 + + """ + if z == 0: + return a ** (-s) + # Faster, but these cases are useful for testing right now + if z == 1: + return ctx.zeta(s, a) + if a == 1: + return ctx.polylog(s, z) / z + if ctx.re(a) < 1: + if ctx.isnpint(a): + raise ValueError("Lerch transcendent complex infinity") + m = int(ctx.ceil(1-ctx.re(a))) + v = ctx.zero + zpow = ctx.one + for n in xrange(m): + v += zpow / (a+n)**s + zpow *= z + return zpow * ctx.lerchphi(z,s, a+m) + v + g = ctx.ln(z) + v = 1/(2*a**s) + ctx.gammainc(1-s, -a*g) * (-g)**(s-1) / z**a + h = s / 2 + r = 2*ctx.pi + f = lambda t: ctx.sin(s*ctx.atan(t/a)-t*g) / \ + ((a**2+t**2)**h * ctx.expm1(r*t)) + v += 2*ctx.quad(f, [0, ctx.inf]) + if not ctx.im(z) and not ctx.im(s) and not ctx.im(a) and ctx.re(z) < 1: + v = ctx.chop(v) + return v diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/zetazeros.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/zetazeros.py new file mode 100644 index 0000000000000000000000000000000000000000..37c11a29426b0114053ae61664541f7ae7de95d8 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/functions/zetazeros.py @@ -0,0 +1,1018 @@ +""" +The function zetazero(n) computes the n-th nontrivial zero of zeta(s). + +The general strategy is to locate a block of Gram intervals B where we +know exactly the number of zeros contained and which of those zeros +is that which we search. + +If n <= 400 000 000 we know exactly the Rosser exceptions, contained +in a list in this file. Hence for n<=400 000 000 we simply +look at these list of exceptions. If our zero is implicated in one of +these exceptions we have our block B. In other case we simply locate +the good Rosser block containing our zero. + +For n > 400 000 000 we apply the method of Turing, as complemented by +Lehman, Brent and Trudgian to find a suitable B. +""" + +from .functions import defun, defun_wrapped + +def find_rosser_block_zero(ctx, n): + """for n<400 000 000 determines a block were one find our zero""" + for k in range(len(_ROSSER_EXCEPTIONS)//2): + a=_ROSSER_EXCEPTIONS[2*k][0] + b=_ROSSER_EXCEPTIONS[2*k][1] + if ((a<= n-2) and (n-1 <= b)): + t0 = ctx.grampoint(a) + t1 = ctx.grampoint(b) + v0 = ctx._fp.siegelz(t0) + v1 = ctx._fp.siegelz(t1) + my_zero_number = n-a-1 + zero_number_block = b-a + pattern = _ROSSER_EXCEPTIONS[2*k+1] + return (my_zero_number, [a,b], [t0,t1], [v0,v1]) + k = n-2 + t,v,b = compute_triple_tvb(ctx, k) + T = [t] + V = [v] + while b < 0: + k -= 1 + t,v,b = compute_triple_tvb(ctx, k) + T.insert(0,t) + V.insert(0,v) + my_zero_number = n-k-1 + m = n-1 + t,v,b = compute_triple_tvb(ctx, m) + T.append(t) + V.append(v) + while b < 0: + m += 1 + t,v,b = compute_triple_tvb(ctx, m) + T.append(t) + V.append(v) + return (my_zero_number, [k,m], T, V) + +def wpzeros(t): + """Precision needed to compute higher zeros""" + wp = 53 + if t > 3*10**8: + wp = 63 + if t > 10**11: + wp = 70 + if t > 10**14: + wp = 83 + return wp + +def separate_zeros_in_block(ctx, zero_number_block, T, V, limitloop=None, + fp_tolerance=None): + """Separate the zeros contained in the block T, limitloop + determines how long one must search""" + if limitloop is None: + limitloop = ctx.inf + loopnumber = 0 + variations = count_variations(V) + while ((variations < zero_number_block) and (loopnumber 0): + alpha = ctx.sqrt(u/v) + b= (alpha*a+b2)/(alpha+1) + else: + b = (a+b2)/2 + if fp_tolerance < 10: + w = ctx._fp.siegelz(b) + if abs(w)ITERATION_LIMIT)and(loopnumber>2)and(variations+2==zero_number_block): + dtMax=0 + dtSec=0 + kMax = 0 + for k1 in range(1,len(T)): + dt = T[k1]-T[k1-1] + if dt > dtMax: + kMax=k1 + dtSec = dtMax + dtMax = dt + elif (dtdtSec): + dtSec = dt + if dtMax>3*dtSec: + f = lambda x: ctx.rs_z(x,derivative=1) + t0=T[kMax-1] + t1 = T[kMax] + t=ctx.findroot(f, (t0,t1), solver ='illinois',verify=False, verbose=False) + v = ctx.siegelz(t) + if (t0 2*wpz: + index +=1 + precs = [precs[0] // 2 +3+2*index] + precs + ctx.prec = precs[0] + guard + r = ctx.findroot(lambda x:ctx.siegelz(x), (t0,t1), solver ='illinois', verbose=False) + #print "first step at", ctx.dps, "digits" + z=ctx.mpc(0.5,r) + for prec in precs[1:]: + ctx.prec = prec + guard + #print "refining to", ctx.dps, "digits" + znew = z - ctx.zeta(z) / ctx.zeta(z, derivative=1) + #print "difference", ctx.nstr(abs(z-znew)) + z=ctx.mpc(0.5,ctx.im(znew)) + return ctx.im(z) + +def sure_number_block(ctx, n): + """The number of good Rosser blocks needed to apply + Turing method + References: + R. P. Brent, On the Zeros of the Riemann Zeta Function + in the Critical Strip, Math. Comp. 33 (1979) 1361--1372 + T. Trudgian, Improvements to Turing Method, Math. Comp.""" + if n < 9*10**5: + return(2) + g = ctx.grampoint(n-100) + lg = ctx._fp.ln(g) + brent = 0.0061 * lg**2 +0.08*lg + trudgian = 0.0031 * lg**2 +0.11*lg + N = ctx.ceil(min(brent,trudgian)) + N = int(N) + return N + +def compute_triple_tvb(ctx, n): + t = ctx.grampoint(n) + v = ctx._fp.siegelz(t) + if ctx.mag(abs(v))400 000 000""" + sb = sure_number_block(ctx, n) + number_goodblocks = 0 + m2 = n-1 + t, v, b = compute_triple_tvb(ctx, m2) + Tf = [t] + Vf = [v] + while b < 0: + m2 += 1 + t,v,b = compute_triple_tvb(ctx, m2) + Tf.append(t) + Vf.append(v) + goodpoints = [m2] + T = [t] + V = [v] + while number_goodblocks < 2*sb: + m2 += 1 + t, v, b = compute_triple_tvb(ctx, m2) + T.append(t) + V.append(v) + while b < 0: + m2 += 1 + t,v,b = compute_triple_tvb(ctx, m2) + T.append(t) + V.append(v) + goodpoints.append(m2) + zn = len(T)-1 + A, B, separated =\ + separate_zeros_in_block(ctx, zn, T, V, limitloop=ITERATION_LIMIT, + fp_tolerance=fp_tolerance) + Tf.pop() + Tf.extend(A) + Vf.pop() + Vf.extend(B) + if separated: + number_goodblocks += 1 + else: + number_goodblocks = 0 + T = [t] + V = [v] + # Now the same procedure to the left + number_goodblocks = 0 + m2 = n-2 + t, v, b = compute_triple_tvb(ctx, m2) + Tf.insert(0,t) + Vf.insert(0,v) + while b < 0: + m2 -= 1 + t,v,b = compute_triple_tvb(ctx, m2) + Tf.insert(0,t) + Vf.insert(0,v) + goodpoints.insert(0,m2) + T = [t] + V = [v] + while number_goodblocks < 2*sb: + m2 -= 1 + t, v, b = compute_triple_tvb(ctx, m2) + T.insert(0,t) + V.insert(0,v) + while b < 0: + m2 -= 1 + t,v,b = compute_triple_tvb(ctx, m2) + T.insert(0,t) + V.insert(0,v) + goodpoints.insert(0,m2) + zn = len(T)-1 + A, B, separated =\ + separate_zeros_in_block(ctx, zn, T, V, limitloop=ITERATION_LIMIT, fp_tolerance=fp_tolerance) + A.pop() + Tf = A+Tf + B.pop() + Vf = B+Vf + if separated: + number_goodblocks += 1 + else: + number_goodblocks = 0 + T = [t] + V = [v] + r = goodpoints[2*sb] + lg = len(goodpoints) + s = goodpoints[lg-2*sb-1] + tr, vr, br = compute_triple_tvb(ctx, r) + ar = Tf.index(tr) + ts, vs, bs = compute_triple_tvb(ctx, s) + as1 = Tf.index(ts) + T = Tf[ar:as1+1] + V = Vf[ar:as1+1] + zn = s-r + A, B, separated =\ + separate_zeros_in_block(ctx, zn,T,V,limitloop=ITERATION_LIMIT, fp_tolerance=fp_tolerance) + if separated: + return (n-r-1,[r,s],A,B) + q = goodpoints[sb] + lg = len(goodpoints) + t = goodpoints[lg-sb-1] + tq, vq, bq = compute_triple_tvb(ctx, q) + aq = Tf.index(tq) + tt, vt, bt = compute_triple_tvb(ctx, t) + at = Tf.index(tt) + T = Tf[aq:at+1] + V = Vf[aq:at+1] + return (n-q-1,[q,t],T,V) + +def count_variations(V): + count = 0 + vold = V[0] + for n in range(1, len(V)): + vnew = V[n] + if vold*vnew < 0: + count +=1 + vold = vnew + return count + +def pattern_construct(ctx, block, T, V): + pattern = '(' + a = block[0] + b = block[1] + t0,v0,b0 = compute_triple_tvb(ctx, a) + k = 0 + k0 = 0 + for n in range(a+1,b+1): + t1,v1,b1 = compute_triple_tvb(ctx, n) + lgT =len(T) + while (k < lgT) and (T[k] <= t1): + k += 1 + L = V[k0:k] + L.append(v1) + L.insert(0,v0) + count = count_variations(L) + pattern = pattern + ("%s" % count) + if b1 > 0: + pattern = pattern + ')(' + k0 = k + t0,v0,b0 = t1,v1,b1 + pattern = pattern[:-1] + return pattern + +@defun +def zetazero(ctx, n, info=False, round=True): + r""" + Computes the `n`-th nontrivial zero of `\zeta(s)` on the critical line, + i.e. returns an approximation of the `n`-th largest complex number + `s = \frac{1}{2} + ti` for which `\zeta(s) = 0`. Equivalently, the + imaginary part `t` is a zero of the Z-function (:func:`~mpmath.siegelz`). + + **Examples** + + The first few zeros:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> zetazero(1) + (0.5 + 14.13472514173469379045725j) + >>> zetazero(2) + (0.5 + 21.02203963877155499262848j) + >>> zetazero(20) + (0.5 + 77.14484006887480537268266j) + + Verifying that the values are zeros:: + + >>> for n in range(1,5): + ... s = zetazero(n) + ... chop(zeta(s)), chop(siegelz(s.imag)) + ... + (0.0, 0.0) + (0.0, 0.0) + (0.0, 0.0) + (0.0, 0.0) + + Negative indices give the conjugate zeros (`n = 0` is undefined):: + + >>> zetazero(-1) + (0.5 - 14.13472514173469379045725j) + + :func:`~mpmath.zetazero` supports arbitrarily large `n` and arbitrary precision:: + + >>> mp.dps = 15 + >>> zetazero(1234567) + (0.5 + 727690.906948208j) + >>> mp.dps = 50 + >>> zetazero(1234567) + (0.5 + 727690.9069482075392389420041147142092708393819935j) + >>> chop(zeta(_)/_) + 0.0 + + with *info=True*, :func:`~mpmath.zetazero` gives additional information:: + + >>> mp.dps = 15 + >>> zetazero(542964976,info=True) + ((0.5 + 209039046.578535j), [542964969, 542964978], 6, '(013111110)') + + This means that the zero is between Gram points 542964969 and 542964978; + it is the 6-th zero between them. Finally (01311110) is the pattern + of zeros in this interval. The numbers indicate the number of zeros + in each Gram interval (Rosser blocks between parenthesis). In this case + there is only one Rosser block of length nine. + """ + n = int(n) + if n < 0: + return ctx.zetazero(-n).conjugate() + if n == 0: + raise ValueError("n must be nonzero") + wpinitial = ctx.prec + try: + wpz, fp_tolerance = comp_fp_tolerance(ctx, n) + ctx.prec = wpz + if n < 400000000: + my_zero_number, block, T, V =\ + find_rosser_block_zero(ctx, n) + else: + my_zero_number, block, T, V =\ + search_supergood_block(ctx, n, fp_tolerance) + zero_number_block = block[1]-block[0] + T, V, separated = separate_zeros_in_block(ctx, zero_number_block, T, V, + limitloop=ctx.inf, fp_tolerance=fp_tolerance) + if info: + pattern = pattern_construct(ctx,block,T,V) + prec = max(wpinitial, wpz) + t = separate_my_zero(ctx, my_zero_number, zero_number_block,T,V,prec) + v = ctx.mpc(0.5,t) + finally: + ctx.prec = wpinitial + if round: + v =+v + if info: + return (v,block,my_zero_number,pattern) + else: + return v + +def gram_index(ctx, t): + if t > 10**13: + wp = 3*ctx.log(t, 10) + else: + wp = 0 + prec = ctx.prec + try: + ctx.prec += wp + h = int(ctx.siegeltheta(t)/ctx.pi) + finally: + ctx.prec = prec + return(h) + +def count_to(ctx, t, T, V): + count = 0 + vold = V[0] + told = T[0] + tnew = T[1] + k = 1 + while tnew < t: + vnew = V[k] + if vold*vnew < 0: + count += 1 + vold = vnew + k += 1 + tnew = T[k] + a = ctx.siegelz(t) + if a*vold < 0: + count += 1 + return count + +def comp_fp_tolerance(ctx, n): + wpz = wpzeros(n*ctx.log(n)) + if n < 15*10**8: + fp_tolerance = 0.0005 + elif n <= 10**14: + fp_tolerance = 0.1 + else: + fp_tolerance = 100 + return wpz, fp_tolerance + +@defun +def nzeros(ctx, t): + r""" + Computes the number of zeros of the Riemann zeta function in + `(0,1) \times (0,t]`, usually denoted by `N(t)`. + + **Examples** + + The first zero has imaginary part between 14 and 15:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> nzeros(14) + 0 + >>> nzeros(15) + 1 + >>> zetazero(1) + (0.5 + 14.1347251417347j) + + Some closely spaced zeros:: + + >>> nzeros(10**7) + 21136125 + >>> zetazero(21136125) + (0.5 + 9999999.32718175j) + >>> zetazero(21136126) + (0.5 + 10000000.2400236j) + >>> nzeros(545439823.215) + 1500000001 + >>> zetazero(1500000001) + (0.5 + 545439823.201985j) + >>> zetazero(1500000002) + (0.5 + 545439823.325697j) + + This confirms the data given by J. van de Lune, + H. J. J. te Riele and D. T. Winter in 1986. + """ + if t < 14.1347251417347: + return 0 + x = gram_index(ctx, t) + k = int(ctx.floor(x)) + wpinitial = ctx.prec + wpz, fp_tolerance = comp_fp_tolerance(ctx, k) + ctx.prec = wpz + a = ctx.siegelz(t) + if k == -1 and a < 0: + return 0 + elif k == -1 and a > 0: + return 1 + if k+2 < 400000000: + Rblock = find_rosser_block_zero(ctx, k+2) + else: + Rblock = search_supergood_block(ctx, k+2, fp_tolerance) + n1, n2 = Rblock[1] + if n2-n1 == 1: + b = Rblock[3][0] + if a*b > 0: + ctx.prec = wpinitial + return k+1 + else: + ctx.prec = wpinitial + return k+2 + my_zero_number,block, T, V = Rblock + zero_number_block = n2-n1 + T, V, separated = separate_zeros_in_block(ctx,\ + zero_number_block, T, V,\ + limitloop=ctx.inf,\ + fp_tolerance=fp_tolerance) + n = count_to(ctx, t, T, V) + ctx.prec = wpinitial + return n+n1+1 + +@defun_wrapped +def backlunds(ctx, t): + r""" + Computes the function + `S(t) = \operatorname{arg} \zeta(\frac{1}{2} + it) / \pi`. + + See Titchmarsh Section 9.3 for details of the definition. + + **Examples** + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> backlunds(217.3) + 0.16302205431184 + + Generally, the value is a small number. At Gram points it is an integer, + frequently equal to 0:: + + >>> chop(backlunds(grampoint(200))) + 0.0 + >>> backlunds(extraprec(10)(grampoint)(211)) + 1.0 + >>> backlunds(extraprec(10)(grampoint)(232)) + -1.0 + + The number of zeros of the Riemann zeta function up to height `t` + satisfies `N(t) = \theta(t)/\pi + 1 + S(t)` (see :func:nzeros` and + :func:`siegeltheta`):: + + >>> t = 1234.55 + >>> nzeros(t) + 842 + >>> siegeltheta(t)/pi+1+backlunds(t) + 842.0 + + """ + return ctx.nzeros(t)-1-ctx.siegeltheta(t)/ctx.pi + + +""" +_ROSSER_EXCEPTIONS is a list of all exceptions to +Rosser's rule for n <= 400 000 000. + +Alternately the entry is of type [n,m], or a string. +The string is the zero pattern of the Block and the relevant +adjacent. For example (010)3 corresponds to a block +composed of three Gram intervals, the first ant third without +a zero and the intermediate with a zero. The next Gram interval +contain three zeros. So that in total we have 4 zeros in 4 Gram +blocks. n and m are the indices of the Gram points of this +interval of four Gram intervals. The Rosser exception is therefore +formed by the three Gram intervals that are signaled between +parenthesis. + +We have included also some Rosser's exceptions beyond n=400 000 000 +that are noted in the literature by some reason. + +The list is composed from the data published in the references: + +R. P. Brent, J. van de Lune, H. J. J. te Riele, D. T. Winter, +'On the Zeros of the Riemann Zeta Function in the Critical Strip. II', +Math. Comp. 39 (1982) 681--688. +See also Corrigenda in Math. Comp. 46 (1986) 771. + +J. van de Lune, H. J. J. te Riele, +'On the Zeros of the Riemann Zeta Function in the Critical Strip. III', +Math. Comp. 41 (1983) 759--767. +See also Corrigenda in Math. Comp. 46 (1986) 771. + +J. van de Lune, +'Sums of Equal Powers of Positive Integers', +Dissertation, +Vrije Universiteit te Amsterdam, Centrum voor Wiskunde en Informatica, +Amsterdam, 1984. + +Thanks to the authors all this papers and those others that have +contributed to make this possible. +""" + + + + + + + +_ROSSER_EXCEPTIONS = \ +[[13999525, 13999528], '(00)3', +[30783329, 30783332], '(00)3', +[30930926, 30930929], '3(00)', +[37592215, 37592218], '(00)3', +[40870156, 40870159], '(00)3', +[43628107, 43628110], '(00)3', +[46082042, 46082045], '(00)3', +[46875667, 46875670], '(00)3', +[49624540, 49624543], '3(00)', +[50799238, 50799241], '(00)3', +[55221453, 55221456], '3(00)', +[56948779, 56948782], '3(00)', +[60515663, 60515666], '(00)3', +[61331766, 61331770], '(00)40', +[69784843, 69784846], '3(00)', +[75052114, 75052117], '(00)3', +[79545240, 79545243], '3(00)', +[79652247, 79652250], '3(00)', +[83088043, 83088046], '(00)3', +[83689522, 83689525], '3(00)', +[85348958, 85348961], '(00)3', +[86513820, 86513823], '(00)3', +[87947596, 87947599], '3(00)', +[88600095, 88600098], '(00)3', +[93681183, 93681186], '(00)3', +[100316551, 100316554], '3(00)', +[100788444, 100788447], '(00)3', +[106236172, 106236175], '(00)3', +[106941327, 106941330], '3(00)', +[107287955, 107287958], '(00)3', +[107532016, 107532019], '3(00)', +[110571044, 110571047], '(00)3', +[111885253, 111885256], '3(00)', +[113239783, 113239786], '(00)3', +[120159903, 120159906], '(00)3', +[121424391, 121424394], '3(00)', +[121692931, 121692934], '3(00)', +[121934170, 121934173], '3(00)', +[122612848, 122612851], '3(00)', +[126116567, 126116570], '(00)3', +[127936513, 127936516], '(00)3', +[128710277, 128710280], '3(00)', +[129398902, 129398905], '3(00)', +[130461096, 130461099], '3(00)', +[131331947, 131331950], '3(00)', +[137334071, 137334074], '3(00)', +[137832603, 137832606], '(00)3', +[138799471, 138799474], '3(00)', +[139027791, 139027794], '(00)3', +[141617806, 141617809], '(00)3', +[144454931, 144454934], '(00)3', +[145402379, 145402382], '3(00)', +[146130245, 146130248], '3(00)', +[147059770, 147059773], '(00)3', +[147896099, 147896102], '3(00)', +[151097113, 151097116], '(00)3', +[152539438, 152539441], '(00)3', +[152863168, 152863171], '3(00)', +[153522726, 153522729], '3(00)', +[155171524, 155171527], '3(00)', +[155366607, 155366610], '(00)3', +[157260686, 157260689], '3(00)', +[157269224, 157269227], '(00)3', +[157755123, 157755126], '(00)3', +[158298484, 158298487], '3(00)', +[160369050, 160369053], '3(00)', +[162962787, 162962790], '(00)3', +[163724709, 163724712], '(00)3', +[164198113, 164198116], '3(00)', +[164689301, 164689305], '(00)40', +[164880228, 164880231], '3(00)', +[166201932, 166201935], '(00)3', +[168573836, 168573839], '(00)3', +[169750763, 169750766], '(00)3', +[170375507, 170375510], '(00)3', +[170704879, 170704882], '3(00)', +[172000992, 172000995], '3(00)', +[173289941, 173289944], '(00)3', +[173737613, 173737616], '3(00)', +[174102513, 174102516], '(00)3', +[174284990, 174284993], '(00)3', +[174500513, 174500516], '(00)3', +[175710609, 175710612], '(00)3', +[176870843, 176870846], '3(00)', +[177332732, 177332735], '3(00)', +[177902861, 177902864], '3(00)', +[179979095, 179979098], '(00)3', +[181233726, 181233729], '3(00)', +[181625435, 181625438], '(00)3', +[182105255, 182105259], '22(00)', +[182223559, 182223562], '3(00)', +[191116404, 191116407], '3(00)', +[191165599, 191165602], '3(00)', +[191297535, 191297539], '(00)22', +[192485616, 192485619], '(00)3', +[193264634, 193264638], '22(00)', +[194696968, 194696971], '(00)3', +[195876805, 195876808], '(00)3', +[195916548, 195916551], '3(00)', +[196395160, 196395163], '3(00)', +[196676303, 196676306], '(00)3', +[197889882, 197889885], '3(00)', +[198014122, 198014125], '(00)3', +[199235289, 199235292], '(00)3', +[201007375, 201007378], '(00)3', +[201030605, 201030608], '3(00)', +[201184290, 201184293], '3(00)', +[201685414, 201685418], '(00)22', +[202762875, 202762878], '3(00)', +[202860957, 202860960], '3(00)', +[203832577, 203832580], '3(00)', +[205880544, 205880547], '(00)3', +[206357111, 206357114], '(00)3', +[207159767, 207159770], '3(00)', +[207167343, 207167346], '3(00)', +[207482539, 207482543], '3(010)', +[207669540, 207669543], '3(00)', +[208053426, 208053429], '(00)3', +[208110027, 208110030], '3(00)', +[209513826, 209513829], '3(00)', +[212623522, 212623525], '(00)3', +[213841715, 213841718], '(00)3', +[214012333, 214012336], '(00)3', +[214073567, 214073570], '(00)3', +[215170600, 215170603], '3(00)', +[215881039, 215881042], '3(00)', +[216274604, 216274607], '3(00)', +[216957120, 216957123], '3(00)', +[217323208, 217323211], '(00)3', +[218799264, 218799267], '(00)3', +[218803557, 218803560], '3(00)', +[219735146, 219735149], '(00)3', +[219830062, 219830065], '3(00)', +[219897904, 219897907], '(00)3', +[221205545, 221205548], '(00)3', +[223601929, 223601932], '(00)3', +[223907076, 223907079], '3(00)', +[223970397, 223970400], '(00)3', +[224874044, 224874048], '22(00)', +[225291157, 225291160], '(00)3', +[227481734, 227481737], '(00)3', +[228006442, 228006445], '3(00)', +[228357900, 228357903], '(00)3', +[228386399, 228386402], '(00)3', +[228907446, 228907449], '(00)3', +[228984552, 228984555], '3(00)', +[229140285, 229140288], '3(00)', +[231810024, 231810027], '(00)3', +[232838062, 232838065], '3(00)', +[234389088, 234389091], '3(00)', +[235588194, 235588197], '(00)3', +[236645695, 236645698], '(00)3', +[236962876, 236962879], '3(00)', +[237516723, 237516727], '04(00)', +[240004911, 240004914], '(00)3', +[240221306, 240221309], '3(00)', +[241389213, 241389217], '(010)3', +[241549003, 241549006], '(00)3', +[241729717, 241729720], '(00)3', +[241743684, 241743687], '3(00)', +[243780200, 243780203], '3(00)', +[243801317, 243801320], '(00)3', +[244122072, 244122075], '(00)3', +[244691224, 244691227], '3(00)', +[244841577, 244841580], '(00)3', +[245813461, 245813464], '(00)3', +[246299475, 246299478], '(00)3', +[246450176, 246450179], '3(00)', +[249069349, 249069352], '(00)3', +[250076378, 250076381], '(00)3', +[252442157, 252442160], '3(00)', +[252904231, 252904234], '3(00)', +[255145220, 255145223], '(00)3', +[255285971, 255285974], '3(00)', +[256713230, 256713233], '(00)3', +[257992082, 257992085], '(00)3', +[258447955, 258447959], '22(00)', +[259298045, 259298048], '3(00)', +[262141503, 262141506], '(00)3', +[263681743, 263681746], '3(00)', +[266527881, 266527885], '(010)3', +[266617122, 266617125], '(00)3', +[266628044, 266628047], '3(00)', +[267305763, 267305766], '(00)3', +[267388404, 267388407], '3(00)', +[267441672, 267441675], '3(00)', +[267464886, 267464889], '(00)3', +[267554907, 267554910], '3(00)', +[269787480, 269787483], '(00)3', +[270881434, 270881437], '(00)3', +[270997583, 270997586], '3(00)', +[272096378, 272096381], '3(00)', +[272583009, 272583012], '(00)3', +[274190881, 274190884], '3(00)', +[274268747, 274268750], '(00)3', +[275297429, 275297432], '3(00)', +[275545476, 275545479], '3(00)', +[275898479, 275898482], '3(00)', +[275953000, 275953003], '(00)3', +[277117197, 277117201], '(00)22', +[277447310, 277447313], '3(00)', +[279059657, 279059660], '3(00)', +[279259144, 279259147], '3(00)', +[279513636, 279513639], '3(00)', +[279849069, 279849072], '3(00)', +[280291419, 280291422], '(00)3', +[281449425, 281449428], '3(00)', +[281507953, 281507956], '3(00)', +[281825600, 281825603], '(00)3', +[282547093, 282547096], '3(00)', +[283120963, 283120966], '3(00)', +[283323493, 283323496], '(00)3', +[284764535, 284764538], '3(00)', +[286172639, 286172642], '3(00)', +[286688824, 286688827], '(00)3', +[287222172, 287222175], '3(00)', +[287235534, 287235537], '3(00)', +[287304861, 287304864], '3(00)', +[287433571, 287433574], '(00)3', +[287823551, 287823554], '(00)3', +[287872422, 287872425], '3(00)', +[288766615, 288766618], '3(00)', +[290122963, 290122966], '3(00)', +[290450849, 290450853], '(00)22', +[291426141, 291426144], '3(00)', +[292810353, 292810356], '3(00)', +[293109861, 293109864], '3(00)', +[293398054, 293398057], '3(00)', +[294134426, 294134429], '3(00)', +[294216438, 294216441], '(00)3', +[295367141, 295367144], '3(00)', +[297834111, 297834114], '3(00)', +[299099969, 299099972], '3(00)', +[300746958, 300746961], '3(00)', +[301097423, 301097426], '(00)3', +[301834209, 301834212], '(00)3', +[302554791, 302554794], '(00)3', +[303497445, 303497448], '3(00)', +[304165344, 304165347], '3(00)', +[304790218, 304790222], '3(010)', +[305302352, 305302355], '(00)3', +[306785996, 306785999], '3(00)', +[307051443, 307051446], '3(00)', +[307481539, 307481542], '3(00)', +[308605569, 308605572], '3(00)', +[309237610, 309237613], '3(00)', +[310509287, 310509290], '(00)3', +[310554057, 310554060], '3(00)', +[310646345, 310646348], '3(00)', +[311274896, 311274899], '(00)3', +[311894272, 311894275], '3(00)', +[312269470, 312269473], '(00)3', +[312306601, 312306605], '(00)40', +[312683193, 312683196], '3(00)', +[314499804, 314499807], '3(00)', +[314636802, 314636805], '(00)3', +[314689897, 314689900], '3(00)', +[314721319, 314721322], '3(00)', +[316132890, 316132893], '3(00)', +[316217470, 316217474], '(010)3', +[316465705, 316465708], '3(00)', +[316542790, 316542793], '(00)3', +[320822347, 320822350], '3(00)', +[321733242, 321733245], '3(00)', +[324413970, 324413973], '(00)3', +[325950140, 325950143], '(00)3', +[326675884, 326675887], '(00)3', +[326704208, 326704211], '3(00)', +[327596247, 327596250], '3(00)', +[328123172, 328123175], '3(00)', +[328182212, 328182215], '(00)3', +[328257498, 328257501], '3(00)', +[328315836, 328315839], '(00)3', +[328800974, 328800977], '(00)3', +[328998509, 328998512], '3(00)', +[329725370, 329725373], '(00)3', +[332080601, 332080604], '(00)3', +[332221246, 332221249], '(00)3', +[332299899, 332299902], '(00)3', +[332532822, 332532825], '(00)3', +[333334544, 333334548], '(00)22', +[333881266, 333881269], '3(00)', +[334703267, 334703270], '3(00)', +[334875138, 334875141], '3(00)', +[336531451, 336531454], '3(00)', +[336825907, 336825910], '(00)3', +[336993167, 336993170], '(00)3', +[337493998, 337494001], '3(00)', +[337861034, 337861037], '3(00)', +[337899191, 337899194], '(00)3', +[337958123, 337958126], '(00)3', +[342331982, 342331985], '3(00)', +[342676068, 342676071], '3(00)', +[347063781, 347063784], '3(00)', +[347697348, 347697351], '3(00)', +[347954319, 347954322], '3(00)', +[348162775, 348162778], '3(00)', +[349210702, 349210705], '(00)3', +[349212913, 349212916], '3(00)', +[349248650, 349248653], '(00)3', +[349913500, 349913503], '3(00)', +[350891529, 350891532], '3(00)', +[351089323, 351089326], '3(00)', +[351826158, 351826161], '3(00)', +[352228580, 352228583], '(00)3', +[352376244, 352376247], '3(00)', +[352853758, 352853761], '(00)3', +[355110439, 355110442], '(00)3', +[355808090, 355808094], '(00)40', +[355941556, 355941559], '3(00)', +[356360231, 356360234], '(00)3', +[356586657, 356586660], '3(00)', +[356892926, 356892929], '(00)3', +[356908232, 356908235], '3(00)', +[357912730, 357912733], '3(00)', +[358120344, 358120347], '3(00)', +[359044096, 359044099], '(00)3', +[360819357, 360819360], '3(00)', +[361399662, 361399666], '(010)3', +[362361315, 362361318], '(00)3', +[363610112, 363610115], '(00)3', +[363964804, 363964807], '3(00)', +[364527375, 364527378], '(00)3', +[365090327, 365090330], '(00)3', +[365414539, 365414542], '3(00)', +[366738474, 366738477], '3(00)', +[368714778, 368714783], '04(010)', +[368831545, 368831548], '(00)3', +[368902387, 368902390], '(00)3', +[370109769, 370109772], '3(00)', +[370963333, 370963336], '3(00)', +[372541136, 372541140], '3(010)', +[372681562, 372681565], '(00)3', +[373009410, 373009413], '(00)3', +[373458970, 373458973], '3(00)', +[375648658, 375648661], '3(00)', +[376834728, 376834731], '3(00)', +[377119945, 377119948], '(00)3', +[377335703, 377335706], '(00)3', +[378091745, 378091748], '3(00)', +[379139522, 379139525], '3(00)', +[380279160, 380279163], '(00)3', +[380619442, 380619445], '3(00)', +[381244231, 381244234], '3(00)', +[382327446, 382327450], '(010)3', +[382357073, 382357076], '3(00)', +[383545479, 383545482], '3(00)', +[384363766, 384363769], '(00)3', +[384401786, 384401790], '22(00)', +[385198212, 385198215], '3(00)', +[385824476, 385824479], '(00)3', +[385908194, 385908197], '3(00)', +[386946806, 386946809], '3(00)', +[387592175, 387592179], '22(00)', +[388329293, 388329296], '(00)3', +[388679566, 388679569], '3(00)', +[388832142, 388832145], '3(00)', +[390087103, 390087106], '(00)3', +[390190926, 390190930], '(00)22', +[390331207, 390331210], '3(00)', +[391674495, 391674498], '3(00)', +[391937831, 391937834], '3(00)', +[391951632, 391951636], '(00)22', +[392963986, 392963989], '(00)3', +[393007921, 393007924], '3(00)', +[393373210, 393373213], '3(00)', +[393759572, 393759575], '(00)3', +[394036662, 394036665], '(00)3', +[395813866, 395813869], '(00)3', +[395956690, 395956693], '3(00)', +[396031670, 396031673], '3(00)', +[397076433, 397076436], '3(00)', +[397470601, 397470604], '3(00)', +[398289458, 398289461], '3(00)', +# +[368714778, 368714783], '04(010)', +[437953499, 437953504], '04(010)', +[526196233, 526196238], '032(00)', +[744719566, 744719571], '(010)40', +[750375857, 750375862], '032(00)', +[958241932, 958241937], '04(010)', +[983377342, 983377347], '(00)410', +[1003780080, 1003780085], '04(010)', +[1070232754, 1070232759], '(00)230', +[1209834865, 1209834870], '032(00)', +[1257209100, 1257209105], '(00)410', +[1368002233, 1368002238], '(00)230' +] diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1573114afc4fbce73f2ba9d2ddc99882c00027c0 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/__init__.py @@ -0,0 +1,77 @@ +from .libmpf import (prec_to_dps, dps_to_prec, repr_dps, + round_down, round_up, round_floor, round_ceiling, round_nearest, + to_pickable, from_pickable, ComplexResult, + fzero, fnzero, fone, fnone, ftwo, ften, fhalf, fnan, finf, fninf, + math_float_inf, round_int, normalize, normalize1, + from_man_exp, from_int, to_man_exp, to_int, mpf_ceil, mpf_floor, + mpf_nint, mpf_frac, + from_float, from_npfloat, from_Decimal, to_float, from_rational, to_rational, to_fixed, + mpf_rand, mpf_eq, mpf_hash, mpf_cmp, mpf_lt, mpf_le, mpf_gt, mpf_ge, + mpf_pos, mpf_neg, mpf_abs, mpf_sign, mpf_add, mpf_sub, mpf_sum, + mpf_mul, mpf_mul_int, mpf_shift, mpf_frexp, + mpf_div, mpf_rdiv_int, mpf_mod, mpf_pow_int, + mpf_perturb, + to_digits_exp, to_str, str_to_man_exp, from_str, from_bstr, to_bstr, + mpf_sqrt, mpf_hypot) + +from .libmpc import (mpc_one, mpc_zero, mpc_two, mpc_half, + mpc_is_inf, mpc_is_infnan, mpc_to_str, mpc_to_complex, mpc_hash, + mpc_conjugate, mpc_is_nonzero, mpc_add, mpc_add_mpf, + mpc_sub, mpc_sub_mpf, mpc_pos, mpc_neg, mpc_shift, mpc_abs, + mpc_arg, mpc_floor, mpc_ceil, mpc_nint, mpc_frac, mpc_mul, mpc_square, + mpc_mul_mpf, mpc_mul_imag_mpf, mpc_mul_int, + mpc_div, mpc_div_mpf, mpc_reciprocal, mpc_mpf_div, + complex_int_pow, mpc_pow, mpc_pow_mpf, mpc_pow_int, + mpc_sqrt, mpc_nthroot, mpc_cbrt, mpc_exp, mpc_log, mpc_cos, mpc_sin, + mpc_tan, mpc_cos_pi, mpc_sin_pi, mpc_cosh, mpc_sinh, mpc_tanh, + mpc_atan, mpc_acos, mpc_asin, mpc_asinh, mpc_acosh, mpc_atanh, + mpc_fibonacci, mpf_expj, mpf_expjpi, mpc_expj, mpc_expjpi, + mpc_cos_sin, mpc_cos_sin_pi) + +from .libelefun import (ln2_fixed, mpf_ln2, ln10_fixed, mpf_ln10, + pi_fixed, mpf_pi, e_fixed, mpf_e, phi_fixed, mpf_phi, + degree_fixed, mpf_degree, + mpf_pow, mpf_nthroot, mpf_cbrt, log_int_fixed, agm_fixed, + mpf_log, mpf_log_hypot, mpf_exp, mpf_cos_sin, mpf_cos, mpf_sin, mpf_tan, + mpf_cos_sin_pi, mpf_cos_pi, mpf_sin_pi, mpf_cosh_sinh, + mpf_cosh, mpf_sinh, mpf_tanh, mpf_atan, mpf_atan2, mpf_asin, + mpf_acos, mpf_asinh, mpf_acosh, mpf_atanh, mpf_fibonacci) + +from .libhyper import (NoConvergence, make_hyp_summator, + mpf_erf, mpf_erfc, mpf_ei, mpc_ei, mpf_e1, mpc_e1, mpf_expint, + mpf_ci_si, mpf_ci, mpf_si, mpc_ci, mpc_si, mpf_besseljn, + mpc_besseljn, mpf_agm, mpf_agm1, mpc_agm, mpc_agm1, + mpf_ellipk, mpc_ellipk, mpf_ellipe, mpc_ellipe) + +from .gammazeta import (catalan_fixed, mpf_catalan, + khinchin_fixed, mpf_khinchin, glaisher_fixed, mpf_glaisher, + apery_fixed, mpf_apery, euler_fixed, mpf_euler, mertens_fixed, + mpf_mertens, twinprime_fixed, mpf_twinprime, + mpf_bernoulli, bernfrac, mpf_gamma_int, + mpf_factorial, mpc_factorial, mpf_gamma, mpc_gamma, + mpf_loggamma, mpc_loggamma, mpf_rgamma, mpc_rgamma, + mpf_harmonic, mpc_harmonic, mpf_psi0, mpc_psi0, + mpf_psi, mpc_psi, mpf_zeta_int, mpf_zeta, mpc_zeta, + mpf_altzeta, mpc_altzeta, mpf_zetasum, mpc_zetasum) + +from .libmpi import (mpi_str, + mpi_from_str, mpi_to_str, + mpi_eq, mpi_ne, + mpi_lt, mpi_le, mpi_gt, mpi_ge, + mpi_add, mpi_sub, mpi_delta, mpi_mid, + mpi_pos, mpi_neg, mpi_abs, mpi_mul, mpi_div, mpi_exp, + mpi_log, mpi_sqrt, mpi_pow_int, mpi_pow, mpi_cos_sin, + mpi_cos, mpi_sin, mpi_tan, mpi_cot, + mpi_atan, mpi_atan2, + mpci_pos, mpci_neg, mpci_add, mpci_sub, mpci_mul, mpci_div, mpci_pow, + mpci_abs, mpci_pow, mpci_exp, mpci_log, mpci_cos, mpci_sin, + mpi_gamma, mpci_gamma, mpi_loggamma, mpci_loggamma, + mpi_rgamma, mpci_rgamma, mpi_factorial, mpci_factorial) + +from .libintmath import (trailing, bitcount, numeral, bin_to_radix, + isqrt, isqrt_small, isqrt_fast, sqrt_fixed, sqrtrem, ifib, ifac, + list_primes, isprime, moebius, gcd, eulernum, stirling1, stirling2) + +from .backend import (gmpy, sage, BACKEND, STRICT, MPZ, MPZ_TYPE, + MPZ_ZERO, MPZ_ONE, MPZ_TWO, MPZ_THREE, MPZ_FIVE, int_types, + HASH_MODULUS, HASH_BITS) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/backend.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/backend.py new file mode 100644 index 0000000000000000000000000000000000000000..5610221290a05078f21f09df3c1a76b0e4ccdc02 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/backend.py @@ -0,0 +1,115 @@ +import os +import sys + +#----------------------------------------------------------------------------# +# Support GMPY for high-speed large integer arithmetic. # +# # +# To allow an external module to handle arithmetic, we need to make sure # +# that all high-precision variables are declared of the correct type. MPZ # +# is the constructor for the high-precision type. It defaults to Python's # +# long type but can be assinged another type, typically gmpy.mpz. # +# # +# MPZ must be used for the mantissa component of an mpf and must be used # +# for internal fixed-point operations. # +# # +# Side-effects # +# 1) "is" cannot be used to test for special values. Must use "==". # +# 2) There are bugs in GMPY prior to v1.02 so we must use v1.03 or later. # +#----------------------------------------------------------------------------# + +# So we can import it from this module +gmpy = None +sage = None +sage_utils = None + +if sys.version_info[0] < 3: + python3 = False +else: + python3 = True + +BACKEND = 'python' + +if not python3: + MPZ = long + xrange = xrange + basestring = basestring + + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") +else: + MPZ = int + xrange = range + basestring = str + + import builtins + exec_ = getattr(builtins, "exec") + +# Define constants for calculating hash on Python 3.2. +if sys.version_info >= (3, 2): + HASH_MODULUS = sys.hash_info.modulus + if sys.hash_info.width == 32: + HASH_BITS = 31 + else: + HASH_BITS = 61 +else: + HASH_MODULUS = None + HASH_BITS = None + +if 'MPMATH_NOGMPY' not in os.environ: + try: + try: + import gmpy2 as gmpy + except ImportError: + try: + import gmpy + except ImportError: + raise ImportError + if gmpy.version() >= '1.03': + BACKEND = 'gmpy' + MPZ = gmpy.mpz + except: + pass + +if ('MPMATH_NOSAGE' not in os.environ and 'SAGE_ROOT' in os.environ or + 'MPMATH_SAGE' in os.environ): + try: + import sage.all + import sage.libs.mpmath.utils as _sage_utils + sage = sage.all + sage_utils = _sage_utils + BACKEND = 'sage' + MPZ = sage.Integer + except: + pass + +if 'MPMATH_STRICT' in os.environ: + STRICT = True +else: + STRICT = False + +MPZ_TYPE = type(MPZ(0)) +MPZ_ZERO = MPZ(0) +MPZ_ONE = MPZ(1) +MPZ_TWO = MPZ(2) +MPZ_THREE = MPZ(3) +MPZ_FIVE = MPZ(5) + +try: + if BACKEND == 'python': + int_types = (int, long) + else: + int_types = (int, long, MPZ_TYPE) +except NameError: + if BACKEND == 'python': + int_types = (int,) + else: + int_types = (int, MPZ_TYPE) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/gammazeta.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/gammazeta.py new file mode 100644 index 0000000000000000000000000000000000000000..3b05cc63c5f00e6c76d8383853dba06f15e46030 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/gammazeta.py @@ -0,0 +1,2167 @@ +""" +----------------------------------------------------------------------- +This module implements gamma- and zeta-related functions: + +* Bernoulli numbers +* Factorials +* The gamma function +* Polygamma functions +* Harmonic numbers +* The Riemann zeta function +* Constants related to these functions + +----------------------------------------------------------------------- +""" + +import math +import sys + +from .backend import xrange +from .backend import MPZ, MPZ_ZERO, MPZ_ONE, MPZ_THREE, gmpy + +from .libintmath import list_primes, ifac, ifac2, moebius + +from .libmpf import (\ + round_floor, round_ceiling, round_down, round_up, + round_nearest, round_fast, + lshift, sqrt_fixed, isqrt_fast, + fzero, fone, fnone, fhalf, ftwo, finf, fninf, fnan, + from_int, to_int, to_fixed, from_man_exp, from_rational, + mpf_pos, mpf_neg, mpf_abs, mpf_add, mpf_sub, + mpf_mul, mpf_mul_int, mpf_div, mpf_sqrt, mpf_pow_int, + mpf_rdiv_int, + mpf_perturb, mpf_le, mpf_lt, mpf_gt, mpf_shift, + negative_rnd, reciprocal_rnd, + bitcount, to_float, mpf_floor, mpf_sign, ComplexResult +) + +from .libelefun import (\ + constant_memo, + def_mpf_constant, + mpf_pi, pi_fixed, ln2_fixed, log_int_fixed, mpf_ln2, + mpf_exp, mpf_log, mpf_pow, mpf_cosh, + mpf_cos_sin, mpf_cosh_sinh, mpf_cos_sin_pi, mpf_cos_pi, mpf_sin_pi, + ln_sqrt2pi_fixed, mpf_ln_sqrt2pi, sqrtpi_fixed, mpf_sqrtpi, + cos_sin_fixed, exp_fixed +) + +from .libmpc import (\ + mpc_zero, mpc_one, mpc_half, mpc_two, + mpc_abs, mpc_shift, mpc_pos, mpc_neg, + mpc_add, mpc_sub, mpc_mul, mpc_div, + mpc_add_mpf, mpc_mul_mpf, mpc_div_mpf, mpc_mpf_div, + mpc_mul_int, mpc_pow_int, + mpc_log, mpc_exp, mpc_pow, + mpc_cos_pi, mpc_sin_pi, + mpc_reciprocal, mpc_square, + mpc_sub_mpf +) + + + +# Catalan's constant is computed using Lupas's rapidly convergent series +# (listed on http://mathworld.wolfram.com/CatalansConstant.html) +# oo +# ___ n-1 8n 2 3 2 +# 1 \ (-1) 2 (40n - 24n + 3) [(2n)!] (n!) +# K = --- ) ----------------------------------------- +# 64 /___ 3 2 +# n (2n-1) [(4n)!] +# n = 1 + +@constant_memo +def catalan_fixed(prec): + prec = prec + 20 + a = one = MPZ_ONE << prec + s, t, n = 0, 1, 1 + while t: + a *= 32 * n**3 * (2*n-1) + a //= (3-16*n+16*n**2)**2 + t = a * (-1)**(n-1) * (40*n**2-24*n+3) // (n**3 * (2*n-1)) + s += t + n += 1 + return s >> (20 + 6) + +# Khinchin's constant is relatively difficult to compute. Here +# we use the rational zeta series + +# oo 2*n-1 +# ___ ___ +# \ ` zeta(2*n)-1 \ ` (-1)^(k+1) +# log(K)*log(2) = ) ------------ ) ---------- +# /___. n /___. k +# n = 1 k = 1 + +# which adds half a digit per term. The essential trick for achieving +# reasonable efficiency is to recycle both the values of the zeta +# function (essentially Bernoulli numbers) and the partial terms of +# the inner sum. + +# An alternative might be to use K = 2*exp[1/log(2) X] where + +# / 1 1 [ pi*x*(1-x^2) ] +# X = | ------ log [ ------------ ]. +# / 0 x(1+x) [ sin(pi*x) ] + +# and integrate numerically. In practice, this seems to be slightly +# slower than the zeta series at high precision. + +@constant_memo +def khinchin_fixed(prec): + wp = int(prec + prec**0.5 + 15) + s = MPZ_ZERO + fac = from_int(4) + t = ONE = MPZ_ONE << wp + pi = mpf_pi(wp) + pipow = twopi2 = mpf_shift(mpf_mul(pi, pi, wp), 2) + n = 1 + while 1: + zeta2n = mpf_abs(mpf_bernoulli(2*n, wp)) + zeta2n = mpf_mul(zeta2n, pipow, wp) + zeta2n = mpf_div(zeta2n, fac, wp) + zeta2n = to_fixed(zeta2n, wp) + term = (((zeta2n - ONE) * t) // n) >> wp + if term < 100: + break + #if not n % 10: + # print n, math.log(int(abs(term))) + s += term + t += ONE//(2*n+1) - ONE//(2*n) + n += 1 + fac = mpf_mul_int(fac, (2*n)*(2*n-1), wp) + pipow = mpf_mul(pipow, twopi2, wp) + s = (s << wp) // ln2_fixed(wp) + K = mpf_exp(from_man_exp(s, -wp), wp) + K = to_fixed(K, prec) + return K + + +# Glaisher's constant is defined as A = exp(1/2 - zeta'(-1)). +# One way to compute it would be to perform direct numerical +# differentiation, but computing arbitrary Riemann zeta function +# values at high precision is expensive. We instead use the formula + +# A = exp((6 (-zeta'(2))/pi^2 + log 2 pi + gamma)/12) + +# and compute zeta'(2) from the series representation + +# oo +# ___ +# \ log k +# -zeta'(2) = ) ----- +# /___ 2 +# k +# k = 2 + +# This series converges exceptionally slowly, but can be accelerated +# using Euler-Maclaurin formula. The important insight is that the +# E-M integral can be done in closed form and that the high order +# are given by + +# n / \ +# d | log x | a + b log x +# --- | ----- | = ----------- +# n | 2 | 2 + n +# dx \ x / x + +# where a and b are integers given by a simple recurrence. Note +# that just one logarithm is needed. However, lots of integer +# logarithms are required for the initial summation. + +# This algorithm could possibly be turned into a faster algorithm +# for general evaluation of zeta(s) or zeta'(s); this should be +# looked into. + +@constant_memo +def glaisher_fixed(prec): + wp = prec + 30 + # Number of direct terms to sum before applying the Euler-Maclaurin + # formula to the tail. TODO: choose more intelligently + N = int(0.33*prec + 5) + ONE = MPZ_ONE << wp + # Euler-Maclaurin, step 1: sum log(k)/k**2 for k from 2 to N-1 + s = MPZ_ZERO + for k in range(2, N): + #print k, N + s += log_int_fixed(k, wp) // k**2 + logN = log_int_fixed(N, wp) + #logN = to_fixed(mpf_log(from_int(N), wp+20), wp) + # E-M step 2: integral of log(x)/x**2 from N to inf + s += (ONE + logN) // N + # E-M step 3: endpoint correction term f(N)/2 + s += logN // (N**2 * 2) + # E-M step 4: the series of derivatives + pN = N**3 + a = 1 + b = -2 + j = 3 + fac = from_int(2) + k = 1 + while 1: + # D(2*k-1) * B(2*k) / fac(2*k) [D(n) = nth derivative] + D = ((a << wp) + b*logN) // pN + D = from_man_exp(D, -wp) + B = mpf_bernoulli(2*k, wp) + term = mpf_mul(B, D, wp) + term = mpf_div(term, fac, wp) + term = to_fixed(term, wp) + if abs(term) < 100: + break + #if not k % 10: + # print k, math.log(int(abs(term)), 10) + s -= term + # Advance derivative twice + a, b, pN, j = b-a*j, -j*b, pN*N, j+1 + a, b, pN, j = b-a*j, -j*b, pN*N, j+1 + k += 1 + fac = mpf_mul_int(fac, (2*k)*(2*k-1), wp) + # A = exp((6*s/pi**2 + log(2*pi) + euler)/12) + pi = pi_fixed(wp) + s *= 6 + s = (s << wp) // (pi**2 >> wp) + s += euler_fixed(wp) + s += to_fixed(mpf_log(from_man_exp(2*pi, -wp), wp), wp) + s //= 12 + A = mpf_exp(from_man_exp(s, -wp), wp) + return to_fixed(A, prec) + +# Apery's constant can be computed using the very rapidly convergent +# series +# oo +# ___ 2 10 +# \ n 205 n + 250 n + 77 (n!) +# zeta(3) = ) (-1) ------------------- ---------- +# /___ 64 5 +# n = 0 ((2n+1)!) + +@constant_memo +def apery_fixed(prec): + prec += 20 + d = MPZ_ONE << prec + term = MPZ(77) << prec + n = 1 + s = MPZ_ZERO + while term: + s += term + d *= (n**10) + d //= (((2*n+1)**5) * (2*n)**5) + term = (-1)**n * (205*(n**2) + 250*n + 77) * d + n += 1 + return s >> (20 + 6) + +""" +Euler's constant (gamma) is computed using the Brent-McMillan formula, +gamma ~= I(n)/J(n) - log(n), where + + I(n) = sum_{k=0,1,2,...} (n**k / k!)**2 * H(k) + J(n) = sum_{k=0,1,2,...} (n**k / k!)**2 + H(k) = 1 + 1/2 + 1/3 + ... + 1/k + +The error is bounded by O(exp(-4n)). Choosing n to be a power +of two, 2**p, the logarithm becomes particularly easy to calculate.[1] + +We use the formulation of Algorithm 3.9 in [2] to make the summation +more efficient. + +Reference: +[1] Xavier Gourdon & Pascal Sebah, The Euler constant: gamma +http://numbers.computation.free.fr/Constants/Gamma/gamma.pdf + +[2] [BorweinBailey]_ +""" + +@constant_memo +def euler_fixed(prec): + extra = 30 + prec += extra + # choose p such that exp(-4*(2**p)) < 2**-n + p = int(math.log((prec/4) * math.log(2), 2)) + 1 + n = 2**p + A = U = -p*ln2_fixed(prec) + B = V = MPZ_ONE << prec + k = 1 + while 1: + B = B*n**2//k**2 + A = (A*n**2//k + B)//k + U += A + V += B + if max(abs(A), abs(B)) < 100: + break + k += 1 + return (U<<(prec-extra))//V + +# Use zeta accelerated formulas for the Mertens and twin +# prime constants; see +# http://mathworld.wolfram.com/MertensConstant.html +# http://mathworld.wolfram.com/TwinPrimesConstant.html + +@constant_memo +def mertens_fixed(prec): + wp = prec + 20 + m = 2 + s = mpf_euler(wp) + while 1: + t = mpf_zeta_int(m, wp) + if t == fone: + break + t = mpf_log(t, wp) + t = mpf_mul_int(t, moebius(m), wp) + t = mpf_div(t, from_int(m), wp) + s = mpf_add(s, t) + m += 1 + return to_fixed(s, prec) + +@constant_memo +def twinprime_fixed(prec): + def I(n): + return sum(moebius(d)<<(n//d) for d in xrange(1,n+1) if not n%d)//n + wp = 2*prec + 30 + res = fone + primes = [from_rational(1,p,wp) for p in [2,3,5,7]] + ppowers = [mpf_mul(p,p,wp) for p in primes] + n = 2 + while 1: + a = mpf_zeta_int(n, wp) + for i in range(4): + a = mpf_mul(a, mpf_sub(fone, ppowers[i]), wp) + ppowers[i] = mpf_mul(ppowers[i], primes[i], wp) + a = mpf_pow_int(a, -I(n), wp) + if mpf_pos(a, prec+10, 'n') == fone: + break + #from libmpf import to_str + #print n, to_str(mpf_sub(fone, a), 6) + res = mpf_mul(res, a, wp) + n += 1 + res = mpf_mul(res, from_int(3*15*35), wp) + res = mpf_div(res, from_int(4*16*36), wp) + return to_fixed(res, prec) + + +mpf_euler = def_mpf_constant(euler_fixed) +mpf_apery = def_mpf_constant(apery_fixed) +mpf_khinchin = def_mpf_constant(khinchin_fixed) +mpf_glaisher = def_mpf_constant(glaisher_fixed) +mpf_catalan = def_mpf_constant(catalan_fixed) +mpf_mertens = def_mpf_constant(mertens_fixed) +mpf_twinprime = def_mpf_constant(twinprime_fixed) + + +#-----------------------------------------------------------------------# +# # +# Bernoulli numbers # +# # +#-----------------------------------------------------------------------# + +MAX_BERNOULLI_CACHE = 3000 + + +r""" +Small Bernoulli numbers and factorials are used in numerous summations, +so it is critical for speed that sequential computation is fast and that +values are cached up to a fairly high threshold. + +On the other hand, we also want to support fast computation of isolated +large numbers. Currently, no such acceleration is provided for integer +factorials (though it is for large floating-point factorials, which are +computed via gamma if the precision is low enough). + +For sequential computation of Bernoulli numbers, we use Ramanujan's formula + + / n + 3 \ + B = (A(n) - S(n)) / | | + n \ n / + +where A(n) = (n+3)/3 when n = 0 or 2 (mod 6), A(n) = -(n+3)/6 +when n = 4 (mod 6), and + + [n/6] + ___ + \ / n + 3 \ + S(n) = ) | | * B + /___ \ n - 6*k / n-6*k + k = 1 + +For isolated large Bernoulli numbers, we use the Riemann zeta function +to calculate a numerical value for B_n. The von Staudt-Clausen theorem +can then be used to optionally find the exact value of the +numerator and denominator. +""" + +bernoulli_cache = {} +f3 = from_int(3) +f6 = from_int(6) + +def bernoulli_size(n): + """Accurately estimate the size of B_n (even n > 2 only)""" + lgn = math.log(n,2) + return int(2.326 + 0.5*lgn + n*(lgn - 4.094)) + +BERNOULLI_PREC_CUTOFF = bernoulli_size(MAX_BERNOULLI_CACHE) + +def mpf_bernoulli(n, prec, rnd=None): + """Computation of Bernoulli numbers (numerically)""" + if n < 2: + if n < 0: + raise ValueError("Bernoulli numbers only defined for n >= 0") + if n == 0: + return fone + if n == 1: + return mpf_neg(fhalf) + # For odd n > 1, the Bernoulli numbers are zero + if n & 1: + return fzero + # If precision is extremely high, we can save time by computing + # the Bernoulli number at a lower precision that is sufficient to + # obtain the exact fraction, round to the exact fraction, and + # convert the fraction back to an mpf value at the original precision + if prec > BERNOULLI_PREC_CUTOFF and prec > bernoulli_size(n)*1.1 + 1000: + p, q = bernfrac(n) + return from_rational(p, q, prec, rnd or round_floor) + if n > MAX_BERNOULLI_CACHE: + return mpf_bernoulli_huge(n, prec, rnd) + wp = prec + 30 + # Reuse nearby precisions + wp += 32 - (prec & 31) + cached = bernoulli_cache.get(wp) + if cached: + numbers, state = cached + if n in numbers: + if not rnd: + return numbers[n] + return mpf_pos(numbers[n], prec, rnd) + m, bin, bin1 = state + if n - m > 10: + return mpf_bernoulli_huge(n, prec, rnd) + else: + if n > 10: + return mpf_bernoulli_huge(n, prec, rnd) + numbers = {0:fone} + m, bin, bin1 = state = [2, MPZ(10), MPZ_ONE] + bernoulli_cache[wp] = (numbers, state) + while m <= n: + #print m + case = m % 6 + # Accurately estimate size of B_m so we can use + # fixed point math without using too much precision + szbm = bernoulli_size(m) + s = 0 + sexp = max(0, szbm) - wp + if m < 6: + a = MPZ_ZERO + else: + a = bin1 + for j in xrange(1, m//6+1): + usign, uman, uexp, ubc = u = numbers[m-6*j] + if usign: + uman = -uman + s += lshift(a*uman, uexp-sexp) + # Update inner binomial coefficient + j6 = 6*j + a *= ((m-5-j6)*(m-4-j6)*(m-3-j6)*(m-2-j6)*(m-1-j6)*(m-j6)) + a //= ((4+j6)*(5+j6)*(6+j6)*(7+j6)*(8+j6)*(9+j6)) + if case == 0: b = mpf_rdiv_int(m+3, f3, wp) + if case == 2: b = mpf_rdiv_int(m+3, f3, wp) + if case == 4: b = mpf_rdiv_int(-m-3, f6, wp) + s = from_man_exp(s, sexp, wp) + b = mpf_div(mpf_sub(b, s, wp), from_int(bin), wp) + numbers[m] = b + m += 2 + # Update outer binomial coefficient + bin = bin * ((m+2)*(m+3)) // (m*(m-1)) + if m > 6: + bin1 = bin1 * ((2+m)*(3+m)) // ((m-7)*(m-6)) + state[:] = [m, bin, bin1] + return numbers[n] + +def mpf_bernoulli_huge(n, prec, rnd=None): + wp = prec + 10 + piprec = wp + int(math.log(n,2)) + v = mpf_gamma_int(n+1, wp) + v = mpf_mul(v, mpf_zeta_int(n, wp), wp) + v = mpf_mul(v, mpf_pow_int(mpf_pi(piprec), -n, wp)) + v = mpf_shift(v, 1-n) + if not n & 3: + v = mpf_neg(v) + return mpf_pos(v, prec, rnd or round_fast) + +def bernfrac(n): + r""" + Returns a tuple of integers `(p, q)` such that `p/q = B_n` exactly, + where `B_n` denotes the `n`-th Bernoulli number. The fraction is + always reduced to lowest terms. Note that for `n > 1` and `n` odd, + `B_n = 0`, and `(0, 1)` is returned. + + **Examples** + + The first few Bernoulli numbers are exactly:: + + >>> from mpmath import * + >>> for n in range(15): + ... p, q = bernfrac(n) + ... print("%s %s/%s" % (n, p, q)) + ... + 0 1/1 + 1 -1/2 + 2 1/6 + 3 0/1 + 4 -1/30 + 5 0/1 + 6 1/42 + 7 0/1 + 8 -1/30 + 9 0/1 + 10 5/66 + 11 0/1 + 12 -691/2730 + 13 0/1 + 14 7/6 + + This function works for arbitrarily large `n`:: + + >>> p, q = bernfrac(10**4) + >>> print(q) + 2338224387510 + >>> print(len(str(p))) + 27692 + >>> mp.dps = 15 + >>> print(mpf(p) / q) + -9.04942396360948e+27677 + >>> print(bernoulli(10**4)) + -9.04942396360948e+27677 + + .. note :: + + :func:`~mpmath.bernoulli` computes a floating-point approximation + directly, without computing the exact fraction first. + This is much faster for large `n`. + + **Algorithm** + + :func:`~mpmath.bernfrac` works by computing the value of `B_n` numerically + and then using the von Staudt-Clausen theorem [1] to reconstruct + the exact fraction. For large `n`, this is significantly faster than + computing `B_1, B_2, \ldots, B_2` recursively with exact arithmetic. + The implementation has been tested for `n = 10^m` up to `m = 6`. + + In practice, :func:`~mpmath.bernfrac` appears to be about three times + slower than the specialized program calcbn.exe [2] + + **References** + + 1. MathWorld, von Staudt-Clausen Theorem: + http://mathworld.wolfram.com/vonStaudt-ClausenTheorem.html + + 2. The Bernoulli Number Page: + http://www.bernoulli.org/ + + """ + n = int(n) + if n < 3: + return [(1, 1), (-1, 2), (1, 6)][n] + if n & 1: + return (0, 1) + q = 1 + for k in list_primes(n+1): + if not (n % (k-1)): + q *= k + prec = bernoulli_size(n) + int(math.log(q,2)) + 20 + b = mpf_bernoulli(n, prec) + p = mpf_mul(b, from_int(q)) + pint = to_int(p, round_nearest) + return (pint, q) + + +#-----------------------------------------------------------------------# +# # +# Polygamma functions # +# # +#-----------------------------------------------------------------------# + +r""" +For all polygamma (psi) functions, we use the Euler-Maclaurin summation +formula. It looks slightly different in the m = 0 and m > 0 cases. + +For m = 0, we have + oo + ___ B + (0) 1 \ 2 k -2 k + psi (z) ~ log z + --- - ) ------ z + 2 z /___ (2 k)! + k = 1 + +Experiment shows that the minimum term of the asymptotic series +reaches 2^(-p) when Re(z) > 0.11*p. So we simply use the recurrence +for psi (equivalent, in fact, to summing to the first few terms +directly before applying E-M) to obtain z large enough. + +Since, very crudely, log z ~= 1 for Re(z) > 1, we can use +fixed-point arithmetic (if z is extremely large, log(z) itself +is a sufficient approximation, so we can stop there already). + +For Re(z) << 0, we could use recurrence, but this is of course +inefficient for large negative z, so there we use the +reflection formula instead. + +For m > 0, we have + + N - 1 + ___ + ~~~(m) [ \ 1 ] 1 1 + psi (z) ~ [ ) -------- ] + ---------- + -------- + + [ /___ m+1 ] m+1 m + k = 1 (z+k) ] 2 (z+N) m (z+N) + + oo + ___ B + \ 2 k (m+1) (m+2) ... (m+2k-1) + + ) ------ ------------------------ + /___ (2 k)! m + 2 k + k = 1 (z+N) + +where ~~~ denotes the function rescaled by 1/((-1)^(m+1) m!). + +Here again N is chosen to make z+N large enough for the minimum +term in the last series to become smaller than eps. + +TODO: the current estimation of N for m > 0 is *very suboptimal*. + +TODO: implement the reflection formula for m > 0, Re(z) << 0. +It is generally a combination of multiple cotangents. Need to +figure out a reasonably simple way to generate these formulas +on the fly. + +TODO: maybe use exact algorithms to compute psi for integral +and certain rational arguments, as this can be much more +efficient. (On the other hand, the availability of these +special values provides a convenient way to test the general +algorithm.) +""" + +# Harmonic numbers are just shifted digamma functions +# We should calculate these exactly when x is an integer +# and when doing so is faster. + +def mpf_harmonic(x, prec, rnd): + if x in (fzero, fnan, finf): + return x + a = mpf_psi0(mpf_add(fone, x, prec+5), prec) + return mpf_add(a, mpf_euler(prec+5, rnd), prec, rnd) + +def mpc_harmonic(z, prec, rnd): + if z[1] == fzero: + return (mpf_harmonic(z[0], prec, rnd), fzero) + a = mpc_psi0(mpc_add_mpf(z, fone, prec+5), prec) + return mpc_add_mpf(a, mpf_euler(prec+5, rnd), prec, rnd) + +def mpf_psi0(x, prec, rnd=round_fast): + """ + Computation of the digamma function (psi function of order 0) + of a real argument. + """ + sign, man, exp, bc = x + wp = prec + 10 + if not man: + if x == finf: return x + if x == fninf or x == fnan: return fnan + if x == fzero or (exp >= 0 and sign): + raise ValueError("polygamma pole") + # Near 0 -- fixed-point arithmetic becomes bad + if exp+bc < -5: + v = mpf_psi0(mpf_add(x, fone, prec, rnd), prec, rnd) + return mpf_sub(v, mpf_div(fone, x, wp, rnd), prec, rnd) + # Reflection formula + if sign and exp+bc > 3: + c, s = mpf_cos_sin_pi(x, wp) + q = mpf_mul(mpf_div(c, s, wp), mpf_pi(wp), wp) + p = mpf_psi0(mpf_sub(fone, x, wp), wp) + return mpf_sub(p, q, prec, rnd) + # The logarithmic term is accurate enough + if (not sign) and bc + exp > wp: + return mpf_log(mpf_sub(x, fone, wp), prec, rnd) + # Initial recurrence to obtain a large enough x + m = to_int(x) + n = int(0.11*wp) + 2 + s = MPZ_ZERO + x = to_fixed(x, wp) + one = MPZ_ONE << wp + if m < n: + for k in xrange(m, n): + s -= (one << wp) // x + x += one + x -= one + # Logarithmic term + s += to_fixed(mpf_log(from_man_exp(x, -wp, wp), wp), wp) + # Endpoint term in Euler-Maclaurin expansion + s += (one << wp) // (2*x) + # Euler-Maclaurin remainder sum + x2 = (x*x) >> wp + t = one + prev = 0 + k = 1 + while 1: + t = (t*x2) >> wp + bsign, bman, bexp, bbc = mpf_bernoulli(2*k, wp) + offset = (bexp + 2*wp) + if offset >= 0: term = (bman << offset) // (t*(2*k)) + else: term = (bman >> (-offset)) // (t*(2*k)) + if k & 1: s -= term + else: s += term + if k > 2 and term >= prev: + break + prev = term + k += 1 + return from_man_exp(s, -wp, wp, rnd) + +def mpc_psi0(z, prec, rnd=round_fast): + """ + Computation of the digamma function (psi function of order 0) + of a complex argument. + """ + re, im = z + # Fall back to the real case + if im == fzero: + return (mpf_psi0(re, prec, rnd), fzero) + wp = prec + 20 + sign, man, exp, bc = re + # Reflection formula + if sign and exp+bc > 3: + c = mpc_cos_pi(z, wp) + s = mpc_sin_pi(z, wp) + q = mpc_mul_mpf(mpc_div(c, s, wp), mpf_pi(wp), wp) + p = mpc_psi0(mpc_sub(mpc_one, z, wp), wp) + return mpc_sub(p, q, prec, rnd) + # Just the logarithmic term + if (not sign) and bc + exp > wp: + return mpc_log(mpc_sub(z, mpc_one, wp), prec, rnd) + # Initial recurrence to obtain a large enough z + w = to_int(re) + n = int(0.11*wp) + 2 + s = mpc_zero + if w < n: + for k in xrange(w, n): + s = mpc_sub(s, mpc_reciprocal(z, wp), wp) + z = mpc_add_mpf(z, fone, wp) + z = mpc_sub(z, mpc_one, wp) + # Logarithmic and endpoint term + s = mpc_add(s, mpc_log(z, wp), wp) + s = mpc_add(s, mpc_div(mpc_half, z, wp), wp) + # Euler-Maclaurin remainder sum + z2 = mpc_square(z, wp) + t = mpc_one + prev = mpc_zero + szprev = fzero + k = 1 + eps = mpf_shift(fone, -wp+2) + while 1: + t = mpc_mul(t, z2, wp) + bern = mpf_bernoulli(2*k, wp) + term = mpc_mpf_div(bern, mpc_mul_int(t, 2*k, wp), wp) + s = mpc_sub(s, term, wp) + szterm = mpc_abs(term, 10) + if k > 2 and (mpf_le(szterm, eps) or mpf_le(szprev, szterm)): + break + prev = term + szprev = szterm + k += 1 + return s + +# Currently unoptimized +def mpf_psi(m, x, prec, rnd=round_fast): + """ + Computation of the polygamma function of arbitrary integer order + m >= 0, for a real argument x. + """ + if m == 0: + return mpf_psi0(x, prec, rnd=round_fast) + return mpc_psi(m, (x, fzero), prec, rnd)[0] + +def mpc_psi(m, z, prec, rnd=round_fast): + """ + Computation of the polygamma function of arbitrary integer order + m >= 0, for a complex argument z. + """ + if m == 0: + return mpc_psi0(z, prec, rnd) + re, im = z + wp = prec + 20 + sign, man, exp, bc = re + if not im[1]: + if im in (finf, fninf, fnan): + return (fnan, fnan) + if not man: + if re == finf and im == fzero: + return (fzero, fzero) + if re == fnan: + return (fnan, fnan) + # Recurrence + w = to_int(re) + n = int(0.4*wp + 4*m) + s = mpc_zero + if w < n: + for k in xrange(w, n): + t = mpc_pow_int(z, -m-1, wp) + s = mpc_add(s, t, wp) + z = mpc_add_mpf(z, fone, wp) + zm = mpc_pow_int(z, -m, wp) + z2 = mpc_pow_int(z, -2, wp) + # 1/m*(z+N)^m + integral_term = mpc_div_mpf(zm, from_int(m), wp) + s = mpc_add(s, integral_term, wp) + # 1/2*(z+N)^(-(m+1)) + s = mpc_add(s, mpc_mul_mpf(mpc_div(zm, z, wp), fhalf, wp), wp) + a = m + 1 + b = 2 + k = 1 + # Important: we want to sum up to the *relative* error, + # not the absolute error, because psi^(m)(z) might be tiny + magn = mpc_abs(s, 10) + magn = magn[2]+magn[3] + eps = mpf_shift(fone, magn-wp+2) + while 1: + zm = mpc_mul(zm, z2, wp) + bern = mpf_bernoulli(2*k, wp) + scal = mpf_mul_int(bern, a, wp) + scal = mpf_div(scal, from_int(b), wp) + term = mpc_mul_mpf(zm, scal, wp) + s = mpc_add(s, term, wp) + szterm = mpc_abs(term, 10) + if k > 2 and mpf_le(szterm, eps): + break + #print k, to_str(szterm, 10), to_str(eps, 10) + a *= (m+2*k)*(m+2*k+1) + b *= (2*k+1)*(2*k+2) + k += 1 + # Scale and sign factor + v = mpc_mul_mpf(s, mpf_gamma(from_int(m+1), wp), prec, rnd) + if not (m & 1): + v = mpf_neg(v[0]), mpf_neg(v[1]) + return v + + +#-----------------------------------------------------------------------# +# # +# Riemann zeta function # +# # +#-----------------------------------------------------------------------# + +r""" +We use zeta(s) = eta(s) / (1 - 2**(1-s)) and Borwein's approximation + + n-1 + ___ k + -1 \ (-1) (d_k - d_n) + eta(s) ~= ---- ) ------------------ + d_n /___ s + k = 0 (k + 1) +where + k + ___ i + \ (n + i - 1)! 4 + d_k = n ) ---------------. + /___ (n - i)! (2i)! + i = 0 + +If s = a + b*I, the absolute error for eta(s) is bounded by + + 3 (1 + 2|b|) + ------------ * exp(|b| pi/2) + n + (3+sqrt(8)) + +Disregarding the linear term, we have approximately, + + log(err) ~= log(exp(1.58*|b|)) - log(5.8**n) + log(err) ~= 1.58*|b| - log(5.8)*n + log(err) ~= 1.58*|b| - 1.76*n + log2(err) ~= 2.28*|b| - 2.54*n + +So for p bits, we should choose n > (p + 2.28*|b|) / 2.54. + +References: +----------- + +Peter Borwein, "An Efficient Algorithm for the Riemann Zeta Function" +http://www.cecm.sfu.ca/personal/pborwein/PAPERS/P117.ps + +http://en.wikipedia.org/wiki/Dirichlet_eta_function +""" + +borwein_cache = {} + +def borwein_coefficients(n): + if n in borwein_cache: + return borwein_cache[n] + ds = [MPZ_ZERO] * (n+1) + d = MPZ_ONE + s = ds[0] = MPZ_ONE + for i in range(1, n+1): + d = d * 4 * (n+i-1) * (n-i+1) + d //= ((2*i) * ((2*i)-1)) + s += d + ds[i] = s + borwein_cache[n] = ds + return ds + +ZETA_INT_CACHE_MAX_PREC = 1000 +zeta_int_cache = {} + +def mpf_zeta_int(s, prec, rnd=round_fast): + """ + Optimized computation of zeta(s) for an integer s. + """ + wp = prec + 20 + s = int(s) + if s in zeta_int_cache and zeta_int_cache[s][0] >= wp: + return mpf_pos(zeta_int_cache[s][1], prec, rnd) + if s < 2: + if s == 1: + raise ValueError("zeta(1) pole") + if not s: + return mpf_neg(fhalf) + return mpf_div(mpf_bernoulli(-s+1, wp), from_int(s-1), prec, rnd) + # 2^-s term vanishes? + if s >= wp: + return mpf_perturb(fone, 0, prec, rnd) + # 5^-s term vanishes? + elif s >= wp*0.431: + t = one = 1 << wp + t += 1 << (wp - s) + t += one // (MPZ_THREE ** s) + t += 1 << max(0, wp - s*2) + return from_man_exp(t, -wp, prec, rnd) + else: + # Fast enough to sum directly? + # Even better, we use the Euler product (idea stolen from pari) + m = (float(wp)/(s-1) + 1) + if m < 30: + needed_terms = int(2.0**m + 1) + if needed_terms < int(wp/2.54 + 5) / 10: + t = fone + for k in list_primes(needed_terms): + #print k, needed_terms + powprec = int(wp - s*math.log(k,2)) + if powprec < 2: + break + a = mpf_sub(fone, mpf_pow_int(from_int(k), -s, powprec), wp) + t = mpf_mul(t, a, wp) + return mpf_div(fone, t, wp) + # Use Borwein's algorithm + n = int(wp/2.54 + 5) + d = borwein_coefficients(n) + t = MPZ_ZERO + s = MPZ(s) + for k in xrange(n): + t += (((-1)**k * (d[k] - d[n])) << wp) // (k+1)**s + t = (t << wp) // (-d[n]) + t = (t << wp) // ((1 << wp) - (1 << (wp+1-s))) + if (s in zeta_int_cache and zeta_int_cache[s][0] < wp) or (s not in zeta_int_cache): + zeta_int_cache[s] = (wp, from_man_exp(t, -wp-wp)) + return from_man_exp(t, -wp-wp, prec, rnd) + +def mpf_zeta(s, prec, rnd=round_fast, alt=0): + sign, man, exp, bc = s + if not man: + if s == fzero: + if alt: + return fhalf + else: + return mpf_neg(fhalf) + if s == finf: + return fone + return fnan + wp = prec + 20 + # First term vanishes? + if (not sign) and (exp + bc > (math.log(wp,2) + 2)): + return mpf_perturb(fone, alt, prec, rnd) + # Optimize for integer arguments + elif exp >= 0: + if alt: + if s == fone: + return mpf_ln2(prec, rnd) + z = mpf_zeta_int(to_int(s), wp, negative_rnd[rnd]) + q = mpf_sub(fone, mpf_pow(ftwo, mpf_sub(fone, s, wp), wp), wp) + return mpf_mul(z, q, prec, rnd) + else: + return mpf_zeta_int(to_int(s), prec, rnd) + # Negative: use the reflection formula + # Borwein only proves the accuracy bound for x >= 1/2. However, based on + # tests, the accuracy without reflection is quite good even some distance + # to the left of 1/2. XXX: verify this. + if sign: + # XXX: could use the separate refl. formula for Dirichlet eta + if alt: + q = mpf_sub(fone, mpf_pow(ftwo, mpf_sub(fone, s, wp), wp), wp) + return mpf_mul(mpf_zeta(s, wp), q, prec, rnd) + # XXX: -1 should be done exactly + y = mpf_sub(fone, s, 10*wp) + a = mpf_gamma(y, wp) + b = mpf_zeta(y, wp) + c = mpf_sin_pi(mpf_shift(s, -1), wp) + wp2 = wp + max(0,exp+bc) + pi = mpf_pi(wp+wp2) + d = mpf_div(mpf_pow(mpf_shift(pi, 1), s, wp2), pi, wp2) + return mpf_mul(a,mpf_mul(b,mpf_mul(c,d,wp),wp),prec,rnd) + + # Near pole + r = mpf_sub(fone, s, wp) + asign, aman, aexp, abc = mpf_abs(r) + pole_dist = -2*(aexp+abc) + if pole_dist > wp: + if alt: + return mpf_ln2(prec, rnd) + else: + q = mpf_neg(mpf_div(fone, r, wp)) + return mpf_add(q, mpf_euler(wp), prec, rnd) + else: + wp += max(0, pole_dist) + + t = MPZ_ZERO + #wp += 16 - (prec & 15) + # Use Borwein's algorithm + n = int(wp/2.54 + 5) + d = borwein_coefficients(n) + t = MPZ_ZERO + sf = to_fixed(s, wp) + ln2 = ln2_fixed(wp) + for k in xrange(n): + u = (-sf*log_int_fixed(k+1, wp, ln2)) >> wp + #esign, eman, eexp, ebc = mpf_exp(u, wp) + #offset = eexp + wp + #if offset >= 0: + # w = ((d[k] - d[n]) * eman) << offset + #else: + # w = ((d[k] - d[n]) * eman) >> (-offset) + eman = exp_fixed(u, wp, ln2) + w = (d[k] - d[n]) * eman + if k & 1: + t -= w + else: + t += w + t = t // (-d[n]) + t = from_man_exp(t, -wp, wp) + if alt: + return mpf_pos(t, prec, rnd) + else: + q = mpf_sub(fone, mpf_pow(ftwo, mpf_sub(fone, s, wp), wp), wp) + return mpf_div(t, q, prec, rnd) + +def mpc_zeta(s, prec, rnd=round_fast, alt=0, force=False): + re, im = s + if im == fzero: + return mpf_zeta(re, prec, rnd, alt), fzero + + # slow for large s + if (not force) and mpf_gt(mpc_abs(s, 10), from_int(prec)): + raise NotImplementedError + + wp = prec + 20 + + # Near pole + r = mpc_sub(mpc_one, s, wp) + asign, aman, aexp, abc = mpc_abs(r, 10) + pole_dist = -2*(aexp+abc) + if pole_dist > wp: + if alt: + q = mpf_ln2(wp) + y = mpf_mul(q, mpf_euler(wp), wp) + g = mpf_shift(mpf_mul(q, q, wp), -1) + g = mpf_sub(y, g) + z = mpc_mul_mpf(r, mpf_neg(g), wp) + z = mpc_add_mpf(z, q, wp) + return mpc_pos(z, prec, rnd) + else: + q = mpc_neg(mpc_div(mpc_one, r, wp)) + q = mpc_add_mpf(q, mpf_euler(wp), wp) + return mpc_pos(q, prec, rnd) + else: + wp += max(0, pole_dist) + + # Reflection formula. To be rigorous, we should reflect to the left of + # re = 1/2 (see comments for mpf_zeta), but this leads to unnecessary + # slowdown for interesting values of s + if mpf_lt(re, fzero): + # XXX: could use the separate refl. formula for Dirichlet eta + if alt: + q = mpc_sub(mpc_one, mpc_pow(mpc_two, mpc_sub(mpc_one, s, wp), + wp), wp) + return mpc_mul(mpc_zeta(s, wp), q, prec, rnd) + # XXX: -1 should be done exactly + y = mpc_sub(mpc_one, s, 10*wp) + a = mpc_gamma(y, wp) + b = mpc_zeta(y, wp) + c = mpc_sin_pi(mpc_shift(s, -1), wp) + rsign, rman, rexp, rbc = re + isign, iman, iexp, ibc = im + mag = max(rexp+rbc, iexp+ibc) + wp2 = wp + max(0, mag) + pi = mpf_pi(wp+wp2) + pi2 = (mpf_shift(pi, 1), fzero) + d = mpc_div_mpf(mpc_pow(pi2, s, wp2), pi, wp2) + return mpc_mul(a,mpc_mul(b,mpc_mul(c,d,wp),wp),prec,rnd) + n = int(wp/2.54 + 5) + n += int(0.9*abs(to_int(im))) + d = borwein_coefficients(n) + ref = to_fixed(re, wp) + imf = to_fixed(im, wp) + tre = MPZ_ZERO + tim = MPZ_ZERO + one = MPZ_ONE << wp + one_2wp = MPZ_ONE << (2*wp) + critical_line = re == fhalf + ln2 = ln2_fixed(wp) + pi2 = pi_fixed(wp-1) + wp2 = wp+wp + for k in xrange(n): + log = log_int_fixed(k+1, wp, ln2) + # A square root is much cheaper than an exp + if critical_line: + w = one_2wp // isqrt_fast((k+1) << wp2) + else: + w = exp_fixed((-ref*log) >> wp, wp) + if k & 1: + w *= (d[n] - d[k]) + else: + w *= (d[k] - d[n]) + wre, wim = cos_sin_fixed((-imf*log)>>wp, wp, pi2) + tre += (w * wre) >> wp + tim += (w * wim) >> wp + tre //= (-d[n]) + tim //= (-d[n]) + tre = from_man_exp(tre, -wp, wp) + tim = from_man_exp(tim, -wp, wp) + if alt: + return mpc_pos((tre, tim), prec, rnd) + else: + q = mpc_sub(mpc_one, mpc_pow(mpc_two, r, wp), wp) + return mpc_div((tre, tim), q, prec, rnd) + +def mpf_altzeta(s, prec, rnd=round_fast): + return mpf_zeta(s, prec, rnd, 1) + +def mpc_altzeta(s, prec, rnd=round_fast): + return mpc_zeta(s, prec, rnd, 1) + +# Not optimized currently +mpf_zetasum = None + + +def pow_fixed(x, n, wp): + if n == 1: + return x + y = MPZ_ONE << wp + while n: + if n & 1: + y = (y*x) >> wp + n -= 1 + x = (x*x) >> wp + n //= 2 + return y + +# TODO: optimize / cleanup interface / unify with list_primes +sieve_cache = [] +primes_cache = [] +mult_cache = [] + +def primesieve(n): + global sieve_cache, primes_cache, mult_cache + if n < len(sieve_cache): + sieve = sieve_cache#[:n+1] + primes = primes_cache[:primes_cache.index(max(sieve))+1] + mult = mult_cache#[:n+1] + return sieve, primes, mult + sieve = [0] * (n+1) + mult = [0] * (n+1) + primes = list_primes(n) + for p in primes: + #sieve[p::p] = p + for k in xrange(p,n+1,p): + sieve[k] = p + for i, p in enumerate(sieve): + if i >= 2: + m = 1 + n = i // p + while not n % p: + n //= p + m += 1 + mult[i] = m + sieve_cache = sieve + primes_cache = primes + mult_cache = mult + return sieve, primes, mult + +def zetasum_sieved(critical_line, sre, sim, a, n, wp): + if a < 1: + raise ValueError("a cannot be less than 1") + sieve, primes, mult = primesieve(a+n) + basic_powers = {} + one = MPZ_ONE << wp + one_2wp = MPZ_ONE << (2*wp) + wp2 = wp+wp + ln2 = ln2_fixed(wp) + pi2 = pi_fixed(wp-1) + for p in primes: + if p*2 > a+n: + break + log = log_int_fixed(p, wp, ln2) + cos, sin = cos_sin_fixed((-sim*log)>>wp, wp, pi2) + if critical_line: + u = one_2wp // isqrt_fast(p<>wp, wp) + pre = (u*cos) >> wp + pim = (u*sin) >> wp + basic_powers[p] = [(pre, pim)] + tre, tim = pre, pim + for m in range(1,int(math.log(a+n,p)+0.01)+1): + tre, tim = ((pre*tre-pim*tim)>>wp), ((pim*tre+pre*tim)>>wp) + basic_powers[p].append((tre,tim)) + xre = MPZ_ZERO + xim = MPZ_ZERO + if a == 1: + xre += one + aa = max(a,2) + for k in xrange(aa, a+n+1): + p = sieve[k] + if p in basic_powers: + m = mult[k] + tre, tim = basic_powers[p][m-1] + while 1: + k //= p**m + if k == 1: + break + p = sieve[k] + m = mult[k] + pre, pim = basic_powers[p][m-1] + tre, tim = ((pre*tre-pim*tim)>>wp), ((pim*tre+pre*tim)>>wp) + else: + log = log_int_fixed(k, wp, ln2) + cos, sin = cos_sin_fixed((-sim*log)>>wp, wp, pi2) + if critical_line: + u = one_2wp // isqrt_fast(k<>wp, wp) + tre = (u*cos) >> wp + tim = (u*sin) >> wp + xre += tre + xim += tim + return xre, xim + +# Set to something large to disable +ZETASUM_SIEVE_CUTOFF = 10 + +def mpc_zetasum(s, a, n, derivatives, reflect, prec): + """ + Fast version of mp._zetasum, assuming s = complex, a = integer. + """ + + wp = prec + 10 + derivatives = list(derivatives) + have_derivatives = derivatives != [0] + have_one_derivative = len(derivatives) == 1 + + # parse s + sre, sim = s + critical_line = (sre == fhalf) + sre = to_fixed(sre, wp) + sim = to_fixed(sim, wp) + + if a > 0 and n > ZETASUM_SIEVE_CUTOFF and not have_derivatives \ + and not reflect and (n < 4e7 or sys.maxsize > 2**32): + re, im = zetasum_sieved(critical_line, sre, sim, a, n, wp) + xs = [(from_man_exp(re, -wp, prec, 'n'), from_man_exp(im, -wp, prec, 'n'))] + return xs, [] + + maxd = max(derivatives) + if not have_one_derivative: + derivatives = range(maxd+1) + + # x_d = 0, y_d = 0 + xre = [MPZ_ZERO for d in derivatives] + xim = [MPZ_ZERO for d in derivatives] + if reflect: + yre = [MPZ_ZERO for d in derivatives] + yim = [MPZ_ZERO for d in derivatives] + else: + yre = yim = [] + + one = MPZ_ONE << wp + one_2wp = MPZ_ONE << (2*wp) + + ln2 = ln2_fixed(wp) + pi2 = pi_fixed(wp-1) + wp2 = wp+wp + + for w in xrange(a, a+n+1): + log = log_int_fixed(w, wp, ln2) + cos, sin = cos_sin_fixed((-sim*log)>>wp, wp, pi2) + if critical_line: + u = one_2wp // isqrt_fast(w<>wp, wp) + xterm_re = (u * cos) >> wp + xterm_im = (u * sin) >> wp + if reflect: + reciprocal = (one_2wp // (u*w)) + yterm_re = (reciprocal * cos) >> wp + yterm_im = (reciprocal * sin) >> wp + + if have_derivatives: + if have_one_derivative: + log = pow_fixed(log, maxd, wp) + xre[0] += (xterm_re * log) >> wp + xim[0] += (xterm_im * log) >> wp + if reflect: + yre[0] += (yterm_re * log) >> wp + yim[0] += (yterm_im * log) >> wp + else: + t = MPZ_ONE << wp + for d in derivatives: + xre[d] += (xterm_re * t) >> wp + xim[d] += (xterm_im * t) >> wp + if reflect: + yre[d] += (yterm_re * t) >> wp + yim[d] += (yterm_im * t) >> wp + t = (t * log) >> wp + else: + xre[0] += xterm_re + xim[0] += xterm_im + if reflect: + yre[0] += yterm_re + yim[0] += yterm_im + if have_derivatives: + if have_one_derivative: + if maxd % 2: + xre[0] = -xre[0] + xim[0] = -xim[0] + if reflect: + yre[0] = -yre[0] + yim[0] = -yim[0] + else: + xre = [(-1)**d * xre[d] for d in derivatives] + xim = [(-1)**d * xim[d] for d in derivatives] + if reflect: + yre = [(-1)**d * yre[d] for d in derivatives] + yim = [(-1)**d * yim[d] for d in derivatives] + xs = [(from_man_exp(xa, -wp, prec, 'n'), from_man_exp(xb, -wp, prec, 'n')) + for (xa, xb) in zip(xre, xim)] + ys = [(from_man_exp(ya, -wp, prec, 'n'), from_man_exp(yb, -wp, prec, 'n')) + for (ya, yb) in zip(yre, yim)] + return xs, ys + + +#-----------------------------------------------------------------------# +# # +# The gamma function (NEW IMPLEMENTATION) # +# # +#-----------------------------------------------------------------------# + +# Higher means faster, but more precomputation time +MAX_GAMMA_TAYLOR_PREC = 5000 +# Need to derive higher bounds for Taylor series to go higher +assert MAX_GAMMA_TAYLOR_PREC < 15000 + +# Use Stirling's series if abs(x) > beta*prec +# Important: must be large enough for convergence! +GAMMA_STIRLING_BETA = 0.2 + +SMALL_FACTORIAL_CACHE_SIZE = 150 + +gamma_taylor_cache = {} +gamma_stirling_cache = {} + +small_factorial_cache = [from_int(ifac(n)) for \ + n in range(SMALL_FACTORIAL_CACHE_SIZE+1)] + +def zeta_array(N, prec): + """ + zeta(n) = A * pi**n / n! + B + + where A is a rational number (A = Bernoulli number + for n even) and B is an infinite sum over powers of exp(2*pi). + (B = 0 for n even). + + TODO: this is currently only used for gamma, but could + be very useful elsewhere. + """ + extra = 30 + wp = prec+extra + zeta_values = [MPZ_ZERO] * (N+2) + pi = pi_fixed(wp) + # STEP 1: + one = MPZ_ONE << wp + zeta_values[0] = -one//2 + f_2pi = mpf_shift(mpf_pi(wp),1) + exp_2pi_k = exp_2pi = mpf_exp(f_2pi, wp) + # Compute exponential series + # Store values of 1/(exp(2*pi*k)-1), + # exp(2*pi*k)/(exp(2*pi*k)-1)**2, 1/(exp(2*pi*k)-1)**2 + # pi*k*exp(2*pi*k)/(exp(2*pi*k)-1)**2 + exps3 = [] + k = 1 + while 1: + tp = wp - 9*k + if tp < 1: + break + # 1/(exp(2*pi*k-1) + q1 = mpf_div(fone, mpf_sub(exp_2pi_k, fone, tp), tp) + # pi*k*exp(2*pi*k)/(exp(2*pi*k)-1)**2 + q2 = mpf_mul(exp_2pi_k, mpf_mul(q1,q1,tp), tp) + q1 = to_fixed(q1, wp) + q2 = to_fixed(q2, wp) + q2 = (k * q2 * pi) >> wp + exps3.append((q1, q2)) + # Multiply for next round + exp_2pi_k = mpf_mul(exp_2pi_k, exp_2pi, wp) + k += 1 + # Exponential sum + for n in xrange(3, N+1, 2): + s = MPZ_ZERO + k = 1 + for e1, e2 in exps3: + if n%4 == 3: + t = e1 // k**n + else: + U = (n-1)//4 + t = (e1 + e2//U) // k**n + if not t: + break + s += t + k += 1 + zeta_values[n] = -2*s + # Even zeta values + B = [mpf_abs(mpf_bernoulli(k,wp)) for k in xrange(N+2)] + pi_pow = fpi = mpf_pow_int(mpf_shift(mpf_pi(wp), 1), 2, wp) + pi_pow = mpf_div(pi_pow, from_int(4), wp) + for n in xrange(2,N+2,2): + z = mpf_mul(B[n], pi_pow, wp) + zeta_values[n] = to_fixed(z, wp) + pi_pow = mpf_mul(pi_pow, fpi, wp) + pi_pow = mpf_div(pi_pow, from_int((n+1)*(n+2)), wp) + # Zeta sum + reciprocal_pi = (one << wp) // pi + for n in xrange(3, N+1, 4): + U = (n-3)//4 + s = zeta_values[4*U+4]*(4*U+7)//4 + for k in xrange(1, U+1): + s -= (zeta_values[4*k] * zeta_values[4*U+4-4*k]) >> wp + zeta_values[n] += (2*s*reciprocal_pi) >> wp + for n in xrange(5, N+1, 4): + U = (n-1)//4 + s = zeta_values[4*U+2]*(2*U+1) + for k in xrange(1, 2*U+1): + s += ((-1)**k*2*k* zeta_values[2*k] * zeta_values[4*U+2-2*k])>>wp + zeta_values[n] += ((s*reciprocal_pi)>>wp)//(2*U) + return [x>>extra for x in zeta_values] + +def gamma_taylor_coefficients(inprec): + """ + Gives the Taylor coefficients of 1/gamma(1+x) as + a list of fixed-point numbers. Enough coefficients are returned + to ensure that the series converges to the given precision + when x is in [0.5, 1.5]. + """ + # Reuse nearby cache values (small case) + if inprec < 400: + prec = inprec + (10-(inprec%10)) + elif inprec < 1000: + prec = inprec + (30-(inprec%30)) + else: + prec = inprec + if prec in gamma_taylor_cache: + return gamma_taylor_cache[prec], prec + + # Experimentally determined bounds + if prec < 1000: + N = int(prec**0.76 + 2) + else: + # Valid to at least 15000 bits + N = int(prec**0.787 + 2) + + # Reuse higher precision values + for cprec in gamma_taylor_cache: + if cprec > prec: + coeffs = [x>>(cprec-prec) for x in gamma_taylor_cache[cprec][-N:]] + if inprec < 1000: + gamma_taylor_cache[prec] = coeffs + return coeffs, prec + + # Cache at a higher precision (large case) + if prec > 1000: + prec = int(prec * 1.2) + + wp = prec + 20 + A = [0] * N + A[0] = MPZ_ZERO + A[1] = MPZ_ONE << wp + A[2] = euler_fixed(wp) + # SLOW, reference implementation + #zeta_values = [0,0]+[to_fixed(mpf_zeta_int(k,wp),wp) for k in xrange(2,N)] + zeta_values = zeta_array(N, wp) + for k in xrange(3, N): + a = (-A[2]*A[k-1])>>wp + for j in xrange(2,k): + a += ((-1)**j * zeta_values[j] * A[k-j]) >> wp + a //= (1-k) + A[k] = a + A = [a>>20 for a in A] + A = A[::-1] + A = A[:-1] + gamma_taylor_cache[prec] = A + #return A, prec + return gamma_taylor_coefficients(inprec) + +def gamma_fixed_taylor(xmpf, x, wp, prec, rnd, type): + # Determine nearest multiple of N/2 + #n = int(x >> (wp-1)) + #steps = (n-1)>>1 + nearest_int = ((x >> (wp-1)) + MPZ_ONE) >> 1 + one = MPZ_ONE << wp + coeffs, cwp = gamma_taylor_coefficients(wp) + if nearest_int > 0: + r = one + for i in xrange(nearest_int-1): + x -= one + r = (r*x) >> wp + x -= one + p = MPZ_ZERO + for c in coeffs: + p = c + ((x*p)>>wp) + p >>= (cwp-wp) + if type == 0: + return from_man_exp((r<> wp + x += one + p = MPZ_ZERO + for c in coeffs: + p = c + ((x*p)>>wp) + p >>= (cwp-wp) + if wp - bitcount(abs(x)) > 10: + # pass very close to 0, so do floating-point multiply + g = mpf_add(xmpf, from_int(-nearest_int)) # exact + r = from_man_exp(p*r,-wp-wp) + r = mpf_mul(r, g, wp) + if type == 0: + return mpf_div(fone, r, prec, rnd) + if type == 2: + return mpf_pos(r, prec, rnd) + if type == 3: + return mpf_log(mpf_abs(mpf_div(fone, r, wp)), prec, rnd) + else: + r = from_man_exp(x*p*r,-3*wp) + if type == 0: return mpf_div(fone, r, prec, rnd) + if type == 2: return mpf_pos(r, prec, rnd) + if type == 3: return mpf_neg(mpf_log(mpf_abs(r), prec, rnd)) + +def stirling_coefficient(n): + if n in gamma_stirling_cache: + return gamma_stirling_cache[n] + p, q = bernfrac(n) + q *= MPZ(n*(n-1)) + gamma_stirling_cache[n] = p, q, bitcount(abs(p)), bitcount(q) + return gamma_stirling_cache[n] + +def real_stirling_series(x, prec): + """ + Sums the rational part of Stirling's expansion, + + log(sqrt(2*pi)) - z + 1/(12*z) - 1/(360*z^3) + ... + + """ + t = (MPZ_ONE<<(prec+prec)) // x # t = 1/x + u = (t*t)>>prec # u = 1/x**2 + s = ln_sqrt2pi_fixed(prec) - x + # Add initial terms of Stirling's series + s += t//12; t = (t*u)>>prec + s -= t//360; t = (t*u)>>prec + s += t//1260; t = (t*u)>>prec + s -= t//1680; t = (t*u)>>prec + if not t: return s + s += t//1188; t = (t*u)>>prec + s -= 691*t//360360; t = (t*u)>>prec + s += t//156; t = (t*u)>>prec + if not t: return s + s -= 3617*t//122400; t = (t*u)>>prec + s += 43867*t//244188; t = (t*u)>>prec + s -= 174611*t//125400; t = (t*u)>>prec + if not t: return s + k = 22 + # From here on, the coefficients are growing, so we + # have to keep t at a roughly constant size + usize = bitcount(abs(u)) + tsize = bitcount(abs(t)) + texp = 0 + while 1: + p, q, pb, qb = stirling_coefficient(k) + term_mag = tsize + pb + texp + shift = -texp + m = pb - term_mag + if m > 0 and shift < m: + p >>= m + shift -= m + m = tsize - term_mag + if m > 0 and shift < m: + w = t >> m + shift -= m + else: + w = t + term = (t*p//q) >> shift + if not term: + break + s += term + t = (t*u) >> usize + texp -= (prec - usize) + k += 2 + return s + +def complex_stirling_series(x, y, prec): + # t = 1/z + _m = (x*x + y*y) >> prec + tre = (x << prec) // _m + tim = (-y << prec) // _m + # u = 1/z**2 + ure = (tre*tre - tim*tim) >> prec + uim = tim*tre >> (prec-1) + # s = log(sqrt(2*pi)) - z + sre = ln_sqrt2pi_fixed(prec) - x + sim = -y + + # Add initial terms of Stirling's series + sre += tre//12; sim += tim//12; + tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec) + sre -= tre//360; sim -= tim//360; + tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec) + sre += tre//1260; sim += tim//1260; + tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec) + sre -= tre//1680; sim -= tim//1680; + tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec) + if abs(tre) + abs(tim) < 5: return sre, sim + sre += tre//1188; sim += tim//1188; + tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec) + sre -= 691*tre//360360; sim -= 691*tim//360360; + tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec) + sre += tre//156; sim += tim//156; + tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec) + if abs(tre) + abs(tim) < 5: return sre, sim + sre -= 3617*tre//122400; sim -= 3617*tim//122400; + tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec) + sre += 43867*tre//244188; sim += 43867*tim//244188; + tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec) + sre -= 174611*tre//125400; sim -= 174611*tim//125400; + tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec) + if abs(tre) + abs(tim) < 5: return sre, sim + + k = 22 + # From here on, the coefficients are growing, so we + # have to keep t at a roughly constant size + usize = bitcount(max(abs(ure), abs(uim))) + tsize = bitcount(max(abs(tre), abs(tim))) + texp = 0 + while 1: + p, q, pb, qb = stirling_coefficient(k) + term_mag = tsize + pb + texp + shift = -texp + m = pb - term_mag + if m > 0 and shift < m: + p >>= m + shift -= m + m = tsize - term_mag + if m > 0 and shift < m: + wre = tre >> m + wim = tim >> m + shift -= m + else: + wre = tre + wim = tim + termre = (tre*p//q) >> shift + termim = (tim*p//q) >> shift + if abs(termre) + abs(termim) < 5: + break + sre += termre + sim += termim + tre, tim = ((tre*ure - tim*uim)>>usize), \ + ((tre*uim + tim*ure)>>usize) + texp -= (prec - usize) + k += 2 + return sre, sim + + +def mpf_gamma(x, prec, rnd='d', type=0): + """ + This function implements multipurpose evaluation of the gamma + function, G(x), as well as the following versions of the same: + + type = 0 -- G(x) [standard gamma function] + type = 1 -- G(x+1) = x*G(x+1) = x! [factorial] + type = 2 -- 1/G(x) [reciprocal gamma function] + type = 3 -- log(|G(x)|) [log-gamma function, real part] + """ + + # Specal values + sign, man, exp, bc = x + if not man: + if x == fzero: + if type == 1: return fone + if type == 2: return fzero + raise ValueError("gamma function pole") + if x == finf: + if type == 2: return fzero + return finf + return fnan + + # First of all, for log gamma, numbers can be well beyond the fixed-point + # range, so we must take care of huge numbers before e.g. trying + # to convert x to the nearest integer + if type == 3: + wp = prec+20 + if exp+bc > wp and not sign: + return mpf_sub(mpf_mul(x, mpf_log(x, wp), wp), x, prec, rnd) + + # We strongly want to special-case small integers + is_integer = exp >= 0 + if is_integer: + # Poles + if sign: + if type == 2: + return fzero + raise ValueError("gamma function pole") + # n = x + n = man << exp + if n < SMALL_FACTORIAL_CACHE_SIZE: + if type == 0: + return mpf_pos(small_factorial_cache[n-1], prec, rnd) + if type == 1: + return mpf_pos(small_factorial_cache[n], prec, rnd) + if type == 2: + return mpf_div(fone, small_factorial_cache[n-1], prec, rnd) + if type == 3: + return mpf_log(small_factorial_cache[n-1], prec, rnd) + else: + # floor(abs(x)) + n = int(man >> (-exp)) + + # Estimate size and precision + # Estimate log(gamma(|x|),2) as x*log(x,2) + mag = exp + bc + gamma_size = n*mag + + if type == 3: + wp = prec + 20 + else: + wp = prec + bitcount(gamma_size) + 20 + + # Very close to 0, pole + if mag < -wp: + if type == 0: + return mpf_sub(mpf_div(fone,x, wp),mpf_shift(fone,-wp),prec,rnd) + if type == 1: return mpf_sub(fone, x, prec, rnd) + if type == 2: return mpf_add(x, mpf_shift(fone,mag-wp), prec, rnd) + if type == 3: return mpf_neg(mpf_log(mpf_abs(x), prec, rnd)) + + # From now on, we assume having a gamma function + if type == 1: + return mpf_gamma(mpf_add(x, fone), prec, rnd, 0) + + # Special case integers (those not small enough to be caught above, + # but still small enough for an exact factorial to be faster + # than an approximate algorithm), and half-integers + if exp >= -1: + if is_integer: + if gamma_size < 10*wp: + if type == 0: + return from_int(ifac(n-1), prec, rnd) + if type == 2: + return from_rational(MPZ_ONE, ifac(n-1), prec, rnd) + if type == 3: + return mpf_log(from_int(ifac(n-1)), prec, rnd) + # half-integer + if n < 100 or gamma_size < 10*wp: + if sign: + w = sqrtpi_fixed(wp) + if n % 2: f = ifac2(2*n+1) + else: f = -ifac2(2*n+1) + if type == 0: + return mpf_shift(from_rational(w, f, prec, rnd), -wp+n+1) + if type == 2: + return mpf_shift(from_rational(f, w, prec, rnd), wp-n-1) + if type == 3: + return mpf_log(mpf_shift(from_rational(w, abs(f), + prec, rnd), -wp+n+1), prec, rnd) + elif n == 0: + if type == 0: return mpf_sqrtpi(prec, rnd) + if type == 2: return mpf_div(fone, mpf_sqrtpi(wp), prec, rnd) + if type == 3: return mpf_log(mpf_sqrtpi(wp), prec, rnd) + else: + w = sqrtpi_fixed(wp) + w = from_man_exp(w * ifac2(2*n-1), -wp-n) + if type == 0: return mpf_pos(w, prec, rnd) + if type == 2: return mpf_div(fone, w, prec, rnd) + if type == 3: return mpf_log(mpf_abs(w), prec, rnd) + + # Convert to fixed point + offset = exp + wp + if offset >= 0: absxman = man << offset + else: absxman = man >> (-offset) + + # For log gamma, provide accurate evaluation for x = 1+eps and 2+eps + if type == 3 and not sign: + one = MPZ_ONE << wp + one_dist = abs(absxman-one) + two_dist = abs(absxman-2*one) + cancellation = (wp - bitcount(min(one_dist, two_dist))) + if cancellation > 10: + xsub1 = mpf_sub(fone, x) + xsub2 = mpf_sub(ftwo, x) + xsub1mag = xsub1[2]+xsub1[3] + xsub2mag = xsub2[2]+xsub2[3] + if xsub1mag < -wp: + return mpf_mul(mpf_euler(wp), mpf_sub(fone, x), prec, rnd) + if xsub2mag < -wp: + return mpf_mul(mpf_sub(fone, mpf_euler(wp)), + mpf_sub(x, ftwo), prec, rnd) + # Proceed but increase precision + wp += max(-xsub1mag, -xsub2mag) + offset = exp + wp + if offset >= 0: absxman = man << offset + else: absxman = man >> (-offset) + + # Use Taylor series if appropriate + n_for_stirling = int(GAMMA_STIRLING_BETA*wp) + if n < max(100, n_for_stirling) and wp < MAX_GAMMA_TAYLOR_PREC: + if sign: + absxman = -absxman + return gamma_fixed_taylor(x, absxman, wp, prec, rnd, type) + + # Use Stirling's series + # First ensure that |x| is large enough for rapid convergence + xorig = x + + # Argument reduction + r = 0 + if n < n_for_stirling: + r = one = MPZ_ONE << wp + d = n_for_stirling - n + for k in xrange(d): + r = (r * absxman) >> wp + absxman += one + x = xabs = from_man_exp(absxman, -wp) + if sign: + x = mpf_neg(x) + else: + xabs = mpf_abs(x) + + # Asymptotic series + y = real_stirling_series(absxman, wp) + u = to_fixed(mpf_log(xabs, wp), wp) + u = ((absxman - (MPZ_ONE<<(wp-1))) * u) >> wp + y += u + w = from_man_exp(y, -wp) + + # Compute final value + if sign: + # Reflection formula + A = mpf_mul(mpf_sin_pi(xorig, wp), xorig, wp) + B = mpf_neg(mpf_pi(wp)) + if type == 0 or type == 2: + A = mpf_mul(A, mpf_exp(w, wp)) + if r: + B = mpf_mul(B, from_man_exp(r, -wp), wp) + if type == 0: + return mpf_div(B, A, prec, rnd) + if type == 2: + return mpf_div(A, B, prec, rnd) + if type == 3: + if r: + B = mpf_mul(B, from_man_exp(r, -wp), wp) + A = mpf_add(mpf_log(mpf_abs(A), wp), w, wp) + return mpf_sub(mpf_log(mpf_abs(B), wp), A, prec, rnd) + else: + if type == 0: + if r: + return mpf_div(mpf_exp(w, wp), + from_man_exp(r, -wp), prec, rnd) + return mpf_exp(w, prec, rnd) + if type == 2: + if r: + return mpf_div(from_man_exp(r, -wp), + mpf_exp(w, wp), prec, rnd) + return mpf_exp(mpf_neg(w), prec, rnd) + if type == 3: + if r: + return mpf_sub(w, mpf_log(from_man_exp(r,-wp), wp), prec, rnd) + return mpf_pos(w, prec, rnd) + + +def mpc_gamma(z, prec, rnd='d', type=0): + a, b = z + asign, aman, aexp, abc = a + bsign, bman, bexp, bbc = b + + if b == fzero: + # Imaginary part on negative half-axis for log-gamma function + if type == 3 and asign: + re = mpf_gamma(a, prec, rnd, 3) + n = (-aman) >> (-aexp) + im = mpf_mul_int(mpf_pi(prec+10), n, prec, rnd) + return re, im + return mpf_gamma(a, prec, rnd, type), fzero + + # Some kind of complex inf/nan + if (not aman and aexp) or (not bman and bexp): + return (fnan, fnan) + + # Initial working precision + wp = prec + 20 + + amag = aexp+abc + bmag = bexp+bbc + if aman: + mag = max(amag, bmag) + else: + mag = bmag + + # Close to 0 + if mag < -8: + if mag < -wp: + # 1/gamma(z) = z + euler*z^2 + O(z^3) + v = mpc_add(z, mpc_mul_mpf(mpc_mul(z,z,wp),mpf_euler(wp),wp), wp) + if type == 0: return mpc_reciprocal(v, prec, rnd) + if type == 1: return mpc_div(z, v, prec, rnd) + if type == 2: return mpc_pos(v, prec, rnd) + if type == 3: return mpc_log(mpc_reciprocal(v, prec), prec, rnd) + elif type != 1: + wp += (-mag) + + # Handle huge log-gamma values; must do this before converting to + # a fixed-point value. TODO: determine a precise cutoff of validity + # depending on amag and bmag + if type == 3 and mag > wp and ((not asign) or (bmag >= amag)): + return mpc_sub(mpc_mul(z, mpc_log(z, wp), wp), z, prec, rnd) + + # From now on, we assume having a gamma function + if type == 1: + return mpc_gamma((mpf_add(a, fone), b), prec, rnd, 0) + + an = abs(to_int(a)) + bn = abs(to_int(b)) + absn = max(an, bn) + gamma_size = absn*mag + if type == 3: + pass + else: + wp += bitcount(gamma_size) + + # Reflect to the right half-plane. Note that Stirling's expansion + # is valid in the left half-plane too, as long as we're not too close + # to the real axis, but in order to use this argument reduction + # in the negative direction must be implemented. + #need_reflection = asign and ((bmag < 0) or (amag-bmag > 4)) + need_reflection = asign + zorig = z + if need_reflection: + z = mpc_neg(z) + asign, aman, aexp, abc = a = z[0] + bsign, bman, bexp, bbc = b = z[1] + + # Imaginary part very small compared to real one? + yfinal = 0 + balance_prec = 0 + if bmag < -10: + # Check z ~= 1 and z ~= 2 for loggamma + if type == 3: + zsub1 = mpc_sub_mpf(z, fone) + if zsub1[0] == fzero: + cancel1 = -bmag + else: + cancel1 = -max(zsub1[0][2]+zsub1[0][3], bmag) + if cancel1 > wp: + pi = mpf_pi(wp) + x = mpc_mul_mpf(zsub1, pi, wp) + x = mpc_mul(x, x, wp) + x = mpc_div_mpf(x, from_int(12), wp) + y = mpc_mul_mpf(zsub1, mpf_neg(mpf_euler(wp)), wp) + yfinal = mpc_add(x, y, wp) + if not need_reflection: + return mpc_pos(yfinal, prec, rnd) + elif cancel1 > 0: + wp += cancel1 + zsub2 = mpc_sub_mpf(z, ftwo) + if zsub2[0] == fzero: + cancel2 = -bmag + else: + cancel2 = -max(zsub2[0][2]+zsub2[0][3], bmag) + if cancel2 > wp: + pi = mpf_pi(wp) + t = mpf_sub(mpf_mul(pi, pi), from_int(6)) + x = mpc_mul_mpf(mpc_mul(zsub2, zsub2, wp), t, wp) + x = mpc_div_mpf(x, from_int(12), wp) + y = mpc_mul_mpf(zsub2, mpf_sub(fone, mpf_euler(wp)), wp) + yfinal = mpc_add(x, y, wp) + if not need_reflection: + return mpc_pos(yfinal, prec, rnd) + elif cancel2 > 0: + wp += cancel2 + if bmag < -wp: + # Compute directly from the real gamma function. + pp = 2*(wp+10) + aabs = mpf_abs(a) + eps = mpf_shift(fone, amag-wp) + x1 = mpf_gamma(aabs, pp, type=type) + x2 = mpf_gamma(mpf_add(aabs, eps), pp, type=type) + xprime = mpf_div(mpf_sub(x2, x1, pp), eps, pp) + y = mpf_mul(b, xprime, prec, rnd) + yfinal = (x1, y) + # Note: we still need to use the reflection formula for + # near-poles, and the correct branch of the log-gamma function + if not need_reflection: + return mpc_pos(yfinal, prec, rnd) + else: + balance_prec += (-bmag) + + wp += balance_prec + n_for_stirling = int(GAMMA_STIRLING_BETA*wp) + need_reduction = absn < n_for_stirling + + afix = to_fixed(a, wp) + bfix = to_fixed(b, wp) + + r = 0 + if not yfinal: + zprered = z + # Argument reduction + if absn < n_for_stirling: + absn = complex(an, bn) + d = int((1 + n_for_stirling**2 - bn**2)**0.5 - an) + rre = one = MPZ_ONE << wp + rim = MPZ_ZERO + for k in xrange(d): + rre, rim = ((afix*rre-bfix*rim)>>wp), ((afix*rim + bfix*rre)>>wp) + afix += one + r = from_man_exp(rre, -wp), from_man_exp(rim, -wp) + a = from_man_exp(afix, -wp) + z = a, b + + yre, yim = complex_stirling_series(afix, bfix, wp) + # (z-1/2)*log(z) + S + lre, lim = mpc_log(z, wp) + lre = to_fixed(lre, wp) + lim = to_fixed(lim, wp) + yre = ((lre*afix - lim*bfix)>>wp) - (lre>>1) + yre + yim = ((lre*bfix + lim*afix)>>wp) - (lim>>1) + yim + y = from_man_exp(yre, -wp), from_man_exp(yim, -wp) + + if r and type == 3: + # If re(z) > 0 and abs(z) <= 4, the branches of loggamma(z) + # and log(gamma(z)) coincide. Otherwise, use the zeroth order + # Stirling expansion to compute the correct imaginary part. + y = mpc_sub(y, mpc_log(r, wp), wp) + zfa = to_float(zprered[0]) + zfb = to_float(zprered[1]) + zfabs = math.hypot(zfa,zfb) + #if not (zfa > 0.0 and zfabs <= 4): + yfb = to_float(y[1]) + u = math.atan2(zfb, zfa) + if zfabs <= 0.5: + gi = 0.577216*zfb - u + else: + gi = -zfb - 0.5*u + zfa*u + zfb*math.log(zfabs) + n = int(math.floor((gi-yfb)/(2*math.pi)+0.5)) + y = (y[0], mpf_add(y[1], mpf_mul_int(mpf_pi(wp), 2*n, wp), wp)) + + if need_reflection: + if type == 0 or type == 2: + A = mpc_mul(mpc_sin_pi(zorig, wp), zorig, wp) + B = (mpf_neg(mpf_pi(wp)), fzero) + if yfinal: + if type == 2: + A = mpc_div(A, yfinal, wp) + else: + A = mpc_mul(A, yfinal, wp) + else: + A = mpc_mul(A, mpc_exp(y, wp), wp) + if r: + B = mpc_mul(B, r, wp) + if type == 0: return mpc_div(B, A, prec, rnd) + if type == 2: return mpc_div(A, B, prec, rnd) + + # Reflection formula for the log-gamma function with correct branch + # http://functions.wolfram.com/GammaBetaErf/LogGamma/16/01/01/0006/ + # LogGamma[z] == -LogGamma[-z] - Log[-z] + + # Sign[Im[z]] Floor[Re[z]] Pi I + Log[Pi] - + # Log[Sin[Pi (z - Floor[Re[z]])]] - + # Pi I (1 - Abs[Sign[Im[z]]]) Abs[Floor[Re[z]]] + if type == 3: + if yfinal: + s1 = mpc_neg(yfinal) + else: + s1 = mpc_neg(y) + # s -= log(-z) + s1 = mpc_sub(s1, mpc_log(mpc_neg(zorig), wp), wp) + # floor(re(z)) + rezfloor = mpf_floor(zorig[0]) + imzsign = mpf_sign(zorig[1]) + pi = mpf_pi(wp) + t = mpf_mul(pi, rezfloor) + t = mpf_mul_int(t, imzsign, wp) + s1 = (s1[0], mpf_add(s1[1], t, wp)) + s1 = mpc_add_mpf(s1, mpf_log(pi, wp), wp) + t = mpc_sin_pi(mpc_sub_mpf(zorig, rezfloor), wp) + t = mpc_log(t, wp) + s1 = mpc_sub(s1, t, wp) + # Note: may actually be unused, because we fall back + # to the mpf_ function for real arguments + if not imzsign: + t = mpf_mul(pi, mpf_floor(rezfloor), wp) + s1 = (s1[0], mpf_sub(s1[1], t, wp)) + return mpc_pos(s1, prec, rnd) + else: + if type == 0: + if r: + return mpc_div(mpc_exp(y, wp), r, prec, rnd) + return mpc_exp(y, prec, rnd) + if type == 2: + if r: + return mpc_div(r, mpc_exp(y, wp), prec, rnd) + return mpc_exp(mpc_neg(y), prec, rnd) + if type == 3: + return mpc_pos(y, prec, rnd) + +def mpf_factorial(x, prec, rnd='d'): + return mpf_gamma(x, prec, rnd, 1) + +def mpc_factorial(x, prec, rnd='d'): + return mpc_gamma(x, prec, rnd, 1) + +def mpf_rgamma(x, prec, rnd='d'): + return mpf_gamma(x, prec, rnd, 2) + +def mpc_rgamma(x, prec, rnd='d'): + return mpc_gamma(x, prec, rnd, 2) + +def mpf_loggamma(x, prec, rnd='d'): + sign, man, exp, bc = x + if sign: + raise ComplexResult + return mpf_gamma(x, prec, rnd, 3) + +def mpc_loggamma(z, prec, rnd='d'): + a, b = z + asign, aman, aexp, abc = a + bsign, bman, bexp, bbc = b + if b == fzero and asign: + re = mpf_gamma(a, prec, rnd, 3) + n = (-aman) >> (-aexp) + im = mpf_mul_int(mpf_pi(prec+10), n, prec, rnd) + return re, im + return mpc_gamma(z, prec, rnd, 3) + +def mpf_gamma_int(n, prec, rnd=round_fast): + if n < SMALL_FACTORIAL_CACHE_SIZE: + return mpf_pos(small_factorial_cache[n-1], prec, rnd) + return mpf_gamma(from_int(n), prec, rnd) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libelefun.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libelefun.py new file mode 100644 index 0000000000000000000000000000000000000000..3de2e5aaef02296ed03dec3df3021b56823f3728 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libelefun.py @@ -0,0 +1,1428 @@ +""" +This module implements computation of elementary transcendental +functions (powers, logarithms, trigonometric and hyperbolic +functions, inverse trigonometric and hyperbolic) for real +floating-point numbers. + +For complex and interval implementations of the same functions, +see libmpc and libmpi. + +""" + +import math +from bisect import bisect + +from .backend import xrange +from .backend import MPZ, MPZ_ZERO, MPZ_ONE, MPZ_TWO, MPZ_FIVE, BACKEND + +from .libmpf import ( + round_floor, round_ceiling, round_down, round_up, + round_nearest, round_fast, + ComplexResult, + bitcount, bctable, lshift, rshift, giant_steps, sqrt_fixed, + from_int, to_int, from_man_exp, to_fixed, to_float, from_float, + from_rational, normalize, + fzero, fone, fnone, fhalf, finf, fninf, fnan, + mpf_cmp, mpf_sign, mpf_abs, + mpf_pos, mpf_neg, mpf_add, mpf_sub, mpf_mul, mpf_div, mpf_shift, + mpf_rdiv_int, mpf_pow_int, mpf_sqrt, + reciprocal_rnd, negative_rnd, mpf_perturb, + isqrt_fast +) + +from .libintmath import ifib + + +#------------------------------------------------------------------------------- +# Tuning parameters +#------------------------------------------------------------------------------- + +# Cutoff for computing exp from cosh+sinh. This reduces the +# number of terms by half, but also requires a square root which +# is expensive with the pure-Python square root code. +if BACKEND == 'python': + EXP_COSH_CUTOFF = 600 +else: + EXP_COSH_CUTOFF = 400 +# Cutoff for using more than 2 series +EXP_SERIES_U_CUTOFF = 1500 + +# Also basically determined by sqrt +if BACKEND == 'python': + COS_SIN_CACHE_PREC = 400 +else: + COS_SIN_CACHE_PREC = 200 +COS_SIN_CACHE_STEP = 8 +cos_sin_cache = {} + +# Number of integer logarithms to cache (for zeta sums) +MAX_LOG_INT_CACHE = 2000 +log_int_cache = {} + +LOG_TAYLOR_PREC = 2500 # Use Taylor series with caching up to this prec +LOG_TAYLOR_SHIFT = 9 # Cache log values in steps of size 2^-N +log_taylor_cache = {} +# prec/size ratio of x for fastest convergence in AGM formula +LOG_AGM_MAG_PREC_RATIO = 20 + +ATAN_TAYLOR_PREC = 3000 # Same as for log +ATAN_TAYLOR_SHIFT = 7 # steps of size 2^-N +atan_taylor_cache = {} + + +# ~= next power of two + 20 +cache_prec_steps = [22,22] +for k in xrange(1, bitcount(LOG_TAYLOR_PREC)+1): + cache_prec_steps += [min(2**k,LOG_TAYLOR_PREC)+20] * 2**(k-1) + + +#----------------------------------------------------------------------------# +# # +# Elementary mathematical constants # +# # +#----------------------------------------------------------------------------# + +def constant_memo(f): + """ + Decorator for caching computed values of mathematical + constants. This decorator should be applied to a + function taking a single argument prec as input and + returning a fixed-point value with the given precision. + """ + f.memo_prec = -1 + f.memo_val = None + def g(prec, **kwargs): + memo_prec = f.memo_prec + if prec <= memo_prec: + return f.memo_val >> (memo_prec-prec) + newprec = int(prec*1.05+10) + f.memo_val = f(newprec, **kwargs) + f.memo_prec = newprec + return f.memo_val >> (newprec-prec) + g.__name__ = f.__name__ + g.__doc__ = f.__doc__ + return g + +def def_mpf_constant(fixed): + """ + Create a function that computes the mpf value for a mathematical + constant, given a function that computes the fixed-point value. + + Assumptions: the constant is positive and has magnitude ~= 1; + the fixed-point function rounds to floor. + """ + def f(prec, rnd=round_fast): + wp = prec + 20 + v = fixed(wp) + if rnd in (round_up, round_ceiling): + v += 1 + return normalize(0, v, -wp, bitcount(v), prec, rnd) + f.__doc__ = fixed.__doc__ + return f + +def bsp_acot(q, a, b, hyperbolic): + if b - a == 1: + a1 = MPZ(2*a + 3) + if hyperbolic or a&1: + return MPZ_ONE, a1 * q**2, a1 + else: + return -MPZ_ONE, a1 * q**2, a1 + m = (a+b)//2 + p1, q1, r1 = bsp_acot(q, a, m, hyperbolic) + p2, q2, r2 = bsp_acot(q, m, b, hyperbolic) + return q2*p1 + r1*p2, q1*q2, r1*r2 + +# the acoth(x) series converges like the geometric series for x^2 +# N = ceil(p*log(2)/(2*log(x))) +def acot_fixed(a, prec, hyperbolic): + """ + Compute acot(a) or acoth(a) for an integer a with binary splitting; see + http://numbers.computation.free.fr/Constants/Algorithms/splitting.html + """ + N = int(0.35 * prec/math.log(a) + 20) + p, q, r = bsp_acot(a, 0,N, hyperbolic) + return ((p+q)<> extraprec) + +# Logarithms of integers are needed for various computations involving +# logarithms, powers, radix conversion, etc + +@constant_memo +def ln2_fixed(prec): + """ + Computes ln(2). This is done with a hyperbolic Machin-type formula, + with binary splitting at high precision. + """ + return machin([(18, 26), (-2, 4801), (8, 8749)], prec, True) + +@constant_memo +def ln10_fixed(prec): + """ + Computes ln(10). This is done with a hyperbolic Machin-type formula. + """ + return machin([(46, 31), (34, 49), (20, 161)], prec, True) + + +r""" +For computation of pi, we use the Chudnovsky series: + + oo + ___ k + 1 \ (-1) (6 k)! (A + B k) + ----- = ) ----------------------- + 12 pi /___ 3 3k+3/2 + (3 k)! (k!) C + k = 0 + +where A, B, and C are certain integer constants. This series adds roughly +14 digits per term. Note that C^(3/2) can be extracted so that the +series contains only rational terms. This makes binary splitting very +efficient. + +The recurrence formulas for the binary splitting were taken from +ftp://ftp.gmplib.org/pub/src/gmp-chudnovsky.c + +Previously, Machin's formula was used at low precision and the AGM iteration +was used at high precision. However, the Chudnovsky series is essentially as +fast as the Machin formula at low precision and in practice about 3x faster +than the AGM at high precision (despite theoretically having a worse +asymptotic complexity), so there is no reason not to use it in all cases. + +""" + +# Constants in Chudnovsky's series +CHUD_A = MPZ(13591409) +CHUD_B = MPZ(545140134) +CHUD_C = MPZ(640320) +CHUD_D = MPZ(12) + +def bs_chudnovsky(a, b, level, verbose): + """ + Computes the sum from a to b of the series in the Chudnovsky + formula. Returns g, p, q where p/q is the sum as an exact + fraction and g is a temporary value used to save work + for recursive calls. + """ + if b-a == 1: + g = MPZ((6*b-5)*(2*b-1)*(6*b-1)) + p = b**3 * CHUD_C**3 // 24 + q = (-1)**b * g * (CHUD_A+CHUD_B*b) + else: + if verbose and level < 4: + print(" binary splitting", a, b) + mid = (a+b)//2 + g1, p1, q1 = bs_chudnovsky(a, mid, level+1, verbose) + g2, p2, q2 = bs_chudnovsky(mid, b, level+1, verbose) + p = p1*p2 + g = g1*g2 + q = q1*p2 + q2*g1 + return g, p, q + +@constant_memo +def pi_fixed(prec, verbose=False, verbose_base=None): + """ + Compute floor(pi * 2**prec) as a big integer. + + This is done using Chudnovsky's series (see comments in + libelefun.py for details). + """ + # The Chudnovsky series gives 14.18 digits per term + N = int(prec/3.3219280948/14.181647462 + 2) + if verbose: + print("binary splitting with N =", N) + g, p, q = bs_chudnovsky(0, N, 0, verbose) + sqrtC = isqrt_fast(CHUD_C<<(2*prec)) + v = p*CHUD_C*sqrtC//((q+CHUD_A*p)*CHUD_D) + return v + +def degree_fixed(prec): + return pi_fixed(prec)//180 + +def bspe(a, b): + """ + Sum series for exp(1)-1 between a, b, returning the result + as an exact fraction (p, q). + """ + if b-a == 1: + return MPZ_ONE, MPZ(b) + m = (a+b)//2 + p1, q1 = bspe(a, m) + p2, q2 = bspe(m, b) + return p1*q2+p2, q1*q2 + +@constant_memo +def e_fixed(prec): + """ + Computes exp(1). This is done using the ordinary Taylor series for + exp, with binary splitting. For a description of the algorithm, + see: + + http://numbers.computation.free.fr/Constants/ + Algorithms/splitting.html + """ + # Slight overestimate of N needed for 1/N! < 2**(-prec) + # This could be tightened for large N. + N = int(1.1*prec/math.log(prec) + 20) + p, q = bspe(0,N) + return ((p+q)<> 11 + +mpf_phi = def_mpf_constant(phi_fixed) +mpf_pi = def_mpf_constant(pi_fixed) +mpf_e = def_mpf_constant(e_fixed) +mpf_degree = def_mpf_constant(degree_fixed) +mpf_ln2 = def_mpf_constant(ln2_fixed) +mpf_ln10 = def_mpf_constant(ln10_fixed) + + +@constant_memo +def ln_sqrt2pi_fixed(prec): + wp = prec + 10 + # ln(sqrt(2*pi)) = ln(2*pi)/2 + return to_fixed(mpf_log(mpf_shift(mpf_pi(wp), 1), wp), prec-1) + +@constant_memo +def sqrtpi_fixed(prec): + return sqrt_fixed(pi_fixed(prec), prec) + +mpf_sqrtpi = def_mpf_constant(sqrtpi_fixed) +mpf_ln_sqrt2pi = def_mpf_constant(ln_sqrt2pi_fixed) + + +#----------------------------------------------------------------------------# +# # +# Powers # +# # +#----------------------------------------------------------------------------# + +def mpf_pow(s, t, prec, rnd=round_fast): + """ + Compute s**t. Raises ComplexResult if s is negative and t is + fractional. + """ + ssign, sman, sexp, sbc = s + tsign, tman, texp, tbc = t + if ssign and texp < 0: + raise ComplexResult("negative number raised to a fractional power") + if texp >= 0: + return mpf_pow_int(s, (-1)**tsign * (tman<> pbc)] + if pbc > workprec: + pm = pm >> (pbc-workprec) + pe += pbc - workprec + pbc = workprec + n -= 1 + if not n: + break + y = y*y + exp = exp+exp + bc = bc + bc - 2 + bc = bc + bctable[int(y >> bc)] + if bc > workprec: + y = y >> (bc-workprec) + exp += bc - workprec + bc = workprec + n = n // 2 + return pm, pe + +# froot(s, n, prec, rnd) computes the real n-th root of a +# positive mpf tuple s. +# To compute the root we start from a 50-bit estimate for r +# generated with ordinary floating-point arithmetic, and then refine +# the value to full accuracy using the iteration + +# 1 / y \ +# r = --- | (n-1) * r + ---------- | +# n+1 n \ n r_n**(n-1) / + +# which is simply Newton's method applied to the equation r**n = y. +# With giant_steps(start, prec+extra) = [p0,...,pm, prec+extra] +# and y = man * 2**-shift one has +# (man * 2**exp)**(1/n) = +# y**(1/n) * 2**(start-prec/n) * 2**(p0-start) * ... * 2**(prec+extra-pm) * +# 2**((exp+shift-(n-1)*prec)/n -extra)) +# The last factor is accounted for in the last line of froot. + +def nthroot_fixed(y, n, prec, exp1): + start = 50 + try: + y1 = rshift(y, prec - n*start) + r = MPZ(int(y1**(1.0/n))) + except OverflowError: + y1 = from_int(y1, start) + fn = from_int(n) + fn = mpf_rdiv_int(1, fn, start) + r = mpf_pow(y1, fn, start) + r = to_int(r) + extra = 10 + extra1 = n + prevp = start + for p in giant_steps(start, prec+extra): + pm, pe = int_pow_fixed(r, n-1, prevp) + r2 = rshift(pm, (n-1)*prevp - p - pe - extra1) + B = lshift(y, 2*p-prec+extra1)//r2 + r = (B + (n-1) * lshift(r, p-prevp))//n + prevp = p + return r + +def mpf_nthroot(s, n, prec, rnd=round_fast): + """nth-root of a positive number + + Use the Newton method when faster, otherwise use x**(1/n) + """ + sign, man, exp, bc = s + if sign: + raise ComplexResult("nth root of a negative number") + if not man: + if s == fnan: + return fnan + if s == fzero: + if n > 0: + return fzero + if n == 0: + return fone + return finf + # Infinity + if not n: + return fnan + if n < 0: + return fzero + return finf + flag_inverse = False + if n < 2: + if n == 0: + return fone + if n == 1: + return mpf_pos(s, prec, rnd) + if n == -1: + return mpf_div(fone, s, prec, rnd) + # n < 0 + rnd = reciprocal_rnd[rnd] + flag_inverse = True + extra_inverse = 5 + prec += extra_inverse + n = -n + if n > 20 and (n >= 20000 or prec < int(233 + 28.3 * n**0.62)): + prec2 = prec + 10 + fn = from_int(n) + nth = mpf_rdiv_int(1, fn, prec2) + r = mpf_pow(s, nth, prec2, rnd) + s = normalize(r[0], r[1], r[2], r[3], prec, rnd) + if flag_inverse: + return mpf_div(fone, s, prec-extra_inverse, rnd) + else: + return s + # Convert to a fixed-point number with prec2 bits. + prec2 = prec + 2*n - (prec%n) + # a few tests indicate that + # for 10 < n < 10**4 a bit more precision is needed + if n > 10: + prec2 += prec2//10 + prec2 = prec2 - prec2%n + # Mantissa may have more bits than we need. Trim it down. + shift = bc - prec2 + # Adjust exponents to make prec2 and exp+shift multiples of n. + sign1 = 0 + es = exp+shift + if es < 0: + sign1 = 1 + es = -es + if sign1: + shift += es%n + else: + shift -= es%n + man = rshift(man, shift) + extra = 10 + exp1 = ((exp+shift-(n-1)*prec2)//n) - extra + rnd_shift = 0 + if flag_inverse: + if rnd == 'u' or rnd == 'c': + rnd_shift = 1 + else: + if rnd == 'd' or rnd == 'f': + rnd_shift = 1 + man = nthroot_fixed(man+rnd_shift, n, prec2, exp1) + s = from_man_exp(man, exp1, prec, rnd) + if flag_inverse: + return mpf_div(fone, s, prec-extra_inverse, rnd) + else: + return s + +def mpf_cbrt(s, prec, rnd=round_fast): + """cubic root of a positive number""" + return mpf_nthroot(s, 3, prec, rnd) + +#----------------------------------------------------------------------------# +# # +# Logarithms # +# # +#----------------------------------------------------------------------------# + + +def log_int_fixed(n, prec, ln2=None): + """ + Fast computation of log(n), caching the value for small n, + intended for zeta sums. + """ + if n in log_int_cache: + value, vprec = log_int_cache[n] + if vprec >= prec: + return value >> (vprec - prec) + wp = prec + 10 + if wp <= LOG_TAYLOR_SHIFT: + if ln2 is None: + ln2 = ln2_fixed(wp) + r = bitcount(n) + x = n << (wp-r) + v = log_taylor_cached(x, wp) + r*ln2 + else: + v = to_fixed(mpf_log(from_int(n), wp+5), wp) + if n < MAX_LOG_INT_CACHE: + log_int_cache[n] = (v, wp) + return v >> (wp-prec) + +def agm_fixed(a, b, prec): + """ + Fixed-point computation of agm(a,b), assuming + a, b both close to unit magnitude. + """ + i = 0 + while 1: + anew = (a+b)>>1 + if i > 4 and abs(a-anew) < 8: + return a + b = isqrt_fast(a*b) + a = anew + i += 1 + return a + +def log_agm(x, prec): + """ + Fixed-point computation of -log(x) = log(1/x), suitable + for large precision. It is required that 0 < x < 1. The + algorithm used is the Sasaki-Kanada formula + + -log(x) = pi/agm(theta2(x)^2,theta3(x)^2). [1] + + For faster convergence in the theta functions, x should + be chosen closer to 0. + + Guard bits must be added by the caller. + + HYPOTHESIS: if x = 2^(-n), n bits need to be added to + account for the truncation to a fixed-point number, + and this is the only significant cancellation error. + + The number of bits lost to roundoff is small and can be + considered constant. + + [1] Richard P. Brent, "Fast Algorithms for High-Precision + Computation of Elementary Functions (extended abstract)", + http://wwwmaths.anu.edu.au/~brent/pd/RNC7-Brent.pdf + + """ + x2 = (x*x) >> prec + # Compute jtheta2(x)**2 + s = a = b = x2 + while a: + b = (b*x2) >> prec + a = (a*b) >> prec + s += a + s += (MPZ_ONE<>(prec-2) + s = (s*isqrt_fast(x<>prec + # Compute jtheta3(x)**2 + t = a = b = x + while a: + b = (b*x2) >> prec + a = (a*b) >> prec + t += a + t = (MPZ_ONE<>prec + # Final formula + p = agm_fixed(s, t, prec) + return (pi_fixed(prec) << prec) // p + +def log_taylor(x, prec, r=0): + """ + Fixed-point calculation of log(x). It is assumed that x is close + enough to 1 for the Taylor series to converge quickly. Convergence + can be improved by specifying r > 0 to compute + log(x^(1/2^r))*2^r, at the cost of performing r square roots. + + The caller must provide sufficient guard bits. + """ + for i in xrange(r): + x = isqrt_fast(x<> prec + v4 = (v2*v2) >> prec + s0 = v + s1 = v//3 + v = (v*v4) >> prec + k = 5 + while v: + s0 += v // k + k += 2 + s1 += v // k + v = (v*v4) >> prec + k += 2 + s1 = (s1*v2) >> prec + s = (s0+s1) << (1+r) + if sign: + return -s + return s + +def log_taylor_cached(x, prec): + """ + Fixed-point computation of log(x), assuming x in (0.5, 2) + and prec <= LOG_TAYLOR_PREC. + """ + n = x >> (prec-LOG_TAYLOR_SHIFT) + cached_prec = cache_prec_steps[prec] + dprec = cached_prec - prec + if (n, cached_prec) in log_taylor_cache: + a, log_a = log_taylor_cache[n, cached_prec] + else: + a = n << (cached_prec - LOG_TAYLOR_SHIFT) + log_a = log_taylor(a, cached_prec, 8) + log_taylor_cache[n, cached_prec] = (a, log_a) + a >>= dprec + log_a >>= dprec + u = ((x - a) << prec) // a + v = (u << prec) // ((MPZ_TWO << prec) + u) + v2 = (v*v) >> prec + v4 = (v2*v2) >> prec + s0 = v + s1 = v//3 + v = (v*v4) >> prec + k = 5 + while v: + s0 += v//k + k += 2 + s1 += v//k + v = (v*v4) >> prec + k += 2 + s1 = (s1*v2) >> prec + s = (s0+s1) << 1 + return log_a + s + +def mpf_log(x, prec, rnd=round_fast): + """ + Compute the natural logarithm of the mpf value x. If x is negative, + ComplexResult is raised. + """ + sign, man, exp, bc = x + #------------------------------------------------------------------ + # Handle special values + if not man: + if x == fzero: return fninf + if x == finf: return finf + if x == fnan: return fnan + if sign: + raise ComplexResult("logarithm of a negative number") + wp = prec + 20 + #------------------------------------------------------------------ + # Handle log(2^n) = log(n)*2. + # Here we catch the only possible exact value, log(1) = 0 + if man == 1: + if not exp: + return fzero + return from_man_exp(exp*ln2_fixed(wp), -wp, prec, rnd) + mag = exp+bc + abs_mag = abs(mag) + #------------------------------------------------------------------ + # Handle x = 1+eps, where log(x) ~ x. We need to check for + # cancellation when moving to fixed-point math and compensate + # by increasing the precision. Note that abs_mag in (0, 1) <=> + # 0.5 < x < 2 and x != 1 + if abs_mag <= 1: + # Calculate t = x-1 to measure distance from 1 in bits + tsign = 1-abs_mag + if tsign: + tman = (MPZ_ONE< wp: + t = normalize(tsign, tman, abs_mag-bc, tbc, tbc, 'n') + return mpf_perturb(t, tsign, prec, rnd) + else: + wp += cancellation + # TODO: if close enough to 1, we could use Taylor series + # even in the AGM precision range, since the Taylor series + # converges rapidly + #------------------------------------------------------------------ + # Another special case: + # n*log(2) is a good enough approximation + if abs_mag > 10000: + if bitcount(abs_mag) > wp: + return from_man_exp(exp*ln2_fixed(wp), -wp, prec, rnd) + #------------------------------------------------------------------ + # General case. + # Perform argument reduction using log(x) = log(x*2^n) - n*log(2): + # If we are in the Taylor precision range, choose magnitude 0 or 1. + # If we are in the AGM precision range, choose magnitude -m for + # some large m; benchmarking on one machine showed m = prec/20 to be + # optimal between 1000 and 100,000 digits. + if wp <= LOG_TAYLOR_PREC: + m = log_taylor_cached(lshift(man, wp-bc), wp) + if mag: + m += mag*ln2_fixed(wp) + else: + optimal_mag = -wp//LOG_AGM_MAG_PREC_RATIO + n = optimal_mag - mag + x = mpf_shift(x, n) + wp += (-optimal_mag) + m = -log_agm(to_fixed(x, wp), wp) + m -= n*ln2_fixed(wp) + return from_man_exp(m, -wp, prec, rnd) + +def mpf_log_hypot(a, b, prec, rnd): + """ + Computes log(sqrt(a^2+b^2)) accurately. + """ + # If either a or b is inf/nan/0, assume it to be a + if not b[1]: + a, b = b, a + # a is inf/nan/0 + if not a[1]: + # both are inf/nan/0 + if not b[1]: + if a == b == fzero: + return fninf + if fnan in (a, b): + return fnan + # at least one term is (+/- inf)^2 + return finf + # only a is inf/nan/0 + if a == fzero: + # log(sqrt(0+b^2)) = log(|b|) + return mpf_log(mpf_abs(b), prec, rnd) + if a == fnan: + return fnan + return finf + # Exact + a2 = mpf_mul(a,a) + b2 = mpf_mul(b,b) + extra = 20 + # Not exact + h2 = mpf_add(a2, b2, prec+extra) + cancelled = mpf_add(h2, fnone, 10) + mag_cancelled = cancelled[2]+cancelled[3] + # Just redo the sum exactly if necessary (could be smarter + # and avoid memory allocation when a or b is precisely 1 + # and the other is tiny...) + if cancelled == fzero or mag_cancelled < -extra//2: + h2 = mpf_add(a2, b2, prec+extra-min(a2[2],b2[2])) + return mpf_shift(mpf_log(h2, prec, rnd), -1) + + +#---------------------------------------------------------------------- +# Inverse tangent +# + +def atan_newton(x, prec): + if prec >= 100: + r = math.atan(int((x>>(prec-53)))/2.0**53) + else: + r = math.atan(int(x)/2.0**prec) + prevp = 50 + r = MPZ(int(r * 2.0**53) >> (53-prevp)) + extra_p = 50 + for wp in giant_steps(prevp, prec): + wp += extra_p + r = r << (wp-prevp) + cos, sin = cos_sin_fixed(r, wp) + tan = (sin << wp) // cos + a = ((tan-rshift(x, prec-wp)) << wp) // ((MPZ_ONE<>wp)) + r = r - a + prevp = wp + return rshift(r, prevp-prec) + +def atan_taylor_get_cached(n, prec): + # Taylor series with caching wins up to huge precisions + # To avoid unnecessary precomputation at low precision, we + # do it in steps + # Round to next power of 2 + prec2 = (1<<(bitcount(prec-1))) + 20 + dprec = prec2 - prec + if (n, prec2) in atan_taylor_cache: + a, atan_a = atan_taylor_cache[n, prec2] + else: + a = n << (prec2 - ATAN_TAYLOR_SHIFT) + atan_a = atan_newton(a, prec2) + atan_taylor_cache[n, prec2] = (a, atan_a) + return (a >> dprec), (atan_a >> dprec) + +def atan_taylor(x, prec): + n = (x >> (prec-ATAN_TAYLOR_SHIFT)) + a, atan_a = atan_taylor_get_cached(n, prec) + d = x - a + s0 = v = (d << prec) // ((a**2 >> prec) + (a*d >> prec) + (MPZ_ONE << prec)) + v2 = (v**2 >> prec) + v4 = (v2 * v2) >> prec + s1 = v//3 + v = (v * v4) >> prec + k = 5 + while v: + s0 += v // k + k += 2 + s1 += v // k + v = (v * v4) >> prec + k += 2 + s1 = (s1 * v2) >> prec + s = s0 - s1 + return atan_a + s + +def atan_inf(sign, prec, rnd): + if not sign: + return mpf_shift(mpf_pi(prec, rnd), -1) + return mpf_neg(mpf_shift(mpf_pi(prec, negative_rnd[rnd]), -1)) + +def mpf_atan(x, prec, rnd=round_fast): + sign, man, exp, bc = x + if not man: + if x == fzero: return fzero + if x == finf: return atan_inf(0, prec, rnd) + if x == fninf: return atan_inf(1, prec, rnd) + return fnan + mag = exp + bc + # Essentially infinity + if mag > prec+20: + return atan_inf(sign, prec, rnd) + # Essentially ~ x + if -mag > prec+20: + return mpf_perturb(x, 1-sign, prec, rnd) + wp = prec + 30 + abs(mag) + # For large x, use atan(x) = pi/2 - atan(1/x) + if mag >= 2: + x = mpf_rdiv_int(1, x, wp) + reciprocal = True + else: + reciprocal = False + t = to_fixed(x, wp) + if sign: + t = -t + if wp < ATAN_TAYLOR_PREC: + a = atan_taylor(t, wp) + else: + a = atan_newton(t, wp) + if reciprocal: + a = ((pi_fixed(wp)>>1)+1) - a + if sign: + a = -a + return from_man_exp(a, -wp, prec, rnd) + +# TODO: cleanup the special cases +def mpf_atan2(y, x, prec, rnd=round_fast): + xsign, xman, xexp, xbc = x + ysign, yman, yexp, ybc = y + if not yman: + if y == fzero and x != fnan: + if mpf_sign(x) >= 0: + return fzero + return mpf_pi(prec, rnd) + if y in (finf, fninf): + if x in (finf, fninf): + return fnan + # pi/2 + if y == finf: + return mpf_shift(mpf_pi(prec, rnd), -1) + # -pi/2 + return mpf_neg(mpf_shift(mpf_pi(prec, negative_rnd[rnd]), -1)) + return fnan + if ysign: + return mpf_neg(mpf_atan2(mpf_neg(y), x, prec, negative_rnd[rnd])) + if not xman: + if x == fnan: + return fnan + if x == finf: + return fzero + if x == fninf: + return mpf_pi(prec, rnd) + if y == fzero: + return fzero + return mpf_shift(mpf_pi(prec, rnd), -1) + tquo = mpf_atan(mpf_div(y, x, prec+4), prec+4) + if xsign: + return mpf_add(mpf_pi(prec+4), tquo, prec, rnd) + else: + return mpf_pos(tquo, prec, rnd) + +def mpf_asin(x, prec, rnd=round_fast): + sign, man, exp, bc = x + if bc+exp > 0 and x not in (fone, fnone): + raise ComplexResult("asin(x) is real only for -1 <= x <= 1") + # asin(x) = 2*atan(x/(1+sqrt(1-x**2))) + wp = prec + 15 + a = mpf_mul(x, x) + b = mpf_add(fone, mpf_sqrt(mpf_sub(fone, a, wp), wp), wp) + c = mpf_div(x, b, wp) + return mpf_shift(mpf_atan(c, prec, rnd), 1) + +def mpf_acos(x, prec, rnd=round_fast): + # acos(x) = 2*atan(sqrt(1-x**2)/(1+x)) + sign, man, exp, bc = x + if bc + exp > 0: + if x not in (fone, fnone): + raise ComplexResult("acos(x) is real only for -1 <= x <= 1") + if x == fnone: + return mpf_pi(prec, rnd) + wp = prec + 15 + a = mpf_mul(x, x) + b = mpf_sqrt(mpf_sub(fone, a, wp), wp) + c = mpf_div(b, mpf_add(fone, x, wp), wp) + return mpf_shift(mpf_atan(c, prec, rnd), 1) + +def mpf_asinh(x, prec, rnd=round_fast): + wp = prec + 20 + sign, man, exp, bc = x + mag = exp+bc + if mag < -8: + if mag < -wp: + return mpf_perturb(x, 1-sign, prec, rnd) + wp += (-mag) + # asinh(x) = log(x+sqrt(x**2+1)) + # use reflection symmetry to avoid cancellation + q = mpf_sqrt(mpf_add(mpf_mul(x, x), fone, wp), wp) + q = mpf_add(mpf_abs(x), q, wp) + if sign: + return mpf_neg(mpf_log(q, prec, negative_rnd[rnd])) + else: + return mpf_log(q, prec, rnd) + +def mpf_acosh(x, prec, rnd=round_fast): + # acosh(x) = log(x+sqrt(x**2-1)) + wp = prec + 15 + if mpf_cmp(x, fone) == -1: + raise ComplexResult("acosh(x) is real only for x >= 1") + q = mpf_sqrt(mpf_add(mpf_mul(x,x), fnone, wp), wp) + return mpf_log(mpf_add(x, q, wp), prec, rnd) + +def mpf_atanh(x, prec, rnd=round_fast): + # atanh(x) = log((1+x)/(1-x))/2 + sign, man, exp, bc = x + if (not man) and exp: + if x in (fzero, fnan): + return x + raise ComplexResult("atanh(x) is real only for -1 <= x <= 1") + mag = bc + exp + if mag > 0: + if mag == 1 and man == 1: + return [finf, fninf][sign] + raise ComplexResult("atanh(x) is real only for -1 <= x <= 1") + wp = prec + 15 + if mag < -8: + if mag < -wp: + return mpf_perturb(x, sign, prec, rnd) + wp += (-mag) + a = mpf_add(x, fone, wp) + b = mpf_sub(fone, x, wp) + return mpf_shift(mpf_log(mpf_div(a, b, wp), prec, rnd), -1) + +def mpf_fibonacci(x, prec, rnd=round_fast): + sign, man, exp, bc = x + if not man: + if x == fninf: + return fnan + return x + # F(2^n) ~= 2^(2^n) + size = abs(exp+bc) + if exp >= 0: + # Exact + if size < 10 or size <= bitcount(prec): + return from_int(ifib(to_int(x)), prec, rnd) + # Use the modified Binet formula + wp = prec + size + 20 + a = mpf_phi(wp) + b = mpf_add(mpf_shift(a, 1), fnone, wp) + u = mpf_pow(a, x, wp) + v = mpf_cos_pi(x, wp) + v = mpf_div(v, u, wp) + u = mpf_sub(u, v, wp) + u = mpf_div(u, b, prec, rnd) + return u + + +#------------------------------------------------------------------------------- +# Exponential-type functions +#------------------------------------------------------------------------------- + +def exponential_series(x, prec, type=0): + """ + Taylor series for cosh/sinh or cos/sin. + + type = 0 -- returns exp(x) (slightly faster than cosh+sinh) + type = 1 -- returns (cosh(x), sinh(x)) + type = 2 -- returns (cos(x), sin(x)) + """ + if x < 0: + x = -x + sign = 1 + else: + sign = 0 + r = int(0.5*prec**0.5) + xmag = bitcount(x) - prec + r = max(0, xmag + r) + extra = 10 + 2*max(r,-xmag) + wp = prec + extra + x <<= (extra - r) + one = MPZ_ONE << wp + alt = (type == 2) + if prec < EXP_SERIES_U_CUTOFF: + x2 = a = (x*x) >> wp + x4 = (x2*x2) >> wp + s0 = s1 = MPZ_ZERO + k = 2 + while a: + a //= (k-1)*k; s0 += a; k += 2 + a //= (k-1)*k; s1 += a; k += 2 + a = (a*x4) >> wp + s1 = (x2*s1) >> wp + if alt: + c = s1 - s0 + one + else: + c = s1 + s0 + one + else: + u = int(0.3*prec**0.35) + x2 = a = (x*x) >> wp + xpowers = [one, x2] + for i in xrange(1, u): + xpowers.append((xpowers[-1]*x2)>>wp) + sums = [MPZ_ZERO] * u + k = 2 + while a: + for i in xrange(u): + a //= (k-1)*k + if alt and k & 2: sums[i] -= a + else: sums[i] += a + k += 2 + a = (a*xpowers[-1]) >> wp + for i in xrange(1, u): + sums[i] = (sums[i]*xpowers[i]) >> wp + c = sum(sums) + one + if type == 0: + s = isqrt_fast(c*c - (one<> wp + return v >> extra + else: + # Repeatedly apply the double-angle formula + # cosh(2*x) = 2*cosh(x)^2 - 1 + # cos(2*x) = 2*cos(x)^2 - 1 + pshift = wp-1 + for i in xrange(r): + c = ((c*c) >> pshift) - one + # With the abs, this is the same for sinh and sin + s = isqrt_fast(abs((one<>extra), (s>>extra) + +def exp_basecase(x, prec): + """ + Compute exp(x) as a fixed-point number. Works for any x, + but for speed should have |x| < 1. For an arbitrary number, + use exp(x) = exp(x-m*log(2)) * 2^m where m = floor(x/log(2)). + """ + if prec > EXP_COSH_CUTOFF: + return exponential_series(x, prec, 0) + r = int(prec**0.5) + prec += r + s0 = s1 = (MPZ_ONE << prec) + k = 2 + a = x2 = (x*x) >> prec + while a: + a //= k; s0 += a; k += 1 + a //= k; s1 += a; k += 1 + a = (a*x2) >> prec + s1 = (s1*x) >> prec + s = s0 + s1 + u = r + while r: + s = (s*s) >> prec + r -= 1 + return s >> u + +def exp_expneg_basecase(x, prec): + """ + Computation of exp(x), exp(-x) + """ + if prec > EXP_COSH_CUTOFF: + cosh, sinh = exponential_series(x, prec, 1) + return cosh+sinh, cosh-sinh + a = exp_basecase(x, prec) + b = (MPZ_ONE << (prec+prec)) // a + return a, b + +def cos_sin_basecase(x, prec): + """ + Compute cos(x), sin(x) as fixed-point numbers, assuming x + in [0, pi/2). For an arbitrary number, use x' = x - m*(pi/2) + where m = floor(x/(pi/2)) along with quarter-period symmetries. + """ + if prec > COS_SIN_CACHE_PREC: + return exponential_series(x, prec, 2) + precs = prec - COS_SIN_CACHE_STEP + t = x >> precs + n = int(t) + if n not in cos_sin_cache: + w = t<<(10+COS_SIN_CACHE_PREC-COS_SIN_CACHE_STEP) + cos_t, sin_t = exponential_series(w, 10+COS_SIN_CACHE_PREC, 2) + cos_sin_cache[n] = (cos_t>>10), (sin_t>>10) + cos_t, sin_t = cos_sin_cache[n] + offset = COS_SIN_CACHE_PREC - prec + cos_t >>= offset + sin_t >>= offset + x -= t << precs + cos = MPZ_ONE << prec + sin = x + k = 2 + a = -((x*x) >> prec) + while a: + a //= k; cos += a; k += 1; a = (a*x) >> prec + a //= k; sin += a; k += 1; a = -((a*x) >> prec) + return ((cos*cos_t-sin*sin_t) >> prec), ((sin*cos_t+cos*sin_t) >> prec) + +def mpf_exp(x, prec, rnd=round_fast): + sign, man, exp, bc = x + if man: + mag = bc + exp + wp = prec + 14 + if sign: + man = -man + # TODO: the best cutoff depends on both x and the precision. + if prec > 600 and exp >= 0: + # Need about log2(exp(n)) ~= 1.45*mag extra precision + e = mpf_e(wp+int(1.45*mag)) + return mpf_pow_int(e, man<= 2 + if mag > 1: + # For large arguments: exp(2^mag*(1+eps)) = + # exp(2^mag)*exp(2^mag*eps) = exp(2^mag)*(1 + 2^mag*eps + ...) + # so about mag extra bits is required. + wpmod = wp + mag + offset = exp + wpmod + if offset >= 0: + t = man << offset + else: + t = man >> (-offset) + lg2 = ln2_fixed(wpmod) + n, t = divmod(t, lg2) + n = int(n) + t >>= mag + else: + offset = exp + wp + if offset >= 0: + t = man << offset + else: + t = man >> (-offset) + n = 0 + man = exp_basecase(t, wp) + return from_man_exp(man, n-wp, prec, rnd) + if not exp: + return fone + if x == fninf: + return fzero + return x + + +def mpf_cosh_sinh(x, prec, rnd=round_fast, tanh=0): + """Simultaneously compute (cosh(x), sinh(x)) for real x""" + sign, man, exp, bc = x + if (not man) and exp: + if tanh: + if x == finf: return fone + if x == fninf: return fnone + return fnan + if x == finf: return (finf, finf) + if x == fninf: return (finf, fninf) + return fnan, fnan + mag = exp+bc + wp = prec+14 + if mag < -4: + # Extremely close to 0, sinh(x) ~= x and cosh(x) ~= 1 + if mag < -wp: + if tanh: + return mpf_perturb(x, 1-sign, prec, rnd) + cosh = mpf_perturb(fone, 0, prec, rnd) + sinh = mpf_perturb(x, sign, prec, rnd) + return cosh, sinh + # Fix for cancellation when computing sinh + wp += (-mag) + # Does exp(-2*x) vanish? + if mag > 10: + if 3*(1<<(mag-1)) > wp: + # XXX: rounding + if tanh: + return mpf_perturb([fone,fnone][sign], 1-sign, prec, rnd) + c = s = mpf_shift(mpf_exp(mpf_abs(x), prec, rnd), -1) + if sign: + s = mpf_neg(s) + return c, s + # |x| > 1 + if mag > 1: + wpmod = wp + mag + offset = exp + wpmod + if offset >= 0: + t = man << offset + else: + t = man >> (-offset) + lg2 = ln2_fixed(wpmod) + n, t = divmod(t, lg2) + n = int(n) + t >>= mag + else: + offset = exp + wp + if offset >= 0: + t = man << offset + else: + t = man >> (-offset) + n = 0 + a, b = exp_expneg_basecase(t, wp) + # TODO: optimize division precision + cosh = a + (b>>(2*n)) + sinh = a - (b>>(2*n)) + if sign: + sinh = -sinh + if tanh: + man = (sinh << wp) // cosh + return from_man_exp(man, -wp, prec, rnd) + else: + cosh = from_man_exp(cosh, n-wp-1, prec, rnd) + sinh = from_man_exp(sinh, n-wp-1, prec, rnd) + return cosh, sinh + + +def mod_pi2(man, exp, mag, wp): + # Reduce to standard interval + if mag > 0: + i = 0 + while 1: + cancellation_prec = 20 << i + wpmod = wp + mag + cancellation_prec + pi2 = pi_fixed(wpmod-1) + pi4 = pi2 >> 1 + offset = wpmod + exp + if offset >= 0: + t = man << offset + else: + t = man >> (-offset) + n, y = divmod(t, pi2) + if y > pi4: + small = pi2 - y + else: + small = y + if small >> (wp+mag-10): + n = int(n) + t = y >> mag + wp = wpmod - mag + break + i += 1 + else: + wp += (-mag) + offset = exp + wp + if offset >= 0: + t = man << offset + else: + t = man >> (-offset) + n = 0 + return t, n, wp + + +def mpf_cos_sin(x, prec, rnd=round_fast, which=0, pi=False): + """ + which: + 0 -- return cos(x), sin(x) + 1 -- return cos(x) + 2 -- return sin(x) + 3 -- return tan(x) + + if pi=True, compute for pi*x + """ + sign, man, exp, bc = x + if not man: + if exp: + c, s = fnan, fnan + else: + c, s = fone, fzero + if which == 0: return c, s + if which == 1: return c + if which == 2: return s + if which == 3: return s + + mag = bc + exp + wp = prec + 10 + + # Extremely small? + if mag < 0: + if mag < -wp: + if pi: + x = mpf_mul(x, mpf_pi(wp)) + c = mpf_perturb(fone, 1, prec, rnd) + s = mpf_perturb(x, 1-sign, prec, rnd) + if which == 0: return c, s + if which == 1: return c + if which == 2: return s + if which == 3: return mpf_perturb(x, sign, prec, rnd) + if pi: + if exp >= -1: + if exp == -1: + c = fzero + s = (fone, fnone)[bool(man & 2) ^ sign] + elif exp == 0: + c, s = (fnone, fzero) + else: + c, s = (fone, fzero) + if which == 0: return c, s + if which == 1: return c + if which == 2: return s + if which == 3: return mpf_div(s, c, prec, rnd) + # Subtract nearest half-integer (= mod by pi/2) + n = ((man >> (-exp-2)) + 1) >> 1 + man = man - (n << (-exp-1)) + mag2 = bitcount(man) + exp + wp = prec + 10 - mag2 + offset = exp + wp + if offset >= 0: + t = man << offset + else: + t = man >> (-offset) + t = (t*pi_fixed(wp)) >> wp + else: + t, n, wp = mod_pi2(man, exp, mag, wp) + c, s = cos_sin_basecase(t, wp) + m = n & 3 + if m == 1: c, s = -s, c + elif m == 2: c, s = -c, -s + elif m == 3: c, s = s, -c + if sign: + s = -s + if which == 0: + c = from_man_exp(c, -wp, prec, rnd) + s = from_man_exp(s, -wp, prec, rnd) + return c, s + if which == 1: + return from_man_exp(c, -wp, prec, rnd) + if which == 2: + return from_man_exp(s, -wp, prec, rnd) + if which == 3: + return from_rational(s, c, prec, rnd) + +def mpf_cos(x, prec, rnd=round_fast): return mpf_cos_sin(x, prec, rnd, 1) +def mpf_sin(x, prec, rnd=round_fast): return mpf_cos_sin(x, prec, rnd, 2) +def mpf_tan(x, prec, rnd=round_fast): return mpf_cos_sin(x, prec, rnd, 3) +def mpf_cos_sin_pi(x, prec, rnd=round_fast): return mpf_cos_sin(x, prec, rnd, 0, 1) +def mpf_cos_pi(x, prec, rnd=round_fast): return mpf_cos_sin(x, prec, rnd, 1, 1) +def mpf_sin_pi(x, prec, rnd=round_fast): return mpf_cos_sin(x, prec, rnd, 2, 1) +def mpf_cosh(x, prec, rnd=round_fast): return mpf_cosh_sinh(x, prec, rnd)[0] +def mpf_sinh(x, prec, rnd=round_fast): return mpf_cosh_sinh(x, prec, rnd)[1] +def mpf_tanh(x, prec, rnd=round_fast): return mpf_cosh_sinh(x, prec, rnd, tanh=1) + + +# Low-overhead fixed-point versions + +def cos_sin_fixed(x, prec, pi2=None): + if pi2 is None: + pi2 = pi_fixed(prec-1) + n, t = divmod(x, pi2) + n = int(n) + c, s = cos_sin_basecase(t, prec) + m = n & 3 + if m == 0: return c, s + if m == 1: return -s, c + if m == 2: return -c, -s + if m == 3: return s, -c + +def exp_fixed(x, prec, ln2=None): + if ln2 is None: + ln2 = ln2_fixed(prec) + n, t = divmod(x, ln2) + n = int(n) + v = exp_basecase(t, prec) + if n >= 0: + return v << n + else: + return v >> (-n) + + +if BACKEND == 'sage': + try: + import sage.libs.mpmath.ext_libmp as _lbmp + mpf_sqrt = _lbmp.mpf_sqrt + mpf_exp = _lbmp.mpf_exp + mpf_log = _lbmp.mpf_log + mpf_cos = _lbmp.mpf_cos + mpf_sin = _lbmp.mpf_sin + mpf_pow = _lbmp.mpf_pow + exp_fixed = _lbmp.exp_fixed + cos_sin_fixed = _lbmp.cos_sin_fixed + log_int_fixed = _lbmp.log_int_fixed + except (ImportError, AttributeError): + print("Warning: Sage imports in libelefun failed") diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libhyper.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libhyper.py new file mode 100644 index 0000000000000000000000000000000000000000..04f52d59710be77819066aea5c1cf4b0883f72d7 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libhyper.py @@ -0,0 +1,1150 @@ +""" +This module implements computation of hypergeometric and related +functions. In particular, it provides code for generic summation +of hypergeometric series. Optimized versions for various special +cases are also provided. +""" + +import operator +import math + +from .backend import MPZ_ZERO, MPZ_ONE, BACKEND, xrange, exec_ + +from .libintmath import gcd + +from .libmpf import (\ + ComplexResult, round_fast, round_nearest, + negative_rnd, bitcount, to_fixed, from_man_exp, from_int, to_int, + from_rational, + fzero, fone, fnone, ftwo, finf, fninf, fnan, + mpf_sign, mpf_add, mpf_abs, mpf_pos, + mpf_cmp, mpf_lt, mpf_le, mpf_gt, mpf_min_max, + mpf_perturb, mpf_neg, mpf_shift, mpf_sub, mpf_mul, mpf_div, + sqrt_fixed, mpf_sqrt, mpf_rdiv_int, mpf_pow_int, + to_rational, +) + +from .libelefun import (\ + mpf_pi, mpf_exp, mpf_log, pi_fixed, mpf_cos_sin, mpf_cos, mpf_sin, + mpf_sqrt, agm_fixed, +) + +from .libmpc import (\ + mpc_one, mpc_sub, mpc_mul_mpf, mpc_mul, mpc_neg, complex_int_pow, + mpc_div, mpc_add_mpf, mpc_sub_mpf, + mpc_log, mpc_add, mpc_pos, mpc_shift, + mpc_is_infnan, mpc_zero, mpc_sqrt, mpc_abs, + mpc_mpf_div, mpc_square, mpc_exp +) + +from .libintmath import ifac +from .gammazeta import mpf_gamma_int, mpf_euler, euler_fixed + +class NoConvergence(Exception): + pass + + +#-----------------------------------------------------------------------# +# # +# Generic hypergeometric series # +# # +#-----------------------------------------------------------------------# + +""" +TODO: + +1. proper mpq parsing +2. imaginary z special-cased (also: rational, integer?) +3. more clever handling of series that don't converge because of stupid + upwards rounding +4. checking for cancellation + +""" + +def make_hyp_summator(key): + """ + Returns a function that sums a generalized hypergeometric series, + for given parameter types (integer, rational, real, complex). + + """ + p, q, param_types, ztype = key + + pstring = "".join(param_types) + fname = "hypsum_%i_%i_%s_%s_%s" % (p, q, pstring[:p], pstring[p:], ztype) + #print "generating hypsum", fname + + have_complex_param = 'C' in param_types + have_complex_arg = ztype == 'C' + have_complex = have_complex_param or have_complex_arg + + source = [] + add = source.append + + aint = [] + arat = [] + bint = [] + brat = [] + areal = [] + breal = [] + acomplex = [] + bcomplex = [] + + #add("wp = prec + 40") + add("MAX = kwargs.get('maxterms', wp*100)") + add("HIGH = MPZ_ONE<= 0:") + add(" ZRE = xm << offset") + add("else:") + add(" ZRE = xm >> (-offset)") + if have_complex_arg: + add("offset = ye + wp") + add("if offset >= 0:") + add(" ZIM = ym << offset") + add("else:") + add(" ZIM = ym >> (-offset)") + + for i, flag in enumerate(param_types): + W = ["A", "B"][i >= p] + if flag == 'Z': + ([aint,bint][i >= p]).append(i) + add("%sINT_%i = coeffs[%i]" % (W, i, i)) + elif flag == 'Q': + ([arat,brat][i >= p]).append(i) + add("%sP_%i, %sQ_%i = coeffs[%i]._mpq_" % (W, i, W, i, i)) + elif flag == 'R': + ([areal,breal][i >= p]).append(i) + add("xsign, xm, xe, xbc = coeffs[%i]._mpf_" % i) + add("if xsign: xm = -xm") + add("offset = xe + wp") + add("if offset >= 0:") + add(" %sREAL_%i = xm << offset" % (W, i)) + add("else:") + add(" %sREAL_%i = xm >> (-offset)" % (W, i)) + elif flag == 'C': + ([acomplex,bcomplex][i >= p]).append(i) + add("__re, __im = coeffs[%i]._mpc_" % i) + add("xsign, xm, xe, xbc = __re") + add("if xsign: xm = -xm") + add("ysign, ym, ye, ybc = __im") + add("if ysign: ym = -ym") + + add("offset = xe + wp") + add("if offset >= 0:") + add(" %sCRE_%i = xm << offset" % (W, i)) + add("else:") + add(" %sCRE_%i = xm >> (-offset)" % (W, i)) + add("offset = ye + wp") + add("if offset >= 0:") + add(" %sCIM_%i = ym << offset" % (W, i)) + add("else:") + add(" %sCIM_%i = ym >> (-offset)" % (W, i)) + else: + raise ValueError + + l_areal = len(areal) + l_breal = len(breal) + cancellable_real = min(l_areal, l_breal) + noncancellable_real_num = areal[cancellable_real:] + noncancellable_real_den = breal[cancellable_real:] + + # LOOP + add("for n in xrange(1,10**8):") + + add(" if n in magnitude_check:") + add(" p_mag = bitcount(abs(PRE))") + if have_complex: + add(" p_mag = max(p_mag, bitcount(abs(PIM)))") + add(" magnitude_check[n] = wp-p_mag") + + # Real factors + multiplier = " * ".join(["AINT_#".replace("#", str(i)) for i in aint] + \ + ["AP_#".replace("#", str(i)) for i in arat] + \ + ["BQ_#".replace("#", str(i)) for i in brat]) + + divisor = " * ".join(["BINT_#".replace("#", str(i)) for i in bint] + \ + ["BP_#".replace("#", str(i)) for i in brat] + \ + ["AQ_#".replace("#", str(i)) for i in arat] + ["n"]) + + if multiplier: + add(" mul = " + multiplier) + add(" div = " + divisor) + + # Check for singular terms + add(" if not div:") + if multiplier: + add(" if not mul:") + add(" break") + add(" raise ZeroDivisionError") + + # Update product + if have_complex: + + # TODO: when there are several real parameters and just a few complex + # (maybe just the complex argument), we only need to do about + # half as many ops if we accumulate the real factor in a single real variable + for k in range(cancellable_real): add(" PRE = PRE * AREAL_%i // BREAL_%i" % (areal[k], breal[k])) + for i in noncancellable_real_num: add(" PRE = (PRE * AREAL_#) >> wp".replace("#", str(i))) + for i in noncancellable_real_den: add(" PRE = (PRE << wp) // BREAL_#".replace("#", str(i))) + for k in range(cancellable_real): add(" PIM = PIM * AREAL_%i // BREAL_%i" % (areal[k], breal[k])) + for i in noncancellable_real_num: add(" PIM = (PIM * AREAL_#) >> wp".replace("#", str(i))) + for i in noncancellable_real_den: add(" PIM = (PIM << wp) // BREAL_#".replace("#", str(i))) + + if multiplier: + if have_complex_arg: + add(" PRE, PIM = (mul*(PRE*ZRE-PIM*ZIM))//div, (mul*(PIM*ZRE+PRE*ZIM))//div") + add(" PRE >>= wp") + add(" PIM >>= wp") + else: + add(" PRE = ((mul * PRE * ZRE) >> wp) // div") + add(" PIM = ((mul * PIM * ZRE) >> wp) // div") + else: + if have_complex_arg: + add(" PRE, PIM = (PRE*ZRE-PIM*ZIM)//div, (PIM*ZRE+PRE*ZIM)//div") + add(" PRE >>= wp") + add(" PIM >>= wp") + else: + add(" PRE = ((PRE * ZRE) >> wp) // div") + add(" PIM = ((PIM * ZRE) >> wp) // div") + + for i in acomplex: + add(" PRE, PIM = PRE*ACRE_#-PIM*ACIM_#, PIM*ACRE_#+PRE*ACIM_#".replace("#", str(i))) + add(" PRE >>= wp") + add(" PIM >>= wp") + + for i in bcomplex: + add(" mag = BCRE_#*BCRE_#+BCIM_#*BCIM_#".replace("#", str(i))) + add(" re = PRE*BCRE_# + PIM*BCIM_#".replace("#", str(i))) + add(" im = PIM*BCRE_# - PRE*BCIM_#".replace("#", str(i))) + add(" PRE = (re << wp) // mag".replace("#", str(i))) + add(" PIM = (im << wp) // mag".replace("#", str(i))) + + else: + for k in range(cancellable_real): add(" PRE = PRE * AREAL_%i // BREAL_%i" % (areal[k], breal[k])) + for i in noncancellable_real_num: add(" PRE = (PRE * AREAL_#) >> wp".replace("#", str(i))) + for i in noncancellable_real_den: add(" PRE = (PRE << wp) // BREAL_#".replace("#", str(i))) + if multiplier: + add(" PRE = ((PRE * mul * ZRE) >> wp) // div") + else: + add(" PRE = ((PRE * ZRE) >> wp) // div") + + # Add product to sum + if have_complex: + add(" SRE += PRE") + add(" SIM += PIM") + add(" if (HIGH > PRE > LOW) and (HIGH > PIM > LOW):") + add(" break") + else: + add(" SRE += PRE") + add(" if HIGH > PRE > LOW:") + add(" break") + + #add(" from mpmath import nprint, log, ldexp") + #add(" nprint([n, log(abs(PRE),2), ldexp(PRE,-wp)])") + + add(" if n > MAX:") + add(" raise NoConvergence('Hypergeometric series converges too slowly. Try increasing maxterms.')") + + # +1 all parameters for next loop + for i in aint: add(" AINT_# += 1".replace("#", str(i))) + for i in bint: add(" BINT_# += 1".replace("#", str(i))) + for i in arat: add(" AP_# += AQ_#".replace("#", str(i))) + for i in brat: add(" BP_# += BQ_#".replace("#", str(i))) + for i in areal: add(" AREAL_# += one".replace("#", str(i))) + for i in breal: add(" BREAL_# += one".replace("#", str(i))) + for i in acomplex: add(" ACRE_# += one".replace("#", str(i))) + for i in bcomplex: add(" BCRE_# += one".replace("#", str(i))) + + if have_complex: + add("a = from_man_exp(SRE, -wp, prec, 'n')") + add("b = from_man_exp(SIM, -wp, prec, 'n')") + + add("if SRE:") + add(" if SIM:") + add(" magn = max(a[2]+a[3], b[2]+b[3])") + add(" else:") + add(" magn = a[2]+a[3]") + add("elif SIM:") + add(" magn = b[2]+b[3]") + add("else:") + add(" magn = -wp+1") + + add("return (a, b), True, magn") + else: + add("a = from_man_exp(SRE, -wp, prec, 'n')") + + add("if SRE:") + add(" magn = a[2]+a[3]") + add("else:") + add(" magn = -wp+1") + + add("return a, False, magn") + + source = "\n".join((" " + line) for line in source) + source = ("def %s(coeffs, z, prec, wp, epsshift, magnitude_check, **kwargs):\n" % fname) + source + + namespace = {} + + exec_(source, globals(), namespace) + + #print source + return source, namespace[fname] + + +if BACKEND == 'sage': + + def make_hyp_summator(key): + """ + Returns a function that sums a generalized hypergeometric series, + for given parameter types (integer, rational, real, complex). + """ + from sage.libs.mpmath.ext_main import hypsum_internal + p, q, param_types, ztype = key + def _hypsum(coeffs, z, prec, wp, epsshift, magnitude_check, **kwargs): + return hypsum_internal(p, q, param_types, ztype, coeffs, z, + prec, wp, epsshift, magnitude_check, kwargs) + + return "(none)", _hypsum + + +#-----------------------------------------------------------------------# +# # +# Error functions # +# # +#-----------------------------------------------------------------------# + +# TODO: mpf_erf should call mpf_erfc when appropriate (currently +# only the converse delegation is implemented) + +def mpf_erf(x, prec, rnd=round_fast): + sign, man, exp, bc = x + if not man: + if x == fzero: return fzero + if x == finf: return fone + if x== fninf: return fnone + return fnan + size = exp + bc + lg = math.log + # The approximation erf(x) = 1 is accurate to > x^2 * log(e,2) bits + if size > 3 and 2*(size-1) + 0.528766 > lg(prec,2): + if sign: + return mpf_perturb(fnone, 0, prec, rnd) + else: + return mpf_perturb(fone, 1, prec, rnd) + # erf(x) ~ 2*x/sqrt(pi) close to 0 + if size < -prec: + # 2*x + x = mpf_shift(x,1) + c = mpf_sqrt(mpf_pi(prec+20), prec+20) + # TODO: interval rounding + return mpf_div(x, c, prec, rnd) + wp = prec + abs(size) + 25 + # Taylor series for erf, fixed-point summation + t = abs(to_fixed(x, wp)) + t2 = (t*t) >> wp + s, term, k = t, 12345, 1 + while term: + t = ((t * t2) >> wp) // k + term = t // (2*k+1) + if k & 1: + s -= term + else: + s += term + k += 1 + s = (s << (wp+1)) // sqrt_fixed(pi_fixed(wp), wp) + if sign: + s = -s + return from_man_exp(s, -wp, prec, rnd) + +# If possible, we use the asymptotic series for erfc. +# This is an alternating divergent asymptotic series, so +# the error is at most equal to the first omitted term. +# Here we check if the smallest term is small enough +# for a given x and precision +def erfc_check_series(x, prec): + n = to_int(x) + if n**2 * 1.44 > prec: + return True + return False + +def mpf_erfc(x, prec, rnd=round_fast): + sign, man, exp, bc = x + if not man: + if x == fzero: return fone + if x == finf: return fzero + if x == fninf: return ftwo + return fnan + wp = prec + 20 + mag = bc+exp + # Preserve full accuracy when exponent grows huge + wp += max(0, 2*mag) + regular_erf = sign or mag < 2 + if regular_erf or not erfc_check_series(x, wp): + if regular_erf: + return mpf_sub(fone, mpf_erf(x, prec+10, negative_rnd[rnd]), prec, rnd) + # 1-erf(x) ~ exp(-x^2), increase prec to deal with cancellation + n = to_int(x)+1 + return mpf_sub(fone, mpf_erf(x, prec + int(n**2*1.44) + 10), prec, rnd) + s = term = MPZ_ONE << wp + term_prev = 0 + t = (2 * to_fixed(x, wp) ** 2) >> wp + k = 1 + while 1: + term = ((term * (2*k - 1)) << wp) // t + if k > 4 and term > term_prev or not term: + break + if k & 1: + s -= term + else: + s += term + term_prev = term + #print k, to_str(from_man_exp(term, -wp, 50), 10) + k += 1 + s = (s << wp) // sqrt_fixed(pi_fixed(wp), wp) + s = from_man_exp(s, -wp, wp) + z = mpf_exp(mpf_neg(mpf_mul(x,x,wp),wp),wp) + y = mpf_div(mpf_mul(z, s, wp), x, prec, rnd) + return y + + +#-----------------------------------------------------------------------# +# # +# Exponential integrals # +# # +#-----------------------------------------------------------------------# + +def ei_taylor(x, prec): + s = t = x + k = 2 + while t: + t = ((t*x) >> prec) // k + s += t // k + k += 1 + return s + +def complex_ei_taylor(zre, zim, prec): + _abs = abs + sre = tre = zre + sim = tim = zim + k = 2 + while _abs(tre) + _abs(tim) > 5: + tre, tim = ((tre*zre-tim*zim)//k)>>prec, ((tre*zim+tim*zre)//k)>>prec + sre += tre // k + sim += tim // k + k += 1 + return sre, sim + +def ei_asymptotic(x, prec): + one = MPZ_ONE << prec + x = t = ((one << prec) // x) + s = one + x + k = 2 + while t: + t = (k*t*x) >> prec + s += t + k += 1 + return s + +def complex_ei_asymptotic(zre, zim, prec): + _abs = abs + one = MPZ_ONE << prec + M = (zim*zim + zre*zre) >> prec + # 1 / z + xre = tre = (zre << prec) // M + xim = tim = ((-zim) << prec) // M + sre = one + xre + sim = xim + k = 2 + while _abs(tre) + _abs(tim) > 1000: + #print tre, tim + tre, tim = ((tre*xre-tim*xim)*k)>>prec, ((tre*xim+tim*xre)*k)>>prec + sre += tre + sim += tim + k += 1 + if k > prec: + raise NoConvergence + return sre, sim + +def mpf_ei(x, prec, rnd=round_fast, e1=False): + if e1: + x = mpf_neg(x) + sign, man, exp, bc = x + if e1 and not sign: + if x == fzero: + return finf + raise ComplexResult("E1(x) for x < 0") + if man: + xabs = 0, man, exp, bc + xmag = exp+bc + wp = prec + 20 + can_use_asymp = xmag > wp + if not can_use_asymp: + if exp >= 0: + xabsint = man << exp + else: + xabsint = man >> (-exp) + can_use_asymp = xabsint > int(wp*0.693) + 10 + if can_use_asymp: + if xmag > wp: + v = fone + else: + v = from_man_exp(ei_asymptotic(to_fixed(x, wp), wp), -wp) + v = mpf_mul(v, mpf_exp(x, wp), wp) + v = mpf_div(v, x, prec, rnd) + else: + wp += 2*int(to_int(xabs)) + u = to_fixed(x, wp) + v = ei_taylor(u, wp) + euler_fixed(wp) + t1 = from_man_exp(v,-wp) + t2 = mpf_log(xabs,wp) + v = mpf_add(t1, t2, prec, rnd) + else: + if x == fzero: v = fninf + elif x == finf: v = finf + elif x == fninf: v = fzero + else: v = fnan + if e1: + v = mpf_neg(v) + return v + +def mpc_ei(z, prec, rnd=round_fast, e1=False): + if e1: + z = mpc_neg(z) + a, b = z + asign, aman, aexp, abc = a + bsign, bman, bexp, bbc = b + if b == fzero: + if e1: + x = mpf_neg(mpf_ei(a, prec, rnd)) + if not asign: + y = mpf_neg(mpf_pi(prec, rnd)) + else: + y = fzero + return x, y + else: + return mpf_ei(a, prec, rnd), fzero + if a != fzero: + if not aman or not bman: + return (fnan, fnan) + wp = prec + 40 + amag = aexp+abc + bmag = bexp+bbc + zmag = max(amag, bmag) + can_use_asymp = zmag > wp + if not can_use_asymp: + zabsint = abs(to_int(a)) + abs(to_int(b)) + can_use_asymp = zabsint > int(wp*0.693) + 20 + try: + if can_use_asymp: + if zmag > wp: + v = fone, fzero + else: + zre = to_fixed(a, wp) + zim = to_fixed(b, wp) + vre, vim = complex_ei_asymptotic(zre, zim, wp) + v = from_man_exp(vre, -wp), from_man_exp(vim, -wp) + v = mpc_mul(v, mpc_exp(z, wp), wp) + v = mpc_div(v, z, wp) + if e1: + v = mpc_neg(v, prec, rnd) + else: + x, y = v + if bsign: + v = mpf_pos(x, prec, rnd), mpf_sub(y, mpf_pi(wp), prec, rnd) + else: + v = mpf_pos(x, prec, rnd), mpf_add(y, mpf_pi(wp), prec, rnd) + return v + except NoConvergence: + pass + #wp += 2*max(0,zmag) + wp += 2*int(to_int(mpc_abs(z, 5))) + zre = to_fixed(a, wp) + zim = to_fixed(b, wp) + vre, vim = complex_ei_taylor(zre, zim, wp) + vre += euler_fixed(wp) + v = from_man_exp(vre,-wp), from_man_exp(vim,-wp) + if e1: + u = mpc_log(mpc_neg(z),wp) + else: + u = mpc_log(z,wp) + v = mpc_add(v, u, prec, rnd) + if e1: + v = mpc_neg(v) + return v + +def mpf_e1(x, prec, rnd=round_fast): + return mpf_ei(x, prec, rnd, True) + +def mpc_e1(x, prec, rnd=round_fast): + return mpc_ei(x, prec, rnd, True) + +def mpf_expint(n, x, prec, rnd=round_fast, gamma=False): + """ + E_n(x), n an integer, x real + + With gamma=True, computes Gamma(n,x) (upper incomplete gamma function) + + Returns (real, None) if real, otherwise (real, imag) + The imaginary part is an optional branch cut term + + """ + sign, man, exp, bc = x + if not man: + if gamma: + if x == fzero: + # Actually gamma function pole + if n <= 0: + return finf, None + return mpf_gamma_int(n, prec, rnd), None + if x == finf: + return fzero, None + # TODO: could return finite imaginary value at -inf + return fnan, fnan + else: + if x == fzero: + if n > 1: + return from_rational(1, n-1, prec, rnd), None + else: + return finf, None + if x == finf: + return fzero, None + return fnan, fnan + n_orig = n + if gamma: + n = 1-n + wp = prec + 20 + xmag = exp + bc + # Beware of near-poles + if xmag < -10: + raise NotImplementedError + nmag = bitcount(abs(n)) + have_imag = n > 0 and sign + negx = mpf_neg(x) + # Skip series if direct convergence + if n == 0 or 2*nmag - xmag < -wp: + if gamma: + v = mpf_exp(negx, wp) + re = mpf_mul(v, mpf_pow_int(x, n_orig-1, wp), prec, rnd) + else: + v = mpf_exp(negx, wp) + re = mpf_div(v, x, prec, rnd) + else: + # Finite number of terms, or... + can_use_asymptotic_series = -3*wp < n <= 0 + # ...large enough? + if not can_use_asymptotic_series: + xi = abs(to_int(x)) + m = min(max(1, xi-n), 2*wp) + siz = -n*nmag + (m+n)*bitcount(abs(m+n)) - m*xmag - (144*m//100) + tol = -wp-10 + can_use_asymptotic_series = siz < tol + if can_use_asymptotic_series: + r = ((-MPZ_ONE) << (wp+wp)) // to_fixed(x, wp) + m = n + t = r*m + s = MPZ_ONE << wp + while m and t: + s += t + m += 1 + t = (m*r*t) >> wp + v = mpf_exp(negx, wp) + if gamma: + # ~ exp(-x) * x^(n-1) * (1 + ...) + v = mpf_mul(v, mpf_pow_int(x, n_orig-1, wp), wp) + else: + # ~ exp(-x)/x * (1 + ...) + v = mpf_div(v, x, wp) + re = mpf_mul(v, from_man_exp(s, -wp), prec, rnd) + elif n == 1: + re = mpf_neg(mpf_ei(negx, prec, rnd)) + elif n > 0 and n < 3*wp: + T1 = mpf_neg(mpf_ei(negx, wp)) + if gamma: + if n_orig & 1: + T1 = mpf_neg(T1) + else: + T1 = mpf_mul(T1, mpf_pow_int(negx, n-1, wp), wp) + r = t = to_fixed(x, wp) + facs = [1] * (n-1) + for k in range(1,n-1): + facs[k] = facs[k-1] * k + facs = facs[::-1] + s = facs[0] << wp + for k in range(1, n-1): + if k & 1: + s -= facs[k] * t + else: + s += facs[k] * t + t = (t*r) >> wp + T2 = from_man_exp(s, -wp, wp) + T2 = mpf_mul(T2, mpf_exp(negx, wp)) + if gamma: + T2 = mpf_mul(T2, mpf_pow_int(x, n_orig, wp), wp) + R = mpf_add(T1, T2) + re = mpf_div(R, from_int(ifac(n-1)), prec, rnd) + else: + raise NotImplementedError + if have_imag: + M = from_int(-ifac(n-1)) + if gamma: + im = mpf_div(mpf_pi(wp), M, prec, rnd) + if n_orig & 1: + im = mpf_neg(im) + else: + im = mpf_div(mpf_mul(mpf_pi(wp), mpf_pow_int(negx, n_orig-1, wp), wp), M, prec, rnd) + return re, im + else: + return re, None + +def mpf_ci_si_taylor(x, wp, which=0): + """ + 0 - Ci(x) - (euler+log(x)) + 1 - Si(x) + """ + x = to_fixed(x, wp) + x2 = -(x*x) >> wp + if which == 0: + s, t, k = 0, (MPZ_ONE<>wp + s += t//k + k += 2 + return from_man_exp(s, -wp) + +def mpc_ci_si_taylor(re, im, wp, which=0): + # The following code is only designed for small arguments, + # and not too small arguments (for relative accuracy) + if re[1]: + mag = re[2]+re[3] + elif im[1]: + mag = im[2]+im[3] + if im[1]: + mag = max(mag, im[2]+im[3]) + if mag > 2 or mag < -wp: + raise NotImplementedError + wp += (2-mag) + zre = to_fixed(re, wp) + zim = to_fixed(im, wp) + z2re = (zim*zim-zre*zre)>>wp + z2im = (-2*zre*zim)>>wp + tre = zre + tim = zim + one = MPZ_ONE< 2: + f = k*(k-1) + tre, tim = ((tre*z2re-tim*z2im)//f)>>wp, ((tre*z2im+tim*z2re)//f)>>wp + sre += tre//k + sim += tim//k + k += 2 + return from_man_exp(sre, -wp), from_man_exp(sim, -wp) + +def mpf_ci_si(x, prec, rnd=round_fast, which=2): + """ + Calculation of Ci(x), Si(x) for real x. + + which = 0 -- returns (Ci(x), -) + which = 1 -- returns (Si(x), -) + which = 2 -- returns (Ci(x), Si(x)) + + Note: if x < 0, Ci(x) needs an additional imaginary term, pi*i. + """ + wp = prec + 20 + sign, man, exp, bc = x + ci, si = None, None + if not man: + if x == fzero: + return (fninf, fzero) + if x == fnan: + return (x, x) + ci = fzero + if which != 0: + if x == finf: + si = mpf_shift(mpf_pi(prec, rnd), -1) + if x == fninf: + si = mpf_neg(mpf_shift(mpf_pi(prec, negative_rnd[rnd]), -1)) + return (ci, si) + # For small x: Ci(x) ~ euler + log(x), Si(x) ~ x + mag = exp+bc + if mag < -wp: + if which != 0: + si = mpf_perturb(x, 1-sign, prec, rnd) + if which != 1: + y = mpf_euler(wp) + xabs = mpf_abs(x) + ci = mpf_add(y, mpf_log(xabs, wp), prec, rnd) + return ci, si + # For huge x: Ci(x) ~ sin(x)/x, Si(x) ~ pi/2 + elif mag > wp: + if which != 0: + if sign: + si = mpf_neg(mpf_pi(prec, negative_rnd[rnd])) + else: + si = mpf_pi(prec, rnd) + si = mpf_shift(si, -1) + if which != 1: + ci = mpf_div(mpf_sin(x, wp), x, prec, rnd) + return ci, si + else: + wp += abs(mag) + # Use an asymptotic series? The smallest value of n!/x^n + # occurs for n ~ x, where the magnitude is ~ exp(-x). + asymptotic = mag-1 > math.log(wp, 2) + # Case 1: convergent series near 0 + if not asymptotic: + if which != 0: + si = mpf_pos(mpf_ci_si_taylor(x, wp, 1), prec, rnd) + if which != 1: + ci = mpf_ci_si_taylor(x, wp, 0) + ci = mpf_add(ci, mpf_euler(wp), wp) + ci = mpf_add(ci, mpf_log(mpf_abs(x), wp), prec, rnd) + return ci, si + x = mpf_abs(x) + # Case 2: asymptotic series for x >> 1 + xf = to_fixed(x, wp) + xr = (MPZ_ONE<<(2*wp)) // xf # 1/x + s1 = (MPZ_ONE << wp) + s2 = xr + t = xr + k = 2 + while t: + t = -t + t = (t*xr*k)>>wp + k += 1 + s1 += t + t = (t*xr*k)>>wp + k += 1 + s2 += t + s1 = from_man_exp(s1, -wp) + s2 = from_man_exp(s2, -wp) + s1 = mpf_div(s1, x, wp) + s2 = mpf_div(s2, x, wp) + cos, sin = mpf_cos_sin(x, wp) + # Ci(x) = sin(x)*s1-cos(x)*s2 + # Si(x) = pi/2-cos(x)*s1-sin(x)*s2 + if which != 0: + si = mpf_add(mpf_mul(cos, s1), mpf_mul(sin, s2), wp) + si = mpf_sub(mpf_shift(mpf_pi(wp), -1), si, wp) + if sign: + si = mpf_neg(si) + si = mpf_pos(si, prec, rnd) + if which != 1: + ci = mpf_sub(mpf_mul(sin, s1), mpf_mul(cos, s2), prec, rnd) + return ci, si + +def mpf_ci(x, prec, rnd=round_fast): + if mpf_sign(x) < 0: + raise ComplexResult + return mpf_ci_si(x, prec, rnd, 0)[0] + +def mpf_si(x, prec, rnd=round_fast): + return mpf_ci_si(x, prec, rnd, 1)[1] + +def mpc_ci(z, prec, rnd=round_fast): + re, im = z + if im == fzero: + ci = mpf_ci_si(re, prec, rnd, 0)[0] + if mpf_sign(re) < 0: + return (ci, mpf_pi(prec, rnd)) + return (ci, fzero) + wp = prec + 20 + cre, cim = mpc_ci_si_taylor(re, im, wp, 0) + cre = mpf_add(cre, mpf_euler(wp), wp) + ci = mpc_add((cre, cim), mpc_log(z, wp), prec, rnd) + return ci + +def mpc_si(z, prec, rnd=round_fast): + re, im = z + if im == fzero: + return (mpf_ci_si(re, prec, rnd, 1)[1], fzero) + wp = prec + 20 + z = mpc_ci_si_taylor(re, im, wp, 1) + return mpc_pos(z, prec, rnd) + + +#-----------------------------------------------------------------------# +# # +# Bessel functions # +# # +#-----------------------------------------------------------------------# + +# A Bessel function of the first kind of integer order, J_n(x), is +# given by the power series + +# oo +# ___ k 2 k + n +# \ (-1) / x \ +# J_n(x) = ) ----------- | - | +# /___ k! (k + n)! \ 2 / +# k = 0 + +# Simplifying the quotient between two successive terms gives the +# ratio x^2 / (-4*k*(k+n)). Hence, we only need one full-precision +# multiplication and one division by a small integer per term. +# The complex version is very similar, the only difference being +# that the multiplication is actually 4 multiplies. + +# In the general case, we have +# J_v(x) = (x/2)**v / v! * 0F1(v+1, (-1/4)*z**2) + +# TODO: for extremely large x, we could use an asymptotic +# trigonometric approximation. + +# TODO: recompute at higher precision if the fixed-point mantissa +# is very small + +def mpf_besseljn(n, x, prec, rounding=round_fast): + prec += 50 + negate = n < 0 and n & 1 + mag = x[2]+x[3] + n = abs(n) + wp = prec + 20 + n*bitcount(n) + if mag < 0: + wp -= n * mag + x = to_fixed(x, wp) + x2 = (x**2) >> wp + if not n: + s = t = MPZ_ONE << wp + else: + s = t = (x**n // ifac(n)) >> ((n-1)*wp + n) + k = 1 + while t: + t = ((t * x2) // (-4*k*(k+n))) >> wp + s += t + k += 1 + if negate: + s = -s + return from_man_exp(s, -wp, prec, rounding) + +def mpc_besseljn(n, z, prec, rounding=round_fast): + negate = n < 0 and n & 1 + n = abs(n) + origprec = prec + zre, zim = z + mag = max(zre[2]+zre[3], zim[2]+zim[3]) + prec += 20 + n*bitcount(n) + abs(mag) + if mag < 0: + prec -= n * mag + zre = to_fixed(zre, prec) + zim = to_fixed(zim, prec) + z2re = (zre**2 - zim**2) >> prec + z2im = (zre*zim) >> (prec-1) + if not n: + sre = tre = MPZ_ONE << prec + sim = tim = MPZ_ZERO + else: + re, im = complex_int_pow(zre, zim, n) + sre = tre = (re // ifac(n)) >> ((n-1)*prec + n) + sim = tim = (im // ifac(n)) >> ((n-1)*prec + n) + k = 1 + while abs(tre) + abs(tim) > 3: + p = -4*k*(k+n) + tre, tim = tre*z2re - tim*z2im, tim*z2re + tre*z2im + tre = (tre // p) >> prec + tim = (tim // p) >> prec + sre += tre + sim += tim + k += 1 + if negate: + sre = -sre + sim = -sim + re = from_man_exp(sre, -prec, origprec, rounding) + im = from_man_exp(sim, -prec, origprec, rounding) + return (re, im) + +def mpf_agm(a, b, prec, rnd=round_fast): + """ + Computes the arithmetic-geometric mean agm(a,b) for + nonnegative mpf values a, b. + """ + asign, aman, aexp, abc = a + bsign, bman, bexp, bbc = b + if asign or bsign: + raise ComplexResult("agm of a negative number") + # Handle inf, nan or zero in either operand + if not (aman and bman): + if a == fnan or b == fnan: + return fnan + if a == finf: + if b == fzero: + return fnan + return finf + if b == finf: + if a == fzero: + return fnan + return finf + # agm(0,x) = agm(x,0) = 0 + return fzero + wp = prec + 20 + amag = aexp+abc + bmag = bexp+bbc + mag_delta = amag - bmag + # Reduce to roughly the same magnitude using floating-point AGM + abs_mag_delta = abs(mag_delta) + if abs_mag_delta > 10: + while abs_mag_delta > 10: + a, b = mpf_shift(mpf_add(a,b,wp),-1), \ + mpf_sqrt(mpf_mul(a,b,wp),wp) + abs_mag_delta //= 2 + asign, aman, aexp, abc = a + bsign, bman, bexp, bbc = b + amag = aexp+abc + bmag = bexp+bbc + mag_delta = amag - bmag + #print to_float(a), to_float(b) + # Use agm(a,b) = agm(x*a,x*b)/x to obtain a, b ~= 1 + min_mag = min(amag,bmag) + max_mag = max(amag,bmag) + n = 0 + # If too small, we lose precision when going to fixed-point + if min_mag < -8: + n = -min_mag + # If too large, we waste time using fixed-point with large numbers + elif max_mag > 20: + n = -max_mag + if n: + a = mpf_shift(a, n) + b = mpf_shift(b, n) + #print to_float(a), to_float(b) + af = to_fixed(a, wp) + bf = to_fixed(b, wp) + g = agm_fixed(af, bf, wp) + return from_man_exp(g, -wp-n, prec, rnd) + +def mpf_agm1(a, prec, rnd=round_fast): + """ + Computes the arithmetic-geometric mean agm(1,a) for a nonnegative + mpf value a. + """ + return mpf_agm(fone, a, prec, rnd) + +def mpc_agm(a, b, prec, rnd=round_fast): + """ + Complex AGM. + + TODO: + * check that convergence works as intended + * optimize + * select a nonarbitrary branch + """ + if mpc_is_infnan(a) or mpc_is_infnan(b): + return fnan, fnan + if mpc_zero in (a, b): + return fzero, fzero + if mpc_neg(a) == b: + return fzero, fzero + wp = prec+20 + eps = mpf_shift(fone, -wp+10) + while 1: + a1 = mpc_shift(mpc_add(a, b, wp), -1) + b1 = mpc_sqrt(mpc_mul(a, b, wp), wp) + a, b = a1, b1 + size = mpf_min_max([mpc_abs(a,10), mpc_abs(b,10)])[1] + err = mpc_abs(mpc_sub(a, b, 10), 10) + if size == fzero or mpf_lt(err, mpf_mul(eps, size)): + return a + +def mpc_agm1(a, prec, rnd=round_fast): + return mpc_agm(mpc_one, a, prec, rnd) + +def mpf_ellipk(x, prec, rnd=round_fast): + if not x[1]: + if x == fzero: + return mpf_shift(mpf_pi(prec, rnd), -1) + if x == fninf: + return fzero + if x == fnan: + return x + if x == fone: + return finf + # TODO: for |x| << 1/2, one could use fall back to + # pi/2 * hyp2f1_rat((1,2),(1,2),(1,1), x) + wp = prec + 15 + # Use K(x) = pi/2/agm(1,a) where a = sqrt(1-x) + # The sqrt raises ComplexResult if x > 0 + a = mpf_sqrt(mpf_sub(fone, x, wp), wp) + v = mpf_agm1(a, wp) + r = mpf_div(mpf_pi(wp), v, prec, rnd) + return mpf_shift(r, -1) + +def mpc_ellipk(z, prec, rnd=round_fast): + re, im = z + if im == fzero: + if re == finf: + return mpc_zero + if mpf_le(re, fone): + return mpf_ellipk(re, prec, rnd), fzero + wp = prec + 15 + a = mpc_sqrt(mpc_sub(mpc_one, z, wp), wp) + v = mpc_agm1(a, wp) + r = mpc_mpf_div(mpf_pi(wp), v, prec, rnd) + return mpc_shift(r, -1) + +def mpf_ellipe(x, prec, rnd=round_fast): + # http://functions.wolfram.com/EllipticIntegrals/ + # EllipticK/20/01/0001/ + # E = (1-m)*(K'(m)*2*m + K(m)) + sign, man, exp, bc = x + if not man: + if x == fzero: + return mpf_shift(mpf_pi(prec, rnd), -1) + if x == fninf: + return finf + if x == fnan: + return x + if x == finf: + raise ComplexResult + if x == fone: + return fone + wp = prec+20 + mag = exp+bc + if mag < -wp: + return mpf_shift(mpf_pi(prec, rnd), -1) + # Compute a finite difference for K' + p = max(mag, 0) - wp + h = mpf_shift(fone, p) + K = mpf_ellipk(x, 2*wp) + Kh = mpf_ellipk(mpf_sub(x, h), 2*wp) + Kdiff = mpf_shift(mpf_sub(K, Kh), -p) + t = mpf_sub(fone, x) + b = mpf_mul(Kdiff, mpf_shift(x,1), wp) + return mpf_mul(t, mpf_add(K, b), prec, rnd) + +def mpc_ellipe(z, prec, rnd=round_fast): + re, im = z + if im == fzero: + if re == finf: + return (fzero, finf) + if mpf_le(re, fone): + return mpf_ellipe(re, prec, rnd), fzero + wp = prec + 15 + mag = mpc_abs(z, 1) + p = max(mag[2]+mag[3], 0) - wp + h = mpf_shift(fone, p) + K = mpc_ellipk(z, 2*wp) + Kh = mpc_ellipk(mpc_add_mpf(z, h, 2*wp), 2*wp) + Kdiff = mpc_shift(mpc_sub(Kh, K, wp), -p) + t = mpc_sub(mpc_one, z, wp) + b = mpc_mul(Kdiff, mpc_shift(z,1), wp) + return mpc_mul(t, mpc_add(K, b, wp), prec, rnd) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libintmath.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libintmath.py new file mode 100644 index 0000000000000000000000000000000000000000..7880546e135639208d136488408b102ad41682a2 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libintmath.py @@ -0,0 +1,584 @@ +""" +Utility functions for integer math. + +TODO: rename, cleanup, perhaps move the gmpy wrapper code +here from settings.py + +""" + +import math +from bisect import bisect + +from .backend import xrange +from .backend import BACKEND, gmpy, sage, sage_utils, MPZ, MPZ_ONE, MPZ_ZERO + +small_trailing = [0] * 256 +for j in range(1,8): + small_trailing[1<>> giant_steps(50,1000) + [66, 128, 253, 502, 1000] + >>> giant_steps(50,1000,4) + [65, 252, 1000] + + """ + L = [target] + while L[-1] > start*n: + L = L + [L[-1]//n + 2] + return L[::-1] + +def rshift(x, n): + """For an integer x, calculate x >> n with the fastest (floor) + rounding. Unlike the plain Python expression (x >> n), n is + allowed to be negative, in which case a left shift is performed.""" + if n >= 0: return x >> n + else: return x << (-n) + +def lshift(x, n): + """For an integer x, calculate x << n. Unlike the plain Python + expression (x << n), n is allowed to be negative, in which case a + right shift with default (floor) rounding is performed.""" + if n >= 0: return x << n + else: return x >> (-n) + +if BACKEND == 'sage': + import operator + rshift = operator.rshift + lshift = operator.lshift + +def python_trailing(n): + """Count the number of trailing zero bits in abs(n).""" + if not n: + return 0 + low_byte = n & 0xff + if low_byte: + return small_trailing[low_byte] + t = 8 + n >>= 8 + while not n & 0xff: + n >>= 8 + t += 8 + return t + small_trailing[n & 0xff] + +if BACKEND == 'gmpy': + if gmpy.version() >= '2': + def gmpy_trailing(n): + """Count the number of trailing zero bits in abs(n) using gmpy.""" + if n: return MPZ(n).bit_scan1() + else: return 0 + else: + def gmpy_trailing(n): + """Count the number of trailing zero bits in abs(n) using gmpy.""" + if n: return MPZ(n).scan1() + else: return 0 + +# Small powers of 2 +powers = [1<<_ for _ in range(300)] + +def python_bitcount(n): + """Calculate bit size of the nonnegative integer n.""" + bc = bisect(powers, n) + if bc != 300: + return bc + bc = int(math.log(n, 2)) - 4 + return bc + bctable[n>>bc] + +def gmpy_bitcount(n): + """Calculate bit size of the nonnegative integer n.""" + if n: return MPZ(n).numdigits(2) + else: return 0 + +#def sage_bitcount(n): +# if n: return MPZ(n).nbits() +# else: return 0 + +def sage_trailing(n): + return MPZ(n).trailing_zero_bits() + +if BACKEND == 'gmpy': + bitcount = gmpy_bitcount + trailing = gmpy_trailing +elif BACKEND == 'sage': + sage_bitcount = sage_utils.bitcount + bitcount = sage_bitcount + trailing = sage_trailing +else: + bitcount = python_bitcount + trailing = python_trailing + +if BACKEND == 'gmpy' and 'bit_length' in dir(gmpy): + bitcount = gmpy.bit_length + +# Used to avoid slow function calls as far as possible +trailtable = [trailing(n) for n in range(256)] +bctable = [bitcount(n) for n in range(1024)] + +# TODO: speed up for bases 2, 4, 8, 16, ... + +def bin_to_radix(x, xbits, base, bdigits): + """Changes radix of a fixed-point number; i.e., converts + x * 2**xbits to floor(x * 10**bdigits).""" + return x * (MPZ(base)**bdigits) >> xbits + +stddigits = '0123456789abcdefghijklmnopqrstuvwxyz' + +def small_numeral(n, base=10, digits=stddigits): + """Return the string numeral of a positive integer in an arbitrary + base. Most efficient for small input.""" + if base == 10: + return str(n) + digs = [] + while n: + n, digit = divmod(n, base) + digs.append(digits[digit]) + return "".join(digs[::-1]) + +def numeral_python(n, base=10, size=0, digits=stddigits): + """Represent the integer n as a string of digits in the given base. + Recursive division is used to make this function about 3x faster + than Python's str() for converting integers to decimal strings. + + The 'size' parameters specifies the number of digits in n; this + number is only used to determine splitting points and need not be + exact.""" + if n <= 0: + if not n: + return "0" + return "-" + numeral(-n, base, size, digits) + # Fast enough to do directly + if size < 250: + return small_numeral(n, base, digits) + # Divide in half + half = (size // 2) + (size & 1) + A, B = divmod(n, base**half) + ad = numeral(A, base, half, digits) + bd = numeral(B, base, half, digits).rjust(half, "0") + return ad + bd + +def numeral_gmpy(n, base=10, size=0, digits=stddigits): + """Represent the integer n as a string of digits in the given base. + Recursive division is used to make this function about 3x faster + than Python's str() for converting integers to decimal strings. + + The 'size' parameters specifies the number of digits in n; this + number is only used to determine splitting points and need not be + exact.""" + if n < 0: + return "-" + numeral(-n, base, size, digits) + # gmpy.digits() may cause a segmentation fault when trying to convert + # extremely large values to a string. The size limit may need to be + # adjusted on some platforms, but 1500000 works on Windows and Linux. + if size < 1500000: + return gmpy.digits(n, base) + # Divide in half + half = (size // 2) + (size & 1) + A, B = divmod(n, MPZ(base)**half) + ad = numeral(A, base, half, digits) + bd = numeral(B, base, half, digits).rjust(half, "0") + return ad + bd + +if BACKEND == "gmpy": + numeral = numeral_gmpy +else: + numeral = numeral_python + +_1_800 = 1<<800 +_1_600 = 1<<600 +_1_400 = 1<<400 +_1_200 = 1<<200 +_1_100 = 1<<100 +_1_50 = 1<<50 + +def isqrt_small_python(x): + """ + Correctly (floor) rounded integer square root, using + division. Fast up to ~200 digits. + """ + if not x: + return x + if x < _1_800: + # Exact with IEEE double precision arithmetic + if x < _1_50: + return int(x**0.5) + # Initial estimate can be any integer >= the true root; round up + r = int(x**0.5 * 1.00000000000001) + 1 + else: + bc = bitcount(x) + n = bc//2 + r = int((x>>(2*n-100))**0.5+2)<<(n-50) # +2 is to round up + # The following iteration now precisely computes floor(sqrt(x)) + # See e.g. Crandall & Pomerance, "Prime Numbers: A Computational + # Perspective" + while 1: + y = (r+x//r)>>1 + if y >= r: + return r + r = y + +def isqrt_fast_python(x): + """ + Fast approximate integer square root, computed using division-free + Newton iteration for large x. For random integers the result is almost + always correct (floor(sqrt(x))), but is 1 ulp too small with a roughly + 0.1% probability. If x is very close to an exact square, the answer is + 1 ulp wrong with high probability. + + With 0 guard bits, the largest error over a set of 10^5 random + inputs of size 1-10^5 bits was 3 ulp. The use of 10 guard bits + almost certainly guarantees a max 1 ulp error. + """ + # Use direct division-based iteration if sqrt(x) < 2^400 + # Assume floating-point square root accurate to within 1 ulp, then: + # 0 Newton iterations good to 52 bits + # 1 Newton iterations good to 104 bits + # 2 Newton iterations good to 208 bits + # 3 Newton iterations good to 416 bits + if x < _1_800: + y = int(x**0.5) + if x >= _1_100: + y = (y + x//y) >> 1 + if x >= _1_200: + y = (y + x//y) >> 1 + if x >= _1_400: + y = (y + x//y) >> 1 + return y + bc = bitcount(x) + guard_bits = 10 + x <<= 2*guard_bits + bc += 2*guard_bits + bc += (bc&1) + hbc = bc//2 + startprec = min(50, hbc) + # Newton iteration for 1/sqrt(x), with floating-point starting value + r = int(2.0**(2*startprec) * (x >> (bc-2*startprec)) ** -0.5) + pp = startprec + for p in giant_steps(startprec, hbc): + # r**2, scaled from real size 2**(-bc) to 2**p + r2 = (r*r) >> (2*pp - p) + # x*r**2, scaled from real size ~1.0 to 2**p + xr2 = ((x >> (bc-p)) * r2) >> p + # New value of r, scaled from real size 2**(-bc/2) to 2**p + r = (r * ((3<> (pp+1) + pp = p + # (1/sqrt(x))*x = sqrt(x) + return (r*(x>>hbc)) >> (p+guard_bits) + +def sqrtrem_python(x): + """Correctly rounded integer (floor) square root with remainder.""" + # to check cutoff: + # plot(lambda x: timing(isqrt, 2**int(x)), [0,2000]) + if x < _1_600: + y = isqrt_small_python(x) + return y, x - y*y + y = isqrt_fast_python(x) + 1 + rem = x - y*y + # Correct remainder + while rem < 0: + y -= 1 + rem += (1+2*y) + else: + if rem: + while rem > 2*(1+y): + y += 1 + rem -= (1+2*y) + return y, rem + +def isqrt_python(x): + """Integer square root with correct (floor) rounding.""" + return sqrtrem_python(x)[0] + +def sqrt_fixed(x, prec): + return isqrt_fast(x<= '2': + isqrt_small = isqrt_fast = isqrt = gmpy.isqrt + sqrtrem = gmpy.isqrt_rem + else: + isqrt_small = isqrt_fast = isqrt = gmpy.sqrt + sqrtrem = gmpy.sqrtrem +elif BACKEND == 'sage': + isqrt_small = isqrt_fast = isqrt = \ + getattr(sage_utils, "isqrt", lambda n: MPZ(n).isqrt()) + sqrtrem = lambda n: MPZ(n).sqrtrem() +else: + isqrt_small = isqrt_small_python + isqrt_fast = isqrt_fast_python + isqrt = isqrt_python + sqrtrem = sqrtrem_python + + +def ifib(n, _cache={}): + """Computes the nth Fibonacci number as an integer, for + integer n.""" + if n < 0: + return (-1)**(-n+1) * ifib(-n) + if n in _cache: + return _cache[n] + m = n + # Use Dijkstra's logarithmic algorithm + # The following implementation is basically equivalent to + # http://en.literateprograms.org/Fibonacci_numbers_(Scheme) + a, b, p, q = MPZ_ONE, MPZ_ZERO, MPZ_ZERO, MPZ_ONE + while n: + if n & 1: + aq = a*q + a, b = b*q+aq+a*p, b*p+aq + n -= 1 + else: + qq = q*q + p, q = p*p+qq, qq+2*p*q + n >>= 1 + if m < 250: + _cache[m] = b + return b + +MAX_FACTORIAL_CACHE = 1000 + +def ifac(n, memo={0:1, 1:1}): + """Return n factorial (for integers n >= 0 only).""" + f = memo.get(n) + if f: + return f + k = len(memo) + p = memo[k-1] + MAX = MAX_FACTORIAL_CACHE + while k <= n: + p *= k + if k <= MAX: + memo[k] = p + k += 1 + return p + +def ifac2(n, memo_pair=[{0:1}, {1:1}]): + """Return n!! (double factorial), integers n >= 0 only.""" + memo = memo_pair[n&1] + f = memo.get(n) + if f: + return f + k = max(memo) + p = memo[k] + MAX = MAX_FACTORIAL_CACHE + while k < n: + k += 2 + p *= k + if k <= MAX: + memo[k] = p + return p + +if BACKEND == 'gmpy': + ifac = gmpy.fac +elif BACKEND == 'sage': + ifac = lambda n: int(sage.factorial(n)) + ifib = sage.fibonacci + +def list_primes(n): + n = n + 1 + sieve = list(xrange(n)) + sieve[:2] = [0, 0] + for i in xrange(2, int(n**0.5)+1): + if sieve[i]: + for j in xrange(i**2, n, i): + sieve[j] = 0 + return [p for p in sieve if p] + +if BACKEND == 'sage': + # Note: it is *VERY* important for performance that we convert + # the list to Python ints. + def list_primes(n): + return [int(_) for _ in sage.primes(n+1)] + +small_odd_primes = (3,5,7,11,13,17,19,23,29,31,37,41,43,47) +small_odd_primes_set = set(small_odd_primes) + +def isprime(n): + """ + Determines whether n is a prime number. A probabilistic test is + performed if n is very large. No special trick is used for detecting + perfect powers. + + >>> sum(list_primes(100000)) + 454396537 + >>> sum(n*isprime(n) for n in range(100000)) + 454396537 + + """ + n = int(n) + if not n & 1: + return n == 2 + if n < 50: + return n in small_odd_primes_set + for p in small_odd_primes: + if not n % p: + return False + m = n-1 + s = trailing(m) + d = m >> s + def test(a): + x = pow(a,d,n) + if x == 1 or x == m: + return True + for r in xrange(1,s): + x = x**2 % n + if x == m: + return True + return False + # See http://primes.utm.edu/prove/prove2_3.html + if n < 1373653: + witnesses = [2,3] + elif n < 341550071728321: + witnesses = [2,3,5,7,11,13,17] + else: + witnesses = small_odd_primes + for a in witnesses: + if not test(a): + return False + return True + +def moebius(n): + """ + Evaluates the Moebius function which is `mu(n) = (-1)^k` if `n` + is a product of `k` distinct primes and `mu(n) = 0` otherwise. + + TODO: speed up using factorization + """ + n = abs(int(n)) + if n < 2: + return n + factors = [] + for p in xrange(2, n+1): + if not (n % p): + if not (n % p**2): + return 0 + if not sum(p % f for f in factors): + factors.append(p) + return (-1)**len(factors) + +def gcd(*args): + a = 0 + for b in args: + if a: + while b: + a, b = b, a % b + else: + a = b + return a + + +# Comment by Juan Arias de Reyna: +# +# I learn this method to compute EulerE[2n] from van de Lune. +# +# We apply the formula EulerE[2n] = (-1)^n 2**(-2n) sum_{j=0}^n a(2n,2j+1) +# +# where the numbers a(n,j) vanish for j > n+1 or j <= -1 and satisfies +# +# a(0,-1) = a(0,0) = 0; a(0,1)= 1; a(0,2) = a(0,3) = 0 +# +# a(n,j) = a(n-1,j) when n+j is even +# a(n,j) = (j-1) a(n-1,j-1) + (j+1) a(n-1,j+1) when n+j is odd +# +# +# But we can use only one array unidimensional a(j) since to compute +# a(n,j) we only need to know a(n-1,k) where k and j are of different parity +# and we have not to conserve the used values. +# +# We cached up the values of Euler numbers to sufficiently high order. +# +# Important Observation: If we pretend to use the numbers +# EulerE[1], EulerE[2], ... , EulerE[n] +# it is convenient to compute first EulerE[n], since the algorithm +# computes first all +# the previous ones, and keeps them in the CACHE + +MAX_EULER_CACHE = 500 + +def eulernum(m, _cache={0:MPZ_ONE}): + r""" + Computes the Euler numbers `E(n)`, which can be defined as + coefficients of the Taylor expansion of `1/cosh x`: + + .. math :: + + \frac{1}{\cosh x} = \sum_{n=0}^\infty \frac{E_n}{n!} x^n + + Example:: + + >>> [int(eulernum(n)) for n in range(11)] + [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0, -50521] + >>> [int(eulernum(n)) for n in range(11)] # test cache + [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0, -50521] + + """ + # for odd m > 1, the Euler numbers are zero + if m & 1: + return MPZ_ZERO + f = _cache.get(m) + if f: + return f + MAX = MAX_EULER_CACHE + n = m + a = [MPZ(_) for _ in [0,0,1,0,0,0]] + for n in range(1, m+1): + for j in range(n+1, -1, -2): + a[j+1] = (j-1)*a[j] + (j+1)*a[j+2] + a.append(0) + suma = 0 + for k in range(n+1, -1, -2): + suma += a[k+1] + if n <= MAX: + _cache[n] = ((-1)**(n//2))*(suma // 2**n) + if n == m: + return ((-1)**(n//2))*suma // 2**n + +def stirling1(n, k): + """ + Stirling number of the first kind. + """ + if n < 0 or k < 0: + raise ValueError + if k >= n: + return MPZ(n == k) + if k < 1: + return MPZ_ZERO + L = [MPZ_ZERO] * (k+1) + L[1] = MPZ_ONE + for m in xrange(2, n+1): + for j in xrange(min(k, m), 0, -1): + L[j] = (m-1) * L[j] + L[j-1] + return (-1)**(n+k) * L[k] + +def stirling2(n, k): + """ + Stirling number of the second kind. + """ + if n < 0 or k < 0: + raise ValueError + if k >= n: + return MPZ(n == k) + if k <= 1: + return MPZ(k == 1) + s = MPZ_ZERO + t = MPZ_ONE + for j in xrange(k+1): + if (k + j) & 1: + s -= t * MPZ(j)**n + else: + s += t * MPZ(j)**n + t = t * (k - j) // (j + 1) + return s // ifac(k) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libmpc.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libmpc.py new file mode 100644 index 0000000000000000000000000000000000000000..cc22d0e73674676c8a9249ebc2d48da7f3be8b0d --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libmpc.py @@ -0,0 +1,835 @@ +""" +Low-level functions for complex arithmetic. +""" + +import sys + +from .backend import MPZ, MPZ_ZERO, MPZ_ONE, MPZ_TWO, BACKEND + +from .libmpf import (\ + round_floor, round_ceiling, round_down, round_up, + round_nearest, round_fast, bitcount, + bctable, normalize, normalize1, reciprocal_rnd, rshift, lshift, giant_steps, + negative_rnd, + to_str, to_fixed, from_man_exp, from_float, to_float, from_int, to_int, + fzero, fone, ftwo, fhalf, finf, fninf, fnan, fnone, + mpf_abs, mpf_pos, mpf_neg, mpf_add, mpf_sub, mpf_mul, + mpf_div, mpf_mul_int, mpf_shift, mpf_sqrt, mpf_hypot, + mpf_rdiv_int, mpf_floor, mpf_ceil, mpf_nint, mpf_frac, + mpf_sign, mpf_hash, + ComplexResult +) + +from .libelefun import (\ + mpf_pi, mpf_exp, mpf_log, mpf_cos_sin, mpf_cosh_sinh, mpf_tan, mpf_pow_int, + mpf_log_hypot, + mpf_cos_sin_pi, mpf_phi, + mpf_cos, mpf_sin, mpf_cos_pi, mpf_sin_pi, + mpf_atan, mpf_atan2, mpf_cosh, mpf_sinh, mpf_tanh, + mpf_asin, mpf_acos, mpf_acosh, mpf_nthroot, mpf_fibonacci +) + +# An mpc value is a (real, imag) tuple +mpc_one = fone, fzero +mpc_zero = fzero, fzero +mpc_two = ftwo, fzero +mpc_half = (fhalf, fzero) + +_infs = (finf, fninf) +_infs_nan = (finf, fninf, fnan) + +def mpc_is_inf(z): + """Check if either real or imaginary part is infinite""" + re, im = z + if re in _infs: return True + if im in _infs: return True + return False + +def mpc_is_infnan(z): + """Check if either real or imaginary part is infinite or nan""" + re, im = z + if re in _infs_nan: return True + if im in _infs_nan: return True + return False + +def mpc_to_str(z, dps, **kwargs): + re, im = z + rs = to_str(re, dps) + if im[0]: + return rs + " - " + to_str(mpf_neg(im), dps, **kwargs) + "j" + else: + return rs + " + " + to_str(im, dps, **kwargs) + "j" + +def mpc_to_complex(z, strict=False, rnd=round_fast): + re, im = z + return complex(to_float(re, strict, rnd), to_float(im, strict, rnd)) + +def mpc_hash(z): + if sys.version_info >= (3, 2): + re, im = z + h = mpf_hash(re) + sys.hash_info.imag * mpf_hash(im) + # Need to reduce either module 2^32 or 2^64 + h = h % (2**sys.hash_info.width) + return int(h) + else: + try: + return hash(mpc_to_complex(z, strict=True)) + except OverflowError: + return hash(z) + +def mpc_conjugate(z, prec, rnd=round_fast): + re, im = z + return re, mpf_neg(im, prec, rnd) + +def mpc_is_nonzero(z): + return z != mpc_zero + +def mpc_add(z, w, prec, rnd=round_fast): + a, b = z + c, d = w + return mpf_add(a, c, prec, rnd), mpf_add(b, d, prec, rnd) + +def mpc_add_mpf(z, x, prec, rnd=round_fast): + a, b = z + return mpf_add(a, x, prec, rnd), b + +def mpc_sub(z, w, prec=0, rnd=round_fast): + a, b = z + c, d = w + return mpf_sub(a, c, prec, rnd), mpf_sub(b, d, prec, rnd) + +def mpc_sub_mpf(z, p, prec=0, rnd=round_fast): + a, b = z + return mpf_sub(a, p, prec, rnd), b + +def mpc_pos(z, prec, rnd=round_fast): + a, b = z + return mpf_pos(a, prec, rnd), mpf_pos(b, prec, rnd) + +def mpc_neg(z, prec=None, rnd=round_fast): + a, b = z + return mpf_neg(a, prec, rnd), mpf_neg(b, prec, rnd) + +def mpc_shift(z, n): + a, b = z + return mpf_shift(a, n), mpf_shift(b, n) + +def mpc_abs(z, prec, rnd=round_fast): + """Absolute value of a complex number, |a+bi|. + Returns an mpf value.""" + a, b = z + return mpf_hypot(a, b, prec, rnd) + +def mpc_arg(z, prec, rnd=round_fast): + """Argument of a complex number. Returns an mpf value.""" + a, b = z + return mpf_atan2(b, a, prec, rnd) + +def mpc_floor(z, prec, rnd=round_fast): + a, b = z + return mpf_floor(a, prec, rnd), mpf_floor(b, prec, rnd) + +def mpc_ceil(z, prec, rnd=round_fast): + a, b = z + return mpf_ceil(a, prec, rnd), mpf_ceil(b, prec, rnd) + +def mpc_nint(z, prec, rnd=round_fast): + a, b = z + return mpf_nint(a, prec, rnd), mpf_nint(b, prec, rnd) + +def mpc_frac(z, prec, rnd=round_fast): + a, b = z + return mpf_frac(a, prec, rnd), mpf_frac(b, prec, rnd) + + +def mpc_mul(z, w, prec, rnd=round_fast): + """ + Complex multiplication. + + Returns the real and imaginary part of (a+bi)*(c+di), rounded to + the specified precision. The rounding mode applies to the real and + imaginary parts separately. + """ + a, b = z + c, d = w + p = mpf_mul(a, c) + q = mpf_mul(b, d) + r = mpf_mul(a, d) + s = mpf_mul(b, c) + re = mpf_sub(p, q, prec, rnd) + im = mpf_add(r, s, prec, rnd) + return re, im + +def mpc_square(z, prec, rnd=round_fast): + # (a+b*I)**2 == a**2 - b**2 + 2*I*a*b + a, b = z + p = mpf_mul(a,a) + q = mpf_mul(b,b) + r = mpf_mul(a,b, prec, rnd) + re = mpf_sub(p, q, prec, rnd) + im = mpf_shift(r, 1) + return re, im + +def mpc_mul_mpf(z, p, prec, rnd=round_fast): + a, b = z + re = mpf_mul(a, p, prec, rnd) + im = mpf_mul(b, p, prec, rnd) + return re, im + +def mpc_mul_imag_mpf(z, x, prec, rnd=round_fast): + """ + Multiply the mpc value z by I*x where x is an mpf value. + """ + a, b = z + re = mpf_neg(mpf_mul(b, x, prec, rnd)) + im = mpf_mul(a, x, prec, rnd) + return re, im + +def mpc_mul_int(z, n, prec, rnd=round_fast): + a, b = z + re = mpf_mul_int(a, n, prec, rnd) + im = mpf_mul_int(b, n, prec, rnd) + return re, im + +def mpc_div(z, w, prec, rnd=round_fast): + a, b = z + c, d = w + wp = prec + 10 + # mag = c*c + d*d + mag = mpf_add(mpf_mul(c, c), mpf_mul(d, d), wp) + # (a*c+b*d)/mag, (b*c-a*d)/mag + t = mpf_add(mpf_mul(a,c), mpf_mul(b,d), wp) + u = mpf_sub(mpf_mul(b,c), mpf_mul(a,d), wp) + return mpf_div(t,mag,prec,rnd), mpf_div(u,mag,prec,rnd) + +def mpc_div_mpf(z, p, prec, rnd=round_fast): + """Calculate z/p where p is real""" + a, b = z + re = mpf_div(a, p, prec, rnd) + im = mpf_div(b, p, prec, rnd) + return re, im + +def mpc_reciprocal(z, prec, rnd=round_fast): + """Calculate 1/z efficiently""" + a, b = z + m = mpf_add(mpf_mul(a,a),mpf_mul(b,b),prec+10) + re = mpf_div(a, m, prec, rnd) + im = mpf_neg(mpf_div(b, m, prec, rnd)) + return re, im + +def mpc_mpf_div(p, z, prec, rnd=round_fast): + """Calculate p/z where p is real efficiently""" + a, b = z + m = mpf_add(mpf_mul(a,a),mpf_mul(b,b), prec+10) + re = mpf_div(mpf_mul(a,p), m, prec, rnd) + im = mpf_div(mpf_neg(mpf_mul(b,p)), m, prec, rnd) + return re, im + +def complex_int_pow(a, b, n): + """Complex integer power: computes (a+b*I)**n exactly for + nonnegative n (a and b must be Python ints).""" + wre = 1 + wim = 0 + while n: + if n & 1: + wre, wim = wre*a - wim*b, wim*a + wre*b + n -= 1 + a, b = a*a - b*b, 2*a*b + n //= 2 + return wre, wim + +def mpc_pow(z, w, prec, rnd=round_fast): + if w[1] == fzero: + return mpc_pow_mpf(z, w[0], prec, rnd) + return mpc_exp(mpc_mul(mpc_log(z, prec+10), w, prec+10), prec, rnd) + +def mpc_pow_mpf(z, p, prec, rnd=round_fast): + psign, pman, pexp, pbc = p + if pexp >= 0: + return mpc_pow_int(z, (-1)**psign * (pman< 0: + aman <<= de + aexp = bexp + else: + bman <<= (-de) + bexp = aexp + re, im = complex_int_pow(aman, bman, n) + re = from_man_exp(re, int(n*aexp), prec, rnd) + im = from_man_exp(im, int(n*bexp), prec, rnd) + return re, im + return mpc_exp(mpc_mul_int(mpc_log(z, prec+10), n, prec+10), prec, rnd) + +def mpc_sqrt(z, prec, rnd=round_fast): + """Complex square root (principal branch). + + We have sqrt(a+bi) = sqrt((r+a)/2) + b/sqrt(2*(r+a))*i where + r = abs(a+bi), when a+bi is not a negative real number.""" + a, b = z + if b == fzero: + if a == fzero: + return (a, b) + # When a+bi is a negative real number, we get a real sqrt times i + if a[0]: + im = mpf_sqrt(mpf_neg(a), prec, rnd) + return (fzero, im) + else: + re = mpf_sqrt(a, prec, rnd) + return (re, fzero) + wp = prec+20 + if not a[0]: # case a positive + t = mpf_add(mpc_abs((a, b), wp), a, wp) # t = abs(a+bi) + a + u = mpf_shift(t, -1) # u = t/2 + re = mpf_sqrt(u, prec, rnd) # re = sqrt(u) + v = mpf_shift(t, 1) # v = 2*t + w = mpf_sqrt(v, wp) # w = sqrt(v) + im = mpf_div(b, w, prec, rnd) # im = b / w + else: # case a negative + t = mpf_sub(mpc_abs((a, b), wp), a, wp) # t = abs(a+bi) - a + u = mpf_shift(t, -1) # u = t/2 + im = mpf_sqrt(u, prec, rnd) # im = sqrt(u) + v = mpf_shift(t, 1) # v = 2*t + w = mpf_sqrt(v, wp) # w = sqrt(v) + re = mpf_div(b, w, prec, rnd) # re = b/w + if b[0]: + re = mpf_neg(re) + im = mpf_neg(im) + return re, im + +def mpc_nthroot_fixed(a, b, n, prec): + # a, b signed integers at fixed precision prec + start = 50 + a1 = int(rshift(a, prec - n*start)) + b1 = int(rshift(b, prec - n*start)) + try: + r = (a1 + 1j * b1)**(1.0/n) + re = r.real + im = r.imag + re = MPZ(int(re)) + im = MPZ(int(im)) + except OverflowError: + a1 = from_int(a1, start) + b1 = from_int(b1, start) + fn = from_int(n) + nth = mpf_rdiv_int(1, fn, start) + re, im = mpc_pow((a1, b1), (nth, fzero), start) + re = to_int(re) + im = to_int(im) + extra = 10 + prevp = start + extra1 = n + for p in giant_steps(start, prec+extra): + # this is slow for large n, unlike int_pow_fixed + re2, im2 = complex_int_pow(re, im, n-1) + re2 = rshift(re2, (n-1)*prevp - p - extra1) + im2 = rshift(im2, (n-1)*prevp - p - extra1) + r4 = (re2*re2 + im2*im2) >> (p + extra1) + ap = rshift(a, prec - p) + bp = rshift(b, prec - p) + rec = (ap * re2 + bp * im2) >> p + imc = (-ap * im2 + bp * re2) >> p + reb = (rec << p) // r4 + imb = (imc << p) // r4 + re = (reb + (n-1)*lshift(re, p-prevp))//n + im = (imb + (n-1)*lshift(im, p-prevp))//n + prevp = p + return re, im + +def mpc_nthroot(z, n, prec, rnd=round_fast): + """ + Complex n-th root. + + Use Newton method as in the real case when it is faster, + otherwise use z**(1/n) + """ + a, b = z + if a[0] == 0 and b == fzero: + re = mpf_nthroot(a, n, prec, rnd) + return (re, fzero) + if n < 2: + if n == 0: + return mpc_one + if n == 1: + return mpc_pos((a, b), prec, rnd) + if n == -1: + return mpc_div(mpc_one, (a, b), prec, rnd) + inverse = mpc_nthroot((a, b), -n, prec+5, reciprocal_rnd[rnd]) + return mpc_div(mpc_one, inverse, prec, rnd) + if n <= 20: + prec2 = int(1.2 * (prec + 10)) + asign, aman, aexp, abc = a + bsign, bman, bexp, bbc = b + pf = mpc_abs((a,b), prec) + if pf[-2] + pf[-1] > -10 and pf[-2] + pf[-1] < prec: + af = to_fixed(a, prec2) + bf = to_fixed(b, prec2) + re, im = mpc_nthroot_fixed(af, bf, n, prec2) + extra = 10 + re = from_man_exp(re, -prec2-extra, prec2, rnd) + im = from_man_exp(im, -prec2-extra, prec2, rnd) + return re, im + fn = from_int(n) + prec2 = prec+10 + 10 + nth = mpf_rdiv_int(1, fn, prec2) + re, im = mpc_pow((a, b), (nth, fzero), prec2, rnd) + re = normalize(re[0], re[1], re[2], re[3], prec, rnd) + im = normalize(im[0], im[1], im[2], im[3], prec, rnd) + return re, im + +def mpc_cbrt(z, prec, rnd=round_fast): + """ + Complex cubic root. + """ + return mpc_nthroot(z, 3, prec, rnd) + +def mpc_exp(z, prec, rnd=round_fast): + """ + Complex exponential function. + + We use the direct formula exp(a+bi) = exp(a) * (cos(b) + sin(b)*i) + for the computation. This formula is very nice because it is + pefectly stable; since we just do real multiplications, the only + numerical errors that can creep in are single-ulp rounding errors. + + The formula is efficient since mpmath's real exp is quite fast and + since we can compute cos and sin simultaneously. + + It is no problem if a and b are large; if the implementations of + exp/cos/sin are accurate and efficient for all real numbers, then + so is this function for all complex numbers. + """ + a, b = z + if a == fzero: + return mpf_cos_sin(b, prec, rnd) + if b == fzero: + return mpf_exp(a, prec, rnd), fzero + mag = mpf_exp(a, prec+4, rnd) + c, s = mpf_cos_sin(b, prec+4, rnd) + re = mpf_mul(mag, c, prec, rnd) + im = mpf_mul(mag, s, prec, rnd) + return re, im + +def mpc_log(z, prec, rnd=round_fast): + re = mpf_log_hypot(z[0], z[1], prec, rnd) + im = mpc_arg(z, prec, rnd) + return re, im + +def mpc_cos(z, prec, rnd=round_fast): + """Complex cosine. The formula used is cos(a+bi) = cos(a)*cosh(b) - + sin(a)*sinh(b)*i. + + The same comments apply as for the complex exp: only real + multiplications are pewrormed, so no cancellation errors are + possible. The formula is also efficient since we can compute both + pairs (cos, sin) and (cosh, sinh) in single stwps.""" + a, b = z + if b == fzero: + return mpf_cos(a, prec, rnd), fzero + if a == fzero: + return mpf_cosh(b, prec, rnd), fzero + wp = prec + 6 + c, s = mpf_cos_sin(a, wp) + ch, sh = mpf_cosh_sinh(b, wp) + re = mpf_mul(c, ch, prec, rnd) + im = mpf_mul(s, sh, prec, rnd) + return re, mpf_neg(im) + +def mpc_sin(z, prec, rnd=round_fast): + """Complex sine. We have sin(a+bi) = sin(a)*cosh(b) + + cos(a)*sinh(b)*i. See the docstring for mpc_cos for additional + comments.""" + a, b = z + if b == fzero: + return mpf_sin(a, prec, rnd), fzero + if a == fzero: + return fzero, mpf_sinh(b, prec, rnd) + wp = prec + 6 + c, s = mpf_cos_sin(a, wp) + ch, sh = mpf_cosh_sinh(b, wp) + re = mpf_mul(s, ch, prec, rnd) + im = mpf_mul(c, sh, prec, rnd) + return re, im + +def mpc_tan(z, prec, rnd=round_fast): + """Complex tangent. Computed as tan(a+bi) = sin(2a)/M + sinh(2b)/M*i + where M = cos(2a) + cosh(2b).""" + a, b = z + asign, aman, aexp, abc = a + bsign, bman, bexp, bbc = b + if b == fzero: return mpf_tan(a, prec, rnd), fzero + if a == fzero: return fzero, mpf_tanh(b, prec, rnd) + wp = prec + 15 + a = mpf_shift(a, 1) + b = mpf_shift(b, 1) + c, s = mpf_cos_sin(a, wp) + ch, sh = mpf_cosh_sinh(b, wp) + # TODO: handle cancellation when c ~= -1 and ch ~= 1 + mag = mpf_add(c, ch, wp) + re = mpf_div(s, mag, prec, rnd) + im = mpf_div(sh, mag, prec, rnd) + return re, im + +def mpc_cos_pi(z, prec, rnd=round_fast): + a, b = z + if b == fzero: + return mpf_cos_pi(a, prec, rnd), fzero + b = mpf_mul(b, mpf_pi(prec+5), prec+5) + if a == fzero: + return mpf_cosh(b, prec, rnd), fzero + wp = prec + 6 + c, s = mpf_cos_sin_pi(a, wp) + ch, sh = mpf_cosh_sinh(b, wp) + re = mpf_mul(c, ch, prec, rnd) + im = mpf_mul(s, sh, prec, rnd) + return re, mpf_neg(im) + +def mpc_sin_pi(z, prec, rnd=round_fast): + a, b = z + if b == fzero: + return mpf_sin_pi(a, prec, rnd), fzero + b = mpf_mul(b, mpf_pi(prec+5), prec+5) + if a == fzero: + return fzero, mpf_sinh(b, prec, rnd) + wp = prec + 6 + c, s = mpf_cos_sin_pi(a, wp) + ch, sh = mpf_cosh_sinh(b, wp) + re = mpf_mul(s, ch, prec, rnd) + im = mpf_mul(c, sh, prec, rnd) + return re, im + +def mpc_cos_sin(z, prec, rnd=round_fast): + a, b = z + if a == fzero: + ch, sh = mpf_cosh_sinh(b, prec, rnd) + return (ch, fzero), (fzero, sh) + if b == fzero: + c, s = mpf_cos_sin(a, prec, rnd) + return (c, fzero), (s, fzero) + wp = prec + 6 + c, s = mpf_cos_sin(a, wp) + ch, sh = mpf_cosh_sinh(b, wp) + cre = mpf_mul(c, ch, prec, rnd) + cim = mpf_mul(s, sh, prec, rnd) + sre = mpf_mul(s, ch, prec, rnd) + sim = mpf_mul(c, sh, prec, rnd) + return (cre, mpf_neg(cim)), (sre, sim) + +def mpc_cos_sin_pi(z, prec, rnd=round_fast): + a, b = z + if b == fzero: + c, s = mpf_cos_sin_pi(a, prec, rnd) + return (c, fzero), (s, fzero) + b = mpf_mul(b, mpf_pi(prec+5), prec+5) + if a == fzero: + ch, sh = mpf_cosh_sinh(b, prec, rnd) + return (ch, fzero), (fzero, sh) + wp = prec + 6 + c, s = mpf_cos_sin_pi(a, wp) + ch, sh = mpf_cosh_sinh(b, wp) + cre = mpf_mul(c, ch, prec, rnd) + cim = mpf_mul(s, sh, prec, rnd) + sre = mpf_mul(s, ch, prec, rnd) + sim = mpf_mul(c, sh, prec, rnd) + return (cre, mpf_neg(cim)), (sre, sim) + +def mpc_cosh(z, prec, rnd=round_fast): + """Complex hyperbolic cosine. Computed as cosh(z) = cos(z*i).""" + a, b = z + return mpc_cos((b, mpf_neg(a)), prec, rnd) + +def mpc_sinh(z, prec, rnd=round_fast): + """Complex hyperbolic sine. Computed as sinh(z) = -i*sin(z*i).""" + a, b = z + b, a = mpc_sin((b, a), prec, rnd) + return a, b + +def mpc_tanh(z, prec, rnd=round_fast): + """Complex hyperbolic tangent. Computed as tanh(z) = -i*tan(z*i).""" + a, b = z + b, a = mpc_tan((b, a), prec, rnd) + return a, b + +# TODO: avoid loss of accuracy +def mpc_atan(z, prec, rnd=round_fast): + a, b = z + # atan(z) = (I/2)*(log(1-I*z) - log(1+I*z)) + # x = 1-I*z = 1 + b - I*a + # y = 1+I*z = 1 - b + I*a + wp = prec + 15 + x = mpf_add(fone, b, wp), mpf_neg(a) + y = mpf_sub(fone, b, wp), a + l1 = mpc_log(x, wp) + l2 = mpc_log(y, wp) + a, b = mpc_sub(l1, l2, prec, rnd) + # (I/2) * (a+b*I) = (-b/2 + a/2*I) + v = mpf_neg(mpf_shift(b,-1)), mpf_shift(a,-1) + # Subtraction at infinity gives correct real part but + # wrong imaginary part (should be zero) + if v[1] == fnan and mpc_is_inf(z): + v = (v[0], fzero) + return v + +beta_crossover = from_float(0.6417) +alpha_crossover = from_float(1.5) + +def acos_asin(z, prec, rnd, n): + """ complex acos for n = 0, asin for n = 1 + The algorithm is described in + T.E. Hull, T.F. Fairgrieve and P.T.P. Tang + 'Implementing the Complex Arcsine and Arcosine Functions + using Exception Handling', + ACM Trans. on Math. Software Vol. 23 (1997), p299 + The complex acos and asin can be defined as + acos(z) = acos(beta) - I*sign(a)* log(alpha + sqrt(alpha**2 -1)) + asin(z) = asin(beta) + I*sign(a)* log(alpha + sqrt(alpha**2 -1)) + where z = a + I*b + alpha = (1/2)*(r + s); beta = (1/2)*(r - s) = a/alpha + r = sqrt((a+1)**2 + y**2); s = sqrt((a-1)**2 + y**2) + These expressions are rewritten in different ways in different + regions, delimited by two crossovers alpha_crossover and beta_crossover, + and by abs(a) <= 1, in order to improve the numerical accuracy. + """ + a, b = z + wp = prec + 10 + # special cases with real argument + if b == fzero: + am = mpf_sub(fone, mpf_abs(a), wp) + # case abs(a) <= 1 + if not am[0]: + if n == 0: + return mpf_acos(a, prec, rnd), fzero + else: + return mpf_asin(a, prec, rnd), fzero + # cases abs(a) > 1 + else: + # case a < -1 + if a[0]: + pi = mpf_pi(prec, rnd) + c = mpf_acosh(mpf_neg(a), prec, rnd) + if n == 0: + return pi, mpf_neg(c) + else: + return mpf_neg(mpf_shift(pi, -1)), c + # case a > 1 + else: + c = mpf_acosh(a, prec, rnd) + if n == 0: + return fzero, c + else: + pi = mpf_pi(prec, rnd) + return mpf_shift(pi, -1), mpf_neg(c) + asign = bsign = 0 + if a[0]: + a = mpf_neg(a) + asign = 1 + if b[0]: + b = mpf_neg(b) + bsign = 1 + am = mpf_sub(fone, a, wp) + ap = mpf_add(fone, a, wp) + r = mpf_hypot(ap, b, wp) + s = mpf_hypot(am, b, wp) + alpha = mpf_shift(mpf_add(r, s, wp), -1) + beta = mpf_div(a, alpha, wp) + b2 = mpf_mul(b,b, wp) + # case beta <= beta_crossover + if not mpf_sub(beta_crossover, beta, wp)[0]: + if n == 0: + re = mpf_acos(beta, wp) + else: + re = mpf_asin(beta, wp) + else: + # to compute the real part in this region use the identity + # asin(beta) = atan(beta/sqrt(1-beta**2)) + # beta/sqrt(1-beta**2) = (alpha + a) * (alpha - a) + # alpha + a is numerically accurate; alpha - a can have + # cancellations leading to numerical inaccuracies, so rewrite + # it in differente ways according to the region + Ax = mpf_add(alpha, a, wp) + # case a <= 1 + if not am[0]: + # c = b*b/(r + (a+1)); d = (s + (1-a)) + # alpha - a = (1/2)*(c + d) + # case n=0: re = atan(sqrt((1/2) * Ax * (c + d))/a) + # case n=1: re = atan(a/sqrt((1/2) * Ax * (c + d))) + c = mpf_div(b2, mpf_add(r, ap, wp), wp) + d = mpf_add(s, am, wp) + re = mpf_shift(mpf_mul(Ax, mpf_add(c, d, wp), wp), -1) + if n == 0: + re = mpf_atan(mpf_div(mpf_sqrt(re, wp), a, wp), wp) + else: + re = mpf_atan(mpf_div(a, mpf_sqrt(re, wp), wp), wp) + else: + # c = Ax/(r + (a+1)); d = Ax/(s - (1-a)) + # alpha - a = (1/2)*(c + d) + # case n = 0: re = atan(b*sqrt(c + d)/2/a) + # case n = 1: re = atan(a/(b*sqrt(c + d)/2) + c = mpf_div(Ax, mpf_add(r, ap, wp), wp) + d = mpf_div(Ax, mpf_sub(s, am, wp), wp) + re = mpf_shift(mpf_add(c, d, wp), -1) + re = mpf_mul(b, mpf_sqrt(re, wp), wp) + if n == 0: + re = mpf_atan(mpf_div(re, a, wp), wp) + else: + re = mpf_atan(mpf_div(a, re, wp), wp) + # to compute alpha + sqrt(alpha**2 - 1), if alpha <= alpha_crossover + # replace it with 1 + Am1 + sqrt(Am1*(alpha+1))) + # where Am1 = alpha -1 + # if alpha <= alpha_crossover: + if not mpf_sub(alpha_crossover, alpha, wp)[0]: + c1 = mpf_div(b2, mpf_add(r, ap, wp), wp) + # case a < 1 + if mpf_neg(am)[0]: + # Am1 = (1/2) * (b*b/(r + (a+1)) + b*b/(s + (1-a)) + c2 = mpf_add(s, am, wp) + c2 = mpf_div(b2, c2, wp) + Am1 = mpf_shift(mpf_add(c1, c2, wp), -1) + else: + # Am1 = (1/2) * (b*b/(r + (a+1)) + (s - (1-a))) + c2 = mpf_sub(s, am, wp) + Am1 = mpf_shift(mpf_add(c1, c2, wp), -1) + # im = log(1 + Am1 + sqrt(Am1*(alpha+1))) + im = mpf_mul(Am1, mpf_add(alpha, fone, wp), wp) + im = mpf_log(mpf_add(fone, mpf_add(Am1, mpf_sqrt(im, wp), wp), wp), wp) + else: + # im = log(alpha + sqrt(alpha*alpha - 1)) + im = mpf_sqrt(mpf_sub(mpf_mul(alpha, alpha, wp), fone, wp), wp) + im = mpf_log(mpf_add(alpha, im, wp), wp) + if asign: + if n == 0: + re = mpf_sub(mpf_pi(wp), re, wp) + else: + re = mpf_neg(re) + if not bsign and n == 0: + im = mpf_neg(im) + if bsign and n == 1: + im = mpf_neg(im) + re = normalize(re[0], re[1], re[2], re[3], prec, rnd) + im = normalize(im[0], im[1], im[2], im[3], prec, rnd) + return re, im + +def mpc_acos(z, prec, rnd=round_fast): + return acos_asin(z, prec, rnd, 0) + +def mpc_asin(z, prec, rnd=round_fast): + return acos_asin(z, prec, rnd, 1) + +def mpc_asinh(z, prec, rnd=round_fast): + # asinh(z) = I * asin(-I z) + a, b = z + a, b = mpc_asin((b, mpf_neg(a)), prec, rnd) + return mpf_neg(b), a + +def mpc_acosh(z, prec, rnd=round_fast): + # acosh(z) = -I * acos(z) for Im(acos(z)) <= 0 + # +I * acos(z) otherwise + a, b = mpc_acos(z, prec, rnd) + if b[0] or b == fzero: + return mpf_neg(b), a + else: + return b, mpf_neg(a) + +def mpc_atanh(z, prec, rnd=round_fast): + # atanh(z) = (log(1+z)-log(1-z))/2 + wp = prec + 15 + a = mpc_add(z, mpc_one, wp) + b = mpc_sub(mpc_one, z, wp) + a = mpc_log(a, wp) + b = mpc_log(b, wp) + v = mpc_shift(mpc_sub(a, b, wp), -1) + # Subtraction at infinity gives correct imaginary part but + # wrong real part (should be zero) + if v[0] == fnan and mpc_is_inf(z): + v = (fzero, v[1]) + return v + +def mpc_fibonacci(z, prec, rnd=round_fast): + re, im = z + if im == fzero: + return (mpf_fibonacci(re, prec, rnd), fzero) + size = max(abs(re[2]+re[3]), abs(re[2]+re[3])) + wp = prec + size + 20 + a = mpf_phi(wp) + b = mpf_add(mpf_shift(a, 1), fnone, wp) + u = mpc_pow((a, fzero), z, wp) + v = mpc_cos_pi(z, wp) + v = mpc_div(v, u, wp) + u = mpc_sub(u, v, wp) + u = mpc_div_mpf(u, b, prec, rnd) + return u + +def mpf_expj(x, prec, rnd='f'): + raise ComplexResult + +def mpc_expj(z, prec, rnd='f'): + re, im = z + if im == fzero: + return mpf_cos_sin(re, prec, rnd) + if re == fzero: + return mpf_exp(mpf_neg(im), prec, rnd), fzero + ey = mpf_exp(mpf_neg(im), prec+10) + c, s = mpf_cos_sin(re, prec+10) + re = mpf_mul(ey, c, prec, rnd) + im = mpf_mul(ey, s, prec, rnd) + return re, im + +def mpf_expjpi(x, prec, rnd='f'): + raise ComplexResult + +def mpc_expjpi(z, prec, rnd='f'): + re, im = z + if im == fzero: + return mpf_cos_sin_pi(re, prec, rnd) + sign, man, exp, bc = im + wp = prec+10 + if man: + wp += max(0, exp+bc) + im = mpf_neg(mpf_mul(mpf_pi(wp), im, wp)) + if re == fzero: + return mpf_exp(im, prec, rnd), fzero + ey = mpf_exp(im, prec+10) + c, s = mpf_cos_sin_pi(re, prec+10) + re = mpf_mul(ey, c, prec, rnd) + im = mpf_mul(ey, s, prec, rnd) + return re, im + + +if BACKEND == 'sage': + try: + import sage.libs.mpmath.ext_libmp as _lbmp + mpc_exp = _lbmp.mpc_exp + mpc_sqrt = _lbmp.mpc_sqrt + except (ImportError, AttributeError): + print("Warning: Sage imports in libmpc failed") diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libmpf.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libmpf.py new file mode 100644 index 0000000000000000000000000000000000000000..5c162e17d4f688c71dc3476b944e2d31c65faab7 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/libmp/libmpf.py @@ -0,0 +1,1414 @@ +""" +Low-level functions for arbitrary-precision floating-point arithmetic. +""" + +__docformat__ = 'plaintext' + +import math + +from bisect import bisect + +import sys + +# Importing random is slow +#from random import getrandbits +getrandbits = None + +from .backend import (MPZ, MPZ_TYPE, MPZ_ZERO, MPZ_ONE, MPZ_TWO, MPZ_FIVE, + BACKEND, STRICT, HASH_MODULUS, HASH_BITS, gmpy, sage, sage_utils) + +from .libintmath import (giant_steps, + trailtable, bctable, lshift, rshift, bitcount, trailing, + sqrt_fixed, numeral, isqrt, isqrt_fast, sqrtrem, + bin_to_radix) + +# We don't pickle tuples directly for the following reasons: +# 1: pickle uses str() for ints, which is inefficient when they are large +# 2: pickle doesn't work for gmpy mpzs +# Both problems are solved by using hex() + +if BACKEND == 'sage': + def to_pickable(x): + sign, man, exp, bc = x + return sign, hex(man), exp, bc +else: + def to_pickable(x): + sign, man, exp, bc = x + return sign, hex(man)[2:], exp, bc + +def from_pickable(x): + sign, man, exp, bc = x + return (sign, MPZ(man, 16), exp, bc) + +class ComplexResult(ValueError): + pass + +try: + intern +except NameError: + intern = lambda x: x + +# All supported rounding modes +round_nearest = intern('n') +round_floor = intern('f') +round_ceiling = intern('c') +round_up = intern('u') +round_down = intern('d') +round_fast = round_down + +def prec_to_dps(n): + """Return number of accurate decimals that can be represented + with a precision of n bits.""" + return max(1, int(round(int(n)/3.3219280948873626)-1)) + +def dps_to_prec(n): + """Return the number of bits required to represent n decimals + accurately.""" + return max(1, int(round((int(n)+1)*3.3219280948873626))) + +def repr_dps(n): + """Return the number of decimal digits required to represent + a number with n-bit precision so that it can be uniquely + reconstructed from the representation.""" + dps = prec_to_dps(n) + if dps == 15: + return 17 + return dps + 3 + +#----------------------------------------------------------------------------# +# Some commonly needed float values # +#----------------------------------------------------------------------------# + +# Regular number format: +# (-1)**sign * mantissa * 2**exponent, plus bitcount of mantissa +fzero = (0, MPZ_ZERO, 0, 0) +fnzero = (1, MPZ_ZERO, 0, 0) +fone = (0, MPZ_ONE, 0, 1) +fnone = (1, MPZ_ONE, 0, 1) +ftwo = (0, MPZ_ONE, 1, 1) +ften = (0, MPZ_FIVE, 1, 3) +fhalf = (0, MPZ_ONE, -1, 1) + +# Arbitrary encoding for special numbers: zero mantissa, nonzero exponent +fnan = (0, MPZ_ZERO, -123, -1) +finf = (0, MPZ_ZERO, -456, -2) +fninf = (1, MPZ_ZERO, -789, -3) + +# Was 1e1000; this is broken in Python 2.4 +math_float_inf = 1e300 * 1e300 + + +#----------------------------------------------------------------------------# +# Rounding # +#----------------------------------------------------------------------------# + +# This function can be used to round a mantissa generally. However, +# we will try to do most rounding inline for efficiency. +def round_int(x, n, rnd): + if rnd == round_nearest: + if x >= 0: + t = x >> (n-1) + if t & 1 and ((t & 2) or (x & h_mask[n<300][n])): + return (t>>1)+1 + else: + return t>>1 + else: + return -round_int(-x, n, rnd) + if rnd == round_floor: + return x >> n + if rnd == round_ceiling: + return -((-x) >> n) + if rnd == round_down: + if x >= 0: + return x >> n + return -((-x) >> n) + if rnd == round_up: + if x >= 0: + return -((-x) >> n) + return x >> n + +# These masks are used to pick out segments of numbers to determine +# which direction to round when rounding to nearest. +class h_mask_big: + def __getitem__(self, n): + return (MPZ_ONE<<(n-1))-1 + +h_mask_small = [0]+[((MPZ_ONE<<(_-1))-1) for _ in range(1, 300)] +h_mask = [h_mask_big(), h_mask_small] + +# The >> operator rounds to floor. shifts_down[rnd][sign] +# tells whether this is the right direction to use, or if the +# number should be negated before shifting +shifts_down = {round_floor:(1,0), round_ceiling:(0,1), + round_down:(1,1), round_up:(0,0)} + + +#----------------------------------------------------------------------------# +# Normalization of raw mpfs # +#----------------------------------------------------------------------------# + +# This function is called almost every time an mpf is created. +# It has been optimized accordingly. + +def _normalize(sign, man, exp, bc, prec, rnd): + """ + Create a raw mpf tuple with value (-1)**sign * man * 2**exp and + normalized mantissa. The mantissa is rounded in the specified + direction if its size exceeds the precision. Trailing zero bits + are also stripped from the mantissa to ensure that the + representation is canonical. + + Conditions on the input: + * The input must represent a regular (finite) number + * The sign bit must be 0 or 1 + * The mantissa must be positive + * The exponent must be an integer + * The bitcount must be exact + + If these conditions are not met, use from_man_exp, mpf_pos, or any + of the conversion functions to create normalized raw mpf tuples. + """ + if not man: + return fzero + # Cut mantissa down to size if larger than target precision + n = bc - prec + if n > 0: + if rnd == round_nearest: + t = man >> (n-1) + if t & 1 and ((t & 2) or (man & h_mask[n<300][n])): + man = (t>>1)+1 + else: + man = t>>1 + elif shifts_down[rnd][sign]: + man >>= n + else: + man = -((-man)>>n) + exp += n + bc = prec + # Strip trailing bits + if not man & 1: + t = trailtable[int(man & 255)] + if not t: + while not man & 255: + man >>= 8 + exp += 8 + bc -= 8 + t = trailtable[int(man & 255)] + man >>= t + exp += t + bc -= t + # Bit count can be wrong if the input mantissa was 1 less than + # a power of 2 and got rounded up, thereby adding an extra bit. + # With trailing bits removed, all powers of two have mantissa 1, + # so this is easy to check for. + if man == 1: + bc = 1 + return sign, man, exp, bc + +def _normalize1(sign, man, exp, bc, prec, rnd): + """same as normalize, but with the added condition that + man is odd or zero + """ + if not man: + return fzero + if bc <= prec: + return sign, man, exp, bc + n = bc - prec + if rnd == round_nearest: + t = man >> (n-1) + if t & 1 and ((t & 2) or (man & h_mask[n<300][n])): + man = (t>>1)+1 + else: + man = t>>1 + elif shifts_down[rnd][sign]: + man >>= n + else: + man = -((-man)>>n) + exp += n + bc = prec + # Strip trailing bits + if not man & 1: + t = trailtable[int(man & 255)] + if not t: + while not man & 255: + man >>= 8 + exp += 8 + bc -= 8 + t = trailtable[int(man & 255)] + man >>= t + exp += t + bc -= t + # Bit count can be wrong if the input mantissa was 1 less than + # a power of 2 and got rounded up, thereby adding an extra bit. + # With trailing bits removed, all powers of two have mantissa 1, + # so this is easy to check for. + if man == 1: + bc = 1 + return sign, man, exp, bc + +try: + _exp_types = (int, long) +except NameError: + _exp_types = (int,) + +def strict_normalize(sign, man, exp, bc, prec, rnd): + """Additional checks on the components of an mpf. Enable tests by setting + the environment variable MPMATH_STRICT to Y.""" + assert type(man) == MPZ_TYPE + assert type(bc) in _exp_types + assert type(exp) in _exp_types + assert bc == bitcount(man) + return _normalize(sign, man, exp, bc, prec, rnd) + +def strict_normalize1(sign, man, exp, bc, prec, rnd): + """Additional checks on the components of an mpf. Enable tests by setting + the environment variable MPMATH_STRICT to Y.""" + assert type(man) == MPZ_TYPE + assert type(bc) in _exp_types + assert type(exp) in _exp_types + assert bc == bitcount(man) + assert (not man) or (man & 1) + return _normalize1(sign, man, exp, bc, prec, rnd) + +if BACKEND == 'gmpy' and '_mpmath_normalize' in dir(gmpy): + _normalize = gmpy._mpmath_normalize + _normalize1 = gmpy._mpmath_normalize + +if BACKEND == 'sage': + _normalize = _normalize1 = sage_utils.normalize + +if STRICT: + normalize = strict_normalize + normalize1 = strict_normalize1 +else: + normalize = _normalize + normalize1 = _normalize1 + +#----------------------------------------------------------------------------# +# Conversion functions # +#----------------------------------------------------------------------------# + +def from_man_exp(man, exp, prec=None, rnd=round_fast): + """Create raw mpf from (man, exp) pair. The mantissa may be signed. + If no precision is specified, the mantissa is stored exactly.""" + man = MPZ(man) + sign = 0 + if man < 0: + sign = 1 + man = -man + if man < 1024: + bc = bctable[int(man)] + else: + bc = bitcount(man) + if not prec: + if not man: + return fzero + if not man & 1: + if man & 2: + return (sign, man >> 1, exp + 1, bc - 1) + t = trailtable[int(man & 255)] + if not t: + while not man & 255: + man >>= 8 + exp += 8 + bc -= 8 + t = trailtable[int(man & 255)] + man >>= t + exp += t + bc -= t + return (sign, man, exp, bc) + return normalize(sign, man, exp, bc, prec, rnd) + +int_cache = dict((n, from_man_exp(n, 0)) for n in range(-10, 257)) + +if BACKEND == 'gmpy' and '_mpmath_create' in dir(gmpy): + from_man_exp = gmpy._mpmath_create + +if BACKEND == 'sage': + from_man_exp = sage_utils.from_man_exp + +def from_int(n, prec=0, rnd=round_fast): + """Create a raw mpf from an integer. If no precision is specified, + the mantissa is stored exactly.""" + if not prec: + if n in int_cache: + return int_cache[n] + return from_man_exp(n, 0, prec, rnd) + +def to_man_exp(s): + """Return (man, exp) of a raw mpf. Raise an error if inf/nan.""" + sign, man, exp, bc = s + if (not man) and exp: + raise ValueError("mantissa and exponent are undefined for %s" % man) + return man, exp + +def to_int(s, rnd=None): + """Convert a raw mpf to the nearest int. Rounding is done down by + default (same as int(float) in Python), but can be changed. If the + input is inf/nan, an exception is raised.""" + sign, man, exp, bc = s + if (not man) and exp: + raise ValueError("cannot convert inf or nan to int") + if exp >= 0: + if sign: + return (-man) << exp + return man << exp + # Make default rounding fast + if not rnd: + if sign: + return -(man >> (-exp)) + else: + return man >> (-exp) + if sign: + return round_int(-man, -exp, rnd) + else: + return round_int(man, -exp, rnd) + +def mpf_round_int(s, rnd): + sign, man, exp, bc = s + if (not man) and exp: + return s + if exp >= 0: + return s + mag = exp+bc + if mag < 1: + if rnd == round_ceiling: + if sign: return fzero + else: return fone + elif rnd == round_floor: + if sign: return fnone + else: return fzero + elif rnd == round_nearest: + if mag < 0 or man == MPZ_ONE: return fzero + elif sign: return fnone + else: return fone + else: + raise NotImplementedError + return mpf_pos(s, min(bc, mag), rnd) + +def mpf_floor(s, prec=0, rnd=round_fast): + v = mpf_round_int(s, round_floor) + if prec: + v = mpf_pos(v, prec, rnd) + return v + +def mpf_ceil(s, prec=0, rnd=round_fast): + v = mpf_round_int(s, round_ceiling) + if prec: + v = mpf_pos(v, prec, rnd) + return v + +def mpf_nint(s, prec=0, rnd=round_fast): + v = mpf_round_int(s, round_nearest) + if prec: + v = mpf_pos(v, prec, rnd) + return v + +def mpf_frac(s, prec=0, rnd=round_fast): + return mpf_sub(s, mpf_floor(s), prec, rnd) + +def from_float(x, prec=53, rnd=round_fast): + """Create a raw mpf from a Python float, rounding if necessary. + If prec >= 53, the result is guaranteed to represent exactly the + same number as the input. If prec is not specified, use prec=53.""" + # frexp only raises an exception for nan on some platforms + if x != x: + return fnan + # in Python2.5 math.frexp gives an exception for float infinity + # in Python2.6 it returns (float infinity, 0) + try: + m, e = math.frexp(x) + except: + if x == math_float_inf: return finf + if x == -math_float_inf: return fninf + return fnan + if x == math_float_inf: return finf + if x == -math_float_inf: return fninf + return from_man_exp(int(m*(1<<53)), e-53, prec, rnd) + +def from_npfloat(x, prec=113, rnd=round_fast): + """Create a raw mpf from a numpy float, rounding if necessary. + If prec >= 113, the result is guaranteed to represent exactly the + same number as the input. If prec is not specified, use prec=113.""" + y = float(x) + if x == y: # ldexp overflows for float16 + return from_float(y, prec, rnd) + import numpy as np + if np.isfinite(x): + m, e = np.frexp(x) + return from_man_exp(int(np.ldexp(m, 113)), int(e-113), prec, rnd) + if np.isposinf(x): return finf + if np.isneginf(x): return fninf + return fnan + +def from_Decimal(x, prec=None, rnd=round_fast): + """Create a raw mpf from a Decimal, rounding if necessary. + If prec is not specified, use the equivalent bit precision + of the number of significant digits in x.""" + if x.is_nan(): return fnan + if x.is_infinite(): return fninf if x.is_signed() else finf + if prec is None: + prec = int(len(x.as_tuple()[1])*3.3219280948873626) + return from_str(str(x), prec, rnd) + +def to_float(s, strict=False, rnd=round_fast): + """ + Convert a raw mpf to a Python float. The result is exact if the + bitcount of s is <= 53 and no underflow/overflow occurs. + + If the number is too large or too small to represent as a regular + float, it will be converted to inf or 0.0. Setting strict=True + forces an OverflowError to be raised instead. + + Warning: with a directed rounding mode, the correct nearest representable + floating-point number in the specified direction might not be computed + in case of overflow or (gradual) underflow. + """ + sign, man, exp, bc = s + if not man: + if s == fzero: return 0.0 + if s == finf: return math_float_inf + if s == fninf: return -math_float_inf + return math_float_inf/math_float_inf + if bc > 53: + sign, man, exp, bc = normalize1(sign, man, exp, bc, 53, rnd) + if sign: + man = -man + try: + return math.ldexp(man, exp) + except OverflowError: + if strict: + raise + # Overflow to infinity + if exp + bc > 0: + if sign: + return -math_float_inf + else: + return math_float_inf + # Underflow to zero + return 0.0 + +def from_rational(p, q, prec, rnd=round_fast): + """Create a raw mpf from a rational number p/q, round if + necessary.""" + return mpf_div(from_int(p), from_int(q), prec, rnd) + +def to_rational(s): + """Convert a raw mpf to a rational number. Return integers (p, q) + such that s = p/q exactly.""" + sign, man, exp, bc = s + if sign: + man = -man + if bc == -1: + raise ValueError("cannot convert %s to a rational number" % man) + if exp >= 0: + return man * (1<= 0: return (-man) << offset + else: return (-man) >> (-offset) + else: + if offset >= 0: return man << offset + else: return man >> (-offset) + + +############################################################################## +############################################################################## + +#----------------------------------------------------------------------------# +# Arithmetic operations, etc. # +#----------------------------------------------------------------------------# + +def mpf_rand(prec): + """Return a raw mpf chosen randomly from [0, 1), with prec bits + in the mantissa.""" + global getrandbits + if not getrandbits: + import random + getrandbits = random.getrandbits + return from_man_exp(getrandbits(prec), -prec, prec, round_floor) + +def mpf_eq(s, t): + """Test equality of two raw mpfs. This is simply tuple comparison + unless either number is nan, in which case the result is False.""" + if not s[1] or not t[1]: + if s == fnan or t == fnan: + return False + return s == t + +def mpf_hash(s): + # Duplicate the new hash algorithm introduces in Python 3.2. + if sys.version_info >= (3, 2): + ssign, sman, sexp, sbc = s + + # Handle special numbers + if not sman: + if s == fnan: return sys.hash_info.nan + if s == finf: return sys.hash_info.inf + if s == fninf: return -sys.hash_info.inf + h = sman % HASH_MODULUS + if sexp >= 0: + sexp = sexp % HASH_BITS + else: + sexp = HASH_BITS - 1 - ((-1 - sexp) % HASH_BITS) + h = (h << sexp) % HASH_MODULUS + if ssign: h = -h + if h == -1: h = -2 + return int(h) + else: + try: + # Try to be compatible with hash values for floats and ints + return hash(to_float(s, strict=1)) + except OverflowError: + # We must unfortunately sacrifice compatibility with ints here. + # We could do hash(man << exp) when the exponent is positive, but + # this would cause unreasonable inefficiency for large numbers. + return hash(s) + +def mpf_cmp(s, t): + """Compare the raw mpfs s and t. Return -1 if s < t, 0 if s == t, + and 1 if s > t. (Same convention as Python's cmp() function.)""" + + # In principle, a comparison amounts to determining the sign of s-t. + # A full subtraction is relatively slow, however, so we first try to + # look at the components. + ssign, sman, sexp, sbc = s + tsign, tman, texp, tbc = t + + # Handle zeros and special numbers + if not sman or not tman: + if s == fzero: return -mpf_sign(t) + if t == fzero: return mpf_sign(s) + if s == t: return 0 + # Follow same convention as Python's cmp for float nan + if t == fnan: return 1 + if s == finf: return 1 + if t == fninf: return 1 + return -1 + # Different sides of zero + if ssign != tsign: + if not ssign: return 1 + return -1 + # This reduces to direct integer comparison + if sexp == texp: + if sman == tman: + return 0 + if sman > tman: + if ssign: return -1 + else: return 1 + else: + if ssign: return 1 + else: return -1 + # Check position of the highest set bit in each number. If + # different, there is certainly an inequality. + a = sbc + sexp + b = tbc + texp + if ssign: + if a < b: return 1 + if a > b: return -1 + else: + if a < b: return -1 + if a > b: return 1 + + # Both numbers have the same highest bit. Subtract to find + # how the lower bits compare. + delta = mpf_sub(s, t, 5, round_floor) + if delta[0]: + return -1 + return 1 + +def mpf_lt(s, t): + if s == fnan or t == fnan: + return False + return mpf_cmp(s, t) < 0 + +def mpf_le(s, t): + if s == fnan or t == fnan: + return False + return mpf_cmp(s, t) <= 0 + +def mpf_gt(s, t): + if s == fnan or t == fnan: + return False + return mpf_cmp(s, t) > 0 + +def mpf_ge(s, t): + if s == fnan or t == fnan: + return False + return mpf_cmp(s, t) >= 0 + +def mpf_min_max(seq): + min = max = seq[0] + for x in seq[1:]: + if mpf_lt(x, min): min = x + if mpf_gt(x, max): max = x + return min, max + +def mpf_pos(s, prec=0, rnd=round_fast): + """Calculate 0+s for a raw mpf (i.e., just round s to the specified + precision).""" + if prec: + sign, man, exp, bc = s + if (not man) and exp: + return s + return normalize1(sign, man, exp, bc, prec, rnd) + return s + +def mpf_neg(s, prec=None, rnd=round_fast): + """Negate a raw mpf (return -s), rounding the result to the + specified precision. The prec argument can be omitted to do the + operation exactly.""" + sign, man, exp, bc = s + if not man: + if exp: + if s == finf: return fninf + if s == fninf: return finf + return s + if not prec: + return (1-sign, man, exp, bc) + return normalize1(1-sign, man, exp, bc, prec, rnd) + +def mpf_abs(s, prec=None, rnd=round_fast): + """Return abs(s) of the raw mpf s, rounded to the specified + precision. The prec argument can be omitted to generate an + exact result.""" + sign, man, exp, bc = s + if (not man) and exp: + if s == fninf: + return finf + return s + if not prec: + if sign: + return (0, man, exp, bc) + return s + return normalize1(0, man, exp, bc, prec, rnd) + +def mpf_sign(s): + """Return -1, 0, or 1 (as a Python int, not a raw mpf) depending on + whether s is negative, zero, or positive. (Nan is taken to give 0.)""" + sign, man, exp, bc = s + if not man: + if s == finf: return 1 + if s == fninf: return -1 + return 0 + return (-1) ** sign + +def mpf_add(s, t, prec=0, rnd=round_fast, _sub=0): + """ + Add the two raw mpf values s and t. + + With prec=0, no rounding is performed. Note that this can + produce a very large mantissa (potentially too large to fit + in memory) if exponents are far apart. + """ + ssign, sman, sexp, sbc = s + tsign, tman, texp, tbc = t + tsign ^= _sub + # Standard case: two nonzero, regular numbers + if sman and tman: + offset = sexp - texp + if offset: + if offset > 0: + # Outside precision range; only need to perturb + if offset > 100 and prec: + delta = sbc + sexp - tbc - texp + if delta > prec + 4: + offset = prec + 4 + sman <<= offset + if tsign == ssign: sman += 1 + else: sman -= 1 + return normalize1(ssign, sman, sexp-offset, + bitcount(sman), prec, rnd) + # Add + if ssign == tsign: + man = tman + (sman << offset) + # Subtract + else: + if ssign: man = tman - (sman << offset) + else: man = (sman << offset) - tman + if man >= 0: + ssign = 0 + else: + man = -man + ssign = 1 + bc = bitcount(man) + return normalize1(ssign, man, texp, bc, prec or bc, rnd) + elif offset < 0: + # Outside precision range; only need to perturb + if offset < -100 and prec: + delta = tbc + texp - sbc - sexp + if delta > prec + 4: + offset = prec + 4 + tman <<= offset + if ssign == tsign: tman += 1 + else: tman -= 1 + return normalize1(tsign, tman, texp-offset, + bitcount(tman), prec, rnd) + # Add + if ssign == tsign: + man = sman + (tman << -offset) + # Subtract + else: + if tsign: man = sman - (tman << -offset) + else: man = (tman << -offset) - sman + if man >= 0: + ssign = 0 + else: + man = -man + ssign = 1 + bc = bitcount(man) + return normalize1(ssign, man, sexp, bc, prec or bc, rnd) + # Equal exponents; no shifting necessary + if ssign == tsign: + man = tman + sman + else: + if ssign: man = tman - sman + else: man = sman - tman + if man >= 0: + ssign = 0 + else: + man = -man + ssign = 1 + bc = bitcount(man) + return normalize(ssign, man, texp, bc, prec or bc, rnd) + # Handle zeros and special numbers + if _sub: + t = mpf_neg(t) + if not sman: + if sexp: + if s == t or tman or not texp: + return s + return fnan + if tman: + return normalize1(tsign, tman, texp, tbc, prec or tbc, rnd) + return t + if texp: + return t + if sman: + return normalize1(ssign, sman, sexp, sbc, prec or sbc, rnd) + return s + +def mpf_sub(s, t, prec=0, rnd=round_fast): + """Return the difference of two raw mpfs, s-t. This function is + simply a wrapper of mpf_add that changes the sign of t.""" + return mpf_add(s, t, prec, rnd, 1) + +def mpf_sum(xs, prec=0, rnd=round_fast, absolute=False): + """ + Sum a list of mpf values efficiently and accurately + (typically no temporary roundoff occurs). If prec=0, + the final result will not be rounded either. + + There may be roundoff error or cancellation if extremely + large exponent differences occur. + + With absolute=True, sums the absolute values. + """ + man = 0 + exp = 0 + max_extra_prec = prec*2 or 1000000 # XXX + special = None + for x in xs: + xsign, xman, xexp, xbc = x + if xman: + if xsign and not absolute: + xman = -xman + delta = xexp - exp + if xexp >= exp: + # x much larger than existing sum? + # first: quick test + if (delta > max_extra_prec) and \ + ((not man) or delta-bitcount(abs(man)) > max_extra_prec): + man = xman + exp = xexp + else: + man += (xman << delta) + else: + delta = -delta + # x much smaller than existing sum? + if delta-xbc > max_extra_prec: + if not man: + man, exp = xman, xexp + else: + man = (man << delta) + xman + exp = xexp + elif xexp: + if absolute: + x = mpf_abs(x) + special = mpf_add(special or fzero, x, 1) + # Will be inf or nan + if special: + return special + return from_man_exp(man, exp, prec, rnd) + +def gmpy_mpf_mul(s, t, prec=0, rnd=round_fast): + """Multiply two raw mpfs""" + ssign, sman, sexp, sbc = s + tsign, tman, texp, tbc = t + sign = ssign ^ tsign + man = sman*tman + if man: + bc = bitcount(man) + if prec: + return normalize1(sign, man, sexp+texp, bc, prec, rnd) + else: + return (sign, man, sexp+texp, bc) + s_special = (not sman) and sexp + t_special = (not tman) and texp + if not s_special and not t_special: + return fzero + if fnan in (s, t): return fnan + if (not tman) and texp: s, t = t, s + if t == fzero: return fnan + return {1:finf, -1:fninf}[mpf_sign(s) * mpf_sign(t)] + +def gmpy_mpf_mul_int(s, n, prec, rnd=round_fast): + """Multiply by a Python integer.""" + sign, man, exp, bc = s + if not man: + return mpf_mul(s, from_int(n), prec, rnd) + if not n: + return fzero + if n < 0: + sign ^= 1 + n = -n + man *= n + return normalize(sign, man, exp, bitcount(man), prec, rnd) + +def python_mpf_mul(s, t, prec=0, rnd=round_fast): + """Multiply two raw mpfs""" + ssign, sman, sexp, sbc = s + tsign, tman, texp, tbc = t + sign = ssign ^ tsign + man = sman*tman + if man: + bc = sbc + tbc - 1 + bc += int(man>>bc) + if prec: + return normalize1(sign, man, sexp+texp, bc, prec, rnd) + else: + return (sign, man, sexp+texp, bc) + s_special = (not sman) and sexp + t_special = (not tman) and texp + if not s_special and not t_special: + return fzero + if fnan in (s, t): return fnan + if (not tman) and texp: s, t = t, s + if t == fzero: return fnan + return {1:finf, -1:fninf}[mpf_sign(s) * mpf_sign(t)] + +def python_mpf_mul_int(s, n, prec, rnd=round_fast): + """Multiply by a Python integer.""" + sign, man, exp, bc = s + if not man: + return mpf_mul(s, from_int(n), prec, rnd) + if not n: + return fzero + if n < 0: + sign ^= 1 + n = -n + man *= n + # Generally n will be small + if n < 1024: + bc += bctable[int(n)] - 1 + else: + bc += bitcount(n) - 1 + bc += int(man>>bc) + return normalize(sign, man, exp, bc, prec, rnd) + + +if BACKEND == 'gmpy': + mpf_mul = gmpy_mpf_mul + mpf_mul_int = gmpy_mpf_mul_int +else: + mpf_mul = python_mpf_mul + mpf_mul_int = python_mpf_mul_int + +def mpf_shift(s, n): + """Quickly multiply the raw mpf s by 2**n without rounding.""" + sign, man, exp, bc = s + if not man: + return s + return sign, man, exp+n, bc + +def mpf_frexp(x): + """Convert x = y*2**n to (y, n) with abs(y) in [0.5, 1) if nonzero""" + sign, man, exp, bc = x + if not man: + if x == fzero: + return (fzero, 0) + else: + raise ValueError + return mpf_shift(x, -bc-exp), bc+exp + +def mpf_div(s, t, prec, rnd=round_fast): + """Floating-point division""" + ssign, sman, sexp, sbc = s + tsign, tman, texp, tbc = t + if not sman or not tman: + if s == fzero: + if t == fzero: raise ZeroDivisionError + if t == fnan: return fnan + return fzero + if t == fzero: + raise ZeroDivisionError + s_special = (not sman) and sexp + t_special = (not tman) and texp + if s_special and t_special: + return fnan + if s == fnan or t == fnan: + return fnan + if not t_special: + if t == fzero: + return fnan + return {1:finf, -1:fninf}[mpf_sign(s) * mpf_sign(t)] + return fzero + sign = ssign ^ tsign + if tman == 1: + return normalize1(sign, sman, sexp-texp, sbc, prec, rnd) + # Same strategy as for addition: if there is a remainder, perturb + # the result a few bits outside the precision range before rounding + extra = prec - sbc + tbc + 5 + if extra < 5: + extra = 5 + quot, rem = divmod(sman< sexp+sbc: + return s + # Another important special case: this allows us to do e.g. x % 1.0 + # to find the fractional part of x, and it will work when x is huge. + if tman == 1 and sexp > texp+tbc: + return fzero + base = min(sexp, texp) + sman = (-1)**ssign * sman + tman = (-1)**tsign * tman + man = (sman << (sexp-base)) % (tman << (texp-base)) + if man >= 0: + sign = 0 + else: + man = -man + sign = 1 + return normalize(sign, man, base, bitcount(man), prec, rnd) + +reciprocal_rnd = { + round_down : round_up, + round_up : round_down, + round_floor : round_ceiling, + round_ceiling : round_floor, + round_nearest : round_nearest +} + +negative_rnd = { + round_down : round_down, + round_up : round_up, + round_floor : round_ceiling, + round_ceiling : round_floor, + round_nearest : round_nearest +} + +def mpf_pow_int(s, n, prec, rnd=round_fast): + """Compute s**n, where s is a raw mpf and n is a Python integer.""" + sign, man, exp, bc = s + + if (not man) and exp: + if s == finf: + if n > 0: return s + if n == 0: return fnan + return fzero + if s == fninf: + if n > 0: return [finf, fninf][n & 1] + if n == 0: return fnan + return fzero + return fnan + + n = int(n) + if n == 0: return fone + if n == 1: return mpf_pos(s, prec, rnd) + if n == 2: + _, man, exp, bc = s + if not man: + return fzero + man = man*man + if man == 1: + return (0, MPZ_ONE, exp+exp, 1) + bc = bc + bc - 2 + bc += bctable[int(man>>bc)] + return normalize1(0, man, exp+exp, bc, prec, rnd) + if n == -1: return mpf_div(fone, s, prec, rnd) + if n < 0: + inverse = mpf_pow_int(s, -n, prec+5, reciprocal_rnd[rnd]) + return mpf_div(fone, inverse, prec, rnd) + + result_sign = sign & n + + # Use exact integer power when the exact mantissa is small + if man == 1: + return (result_sign, MPZ_ONE, exp*n, 1) + if bc*n < 1000: + man **= n + return normalize1(result_sign, man, exp*n, bitcount(man), prec, rnd) + + # Use directed rounding all the way through to maintain rigorous + # bounds for interval arithmetic + rounds_down = (rnd == round_nearest) or \ + shifts_down[rnd][result_sign] + + # Now we perform binary exponentiation. Need to estimate precision + # to avoid rounding errors from temporary operations. Roughly log_2(n) + # operations are performed. + workprec = prec + 4*bitcount(n) + 4 + _, pm, pe, pbc = fone + while 1: + if n & 1: + pm = pm*man + pe = pe+exp + pbc += bc - 2 + pbc = pbc + bctable[int(pm >> pbc)] + if pbc > workprec: + if rounds_down: + pm = pm >> (pbc-workprec) + else: + pm = -((-pm) >> (pbc-workprec)) + pe += pbc - workprec + pbc = workprec + n -= 1 + if not n: + break + man = man*man + exp = exp+exp + bc = bc + bc - 2 + bc = bc + bctable[int(man >> bc)] + if bc > workprec: + if rounds_down: + man = man >> (bc-workprec) + else: + man = -((-man) >> (bc-workprec)) + exp += bc - workprec + bc = workprec + n = n // 2 + + return normalize(result_sign, pm, pe, pbc, prec, rnd) + + +def mpf_perturb(x, eps_sign, prec, rnd): + """ + For nonzero x, calculate x + eps with directed rounding, where + eps < prec relatively and eps has the given sign (0 for + positive, 1 for negative). + + With rounding to nearest, this is taken to simply normalize + x to the given precision. + """ + if rnd == round_nearest: + return mpf_pos(x, prec, rnd) + sign, man, exp, bc = x + eps = (eps_sign, MPZ_ONE, exp+bc-prec-1, 1) + if sign: + away = (rnd in (round_down, round_ceiling)) ^ eps_sign + else: + away = (rnd in (round_up, round_ceiling)) ^ eps_sign + if away: + return mpf_add(x, eps, prec, rnd) + else: + return mpf_pos(x, prec, rnd) + + +#----------------------------------------------------------------------------# +# Radix conversion # +#----------------------------------------------------------------------------# + +def to_digits_exp(s, dps): + """Helper function for representing the floating-point number s as + a decimal with dps digits. Returns (sign, string, exponent) where + sign is '' or '-', string is the digit string, and exponent is + the decimal exponent as an int. + + If inexact, the decimal representation is rounded toward zero.""" + + # Extract sign first so it doesn't mess up the string digit count + if s[0]: + sign = '-' + s = mpf_neg(s) + else: + sign = '' + _sign, man, exp, bc = s + + if not man: + return '', '0', 0 + + bitprec = int(dps * math.log(10,2)) + 10 + + # Cut down to size + # TODO: account for precision when doing this + exp_from_1 = exp + bc + if abs(exp_from_1) > 3500: + from .libelefun import mpf_ln2, mpf_ln10 + # Set b = int(exp * log(2)/log(10)) + # If exp is huge, we must use high-precision arithmetic to + # find the nearest power of ten + expprec = bitcount(abs(exp)) + 5 + tmp = from_int(exp) + tmp = mpf_mul(tmp, mpf_ln2(expprec)) + tmp = mpf_div(tmp, mpf_ln10(expprec), expprec) + b = to_int(tmp) + s = mpf_div(s, mpf_pow_int(ften, b, bitprec), bitprec) + _sign, man, exp, bc = s + exponent = b + else: + exponent = 0 + + # First, calculate mantissa digits by converting to a binary + # fixed-point number and then converting that number to + # a decimal fixed-point number. + fixprec = max(bitprec - exp - bc, 0) + fixdps = int(fixprec / math.log(10,2) + 0.5) + sf = to_fixed(s, fixprec) + sd = bin_to_radix(sf, fixprec, 10, fixdps) + digits = numeral(sd, base=10, size=dps) + + exponent += len(digits) - fixdps - 1 + return sign, digits, exponent + +def to_str(s, dps, strip_zeros=True, min_fixed=None, max_fixed=None, + show_zero_exponent=False): + """ + Convert a raw mpf to a decimal floating-point literal with at + most `dps` decimal digits in the mantissa (not counting extra zeros + that may be inserted for visual purposes). + + The number will be printed in fixed-point format if the position + of the leading digit is strictly between min_fixed + (default = min(-dps/3,-5)) and max_fixed (default = dps). + + To force fixed-point format always, set min_fixed = -inf, + max_fixed = +inf. To force floating-point format, set + min_fixed >= max_fixed. + + The literal is formatted so that it can be parsed back to a number + by to_str, float() or Decimal(). + """ + + # Special numbers + if not s[1]: + if s == fzero: + if dps: t = '0.0' + else: t = '.0' + if show_zero_exponent: + t += 'e+0' + return t + if s == finf: return '+inf' + if s == fninf: return '-inf' + if s == fnan: return 'nan' + raise ValueError + + if min_fixed is None: min_fixed = min(-(dps//3), -5) + if max_fixed is None: max_fixed = dps + + # to_digits_exp rounds to floor. + # This sometimes kills some instances of "...00001" + sign, digits, exponent = to_digits_exp(s, dps+3) + + # No digits: show only .0; round exponent to nearest + if not dps: + if digits[0] in '56789': + exponent += 1 + digits = ".0" + + else: + # Rounding up kills some instances of "...99999" + if len(digits) > dps and digits[dps] in '56789': + digits = digits[:dps] + i = dps - 1 + while i >= 0 and digits[i] == '9': + i -= 1 + if i >= 0: + digits = digits[:i] + str(int(digits[i]) + 1) + '0' * (dps - i - 1) + else: + digits = '1' + '0' * (dps - 1) + exponent += 1 + else: + digits = digits[:dps] + + # Prettify numbers close to unit magnitude + if min_fixed < exponent < max_fixed: + if exponent < 0: + digits = ("0"*int(-exponent)) + digits + split = 1 + else: + split = exponent + 1 + if split > dps: + digits += "0"*(split-dps) + exponent = 0 + else: + split = 1 + + digits = (digits[:split] + "." + digits[split:]) + + if strip_zeros: + # Clean up trailing zeros + digits = digits.rstrip('0') + if digits[-1] == ".": + digits += "0" + + if exponent == 0 and dps and not show_zero_exponent: return sign + digits + if exponent >= 0: return sign + digits + "e+" + str(exponent) + if exponent < 0: return sign + digits + "e" + str(exponent) + +def str_to_man_exp(x, base=10): + """Helper function for from_str.""" + x = x.lower().rstrip('l') + # Verify that the input is a valid float literal + float(x) + # Split into mantissa, exponent + parts = x.split('e') + if len(parts) == 1: + exp = 0 + else: # == 2 + x = parts[0] + exp = int(parts[1]) + # Look for radix point in mantissa + parts = x.split('.') + if len(parts) == 2: + a, b = parts[0], parts[1].rstrip('0') + exp -= len(b) + x = a + b + x = MPZ(int(x, base)) + return x, exp + +special_str = {'inf':finf, '+inf':finf, '-inf':fninf, 'nan':fnan} + +def from_str(x, prec, rnd=round_fast): + """Create a raw mpf from a decimal literal, rounding in the + specified direction if the input number cannot be represented + exactly as a binary floating-point number with the given number of + bits. The literal syntax accepted is the same as for Python + floats. + + TODO: the rounding does not work properly for large exponents. + """ + x = x.lower().strip() + if x in special_str: + return special_str[x] + + if '/' in x: + p, q = x.split('/') + p, q = p.rstrip('l'), q.rstrip('l') + return from_rational(int(p), int(q), prec, rnd) + + man, exp = str_to_man_exp(x, base=10) + + # XXX: appropriate cutoffs & track direction + # note no factors of 5 + if abs(exp) > 400: + s = from_int(man, prec+10) + s = mpf_mul(s, mpf_pow_int(ften, exp, prec+10), prec, rnd) + else: + if exp >= 0: + s = from_int(man * 10**exp, prec, rnd) + else: + s = from_rational(man, 10**-exp, prec, rnd) + return s + +# Binary string conversion. These are currently mainly used for debugging +# and could use some improvement in the future + +def from_bstr(x): + man, exp = str_to_man_exp(x, base=2) + man = MPZ(man) + sign = 0 + if man < 0: + man = -man + sign = 1 + bc = bitcount(man) + return normalize(sign, man, exp, bc, bc, round_floor) + +def to_bstr(x): + sign, man, exp, bc = x + return ['','-'][sign] + numeral(man, size=bitcount(man), base=2) + ("e%i" % exp) + + +#----------------------------------------------------------------------------# +# Square roots # +#----------------------------------------------------------------------------# + + +def mpf_sqrt(s, prec, rnd=round_fast): + """ + Compute the square root of a nonnegative mpf value. The + result is correctly rounded. + """ + sign, man, exp, bc = s + if sign: + raise ComplexResult("square root of a negative number") + if not man: + return s + if exp & 1: + exp -= 1 + man <<= 1 + bc += 1 + elif man == 1: + return normalize1(sign, man, exp//2, bc, prec, rnd) + shift = max(4, 2*prec-bc+4) + shift += shift & 1 + if rnd in 'fd': + man = isqrt(man<= 0: + a = mpf_pos(sa, prec, round_floor) + b = mpf_pos(sb, prec, round_ceiling) + # Upper point nonnegative? + elif sbs >= 0: + a = fzero + negsa = mpf_neg(sa) + if mpf_lt(negsa, sb): + b = mpf_pos(sb, prec, round_ceiling) + else: + b = mpf_pos(negsa, prec, round_ceiling) + # Both negative? + else: + a = mpf_neg(sb, prec, round_floor) + b = mpf_neg(sa, prec, round_ceiling) + return a, b + +# TODO: optimize +def mpi_mul_mpf(s, t, prec): + return mpi_mul(s, (t, t), prec) + +def mpi_div_mpf(s, t, prec): + return mpi_div(s, (t, t), prec) + +def mpi_mul(s, t, prec=0): + sa, sb = s + ta, tb = t + sas = mpf_sign(sa) + sbs = mpf_sign(sb) + tas = mpf_sign(ta) + tbs = mpf_sign(tb) + if sas == sbs == 0: + # Should maybe be undefined + if ta == fninf or tb == finf: + return fninf, finf + return fzero, fzero + if tas == tbs == 0: + # Should maybe be undefined + if sa == fninf or sb == finf: + return fninf, finf + return fzero, fzero + if sas >= 0: + # positive * positive + if tas >= 0: + a = mpf_mul(sa, ta, prec, round_floor) + b = mpf_mul(sb, tb, prec, round_ceiling) + if a == fnan: a = fzero + if b == fnan: b = finf + # positive * negative + elif tbs <= 0: + a = mpf_mul(sb, ta, prec, round_floor) + b = mpf_mul(sa, tb, prec, round_ceiling) + if a == fnan: a = fninf + if b == fnan: b = fzero + # positive * both signs + else: + a = mpf_mul(sb, ta, prec, round_floor) + b = mpf_mul(sb, tb, prec, round_ceiling) + if a == fnan: a = fninf + if b == fnan: b = finf + elif sbs <= 0: + # negative * positive + if tas >= 0: + a = mpf_mul(sa, tb, prec, round_floor) + b = mpf_mul(sb, ta, prec, round_ceiling) + if a == fnan: a = fninf + if b == fnan: b = fzero + # negative * negative + elif tbs <= 0: + a = mpf_mul(sb, tb, prec, round_floor) + b = mpf_mul(sa, ta, prec, round_ceiling) + if a == fnan: a = fzero + if b == fnan: b = finf + # negative * both signs + else: + a = mpf_mul(sa, tb, prec, round_floor) + b = mpf_mul(sa, ta, prec, round_ceiling) + if a == fnan: a = fninf + if b == fnan: b = finf + else: + # General case: perform all cross-multiplications and compare + # Since the multiplications can be done exactly, we need only + # do 4 (instead of 8: two for each rounding mode) + cases = [mpf_mul(sa, ta), mpf_mul(sa, tb), mpf_mul(sb, ta), mpf_mul(sb, tb)] + if fnan in cases: + a, b = (fninf, finf) + else: + a, b = mpf_min_max(cases) + a = mpf_pos(a, prec, round_floor) + b = mpf_pos(b, prec, round_ceiling) + return a, b + +def mpi_square(s, prec=0): + sa, sb = s + if mpf_ge(sa, fzero): + a = mpf_mul(sa, sa, prec, round_floor) + b = mpf_mul(sb, sb, prec, round_ceiling) + elif mpf_le(sb, fzero): + a = mpf_mul(sb, sb, prec, round_floor) + b = mpf_mul(sa, sa, prec, round_ceiling) + else: + sa = mpf_neg(sa) + sa, sb = mpf_min_max([sa, sb]) + a = fzero + b = mpf_mul(sb, sb, prec, round_ceiling) + return a, b + +def mpi_div(s, t, prec): + sa, sb = s + ta, tb = t + sas = mpf_sign(sa) + sbs = mpf_sign(sb) + tas = mpf_sign(ta) + tbs = mpf_sign(tb) + # 0 / X + if sas == sbs == 0: + # 0 / + if (tas < 0 and tbs > 0) or (tas == 0 or tbs == 0): + return fninf, finf + return fzero, fzero + # Denominator contains both negative and positive numbers; + # this should properly be a multi-interval, but the closest + # match is the entire (extended) real line + if tas < 0 and tbs > 0: + return fninf, finf + # Assume denominator to be nonnegative + if tas < 0: + return mpi_div(mpi_neg(s), mpi_neg(t), prec) + # Division by zero + # XXX: make sure all results make sense + if tas == 0: + # Numerator contains both signs? + if sas < 0 and sbs > 0: + return fninf, finf + if tas == tbs: + return fninf, finf + # Numerator positive? + if sas >= 0: + a = mpf_div(sa, tb, prec, round_floor) + b = finf + if sbs <= 0: + a = fninf + b = mpf_div(sb, tb, prec, round_ceiling) + # Division with positive denominator + # We still have to handle nans resulting from inf/0 or inf/inf + else: + # Nonnegative numerator + if sas >= 0: + a = mpf_div(sa, tb, prec, round_floor) + b = mpf_div(sb, ta, prec, round_ceiling) + if a == fnan: a = fzero + if b == fnan: b = finf + # Nonpositive numerator + elif sbs <= 0: + a = mpf_div(sa, ta, prec, round_floor) + b = mpf_div(sb, tb, prec, round_ceiling) + if a == fnan: a = fninf + if b == fnan: b = fzero + # Numerator contains both signs? + else: + a = mpf_div(sa, ta, prec, round_floor) + b = mpf_div(sb, ta, prec, round_ceiling) + if a == fnan: a = fninf + if b == fnan: b = finf + return a, b + +def mpi_pi(prec): + a = mpf_pi(prec, round_floor) + b = mpf_pi(prec, round_ceiling) + return a, b + +def mpi_exp(s, prec): + sa, sb = s + # exp is monotonic + a = mpf_exp(sa, prec, round_floor) + b = mpf_exp(sb, prec, round_ceiling) + return a, b + +def mpi_log(s, prec): + sa, sb = s + # log is monotonic + a = mpf_log(sa, prec, round_floor) + b = mpf_log(sb, prec, round_ceiling) + return a, b + +def mpi_sqrt(s, prec): + sa, sb = s + # sqrt is monotonic + a = mpf_sqrt(sa, prec, round_floor) + b = mpf_sqrt(sb, prec, round_ceiling) + return a, b + +def mpi_atan(s, prec): + sa, sb = s + a = mpf_atan(sa, prec, round_floor) + b = mpf_atan(sb, prec, round_ceiling) + return a, b + +def mpi_pow_int(s, n, prec): + sa, sb = s + if n < 0: + return mpi_div((fone, fone), mpi_pow_int(s, -n, prec+20), prec) + if n == 0: + return (fone, fone) + if n == 1: + return s + if n == 2: + return mpi_square(s, prec) + # Odd -- signs are preserved + if n & 1: + a = mpf_pow_int(sa, n, prec, round_floor) + b = mpf_pow_int(sb, n, prec, round_ceiling) + # Even -- important to ensure positivity + else: + sas = mpf_sign(sa) + sbs = mpf_sign(sb) + # Nonnegative? + if sas >= 0: + a = mpf_pow_int(sa, n, prec, round_floor) + b = mpf_pow_int(sb, n, prec, round_ceiling) + # Nonpositive? + elif sbs <= 0: + a = mpf_pow_int(sb, n, prec, round_floor) + b = mpf_pow_int(sa, n, prec, round_ceiling) + # Mixed signs? + else: + a = fzero + # max(-a,b)**n + sa = mpf_neg(sa) + if mpf_ge(sa, sb): + b = mpf_pow_int(sa, n, prec, round_ceiling) + else: + b = mpf_pow_int(sb, n, prec, round_ceiling) + return a, b + +def mpi_pow(s, t, prec): + ta, tb = t + if ta == tb and ta not in (finf, fninf): + if ta == from_int(to_int(ta)): + return mpi_pow_int(s, to_int(ta), prec) + if ta == fhalf: + return mpi_sqrt(s, prec) + u = mpi_log(s, prec + 20) + v = mpi_mul(u, t, prec + 20) + return mpi_exp(v, prec) + +def MIN(x, y): + if mpf_le(x, y): + return x + return y + +def MAX(x, y): + if mpf_ge(x, y): + return x + return y + +def cos_sin_quadrant(x, wp): + sign, man, exp, bc = x + if x == fzero: + return fone, fzero, 0 + # TODO: combine evaluation code to avoid duplicate modulo + c, s = mpf_cos_sin(x, wp) + t, n, wp_ = mod_pi2(man, exp, exp+bc, 15) + if sign: + n = -1-n + return c, s, n + +def mpi_cos_sin(x, prec): + a, b = x + if a == b == fzero: + return (fone, fone), (fzero, fzero) + # Guaranteed to contain both -1 and 1 + if (finf in x) or (fninf in x): + return (fnone, fone), (fnone, fone) + wp = prec + 20 + ca, sa, na = cos_sin_quadrant(a, wp) + cb, sb, nb = cos_sin_quadrant(b, wp) + ca, cb = mpf_min_max([ca, cb]) + sa, sb = mpf_min_max([sa, sb]) + # Both functions are monotonic within one quadrant + if na == nb: + pass + # Guaranteed to contain both -1 and 1 + elif nb - na >= 4: + return (fnone, fone), (fnone, fone) + else: + # cos has maximum between a and b + if na//4 != nb//4: + cb = fone + # cos has minimum + if (na-2)//4 != (nb-2)//4: + ca = fnone + # sin has maximum + if (na-1)//4 != (nb-1)//4: + sb = fone + # sin has minimum + if (na-3)//4 != (nb-3)//4: + sa = fnone + # Perturb to force interval rounding + more = from_man_exp((MPZ_ONE<= 1: + if sign: + return fnone + return fone + return v + ca = finalize(ca, round_floor) + cb = finalize(cb, round_ceiling) + sa = finalize(sa, round_floor) + sb = finalize(sb, round_ceiling) + return (ca,cb), (sa,sb) + +def mpi_cos(x, prec): + return mpi_cos_sin(x, prec)[0] + +def mpi_sin(x, prec): + return mpi_cos_sin(x, prec)[1] + +def mpi_tan(x, prec): + cos, sin = mpi_cos_sin(x, prec+20) + return mpi_div(sin, cos, prec) + +def mpi_cot(x, prec): + cos, sin = mpi_cos_sin(x, prec+20) + return mpi_div(cos, sin, prec) + +def mpi_from_str_a_b(x, y, percent, prec): + wp = prec + 20 + xa = from_str(x, wp, round_floor) + xb = from_str(x, wp, round_ceiling) + #ya = from_str(y, wp, round_floor) + y = from_str(y, wp, round_ceiling) + assert mpf_ge(y, fzero) + if percent: + y = mpf_mul(MAX(mpf_abs(xa), mpf_abs(xb)), y, wp, round_ceiling) + y = mpf_div(y, from_int(100), wp, round_ceiling) + a = mpf_sub(xa, y, prec, round_floor) + b = mpf_add(xb, y, prec, round_ceiling) + return a, b + +def mpi_from_str(s, prec): + """ + Parse an interval number given as a string. + + Allowed forms are + + "-1.23e-27" + Any single decimal floating-point literal. + "a +- b" or "a (b)" + a is the midpoint of the interval and b is the half-width + "a +- b%" or "a (b%)" + a is the midpoint of the interval and the half-width + is b percent of a (`a \times b / 100`). + "[a, b]" + The interval indicated directly. + "x[y,z]e" + x are shared digits, y and z are unequal digits, e is the exponent. + + """ + e = ValueError("Improperly formed interval number '%s'" % s) + s = s.replace(" ", "") + wp = prec + 20 + if "+-" in s: + x, y = s.split("+-") + return mpi_from_str_a_b(x, y, False, prec) + # case 2 + elif "(" in s: + # Don't confuse with a complex number (x,y) + if s[0] == "(" or ")" not in s: + raise e + s = s.replace(")", "") + percent = False + if "%" in s: + if s[-1] != "%": + raise e + percent = True + s = s.replace("%", "") + x, y = s.split("(") + return mpi_from_str_a_b(x, y, percent, prec) + elif "," in s: + if ('[' not in s) or (']' not in s): + raise e + if s[0] == '[': + # case 3 + s = s.replace("[", "") + s = s.replace("]", "") + a, b = s.split(",") + a = from_str(a, prec, round_floor) + b = from_str(b, prec, round_ceiling) + return a, b + else: + # case 4 + x, y = s.split('[') + y, z = y.split(',') + if 'e' in s: + z, e = z.split(']') + else: + z, e = z.rstrip(']'), '' + a = from_str(x+y+e, prec, round_floor) + b = from_str(x+z+e, prec, round_ceiling) + return a, b + else: + a = from_str(s, prec, round_floor) + b = from_str(s, prec, round_ceiling) + return a, b + +def mpi_to_str(x, dps, use_spaces=True, brackets='[]', mode='brackets', error_dps=4, **kwargs): + """ + Convert a mpi interval to a string. + + **Arguments** + + *dps* + decimal places to use for printing + *use_spaces* + use spaces for more readable output, defaults to true + *brackets* + pair of strings (or two-character string) giving left and right brackets + *mode* + mode of display: 'plusminus', 'percent', 'brackets' (default) or 'diff' + *error_dps* + limit the error to *error_dps* digits (mode 'plusminus and 'percent') + + Additional keyword arguments are forwarded to the mpf-to-string conversion + for the components of the output. + + **Examples** + + >>> from mpmath import mpi, mp + >>> mp.dps = 30 + >>> x = mpi(1, 2)._mpi_ + >>> mpi_to_str(x, 2, mode='plusminus') + '1.5 +- 0.5' + >>> mpi_to_str(x, 2, mode='percent') + '1.5 (33.33%)' + >>> mpi_to_str(x, 2, mode='brackets') + '[1.0, 2.0]' + >>> mpi_to_str(x, 2, mode='brackets' , brackets=('<', '>')) + '<1.0, 2.0>' + >>> x = mpi('5.2582327113062393041', '5.2582327113062749951')._mpi_ + >>> mpi_to_str(x, 15, mode='diff') + '5.2582327113062[4, 7]' + >>> mpi_to_str(mpi(0)._mpi_, 2, mode='percent') + '0.0 (0.0%)' + + """ + prec = dps_to_prec(dps) + wp = prec + 20 + a, b = x + mid = mpi_mid(x, prec) + delta = mpi_delta(x, prec) + a_str = to_str(a, dps, **kwargs) + b_str = to_str(b, dps, **kwargs) + mid_str = to_str(mid, dps, **kwargs) + sp = "" + if use_spaces: + sp = " " + br1, br2 = brackets + if mode == 'plusminus': + delta_str = to_str(mpf_shift(delta,-1), dps, **kwargs) + s = mid_str + sp + "+-" + sp + delta_str + elif mode == 'percent': + if mid == fzero: + p = fzero + else: + # p = 100 * delta(x) / (2*mid(x)) + p = mpf_mul(delta, from_int(100)) + p = mpf_div(p, mpf_mul(mid, from_int(2)), wp) + s = mid_str + sp + "(" + to_str(p, error_dps) + "%)" + elif mode == 'brackets': + s = br1 + a_str + "," + sp + b_str + br2 + elif mode == 'diff': + # use more digits if str(x.a) and str(x.b) are equal + if a_str == b_str: + a_str = to_str(a, dps+3, **kwargs) + b_str = to_str(b, dps+3, **kwargs) + # separate mantissa and exponent + a = a_str.split('e') + if len(a) == 1: + a.append('') + b = b_str.split('e') + if len(b) == 1: + b.append('') + if a[1] == b[1]: + if a[0] != b[0]: + for i in xrange(len(a[0]) + 1): + if a[0][i] != b[0][i]: + break + s = (a[0][:i] + br1 + a[0][i:] + ',' + sp + b[0][i:] + br2 + + 'e'*min(len(a[1]), 1) + a[1]) + else: # no difference + s = a[0] + br1 + br2 + 'e'*min(len(a[1]), 1) + a[1] + else: + s = br1 + 'e'.join(a) + ',' + sp + 'e'.join(b) + br2 + else: + raise ValueError("'%s' is unknown mode for printing mpi" % mode) + return s + +def mpci_add(x, y, prec): + a, b = x + c, d = y + return mpi_add(a, c, prec), mpi_add(b, d, prec) + +def mpci_sub(x, y, prec): + a, b = x + c, d = y + return mpi_sub(a, c, prec), mpi_sub(b, d, prec) + +def mpci_neg(x, prec=0): + a, b = x + return mpi_neg(a, prec), mpi_neg(b, prec) + +def mpci_pos(x, prec): + a, b = x + return mpi_pos(a, prec), mpi_pos(b, prec) + +def mpci_mul(x, y, prec): + # TODO: optimize for real/imag cases + a, b = x + c, d = y + r1 = mpi_mul(a,c) + r2 = mpi_mul(b,d) + re = mpi_sub(r1,r2,prec) + i1 = mpi_mul(a,d) + i2 = mpi_mul(b,c) + im = mpi_add(i1,i2,prec) + return re, im + +def mpci_div(x, y, prec): + # TODO: optimize for real/imag cases + a, b = x + c, d = y + wp = prec+20 + m1 = mpi_square(c) + m2 = mpi_square(d) + m = mpi_add(m1,m2,wp) + re = mpi_add(mpi_mul(a,c), mpi_mul(b,d), wp) + im = mpi_sub(mpi_mul(b,c), mpi_mul(a,d), wp) + re = mpi_div(re, m, prec) + im = mpi_div(im, m, prec) + return re, im + +def mpci_exp(x, prec): + a, b = x + wp = prec+20 + r = mpi_exp(a, wp) + c, s = mpi_cos_sin(b, wp) + a = mpi_mul(r, c, prec) + b = mpi_mul(r, s, prec) + return a, b + +def mpi_shift(x, n): + a, b = x + return mpf_shift(a,n), mpf_shift(b,n) + +def mpi_cosh_sinh(x, prec): + # TODO: accuracy for small x + wp = prec+20 + e1 = mpi_exp(x, wp) + e2 = mpi_div(mpi_one, e1, wp) + c = mpi_add(e1, e2, prec) + s = mpi_sub(e1, e2, prec) + c = mpi_shift(c, -1) + s = mpi_shift(s, -1) + return c, s + +def mpci_cos(x, prec): + a, b = x + wp = prec+10 + c, s = mpi_cos_sin(a, wp) + ch, sh = mpi_cosh_sinh(b, wp) + re = mpi_mul(c, ch, prec) + im = mpi_mul(s, sh, prec) + return re, mpi_neg(im) + +def mpci_sin(x, prec): + a, b = x + wp = prec+10 + c, s = mpi_cos_sin(a, wp) + ch, sh = mpi_cosh_sinh(b, wp) + re = mpi_mul(s, ch, prec) + im = mpi_mul(c, sh, prec) + return re, im + +def mpci_abs(x, prec): + a, b = x + if a == mpi_zero: + return mpi_abs(b) + if b == mpi_zero: + return mpi_abs(a) + # Important: nonnegative + a = mpi_square(a) + b = mpi_square(b) + t = mpi_add(a, b, prec+20) + return mpi_sqrt(t, prec) + +def mpi_atan2(y, x, prec): + ya, yb = y + xa, xb = x + # Constrained to the real line + if ya == yb == fzero: + if mpf_ge(xa, fzero): + return mpi_zero + return mpi_pi(prec) + # Right half-plane + if mpf_ge(xa, fzero): + if mpf_ge(ya, fzero): + a = mpf_atan2(ya, xb, prec, round_floor) + else: + a = mpf_atan2(ya, xa, prec, round_floor) + if mpf_ge(yb, fzero): + b = mpf_atan2(yb, xa, prec, round_ceiling) + else: + b = mpf_atan2(yb, xb, prec, round_ceiling) + # Upper half-plane + elif mpf_ge(ya, fzero): + b = mpf_atan2(ya, xa, prec, round_ceiling) + if mpf_le(xb, fzero): + a = mpf_atan2(yb, xb, prec, round_floor) + else: + a = mpf_atan2(ya, xb, prec, round_floor) + # Lower half-plane + elif mpf_le(yb, fzero): + a = mpf_atan2(yb, xa, prec, round_floor) + if mpf_le(xb, fzero): + b = mpf_atan2(ya, xb, prec, round_ceiling) + else: + b = mpf_atan2(yb, xb, prec, round_ceiling) + # Covering the origin + else: + b = mpf_pi(prec, round_ceiling) + a = mpf_neg(b) + return a, b + +def mpci_arg(z, prec): + x, y = z + return mpi_atan2(y, x, prec) + +def mpci_log(z, prec): + x, y = z + re = mpi_log(mpci_abs(z, prec+20), prec) + im = mpci_arg(z, prec) + return re, im + +def mpci_pow(x, y, prec): + # TODO: recognize/speed up real cases, integer y + yre, yim = y + if yim == mpi_zero: + ya, yb = yre + if ya == yb: + sign, man, exp, bc = yb + if man and exp >= 0: + return mpci_pow_int(x, (-1)**sign * int(man<>= 1 + return mpci_pos(result, prec) + +gamma_min_a = from_float(1.46163214496) +gamma_min_b = from_float(1.46163214497) +gamma_min = (gamma_min_a, gamma_min_b) +gamma_mono_imag_a = from_float(-1.1) +gamma_mono_imag_b = from_float(1.1) + +def mpi_overlap(x, y): + a, b = x + c, d = y + if mpf_lt(d, a): return False + if mpf_gt(c, b): return False + return True + +# type = 0 -- gamma +# type = 1 -- factorial +# type = 2 -- 1/gamma +# type = 3 -- log-gamma + +def mpi_gamma(z, prec, type=0): + a, b = z + wp = prec+20 + + if type == 1: + return mpi_gamma(mpi_add(z, mpi_one, wp), prec, 0) + + # increasing + if mpf_gt(a, gamma_min_b): + if type == 0: + c = mpf_gamma(a, prec, round_floor) + d = mpf_gamma(b, prec, round_ceiling) + elif type == 2: + c = mpf_rgamma(b, prec, round_floor) + d = mpf_rgamma(a, prec, round_ceiling) + elif type == 3: + c = mpf_loggamma(a, prec, round_floor) + d = mpf_loggamma(b, prec, round_ceiling) + # decreasing + elif mpf_gt(a, fzero) and mpf_lt(b, gamma_min_a): + if type == 0: + c = mpf_gamma(b, prec, round_floor) + d = mpf_gamma(a, prec, round_ceiling) + elif type == 2: + c = mpf_rgamma(a, prec, round_floor) + d = mpf_rgamma(b, prec, round_ceiling) + elif type == 3: + c = mpf_loggamma(b, prec, round_floor) + d = mpf_loggamma(a, prec, round_ceiling) + else: + # TODO: reflection formula + znew = mpi_add(z, mpi_one, wp) + if type == 0: return mpi_div(mpi_gamma(znew, prec+2, 0), z, prec) + if type == 2: return mpi_mul(mpi_gamma(znew, prec+2, 2), z, prec) + if type == 3: return mpi_sub(mpi_gamma(znew, prec+2, 3), mpi_log(z, prec+2), prec) + return c, d + +def mpci_gamma(z, prec, type=0): + (a1,a2), (b1,b2) = z + + # Real case + if b1 == b2 == fzero and (type != 3 or mpf_gt(a1,fzero)): + return mpi_gamma(z, prec, type), mpi_zero + + # Estimate precision + wp = prec+20 + if type != 3: + amag = a2[2]+a2[3] + bmag = b2[2]+b2[3] + if a2 != fzero: + mag = max(amag, bmag) + else: + mag = bmag + an = abs(to_int(a2)) + bn = abs(to_int(b2)) + absn = max(an, bn) + gamma_size = max(0,absn*mag) + wp += bitcount(gamma_size) + + # Assume type != 1 + if type == 1: + (a1,a2) = mpi_add((a1,a2), mpi_one, wp); z = (a1,a2), (b1,b2) + type = 0 + + # Avoid non-monotonic region near the negative real axis + if mpf_lt(a1, gamma_min_b): + if mpi_overlap((b1,b2), (gamma_mono_imag_a, gamma_mono_imag_b)): + # TODO: reflection formula + #if mpf_lt(a2, mpf_shift(fone,-1)): + # znew = mpci_sub((mpi_one,mpi_zero),z,wp) + # ... + # Recurrence: + # gamma(z) = gamma(z+1)/z + znew = mpi_add((a1,a2), mpi_one, wp), (b1,b2) + if type == 0: return mpci_div(mpci_gamma(znew, prec+2, 0), z, prec) + if type == 2: return mpci_mul(mpci_gamma(znew, prec+2, 2), z, prec) + if type == 3: return mpci_sub(mpci_gamma(znew, prec+2, 3), mpci_log(z,prec+2), prec) + + # Use monotonicity (except for a small region close to the + # origin and near poles) + # upper half-plane + if mpf_ge(b1, fzero): + minre = mpc_loggamma((a1,b2), wp, round_floor) + maxre = mpc_loggamma((a2,b1), wp, round_ceiling) + minim = mpc_loggamma((a1,b1), wp, round_floor) + maxim = mpc_loggamma((a2,b2), wp, round_ceiling) + # lower half-plane + elif mpf_le(b2, fzero): + minre = mpc_loggamma((a1,b1), wp, round_floor) + maxre = mpc_loggamma((a2,b2), wp, round_ceiling) + minim = mpc_loggamma((a2,b1), wp, round_floor) + maxim = mpc_loggamma((a1,b2), wp, round_ceiling) + # crosses real axis + else: + maxre = mpc_loggamma((a2,fzero), wp, round_ceiling) + # stretches more into the lower half-plane + if mpf_gt(mpf_neg(b1), b2): + minre = mpc_loggamma((a1,b1), wp, round_ceiling) + else: + minre = mpc_loggamma((a1,b2), wp, round_ceiling) + minim = mpc_loggamma((a2,b1), wp, round_floor) + maxim = mpc_loggamma((a2,b2), wp, round_floor) + + w = (minre[0], maxre[0]), (minim[1], maxim[1]) + if type == 3: + return mpi_pos(w[0], prec), mpi_pos(w[1], prec) + if type == 2: + w = mpci_neg(w) + return mpci_exp(w, prec) + +def mpi_loggamma(z, prec): return mpi_gamma(z, prec, type=3) +def mpci_loggamma(z, prec): return mpci_gamma(z, prec, type=3) + +def mpi_rgamma(z, prec): return mpi_gamma(z, prec, type=2) +def mpci_rgamma(z, prec): return mpci_gamma(z, prec, type=2) + +def mpi_factorial(z, prec): return mpi_gamma(z, prec, type=1) +def mpci_factorial(z, prec): return mpci_gamma(z, prec, type=1) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..293697b9fcf8bd82d58ac4ff45acd73fadac82f9 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/__init__.py @@ -0,0 +1,2 @@ +from . import eigen # to set methods +from . import eigen_symmetric # to set methods diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/calculus.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/calculus.py new file mode 100644 index 0000000000000000000000000000000000000000..7fae2a7a9a29898241ed41810331b480ff70798f --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/calculus.py @@ -0,0 +1,531 @@ +from ..libmp.backend import xrange + +# TODO: should use diagonalization-based algorithms + +class MatrixCalculusMethods(object): + + def _exp_pade(ctx, a): + """ + Exponential of a matrix using Pade approximants. + + See G. H. Golub, C. F. van Loan 'Matrix Computations', + third Ed., page 572 + + TODO: + - find a good estimate for q + - reduce the number of matrix multiplications to improve + performance + """ + def eps_pade(p): + return ctx.mpf(2)**(3-2*p) * \ + ctx.factorial(p)**2/(ctx.factorial(2*p)**2 * (2*p + 1)) + q = 4 + extraq = 8 + while 1: + if eps_pade(q) < ctx.eps: + break + q += 1 + q += extraq + j = int(max(1, ctx.mag(ctx.mnorm(a,'inf')))) + extra = q + prec = ctx.prec + ctx.dps += extra + 3 + try: + a = a/2**j + na = a.rows + den = ctx.eye(na) + num = ctx.eye(na) + x = ctx.eye(na) + c = ctx.mpf(1) + for k in range(1, q+1): + c *= ctx.mpf(q - k + 1)/((2*q - k + 1) * k) + x = a*x + cx = c*x + num += cx + den += (-1)**k * cx + f = ctx.lu_solve_mat(den, num) + for k in range(j): + f = f*f + finally: + ctx.prec = prec + return f*1 + + def expm(ctx, A, method='taylor'): + r""" + Computes the matrix exponential of a square matrix `A`, which is defined + by the power series + + .. math :: + + \exp(A) = I + A + \frac{A^2}{2!} + \frac{A^3}{3!} + \ldots + + With method='taylor', the matrix exponential is computed + using the Taylor series. With method='pade', Pade approximants + are used instead. + + **Examples** + + Basic examples:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> expm(zeros(3)) + [1.0 0.0 0.0] + [0.0 1.0 0.0] + [0.0 0.0 1.0] + >>> expm(eye(3)) + [2.71828182845905 0.0 0.0] + [ 0.0 2.71828182845905 0.0] + [ 0.0 0.0 2.71828182845905] + >>> expm([[1,1,0],[1,0,1],[0,1,0]]) + [ 3.86814500615414 2.26812870852145 0.841130841230196] + [ 2.26812870852145 2.44114713886289 1.42699786729125] + [0.841130841230196 1.42699786729125 1.6000162976327] + >>> expm([[1,1,0],[1,0,1],[0,1,0]], method='pade') + [ 3.86814500615414 2.26812870852145 0.841130841230196] + [ 2.26812870852145 2.44114713886289 1.42699786729125] + [0.841130841230196 1.42699786729125 1.6000162976327] + >>> expm([[1+j, 0], [1+j,1]]) + [(1.46869393991589 + 2.28735528717884j) 0.0] + [ (1.03776739863568 + 3.536943175722j) (2.71828182845905 + 0.0j)] + + Matrices with large entries are allowed:: + + >>> expm(matrix([[1,2],[2,3]])**25) + [5.65024064048415e+2050488462815550 9.14228140091932e+2050488462815550] + [9.14228140091932e+2050488462815550 1.47925220414035e+2050488462815551] + + The identity `\exp(A+B) = \exp(A) \exp(B)` does not hold for + noncommuting matrices:: + + >>> A = hilbert(3) + >>> B = A + eye(3) + >>> chop(mnorm(A*B - B*A)) + 0.0 + >>> chop(mnorm(expm(A+B) - expm(A)*expm(B))) + 0.0 + >>> B = A + ones(3) + >>> mnorm(A*B - B*A) + 1.8 + >>> mnorm(expm(A+B) - expm(A)*expm(B)) + 42.0927851137247 + + """ + if method == 'pade': + prec = ctx.prec + try: + A = ctx.matrix(A) + ctx.prec += 2*A.rows + res = ctx._exp_pade(A) + finally: + ctx.prec = prec + return res + A = ctx.matrix(A) + prec = ctx.prec + j = int(max(1, ctx.mag(ctx.mnorm(A,'inf')))) + j += int(0.5*prec**0.5) + try: + ctx.prec += 10 + 2*j + tol = +ctx.eps + A = A/2**j + T = A + Y = A**0 + A + k = 2 + while 1: + T *= A * (1/ctx.mpf(k)) + if ctx.mnorm(T, 'inf') < tol: + break + Y += T + k += 1 + for k in xrange(j): + Y = Y*Y + finally: + ctx.prec = prec + Y *= 1 + return Y + + def cosm(ctx, A): + r""" + Gives the cosine of a square matrix `A`, defined in analogy + with the matrix exponential. + + Examples:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> X = eye(3) + >>> cosm(X) + [0.54030230586814 0.0 0.0] + [ 0.0 0.54030230586814 0.0] + [ 0.0 0.0 0.54030230586814] + >>> X = hilbert(3) + >>> cosm(X) + [ 0.424403834569555 -0.316643413047167 -0.221474945949293] + [-0.316643413047167 0.820646708837824 -0.127183694770039] + [-0.221474945949293 -0.127183694770039 0.909236687217541] + >>> X = matrix([[1+j,-2],[0,-j]]) + >>> cosm(X) + [(0.833730025131149 - 0.988897705762865j) (1.07485840848393 - 0.17192140544213j)] + [ 0.0 (1.54308063481524 + 0.0j)] + """ + B = 0.5 * (ctx.expm(A*ctx.j) + ctx.expm(A*(-ctx.j))) + if not sum(A.apply(ctx.im).apply(abs)): + B = B.apply(ctx.re) + return B + + def sinm(ctx, A): + r""" + Gives the sine of a square matrix `A`, defined in analogy + with the matrix exponential. + + Examples:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> X = eye(3) + >>> sinm(X) + [0.841470984807897 0.0 0.0] + [ 0.0 0.841470984807897 0.0] + [ 0.0 0.0 0.841470984807897] + >>> X = hilbert(3) + >>> sinm(X) + [0.711608512150994 0.339783913247439 0.220742837314741] + [0.339783913247439 0.244113865695532 0.187231271174372] + [0.220742837314741 0.187231271174372 0.155816730769635] + >>> X = matrix([[1+j,-2],[0,-j]]) + >>> sinm(X) + [(1.29845758141598 + 0.634963914784736j) (-1.96751511930922 + 0.314700021761367j)] + [ 0.0 (0.0 - 1.1752011936438j)] + """ + B = (-0.5j) * (ctx.expm(A*ctx.j) - ctx.expm(A*(-ctx.j))) + if not sum(A.apply(ctx.im).apply(abs)): + B = B.apply(ctx.re) + return B + + def _sqrtm_rot(ctx, A, _may_rotate): + # If the iteration fails to converge, cheat by performing + # a rotation by a complex number + u = ctx.j**0.3 + return ctx.sqrtm(u*A, _may_rotate) / ctx.sqrt(u) + + def sqrtm(ctx, A, _may_rotate=2): + r""" + Computes a square root of the square matrix `A`, i.e. returns + a matrix `B = A^{1/2}` such that `B^2 = A`. The square root + of a matrix, if it exists, is not unique. + + **Examples** + + Square roots of some simple matrices:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> sqrtm([[1,0], [0,1]]) + [1.0 0.0] + [0.0 1.0] + >>> sqrtm([[0,0], [0,0]]) + [0.0 0.0] + [0.0 0.0] + >>> sqrtm([[2,0],[0,1]]) + [1.4142135623731 0.0] + [ 0.0 1.0] + >>> sqrtm([[1,1],[1,0]]) + [ (0.920442065259926 - 0.21728689675164j) (0.568864481005783 + 0.351577584254143j)] + [(0.568864481005783 + 0.351577584254143j) (0.351577584254143 - 0.568864481005783j)] + >>> sqrtm([[1,0],[0,1]]) + [1.0 0.0] + [0.0 1.0] + >>> sqrtm([[-1,0],[0,1]]) + [(0.0 - 1.0j) 0.0] + [ 0.0 (1.0 + 0.0j)] + >>> sqrtm([[j,0],[0,j]]) + [(0.707106781186547 + 0.707106781186547j) 0.0] + [ 0.0 (0.707106781186547 + 0.707106781186547j)] + + A square root of a rotation matrix, giving the corresponding + half-angle rotation matrix:: + + >>> t1 = 0.75 + >>> t2 = t1 * 0.5 + >>> A1 = matrix([[cos(t1), -sin(t1)], [sin(t1), cos(t1)]]) + >>> A2 = matrix([[cos(t2), -sin(t2)], [sin(t2), cos(t2)]]) + >>> sqrtm(A1) + [0.930507621912314 -0.366272529086048] + [0.366272529086048 0.930507621912314] + >>> A2 + [0.930507621912314 -0.366272529086048] + [0.366272529086048 0.930507621912314] + + The identity `(A^2)^{1/2} = A` does not necessarily hold:: + + >>> A = matrix([[4,1,4],[7,8,9],[10,2,11]]) + >>> sqrtm(A**2) + [ 4.0 1.0 4.0] + [ 7.0 8.0 9.0] + [10.0 2.0 11.0] + >>> sqrtm(A)**2 + [ 4.0 1.0 4.0] + [ 7.0 8.0 9.0] + [10.0 2.0 11.0] + >>> A = matrix([[-4,1,4],[7,-8,9],[10,2,11]]) + >>> sqrtm(A**2) + [ 7.43715112194995 -0.324127569985474 1.8481718827526] + [-0.251549715716942 9.32699765900402 2.48221180985147] + [ 4.11609388833616 0.775751877098258 13.017955697342] + >>> chop(sqrtm(A)**2) + [-4.0 1.0 4.0] + [ 7.0 -8.0 9.0] + [10.0 2.0 11.0] + + For some matrices, a square root does not exist:: + + >>> sqrtm([[0,1], [0,0]]) + Traceback (most recent call last): + ... + ZeroDivisionError: matrix is numerically singular + + Two examples from the documentation for Matlab's ``sqrtm``:: + + >>> mp.dps = 15; mp.pretty = True + >>> sqrtm([[7,10],[15,22]]) + [1.56669890360128 1.74077655955698] + [2.61116483933547 4.17786374293675] + >>> + >>> X = matrix(\ + ... [[5,-4,1,0,0], + ... [-4,6,-4,1,0], + ... [1,-4,6,-4,1], + ... [0,1,-4,6,-4], + ... [0,0,1,-4,5]]) + >>> Y = matrix(\ + ... [[2,-1,-0,-0,-0], + ... [-1,2,-1,0,-0], + ... [0,-1,2,-1,0], + ... [-0,0,-1,2,-1], + ... [-0,-0,-0,-1,2]]) + >>> mnorm(sqrtm(X) - Y) + 4.53155328326114e-19 + + """ + A = ctx.matrix(A) + # Trivial + if A*0 == A: + return A + prec = ctx.prec + if _may_rotate: + d = ctx.det(A) + if abs(ctx.im(d)) < 16*ctx.eps and ctx.re(d) < 0: + return ctx._sqrtm_rot(A, _may_rotate-1) + try: + ctx.prec += 10 + tol = ctx.eps * 128 + Y = A + Z = I = A**0 + k = 0 + # Denman-Beavers iteration + while 1: + Yprev = Y + try: + Y, Z = 0.5*(Y+ctx.inverse(Z)), 0.5*(Z+ctx.inverse(Y)) + except ZeroDivisionError: + if _may_rotate: + Y = ctx._sqrtm_rot(A, _may_rotate-1) + break + else: + raise + mag1 = ctx.mnorm(Y-Yprev, 'inf') + mag2 = ctx.mnorm(Y, 'inf') + if mag1 <= mag2*tol: + break + if _may_rotate and k > 6 and not mag1 < mag2 * 0.001: + return ctx._sqrtm_rot(A, _may_rotate-1) + k += 1 + if k > ctx.prec: + raise ctx.NoConvergence + finally: + ctx.prec = prec + Y *= 1 + return Y + + def logm(ctx, A): + r""" + Computes a logarithm of the square matrix `A`, i.e. returns + a matrix `B = \log(A)` such that `\exp(B) = A`. The logarithm + of a matrix, if it exists, is not unique. + + **Examples** + + Logarithms of some simple matrices:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> X = eye(3) + >>> logm(X) + [0.0 0.0 0.0] + [0.0 0.0 0.0] + [0.0 0.0 0.0] + >>> logm(2*X) + [0.693147180559945 0.0 0.0] + [ 0.0 0.693147180559945 0.0] + [ 0.0 0.0 0.693147180559945] + >>> logm(expm(X)) + [1.0 0.0 0.0] + [0.0 1.0 0.0] + [0.0 0.0 1.0] + + A logarithm of a complex matrix:: + + >>> X = matrix([[2+j, 1, 3], [1-j, 1-2*j, 1], [-4, -5, j]]) + >>> B = logm(X) + >>> nprint(B) + [ (0.808757 + 0.107759j) (2.20752 + 0.202762j) (1.07376 - 0.773874j)] + [ (0.905709 - 0.107795j) (0.0287395 - 0.824993j) (0.111619 + 0.514272j)] + [(-0.930151 + 0.399512j) (-2.06266 - 0.674397j) (0.791552 + 0.519839j)] + >>> chop(expm(B)) + [(2.0 + 1.0j) 1.0 3.0] + [(1.0 - 1.0j) (1.0 - 2.0j) 1.0] + [ -4.0 -5.0 (0.0 + 1.0j)] + + A matrix `X` close to the identity matrix, for which + `\log(\exp(X)) = \exp(\log(X)) = X` holds:: + + >>> X = eye(3) + hilbert(3)/4 + >>> X + [ 1.25 0.125 0.0833333333333333] + [ 0.125 1.08333333333333 0.0625] + [0.0833333333333333 0.0625 1.05] + >>> logm(expm(X)) + [ 1.25 0.125 0.0833333333333333] + [ 0.125 1.08333333333333 0.0625] + [0.0833333333333333 0.0625 1.05] + >>> expm(logm(X)) + [ 1.25 0.125 0.0833333333333333] + [ 0.125 1.08333333333333 0.0625] + [0.0833333333333333 0.0625 1.05] + + A logarithm of a rotation matrix, giving back the angle of + the rotation:: + + >>> t = 3.7 + >>> A = matrix([[cos(t),sin(t)],[-sin(t),cos(t)]]) + >>> chop(logm(A)) + [ 0.0 -2.58318530717959] + [2.58318530717959 0.0] + >>> (2*pi-t) + 2.58318530717959 + + For some matrices, a logarithm does not exist:: + + >>> logm([[1,0], [0,0]]) + Traceback (most recent call last): + ... + ZeroDivisionError: matrix is numerically singular + + Logarithm of a matrix with large entries:: + + >>> logm(hilbert(3) * 10**20).apply(re) + [ 45.5597513593433 1.27721006042799 0.317662687717978] + [ 1.27721006042799 42.5222778973542 2.24003708791604] + [0.317662687717978 2.24003708791604 42.395212822267] + + """ + A = ctx.matrix(A) + prec = ctx.prec + try: + ctx.prec += 10 + tol = ctx.eps * 128 + I = A**0 + B = A + n = 0 + while 1: + B = ctx.sqrtm(B) + n += 1 + if ctx.mnorm(B-I, 'inf') < 0.125: + break + T = X = B-I + L = X*0 + k = 1 + while 1: + if k & 1: + L += T / k + else: + L -= T / k + T *= X + if ctx.mnorm(T, 'inf') < tol: + break + k += 1 + if k > ctx.prec: + raise ctx.NoConvergence + finally: + ctx.prec = prec + L *= 2**n + return L + + def powm(ctx, A, r): + r""" + Computes `A^r = \exp(A \log r)` for a matrix `A` and complex + number `r`. + + **Examples** + + Powers and inverse powers of a matrix:: + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = True + >>> A = matrix([[4,1,4],[7,8,9],[10,2,11]]) + >>> powm(A, 2) + [ 63.0 20.0 69.0] + [174.0 89.0 199.0] + [164.0 48.0 179.0] + >>> chop(powm(powm(A, 4), 1/4.)) + [ 4.0 1.0 4.0] + [ 7.0 8.0 9.0] + [10.0 2.0 11.0] + >>> powm(extraprec(20)(powm)(A, -4), -1/4.) + [ 4.0 1.0 4.0] + [ 7.0 8.0 9.0] + [10.0 2.0 11.0] + >>> chop(powm(powm(A, 1+0.5j), 1/(1+0.5j))) + [ 4.0 1.0 4.0] + [ 7.0 8.0 9.0] + [10.0 2.0 11.0] + >>> powm(extraprec(5)(powm)(A, -1.5), -1/(1.5)) + [ 4.0 1.0 4.0] + [ 7.0 8.0 9.0] + [10.0 2.0 11.0] + + A Fibonacci-generating matrix:: + + >>> powm([[1,1],[1,0]], 10) + [89.0 55.0] + [55.0 34.0] + >>> fib(10) + 55.0 + >>> powm([[1,1],[1,0]], 6.5) + [(16.5166626964253 - 0.0121089837381789j) (10.2078589271083 + 0.0195927472575932j)] + [(10.2078589271083 + 0.0195927472575932j) (6.30880376931698 - 0.0317017309957721j)] + >>> (phi**6.5 - (1-phi)**6.5)/sqrt(5) + (10.2078589271083 - 0.0195927472575932j) + >>> powm([[1,1],[1,0]], 6.2) + [ (14.3076953002666 - 0.008222855781077j) (8.81733464837593 + 0.0133048601383712j)] + [(8.81733464837593 + 0.0133048601383712j) (5.49036065189071 - 0.0215277159194482j)] + >>> (phi**6.2 - (1-phi)**6.2)/sqrt(5) + (8.81733464837593 - 0.0133048601383712j) + + """ + A = ctx.matrix(A) + r = ctx.convert(r) + prec = ctx.prec + try: + ctx.prec += 10 + if ctx.isint(r): + v = A ** int(r) + elif ctx.isint(r*2): + y = int(r*2) + v = ctx.sqrtm(A) ** y + else: + v = ctx.expm(r*ctx.logm(A)) + finally: + ctx.prec = prec + v *= 1 + return v diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/eigen.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/eigen.py new file mode 100644 index 0000000000000000000000000000000000000000..885d604203195b695183329acc637de91aeaf5ea --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/eigen.py @@ -0,0 +1,877 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +################################################################################################## +# module for the eigenvalue problem +# Copyright 2013 Timo Hartmann (thartmann15 at gmail.com) +# +# todo: +# - implement balancing +# - agressive early deflation +# +################################################################################################## + +""" +The eigenvalue problem +---------------------- + +This file contains routines for the eigenvalue problem. + +high level routines: + + hessenberg : reduction of a real or complex square matrix to upper Hessenberg form + schur : reduction of a real or complex square matrix to upper Schur form + eig : eigenvalues and eigenvectors of a real or complex square matrix + +low level routines: + + hessenberg_reduce_0 : reduction of a real or complex square matrix to upper Hessenberg form + hessenberg_reduce_1 : auxiliary routine to hessenberg_reduce_0 + qr_step : a single implicitly shifted QR step for an upper Hessenberg matrix + hessenberg_qr : Schur decomposition of an upper Hessenberg matrix + eig_tr_r : right eigenvectors of an upper triangular matrix + eig_tr_l : left eigenvectors of an upper triangular matrix +""" + +from ..libmp.backend import xrange + +class Eigen(object): + pass + +def defun(f): + setattr(Eigen, f.__name__, f) + return f + +def hessenberg_reduce_0(ctx, A, T): + """ + This routine computes the (upper) Hessenberg decomposition of a square matrix A. + Given A, an unitary matrix Q is calculated such that + + Q' A Q = H and Q' Q = Q Q' = 1 + + where H is an upper Hessenberg matrix, meaning that it only contains zeros + below the first subdiagonal. Here ' denotes the hermitian transpose (i.e. + transposition and conjugation). + + parameters: + A (input/output) On input, A contains the square matrix A of + dimension (n,n). On output, A contains a compressed representation + of Q and H. + T (output) An array of length n containing the first elements of + the Householder reflectors. + """ + + # internally we work with householder reflections from the right. + # let u be a row vector (i.e. u[i]=A[i,:i]). then + # Q is build up by reflectors of the type (1-v'v) where v is a suitable + # modification of u. these reflectors are applyed to A from the right. + # because we work with reflectors from the right we have to start with + # the bottom row of A and work then upwards (this corresponds to + # some kind of RQ decomposition). + # the first part of the vectors v (i.e. A[i,:(i-1)]) are stored as row vectors + # in the lower left part of A (excluding the diagonal and subdiagonal). + # the last entry of v is stored in T. + # the upper right part of A (including diagonal and subdiagonal) becomes H. + + + n = A.rows + if n <= 2: return + + for i in xrange(n-1, 1, -1): + + # scale the vector + + scale = 0 + for k in xrange(0, i): + scale += abs(ctx.re(A[i,k])) + abs(ctx.im(A[i,k])) + + scale_inv = 0 + if scale != 0: + scale_inv = 1 / scale + + if scale == 0 or ctx.isinf(scale_inv): + # sadly there are floating point numbers not equal to zero whose reciprocal is infinity + T[i] = 0 + A[i,i-1] = 0 + continue + + # calculate parameters for housholder transformation + + H = 0 + for k in xrange(0, i): + A[i,k] *= scale_inv + rr = ctx.re(A[i,k]) + ii = ctx.im(A[i,k]) + H += rr * rr + ii * ii + + F = A[i,i-1] + f = abs(F) + G = ctx.sqrt(H) + A[i,i-1] = - G * scale + + if f == 0: + T[i] = G + else: + ff = F / f + T[i] = F + G * ff + A[i,i-1] *= ff + + H += G * f + H = 1 / ctx.sqrt(H) + + T[i] *= H + for k in xrange(0, i - 1): + A[i,k] *= H + + for j in xrange(0, i): + # apply housholder transformation (from right) + + G = ctx.conj(T[i]) * A[j,i-1] + for k in xrange(0, i-1): + G += ctx.conj(A[i,k]) * A[j,k] + + A[j,i-1] -= G * T[i] + for k in xrange(0, i-1): + A[j,k] -= G * A[i,k] + + for j in xrange(0, n): + # apply housholder transformation (from left) + + G = T[i] * A[i-1,j] + for k in xrange(0, i-1): + G += A[i,k] * A[k,j] + + A[i-1,j] -= G * ctx.conj(T[i]) + for k in xrange(0, i-1): + A[k,j] -= G * ctx.conj(A[i,k]) + + + +def hessenberg_reduce_1(ctx, A, T): + """ + This routine forms the unitary matrix Q described in hessenberg_reduce_0. + + parameters: + A (input/output) On input, A is the same matrix as delivered by + hessenberg_reduce_0. On output, A is set to Q. + + T (input) On input, T is the same array as delivered by hessenberg_reduce_0. + """ + + n = A.rows + + if n == 1: + A[0,0] = 1 + return + + A[0,0] = A[1,1] = 1 + A[0,1] = A[1,0] = 0 + + for i in xrange(2, n): + if T[i] != 0: + + for j in xrange(0, i): + G = T[i] * A[i-1,j] + for k in xrange(0, i-1): + G += A[i,k] * A[k,j] + + A[i-1,j] -= G * ctx.conj(T[i]) + for k in xrange(0, i-1): + A[k,j] -= G * ctx.conj(A[i,k]) + + A[i,i] = 1 + for j in xrange(0, i): + A[j,i] = A[i,j] = 0 + + + +@defun +def hessenberg(ctx, A, overwrite_a = False): + """ + This routine computes the Hessenberg decomposition of a square matrix A. + Given A, an unitary matrix Q is determined such that + + Q' A Q = H and Q' Q = Q Q' = 1 + + where H is an upper right Hessenberg matrix. Here ' denotes the hermitian + transpose (i.e. transposition and conjugation). + + input: + A : a real or complex square matrix + overwrite_a : if true, allows modification of A which may improve + performance. if false, A is not modified. + + output: + Q : an unitary matrix + H : an upper right Hessenberg matrix + + example: + >>> from mpmath import mp + >>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]]) + >>> Q, H = mp.hessenberg(A) + >>> mp.nprint(H, 3) # doctest:+SKIP + [ 3.15 2.23 4.44] + [-0.769 4.85 3.05] + [ 0.0 3.61 7.0] + >>> print(mp.chop(A - Q * H * Q.transpose_conj())) + [0.0 0.0 0.0] + [0.0 0.0 0.0] + [0.0 0.0 0.0] + + return value: (Q, H) + """ + + n = A.rows + + if n == 1: + return (ctx.matrix([[1]]), A) + + if not overwrite_a: + A = A.copy() + + T = ctx.matrix(n, 1) + + hessenberg_reduce_0(ctx, A, T) + Q = A.copy() + hessenberg_reduce_1(ctx, Q, T) + + for x in xrange(n): + for y in xrange(x+2, n): + A[y,x] = 0 + + return Q, A + + +########################################################################### + + +def qr_step(ctx, n0, n1, A, Q, shift): + """ + This subroutine executes a single implicitly shifted QR step applied to an + upper Hessenberg matrix A. Given A and shift as input, first an QR + decomposition is calculated: + + Q R = A - shift * 1 . + + The output is then following matrix: + + R Q + shift * 1 + + parameters: + n0, n1 (input) Two integers which specify the submatrix A[n0:n1,n0:n1] + on which this subroutine operators. The subdiagonal elements + to the left and below this submatrix must be deflated (i.e. zero). + following restriction is imposed: n1>=n0+2 + A (input/output) On input, A is an upper Hessenberg matrix. + On output, A is replaced by "R Q + shift * 1" + Q (input/output) The parameter Q is multiplied by the unitary matrix + Q arising from the QR decomposition. Q can also be false, in which + case the unitary matrix Q is not computated. + shift (input) a complex number specifying the shift. idealy close to an + eigenvalue of the bottemmost part of the submatrix A[n0:n1,n0:n1]. + + references: + Stoer, Bulirsch - Introduction to Numerical Analysis. + Kresser : Numerical Methods for General and Structured Eigenvalue Problems + """ + + # implicitly shifted and bulge chasing is explained at p.398/399 in "Stoer, Bulirsch - Introduction to Numerical Analysis" + # for bulge chasing see also "Watkins - The Matrix Eigenvalue Problem" sec.4.5,p.173 + + # the Givens rotation we used is determined as follows: let c,s be two complex + # numbers. then we have following relation: + # + # v = sqrt(|c|^2 + |s|^2) + # + # 1/v [ c~ s~] [c] = [v] + # [-s c ] [s] [0] + # + # the matrix on the left is our Givens rotation. + + n = A.rows + + # first step + + # calculate givens rotation + c = A[n0 ,n0] - shift + s = A[n0+1,n0] + + v = ctx.hypot(ctx.hypot(ctx.re(c), ctx.im(c)), ctx.hypot(ctx.re(s), ctx.im(s))) + + if v == 0: + v = 1 + c = 1 + s = 0 + else: + c /= v + s /= v + + cc = ctx.conj(c) + cs = ctx.conj(s) + + for k in xrange(n0, n): + # apply givens rotation from the left + x = A[n0 ,k] + y = A[n0+1,k] + A[n0 ,k] = cc * x + cs * y + A[n0+1,k] = c * y - s * x + + for k in xrange(min(n1, n0+3)): + # apply givens rotation from the right + x = A[k,n0 ] + y = A[k,n0+1] + A[k,n0 ] = c * x + s * y + A[k,n0+1] = cc * y - cs * x + + if not isinstance(Q, bool): + for k in xrange(n): + # eigenvectors + x = Q[k,n0 ] + y = Q[k,n0+1] + Q[k,n0 ] = c * x + s * y + Q[k,n0+1] = cc * y - cs * x + + # chase the bulge + + for j in xrange(n0, n1 - 2): + # calculate givens rotation + + c = A[j+1,j] + s = A[j+2,j] + + v = ctx.hypot(ctx.hypot(ctx.re(c), ctx.im(c)), ctx.hypot(ctx.re(s), ctx.im(s))) + + if v == 0: + A[j+1,j] = 0 + v = 1 + c = 1 + s = 0 + else: + A[j+1,j] = v + c /= v + s /= v + + A[j+2,j] = 0 + + cc = ctx.conj(c) + cs = ctx.conj(s) + + for k in xrange(j+1, n): + # apply givens rotation from the left + x = A[j+1,k] + y = A[j+2,k] + A[j+1,k] = cc * x + cs * y + A[j+2,k] = c * y - s * x + + for k in xrange(0, min(n1, j+4)): + # apply givens rotation from the right + x = A[k,j+1] + y = A[k,j+2] + A[k,j+1] = c * x + s * y + A[k,j+2] = cc * y - cs * x + + if not isinstance(Q, bool): + for k in xrange(0, n): + # eigenvectors + x = Q[k,j+1] + y = Q[k,j+2] + Q[k,j+1] = c * x + s * y + Q[k,j+2] = cc * y - cs * x + + + +def hessenberg_qr(ctx, A, Q): + """ + This routine computes the Schur decomposition of an upper Hessenberg matrix A. + Given A, an unitary matrix Q is determined such that + + Q' A Q = R and Q' Q = Q Q' = 1 + + where R is an upper right triangular matrix. Here ' denotes the hermitian + transpose (i.e. transposition and conjugation). + + parameters: + A (input/output) On input, A contains an upper Hessenberg matrix. + On output, A is replace by the upper right triangluar matrix R. + + Q (input/output) The parameter Q is multiplied by the unitary + matrix Q arising from the Schur decomposition. Q can also be + false, in which case the unitary matrix Q is not computated. + """ + + n = A.rows + + norm = 0 + for x in xrange(n): + for y in xrange(min(x+2, n)): + norm += ctx.re(A[y,x]) ** 2 + ctx.im(A[y,x]) ** 2 + norm = ctx.sqrt(norm) / n + + if norm == 0: + return + + n0 = 0 + n1 = n + + eps = ctx.eps / (100 * n) + maxits = ctx.dps * 4 + + its = totalits = 0 + + while 1: + # kressner p.32 algo 3 + # the active submatrix is A[n0:n1,n0:n1] + + k = n0 + + while k + 1 < n1: + s = abs(ctx.re(A[k,k])) + abs(ctx.im(A[k,k])) + abs(ctx.re(A[k+1,k+1])) + abs(ctx.im(A[k+1,k+1])) + if s < eps * norm: + s = norm + if abs(A[k+1,k]) < eps * s: + break + k += 1 + + if k + 1 < n1: + # deflation found at position (k+1, k) + + A[k+1,k] = 0 + n0 = k + 1 + + its = 0 + + if n0 + 1 >= n1: + # block of size at most two has converged + n0 = 0 + n1 = k + 1 + if n1 < 2: + # QR algorithm has converged + return + else: + if (its % 30) == 10: + # exceptional shift + shift = A[n1-1,n1-2] + elif (its % 30) == 20: + # exceptional shift + shift = abs(A[n1-1,n1-2]) + elif (its % 30) == 29: + # exceptional shift + shift = norm + else: + # A = [ a b ] det(x-A)=x*x-x*tr(A)+det(A) + # [ c d ] + # + # eigenvalues bad: (tr(A)+sqrt((tr(A))**2-4*det(A)))/2 + # bad because of cancellation if |c| is small and |a-d| is small, too. + # + # eigenvalues good: (a+d+sqrt((a-d)**2+4*b*c))/2 + + t = A[n1-2,n1-2] + A[n1-1,n1-1] + s = (A[n1-1,n1-1] - A[n1-2,n1-2]) ** 2 + 4 * A[n1-1,n1-2] * A[n1-2,n1-1] + if ctx.re(s) > 0: + s = ctx.sqrt(s) + else: + s = ctx.sqrt(-s) * 1j + a = (t + s) / 2 + b = (t - s) / 2 + if abs(A[n1-1,n1-1] - a) > abs(A[n1-1,n1-1] - b): + shift = b + else: + shift = a + + its += 1 + totalits += 1 + + qr_step(ctx, n0, n1, A, Q, shift) + + if its > maxits: + raise RuntimeError("qr: failed to converge after %d steps" % its) + + +@defun +def schur(ctx, A, overwrite_a = False): + """ + This routine computes the Schur decomposition of a square matrix A. + Given A, an unitary matrix Q is determined such that + + Q' A Q = R and Q' Q = Q Q' = 1 + + where R is an upper right triangular matrix. Here ' denotes the + hermitian transpose (i.e. transposition and conjugation). + + input: + A : a real or complex square matrix + overwrite_a : if true, allows modification of A which may improve + performance. if false, A is not modified. + + output: + Q : an unitary matrix + R : an upper right triangular matrix + + return value: (Q, R) + + example: + >>> from mpmath import mp + >>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]]) + >>> Q, R = mp.schur(A) + >>> mp.nprint(R, 3) # doctest:+SKIP + [2.0 0.417 -2.53] + [0.0 4.0 -4.74] + [0.0 0.0 9.0] + >>> print(mp.chop(A - Q * R * Q.transpose_conj())) + [0.0 0.0 0.0] + [0.0 0.0 0.0] + [0.0 0.0 0.0] + + warning: The Schur decomposition is not unique. + """ + + n = A.rows + + if n == 1: + return (ctx.matrix([[1]]), A) + + if not overwrite_a: + A = A.copy() + + T = ctx.matrix(n, 1) + + hessenberg_reduce_0(ctx, A, T) + Q = A.copy() + hessenberg_reduce_1(ctx, Q, T) + + for x in xrange(n): + for y in xrange(x + 2, n): + A[y,x] = 0 + + hessenberg_qr(ctx, A, Q) + + return Q, A + + +def eig_tr_r(ctx, A): + """ + This routine calculates the right eigenvectors of an upper right triangular matrix. + + input: + A an upper right triangular matrix + + output: + ER a matrix whose columns form the right eigenvectors of A + + return value: ER + """ + + # this subroutine is inspired by the lapack routines ctrevc.f,clatrs.f + + n = A.rows + + ER = ctx.eye(n) + + eps = ctx.eps + + unfl = ctx.ldexp(ctx.one, -ctx.prec * 30) + # since mpmath effectively has no limits on the exponent, we simply scale doubles up + # original double has prec*20 + + smlnum = unfl * (n / eps) + simin = 1 / ctx.sqrt(eps) + + rmax = 1 + + for i in xrange(1, n): + s = A[i,i] + + smin = max(eps * abs(s), smlnum) + + for j in xrange(i - 1, -1, -1): + + r = 0 + for k in xrange(j + 1, i + 1): + r += A[j,k] * ER[k,i] + + t = A[j,j] - s + if abs(t) < smin: + t = smin + + r = -r / t + ER[j,i] = r + + rmax = max(rmax, abs(r)) + if rmax > simin: + for k in xrange(j, i+1): + ER[k,i] /= rmax + rmax = 1 + + if rmax != 1: + for k in xrange(0, i + 1): + ER[k,i] /= rmax + + return ER + +def eig_tr_l(ctx, A): + """ + This routine calculates the left eigenvectors of an upper right triangular matrix. + + input: + A an upper right triangular matrix + + output: + EL a matrix whose rows form the left eigenvectors of A + + return value: EL + """ + + n = A.rows + + EL = ctx.eye(n) + + eps = ctx.eps + + unfl = ctx.ldexp(ctx.one, -ctx.prec * 30) + # since mpmath effectively has no limits on the exponent, we simply scale doubles up + # original double has prec*20 + + smlnum = unfl * (n / eps) + simin = 1 / ctx.sqrt(eps) + + rmax = 1 + + for i in xrange(0, n - 1): + s = A[i,i] + + smin = max(eps * abs(s), smlnum) + + for j in xrange(i + 1, n): + + r = 0 + for k in xrange(i, j): + r += EL[i,k] * A[k,j] + + t = A[j,j] - s + if abs(t) < smin: + t = smin + + r = -r / t + EL[i,j] = r + + rmax = max(rmax, abs(r)) + if rmax > simin: + for k in xrange(i, j + 1): + EL[i,k] /= rmax + rmax = 1 + + if rmax != 1: + for k in xrange(i, n): + EL[i,k] /= rmax + + return EL + +@defun +def eig(ctx, A, left = False, right = True, overwrite_a = False): + """ + This routine computes the eigenvalues and optionally the left and right + eigenvectors of a square matrix A. Given A, a vector E and matrices ER + and EL are calculated such that + + A ER[:,i] = E[i] ER[:,i] + EL[i,:] A = EL[i,:] E[i] + + E contains the eigenvalues of A. The columns of ER contain the right eigenvectors + of A whereas the rows of EL contain the left eigenvectors. + + + input: + A : a real or complex square matrix of shape (n, n) + left : if true, the left eigenvectors are calculated. + right : if true, the right eigenvectors are calculated. + overwrite_a : if true, allows modification of A which may improve + performance. if false, A is not modified. + + output: + E : a list of length n containing the eigenvalues of A. + ER : a matrix whose columns contain the right eigenvectors of A. + EL : a matrix whose rows contain the left eigenvectors of A. + + return values: + E if left and right are both false. + (E, ER) if right is true and left is false. + (E, EL) if left is true and right is false. + (E, EL, ER) if left and right are true. + + + examples: + >>> from mpmath import mp + >>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]]) + >>> E, ER = mp.eig(A) + >>> print(mp.chop(A * ER[:,0] - E[0] * ER[:,0])) + [0.0] + [0.0] + [0.0] + + >>> E, EL, ER = mp.eig(A,left = True, right = True) + >>> E, EL, ER = mp.eig_sort(E, EL, ER) + >>> mp.nprint(E) + [2.0, 4.0, 9.0] + >>> print(mp.chop(A * ER[:,0] - E[0] * ER[:,0])) + [0.0] + [0.0] + [0.0] + >>> print(mp.chop( EL[0,:] * A - EL[0,:] * E[0])) + [0.0 0.0 0.0] + + warning: + - If there are multiple eigenvalues, the eigenvectors do not necessarily + span the whole vectorspace, i.e. ER and EL may have not full rank. + Furthermore in that case the eigenvectors are numerical ill-conditioned. + - In the general case the eigenvalues have no natural order. + + see also: + - eigh (or eigsy, eighe) for the symmetric eigenvalue problem. + - eig_sort for sorting of eigenvalues and eigenvectors + """ + + n = A.rows + + if n == 1: + if left and (not right): + return ([A[0]], ctx.matrix([[1]])) + + if right and (not left): + return ([A[0]], ctx.matrix([[1]])) + + return ([A[0]], ctx.matrix([[1]]), ctx.matrix([[1]])) + + if not overwrite_a: + A = A.copy() + + T = ctx.zeros(n, 1) + + hessenberg_reduce_0(ctx, A, T) + + if left or right: + Q = A.copy() + hessenberg_reduce_1(ctx, Q, T) + else: + Q = False + + for x in xrange(n): + for y in xrange(x + 2, n): + A[y,x] = 0 + + hessenberg_qr(ctx, A, Q) + + E = [0 for i in xrange(n)] + for i in xrange(n): + E[i] = A[i,i] + + if not (left or right): + return E + + if left: + EL = eig_tr_l(ctx, A) + EL = EL * Q.transpose_conj() + + if right: + ER = eig_tr_r(ctx, A) + ER = Q * ER + + if left and (not right): + return (E, EL) + + if right and (not left): + return (E, ER) + + return (E, EL, ER) + +@defun +def eig_sort(ctx, E, EL = False, ER = False, f = "real"): + """ + This routine sorts the eigenvalues and eigenvectors delivered by ``eig``. + + parameters: + E : the eigenvalues as delivered by eig + EL : the left eigenvectors as delivered by eig, or false + ER : the right eigenvectors as delivered by eig, or false + f : either a string ("real" sort by increasing real part, "imag" sort by + increasing imag part, "abs" sort by absolute value) or a function + mapping complexs to the reals, i.e. ``f = lambda x: -mp.re(x) `` + would sort the eigenvalues by decreasing real part. + + return values: + E if EL and ER are both false. + (E, ER) if ER is not false and left is false. + (E, EL) if EL is not false and right is false. + (E, EL, ER) if EL and ER are not false. + + example: + >>> from mpmath import mp + >>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]]) + >>> E, EL, ER = mp.eig(A,left = True, right = True) + >>> E, EL, ER = mp.eig_sort(E, EL, ER) + >>> mp.nprint(E) + [2.0, 4.0, 9.0] + >>> E, EL, ER = mp.eig_sort(E, EL, ER,f = lambda x: -mp.re(x)) + >>> mp.nprint(E) + [9.0, 4.0, 2.0] + >>> print(mp.chop(A * ER[:,0] - E[0] * ER[:,0])) + [0.0] + [0.0] + [0.0] + >>> print(mp.chop( EL[0,:] * A - EL[0,:] * E[0])) + [0.0 0.0 0.0] + """ + + if isinstance(f, str): + if f == "real": + f = ctx.re + elif f == "imag": + f = ctx.im + elif f == "abs": + f = abs + else: + raise RuntimeError("unknown function %s" % f) + + n = len(E) + + # Sort eigenvalues (bubble-sort) + + for i in xrange(n): + imax = i + s = f(E[i]) # s is the current maximal element + + for j in xrange(i + 1, n): + c = f(E[j]) + if c < s: + s = c + imax = j + + if imax != i: + # swap eigenvalues + + z = E[i] + E[i] = E[imax] + E[imax] = z + + if not isinstance(EL, bool): + for j in xrange(n): + z = EL[i,j] + EL[i,j] = EL[imax,j] + EL[imax,j] = z + + if not isinstance(ER, bool): + for j in xrange(n): + z = ER[j,i] + ER[j,i] = ER[j,imax] + ER[j,imax] = z + + if isinstance(EL, bool) and isinstance(ER, bool): + return E + + if isinstance(EL, bool) and not(isinstance(ER, bool)): + return (E, ER) + + if isinstance(ER, bool) and not(isinstance(EL, bool)): + return (E, EL) + + return (E, EL, ER) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/eigen_symmetric.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/eigen_symmetric.py new file mode 100644 index 0000000000000000000000000000000000000000..c82c0bb061d22c37a89f82a0b9bdab3e9ba7ddde --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/eigen_symmetric.py @@ -0,0 +1,1807 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +################################################################################################## +# module for the symmetric eigenvalue problem +# Copyright 2013 Timo Hartmann (thartmann15 at gmail.com) +# +# todo: +# - implement balancing +# +################################################################################################## + +""" +The symmetric eigenvalue problem. +--------------------------------- + +This file contains routines for the symmetric eigenvalue problem. + +high level routines: + + eigsy : real symmetric (ordinary) eigenvalue problem + eighe : complex hermitian (ordinary) eigenvalue problem + eigh : unified interface for eigsy and eighe + svd_r : singular value decomposition for real matrices + svd_c : singular value decomposition for complex matrices + svd : unified interface for svd_r and svd_c + + +low level routines: + + r_sy_tridiag : reduction of real symmetric matrix to real symmetric tridiagonal matrix + c_he_tridiag_0 : reduction of complex hermitian matrix to real symmetric tridiagonal matrix + c_he_tridiag_1 : auxiliary routine to c_he_tridiag_0 + c_he_tridiag_2 : auxiliary routine to c_he_tridiag_0 + tridiag_eigen : solves the real symmetric tridiagonal matrix eigenvalue problem + svd_r_raw : raw singular value decomposition for real matrices + svd_c_raw : raw singular value decomposition for complex matrices +""" + +from ..libmp.backend import xrange +from .eigen import defun + + +def r_sy_tridiag(ctx, A, D, E, calc_ev = True): + """ + This routine transforms a real symmetric matrix A to a real symmetric + tridiagonal matrix T using an orthogonal similarity transformation: + Q' * A * Q = T (here ' denotes the matrix transpose). + The orthogonal matrix Q is build up from Householder reflectors. + + parameters: + A (input/output) On input, A contains the real symmetric matrix of + dimension (n,n). On output, if calc_ev is true, A contains the + orthogonal matrix Q, otherwise A is destroyed. + + D (output) real array of length n, contains the diagonal elements + of the tridiagonal matrix + + E (output) real array of length n, contains the offdiagonal elements + of the tridiagonal matrix in E[0:(n-1)] where is the dimension of + the matrix A. E[n-1] is undefined. + + calc_ev (input) If calc_ev is true, this routine explicitly calculates the + orthogonal matrix Q which is then returned in A. If calc_ev is + false, Q is not explicitly calculated resulting in a shorter run time. + + This routine is a python translation of the fortran routine tred2.f in the + software library EISPACK (see netlib.org) which itself is based on the algol + procedure tred2 described in: + - Num. Math. 11, p.181-195 (1968) by Martin, Reinsch and Wilkonson + - Handbook for auto. comp., Vol II, Linear Algebra, p.212-226 (1971) + + For a good introduction to Householder reflections, see also + Stoer, Bulirsch - Introduction to Numerical Analysis. + """ + + # note : the vector v of the i-th houshoulder reflector is stored in a[(i+1):,i] + # whereas v/ is stored in a[i,(i+1):] + + n = A.rows + for i in xrange(n - 1, 0, -1): + # scale the vector + + scale = 0 + for k in xrange(0, i): + scale += abs(A[k,i]) + + scale_inv = 0 + if scale != 0: + scale_inv = 1/scale + + # sadly there are floating point numbers not equal to zero whose reciprocal is infinity + + if i == 1 or scale == 0 or ctx.isinf(scale_inv): + E[i] = A[i-1,i] # nothing to do + D[i] = 0 + continue + + # calculate parameters for housholder transformation + + H = 0 + for k in xrange(0, i): + A[k,i] *= scale_inv + H += A[k,i] * A[k,i] + + F = A[i-1,i] + G = ctx.sqrt(H) + if F > 0: + G = -G + E[i] = scale * G + H -= F * G + A[i-1,i] = F - G + F = 0 + + # apply housholder transformation + + for j in xrange(0, i): + if calc_ev: + A[i,j] = A[j,i] / H + + G = 0 # calculate A*U + for k in xrange(0, j + 1): + G += A[k,j] * A[k,i] + for k in xrange(j + 1, i): + G += A[j,k] * A[k,i] + + E[j] = G / H # calculate P + F += E[j] * A[j,i] + + HH = F / (2 * H) + + for j in xrange(0, i): # calculate reduced A + F = A[j,i] + G = E[j] - HH * F # calculate Q + E[j] = G + + for k in xrange(0, j + 1): + A[k,j] -= F * E[k] + G * A[k,i] + + D[i] = H + + for i in xrange(1, n): # better for compatibility + E[i-1] = E[i] + E[n-1] = 0 + + if calc_ev: + D[0] = 0 + for i in xrange(0, n): + if D[i] != 0: + for j in xrange(0, i): # accumulate transformation matrices + G = 0 + for k in xrange(0, i): + G += A[i,k] * A[k,j] + for k in xrange(0, i): + A[k,j] -= G * A[k,i] + + D[i] = A[i,i] + A[i,i] = 1 + + for j in xrange(0, i): + A[j,i] = A[i,j] = 0 + else: + for i in xrange(0, n): + D[i] = A[i,i] + + + + + +def c_he_tridiag_0(ctx, A, D, E, T): + """ + This routine transforms a complex hermitian matrix A to a real symmetric + tridiagonal matrix T using an unitary similarity transformation: + Q' * A * Q = T (here ' denotes the hermitian matrix transpose, + i.e. transposition und conjugation). + The unitary matrix Q is build up from Householder reflectors and + an unitary diagonal matrix. + + parameters: + A (input/output) On input, A contains the complex hermitian matrix + of dimension (n,n). On output, A contains the unitary matrix Q + in compressed form. + + D (output) real array of length n, contains the diagonal elements + of the tridiagonal matrix. + + E (output) real array of length n, contains the offdiagonal elements + of the tridiagonal matrix in E[0:(n-1)] where is the dimension of + the matrix A. E[n-1] is undefined. + + T (output) complex array of length n, contains a unitary diagonal + matrix. + + This routine is a python translation (in slightly modified form) of the fortran + routine htridi.f in the software library EISPACK (see netlib.org) which itself + is a complex version of the algol procedure tred1 described in: + - Num. Math. 11, p.181-195 (1968) by Martin, Reinsch and Wilkonson + - Handbook for auto. comp., Vol II, Linear Algebra, p.212-226 (1971) + + For a good introduction to Householder reflections, see also + Stoer, Bulirsch - Introduction to Numerical Analysis. + """ + + n = A.rows + T[n-1] = 1 + for i in xrange(n - 1, 0, -1): + + # scale the vector + + scale = 0 + for k in xrange(0, i): + scale += abs(ctx.re(A[k,i])) + abs(ctx.im(A[k,i])) + + scale_inv = 0 + if scale != 0: + scale_inv = 1 / scale + + # sadly there are floating point numbers not equal to zero whose reciprocal is infinity + + if scale == 0 or ctx.isinf(scale_inv): + E[i] = 0 + D[i] = 0 + T[i-1] = 1 + continue + + if i == 1: + F = A[i-1,i] + f = abs(F) + E[i] = f + D[i] = 0 + if f != 0: + T[i-1] = T[i] * F / f + else: + T[i-1] = T[i] + continue + + # calculate parameters for housholder transformation + + H = 0 + for k in xrange(0, i): + A[k,i] *= scale_inv + rr = ctx.re(A[k,i]) + ii = ctx.im(A[k,i]) + H += rr * rr + ii * ii + + F = A[i-1,i] + f = abs(F) + G = ctx.sqrt(H) + H += G * f + E[i] = scale * G + if f != 0: + F = F / f + TZ = - T[i] * F # T[i-1]=-T[i]*F, but we need T[i-1] as temporary storage + G *= F + else: + TZ = -T[i] # T[i-1]=-T[i] + A[i-1,i] += G + F = 0 + + # apply housholder transformation + + for j in xrange(0, i): + A[i,j] = A[j,i] / H + + G = 0 # calculate A*U + for k in xrange(0, j + 1): + G += ctx.conj(A[k,j]) * A[k,i] + for k in xrange(j + 1, i): + G += A[j,k] * A[k,i] + + T[j] = G / H # calculate P + F += ctx.conj(T[j]) * A[j,i] + + HH = F / (2 * H) + + for j in xrange(0, i): # calculate reduced A + F = A[j,i] + G = T[j] - HH * F # calculate Q + T[j] = G + + for k in xrange(0, j + 1): + A[k,j] -= ctx.conj(F) * T[k] + ctx.conj(G) * A[k,i] + # as we use the lower left part for storage + # we have to use the transpose of the normal formula + + T[i-1] = TZ + D[i] = H + + for i in xrange(1, n): # better for compatibility + E[i-1] = E[i] + E[n-1] = 0 + + D[0] = 0 + for i in xrange(0, n): + zw = D[i] + D[i] = ctx.re(A[i,i]) + A[i,i] = zw + + + + + + + +def c_he_tridiag_1(ctx, A, T): + """ + This routine forms the unitary matrix Q described in c_he_tridiag_0. + + parameters: + A (input/output) On input, A is the same matrix as delivered by + c_he_tridiag_0. On output, A is set to Q. + + T (input) On input, T is the same array as delivered by c_he_tridiag_0. + + """ + + n = A.rows + + for i in xrange(0, n): + if A[i,i] != 0: + for j in xrange(0, i): + G = 0 + for k in xrange(0, i): + G += ctx.conj(A[i,k]) * A[k,j] + for k in xrange(0, i): + A[k,j] -= G * A[k,i] + + A[i,i] = 1 + + for j in xrange(0, i): + A[j,i] = A[i,j] = 0 + + for i in xrange(0, n): + for k in xrange(0, n): + A[i,k] *= T[k] + + + + +def c_he_tridiag_2(ctx, A, T, B): + """ + This routine applied the unitary matrix Q described in c_he_tridiag_0 + onto the the matrix B, i.e. it forms Q*B. + + parameters: + A (input) On input, A is the same matrix as delivered by c_he_tridiag_0. + + T (input) On input, T is the same array as delivered by c_he_tridiag_0. + + B (input/output) On input, B is a complex matrix. On output B is replaced + by Q*B. + + This routine is a python translation of the fortran routine htribk.f in the + software library EISPACK (see netlib.org). See c_he_tridiag_0 for more + references. + """ + + n = A.rows + + for i in xrange(0, n): + for k in xrange(0, n): + B[k,i] *= T[k] + + for i in xrange(0, n): + if A[i,i] != 0: + for j in xrange(0, n): + G = 0 + for k in xrange(0, i): + G += ctx.conj(A[i,k]) * B[k,j] + for k in xrange(0, i): + B[k,j] -= G * A[k,i] + + + + + +def tridiag_eigen(ctx, d, e, z = False): + """ + This subroutine find the eigenvalues and the first components of the + eigenvectors of a real symmetric tridiagonal matrix using the implicit + QL method. + + parameters: + + d (input/output) real array of length n. on input, d contains the diagonal + elements of the input matrix. on output, d contains the eigenvalues in + ascending order. + + e (input) real array of length n. on input, e contains the offdiagonal + elements of the input matrix in e[0:(n-1)]. On output, e has been + destroyed. + + z (input/output) If z is equal to False, no eigenvectors will be computed. + Otherwise on input z should have the format z[0:m,0:n] (i.e. a real or + complex matrix of dimension (m,n) ). On output this matrix will be + multiplied by the matrix of the eigenvectors (i.e. the columns of this + matrix are the eigenvectors): z --> z*EV + That means if z[i,j]={1 if j==j; 0 otherwise} on input, then on output + z will contain the first m components of the eigenvectors. That means + if m is equal to n, the i-th eigenvector will be z[:,i]. + + This routine is a python translation (in slightly modified form) of the + fortran routine imtql2.f in the software library EISPACK (see netlib.org) + which itself is based on the algol procudure imtql2 desribed in: + - num. math. 12, p. 377-383(1968) by matrin and wilkinson + - modified in num. math. 15, p. 450(1970) by dubrulle + - handbook for auto. comp., vol. II-linear algebra, p. 241-248 (1971) + See also the routine gaussq.f in netlog.org or acm algorithm 726. + """ + + n = len(d) + e[n-1] = 0 + iterlim = 2 * ctx.dps + + for l in xrange(n): + j = 0 + while 1: + m = l + while 1: + # look for a small subdiagonal element + if m + 1 == n: + break + if abs(e[m]) <= ctx.eps * (abs(d[m]) + abs(d[m + 1])): + break + m = m + 1 + if m == l: + break + + if j >= iterlim: + raise RuntimeError("tridiag_eigen: no convergence to an eigenvalue after %d iterations" % iterlim) + + j += 1 + + # form shift + + p = d[l] + g = (d[l + 1] - p) / (2 * e[l]) + r = ctx.hypot(g, 1) + + if g < 0: + s = g - r + else: + s = g + r + + g = d[m] - p + e[l] / s + + s, c, p = 1, 1, 0 + + for i in xrange(m - 1, l - 1, -1): + f = s * e[i] + b = c * e[i] + if abs(f) > abs(g): # this here is a slight improvement also used in gaussq.f or acm algorithm 726. + c = g / f + r = ctx.hypot(c, 1) + e[i + 1] = f * r + s = 1 / r + c = c * s + else: + s = f / g + r = ctx.hypot(s, 1) + e[i + 1] = g * r + c = 1 / r + s = s * c + g = d[i + 1] - p + r = (d[i] - g) * s + 2 * c * b + p = s * r + d[i + 1] = g + p + g = c * r - b + + if not isinstance(z, bool): + # calculate eigenvectors + for w in xrange(z.rows): + f = z[w,i+1] + z[w,i+1] = s * z[w,i] + c * f + z[w,i ] = c * z[w,i] - s * f + + d[l] = d[l] - p + e[l] = g + e[m] = 0 + + for ii in xrange(1, n): + # sort eigenvalues and eigenvectors (bubble-sort) + i = ii - 1 + k = i + p = d[i] + for j in xrange(ii, n): + if d[j] >= p: + continue + k = j + p = d[k] + if k == i: + continue + d[k] = d[i] + d[i] = p + + if not isinstance(z, bool): + for w in xrange(z.rows): + p = z[w,i] + z[w,i] = z[w,k] + z[w,k] = p + +######################################################################################## + +@defun +def eigsy(ctx, A, eigvals_only = False, overwrite_a = False): + """ + This routine solves the (ordinary) eigenvalue problem for a real symmetric + square matrix A. Given A, an orthogonal matrix Q is calculated which + diagonalizes A: + + Q' A Q = diag(E) and Q Q' = Q' Q = 1 + + Here diag(E) is a diagonal matrix whose diagonal is E. + ' denotes the transpose. + + The columns of Q are the eigenvectors of A and E contains the eigenvalues: + + A Q[:,i] = E[i] Q[:,i] + + + input: + + A: real matrix of format (n,n) which is symmetric + (i.e. A=A' or A[i,j]=A[j,i]) + + eigvals_only: if true, calculates only the eigenvalues E. + if false, calculates both eigenvectors and eigenvalues. + + overwrite_a: if true, allows modification of A which may improve + performance. if false, A is not modified. + + output: + + E: vector of format (n). contains the eigenvalues of A in ascending order. + + Q: orthogonal matrix of format (n,n). contains the eigenvectors + of A as columns. + + return value: + + E if eigvals_only is true + (E, Q) if eigvals_only is false + + example: + >>> from mpmath import mp + >>> A = mp.matrix([[3, 2], [2, 0]]) + >>> E = mp.eigsy(A, eigvals_only = True) + >>> print(E) + [-1.0] + [ 4.0] + + >>> A = mp.matrix([[1, 2], [2, 3]]) + >>> E, Q = mp.eigsy(A) + >>> print(mp.chop(A * Q[:,0] - E[0] * Q[:,0])) + [0.0] + [0.0] + + see also: eighe, eigh, eig + """ + + if not overwrite_a: + A = A.copy() + + d = ctx.zeros(A.rows, 1) + e = ctx.zeros(A.rows, 1) + + if eigvals_only: + r_sy_tridiag(ctx, A, d, e, calc_ev = False) + tridiag_eigen(ctx, d, e, False) + return d + else: + r_sy_tridiag(ctx, A, d, e, calc_ev = True) + tridiag_eigen(ctx, d, e, A) + return (d, A) + + +@defun +def eighe(ctx, A, eigvals_only = False, overwrite_a = False): + """ + This routine solves the (ordinary) eigenvalue problem for a complex + hermitian square matrix A. Given A, an unitary matrix Q is calculated which + diagonalizes A: + + Q' A Q = diag(E) and Q Q' = Q' Q = 1 + + Here diag(E) a is diagonal matrix whose diagonal is E. + ' denotes the hermitian transpose (i.e. ordinary transposition and + complex conjugation). + + The columns of Q are the eigenvectors of A and E contains the eigenvalues: + + A Q[:,i] = E[i] Q[:,i] + + + input: + + A: complex matrix of format (n,n) which is hermitian + (i.e. A=A' or A[i,j]=conj(A[j,i])) + + eigvals_only: if true, calculates only the eigenvalues E. + if false, calculates both eigenvectors and eigenvalues. + + overwrite_a: if true, allows modification of A which may improve + performance. if false, A is not modified. + + output: + + E: vector of format (n). contains the eigenvalues of A in ascending order. + + Q: unitary matrix of format (n,n). contains the eigenvectors + of A as columns. + + return value: + + E if eigvals_only is true + (E, Q) if eigvals_only is false + + example: + >>> from mpmath import mp + >>> A = mp.matrix([[1, -3 - 1j], [-3 + 1j, -2]]) + >>> E = mp.eighe(A, eigvals_only = True) + >>> print(E) + [-4.0] + [ 3.0] + + >>> A = mp.matrix([[1, 2 + 5j], [2 - 5j, 3]]) + >>> E, Q = mp.eighe(A) + >>> print(mp.chop(A * Q[:,0] - E[0] * Q[:,0])) + [0.0] + [0.0] + + see also: eigsy, eigh, eig + """ + + if not overwrite_a: + A = A.copy() + + d = ctx.zeros(A.rows, 1) + e = ctx.zeros(A.rows, 1) + t = ctx.zeros(A.rows, 1) + + if eigvals_only: + c_he_tridiag_0(ctx, A, d, e, t) + tridiag_eigen(ctx, d, e, False) + return d + else: + c_he_tridiag_0(ctx, A, d, e, t) + B = ctx.eye(A.rows) + tridiag_eigen(ctx, d, e, B) + c_he_tridiag_2(ctx, A, t, B) + return (d, B) + +@defun +def eigh(ctx, A, eigvals_only = False, overwrite_a = False): + """ + "eigh" is a unified interface for "eigsy" and "eighe". Depending on + whether A is real or complex the appropriate function is called. + + This routine solves the (ordinary) eigenvalue problem for a real symmetric + or complex hermitian square matrix A. Given A, an orthogonal (A real) or + unitary (A complex) matrix Q is calculated which diagonalizes A: + + Q' A Q = diag(E) and Q Q' = Q' Q = 1 + + Here diag(E) a is diagonal matrix whose diagonal is E. + ' denotes the hermitian transpose (i.e. ordinary transposition and + complex conjugation). + + The columns of Q are the eigenvectors of A and E contains the eigenvalues: + + A Q[:,i] = E[i] Q[:,i] + + input: + + A: a real or complex square matrix of format (n,n) which is symmetric + (i.e. A[i,j]=A[j,i]) or hermitian (i.e. A[i,j]=conj(A[j,i])). + + eigvals_only: if true, calculates only the eigenvalues E. + if false, calculates both eigenvectors and eigenvalues. + + overwrite_a: if true, allows modification of A which may improve + performance. if false, A is not modified. + + output: + + E: vector of format (n). contains the eigenvalues of A in ascending order. + + Q: an orthogonal or unitary matrix of format (n,n). contains the + eigenvectors of A as columns. + + return value: + + E if eigvals_only is true + (E, Q) if eigvals_only is false + + example: + >>> from mpmath import mp + >>> A = mp.matrix([[3, 2], [2, 0]]) + >>> E = mp.eigh(A, eigvals_only = True) + >>> print(E) + [-1.0] + [ 4.0] + + >>> A = mp.matrix([[1, 2], [2, 3]]) + >>> E, Q = mp.eigh(A) + >>> print(mp.chop(A * Q[:,0] - E[0] * Q[:,0])) + [0.0] + [0.0] + + >>> A = mp.matrix([[1, 2 + 5j], [2 - 5j, 3]]) + >>> E, Q = mp.eigh(A) + >>> print(mp.chop(A * Q[:,0] - E[0] * Q[:,0])) + [0.0] + [0.0] + + see also: eigsy, eighe, eig + """ + + iscomplex = any(type(x) is ctx.mpc for x in A) + + if iscomplex: + return ctx.eighe(A, eigvals_only = eigvals_only, overwrite_a = overwrite_a) + else: + return ctx.eigsy(A, eigvals_only = eigvals_only, overwrite_a = overwrite_a) + + +@defun +def gauss_quadrature(ctx, n, qtype = "legendre", alpha = 0, beta = 0): + """ + This routine calulates gaussian quadrature rules for different + families of orthogonal polynomials. Let (a, b) be an interval, + W(x) a positive weight function and n a positive integer. + Then the purpose of this routine is to calculate pairs (x_k, w_k) + for k=0, 1, 2, ... (n-1) which give + + int(W(x) * F(x), x = a..b) = sum(w_k * F(x_k),k = 0..(n-1)) + + exact for all polynomials F(x) of degree (strictly) less than 2*n. For all + integrable functions F(x) the sum is a (more or less) good approximation to + the integral. The x_k are called nodes (which are the zeros of the + related orthogonal polynomials) and the w_k are called the weights. + + parameters + n (input) The degree of the quadrature rule, i.e. its number of + nodes. + + qtype (input) The family of orthogonal polynmomials for which to + compute the quadrature rule. See the list below. + + alpha (input) real number, used as parameter for some orthogonal + polynomials + + beta (input) real number, used as parameter for some orthogonal + polynomials. + + return value + + (X, W) a pair of two real arrays where x_k = X[k] and w_k = W[k]. + + + orthogonal polynomials: + + qtype polynomial + ----- ---------- + + "legendre" Legendre polynomials, W(x)=1 on the interval (-1, +1) + "legendre01" shifted Legendre polynomials, W(x)=1 on the interval (0, +1) + "hermite" Hermite polynomials, W(x)=exp(-x*x) on (-infinity,+infinity) + "laguerre" Laguerre polynomials, W(x)=exp(-x) on (0,+infinity) + "glaguerre" generalized Laguerre polynomials, W(x)=exp(-x)*x**alpha + on (0, +infinity) + "chebyshev1" Chebyshev polynomials of the first kind, W(x)=1/sqrt(1-x*x) + on (-1, +1) + "chebyshev2" Chebyshev polynomials of the second kind, W(x)=sqrt(1-x*x) + on (-1, +1) + "jacobi" Jacobi polynomials, W(x)=(1-x)**alpha * (1+x)**beta on (-1, +1) + with alpha>-1 and beta>-1 + + examples: + >>> from mpmath import mp + >>> f = lambda x: x**8 + 2 * x**6 - 3 * x**4 + 5 * x**2 - 7 + >>> X, W = mp.gauss_quadrature(5, "hermite") + >>> A = mp.fdot([(f(x), w) for x, w in zip(X, W)]) + >>> B = mp.sqrt(mp.pi) * 57 / 16 + >>> C = mp.quad(lambda x: mp.exp(- x * x) * f(x), [-mp.inf, +mp.inf]) + >>> mp.nprint((mp.chop(A-B, tol = 1e-10), mp.chop(A-C, tol = 1e-10))) + (0.0, 0.0) + + >>> f = lambda x: x**5 - 2 * x**4 + 3 * x**3 - 5 * x**2 + 7 * x - 11 + >>> X, W = mp.gauss_quadrature(3, "laguerre") + >>> A = mp.fdot([(f(x), w) for x, w in zip(X, W)]) + >>> B = 76 + >>> C = mp.quad(lambda x: mp.exp(-x) * f(x), [0, +mp.inf]) + >>> mp.nprint(mp.chop(A-B, tol = 1e-10), mp.chop(A-C, tol = 1e-10)) + .0 + + # orthogonality of the chebyshev polynomials: + >>> f = lambda x: mp.chebyt(3, x) * mp.chebyt(2, x) + >>> X, W = mp.gauss_quadrature(3, "chebyshev1") + >>> A = mp.fdot([(f(x), w) for x, w in zip(X, W)]) + >>> print(mp.chop(A, tol = 1e-10)) + 0.0 + + references: + - golub and welsch, "calculations of gaussian quadrature rules", mathematics of + computation 23, p. 221-230 (1969) + - golub, "some modified matrix eigenvalue problems", siam review 15, p. 318-334 (1973) + - stroud and secrest, "gaussian quadrature formulas", prentice-hall (1966) + + See also the routine gaussq.f in netlog.org or ACM Transactions on + Mathematical Software algorithm 726. + """ + + d = ctx.zeros(n, 1) + e = ctx.zeros(n, 1) + z = ctx.zeros(1, n) + + z[0,0] = 1 + + if qtype == "legendre": + # legendre on the range -1 +1 , abramowitz, table 25.4, p.916 + w = 2 + for i in xrange(n): + j = i + 1 + e[i] = ctx.sqrt(j * j / (4 * j * j - ctx.mpf(1))) + elif qtype == "legendre01": + # legendre shifted to 0 1 , abramowitz, table 25.8, p.921 + w = 1 + for i in xrange(n): + d[i] = 1 / ctx.mpf(2) + j = i + 1 + e[i] = ctx.sqrt(j * j / (16 * j * j - ctx.mpf(4))) + elif qtype == "hermite": + # hermite on the range -inf +inf , abramowitz, table 25.10,p.924 + w = ctx.sqrt(ctx.pi) + for i in xrange(n): + j = i + 1 + e[i] = ctx.sqrt(j / ctx.mpf(2)) + elif qtype == "laguerre": + # laguerre on the range 0 +inf , abramowitz, table 25.9, p. 923 + w = 1 + for i in xrange(n): + j = i + 1 + d[i] = 2 * j - 1 + e[i] = j + elif qtype=="chebyshev1": + # chebyshev polynimials of the first kind + w = ctx.pi + for i in xrange(n): + e[i] = 1 / ctx.mpf(2) + e[0] = ctx.sqrt(1 / ctx.mpf(2)) + elif qtype == "chebyshev2": + # chebyshev polynimials of the second kind + w = ctx.pi / 2 + for i in xrange(n): + e[i] = 1 / ctx.mpf(2) + elif qtype == "glaguerre": + # generalized laguerre on the range 0 +inf + w = ctx.gamma(1 + alpha) + for i in xrange(n): + j = i + 1 + d[i] = 2 * j - 1 + alpha + e[i] = ctx.sqrt(j * (j + alpha)) + elif qtype == "jacobi": + # jacobi polynomials + alpha = ctx.mpf(alpha) + beta = ctx.mpf(beta) + ab = alpha + beta + abi = ab + 2 + w = (2**(ab+1)) * ctx.gamma(alpha + 1) * ctx.gamma(beta + 1) / ctx.gamma(abi) + d[0] = (beta - alpha) / abi + e[0] = ctx.sqrt(4 * (1 + alpha) * (1 + beta) / ((abi + 1) * (abi * abi))) + a2b2 = beta * beta - alpha * alpha + for i in xrange(1, n): + j = i + 1 + abi = 2 * j + ab + d[i] = a2b2 / ((abi - 2) * abi) + e[i] = ctx.sqrt(4 * j * (j + alpha) * (j + beta) * (j + ab) / ((abi * abi - 1) * abi * abi)) + elif isinstance(qtype, str): + raise ValueError("unknown quadrature rule \"%s\"" % qtype) + elif not isinstance(qtype, str): + w = qtype(d, e) + else: + assert 0 + + tridiag_eigen(ctx, d, e, z) + + for i in xrange(len(z)): + z[i] *= z[i] + + z = z.transpose() + return (d, w * z) + +################################################################################################## +################################################################################################## +################################################################################################## + +def svd_r_raw(ctx, A, V = False, calc_u = False): + """ + This routine computes the singular value decomposition of a matrix A. + Given A, two orthogonal matrices U and V are calculated such that + + A = U S V + + where S is a suitable shaped matrix whose off-diagonal elements are zero. + The diagonal elements of S are the singular values of A, i.e. the + squareroots of the eigenvalues of A' A or A A'. Here ' denotes the transpose. + Householder bidiagonalization and a variant of the QR algorithm is used. + + overview of the matrices : + + A : m*n A gets replaced by U + U : m*n U replaces A. If n>m then only the first m*m block of U is + non-zero. column-orthogonal: U' U = B + here B is a n*n matrix whose first min(m,n) diagonal + elements are 1 and all other elements are zero. + S : n*n diagonal matrix, only the diagonal elements are stored in + the array S. only the first min(m,n) diagonal elements are non-zero. + V : n*n orthogonal: V V' = V' V = 1 + + parameters: + A (input/output) On input, A contains a real matrix of shape m*n. + On output, if calc_u is true A contains the column-orthogonal + matrix U; otherwise A is simply used as workspace and thus destroyed. + + V (input/output) if false, the matrix V is not calculated. otherwise + V must be a matrix of shape n*n. + + calc_u (input) If true, the matrix U is calculated and replaces A. + if false, U is not calculated and A is simply destroyed + + return value: + S an array of length n containing the singular values of A sorted by + decreasing magnitude. only the first min(m,n) elements are non-zero. + + This routine is a python translation of the fortran routine svd.f in the + software library EISPACK (see netlib.org) which itself is based on the + algol procedure svd described in: + - num. math. 14, 403-420(1970) by golub and reinsch. + - wilkinson/reinsch: handbook for auto. comp., vol ii-linear algebra, 134-151(1971). + + """ + + m, n = A.rows, A.cols + + S = ctx.zeros(n, 1) + + # work is a temporary array of size n + work = ctx.zeros(n, 1) + + g = scale = anorm = 0 + maxits = 3 * ctx.dps + + for i in xrange(n): # householder reduction to bidiagonal form + work[i] = scale*g + g = s = scale = 0 + if i < m: + for k in xrange(i, m): + scale += ctx.fabs(A[k,i]) + if scale != 0: + for k in xrange(i, m): + A[k,i] /= scale + s += A[k,i] * A[k,i] + f = A[i,i] + g = -ctx.sqrt(s) + if f < 0: + g = -g + h = f * g - s + A[i,i] = f - g + for j in xrange(i+1, n): + s = 0 + for k in xrange(i, m): + s += A[k,i] * A[k,j] + f = s / h + for k in xrange(i, m): + A[k,j] += f * A[k,i] + for k in xrange(i,m): + A[k,i] *= scale + + S[i] = scale * g + g = s = scale = 0 + + if i < m and i != n - 1: + for k in xrange(i+1, n): + scale += ctx.fabs(A[i,k]) + if scale: + for k in xrange(i+1, n): + A[i,k] /= scale + s += A[i,k] * A[i,k] + f = A[i,i+1] + g = -ctx.sqrt(s) + if f < 0: + g = -g + h = f * g - s + A[i,i+1] = f - g + + for k in xrange(i+1, n): + work[k] = A[i,k] / h + + for j in xrange(i+1, m): + s = 0 + for k in xrange(i+1, n): + s += A[j,k] * A[i,k] + for k in xrange(i+1, n): + A[j,k] += s * work[k] + + for k in xrange(i+1, n): + A[i,k] *= scale + + anorm = max(anorm, ctx.fabs(S[i]) + ctx.fabs(work[i])) + + if not isinstance(V, bool): + for i in xrange(n-2, -1, -1): # accumulation of right hand transformations + V[i+1,i+1] = 1 + + if work[i+1] != 0: + for j in xrange(i+1, n): + V[i,j] = (A[i,j] / A[i,i+1]) / work[i+1] + for j in xrange(i+1, n): + s = 0 + for k in xrange(i+1, n): + s += A[i,k] * V[j,k] + for k in xrange(i+1, n): + V[j,k] += s * V[i,k] + + for j in xrange(i+1, n): + V[j,i] = V[i,j] = 0 + + V[0,0] = 1 + + if m= maxits: + raise RuntimeError("svd: no convergence to an eigenvalue after %d iterations" % its) + + x = S[l] # shift from bottom 2 by 2 minor + nm = k-1 + y = S[nm] + g = work[nm] + h = work[k] + f = ((y - z) * (y + z) + (g - h) * (g + h))/(2 * h * y) + g = ctx.hypot(f, 1) + if f >= 0: f = ((x - z) * (x + z) + h * ((y / (f + g)) - h)) / x + else: f = ((x - z) * (x + z) + h * ((y / (f - g)) - h)) / x + + c = s = 1 # next qt transformation + + for j in xrange(l, nm + 1): + g = work[j+1] + y = S[j+1] + h = s * g + g = c * g + z = ctx.hypot(f, h) + work[j] = z + c = f / z + s = h / z + f = x * c + g * s + g = g * c - x * s + h = y * s + y *= c + if not isinstance(V, bool): + for jj in xrange(n): + x = V[j ,jj] + z = V[j+1,jj] + V[j ,jj]= x * c + z * s + V[j+1 ,jj]= z * c - x * s + z = ctx.hypot(f, h) + S[j] = z + if z != 0: # rotation can be arbitray if z=0 + z = 1 / z + c = f * z + s = h * z + f = c * g + s * y + x = c * y - s * g + + if calc_u: + for jj in xrange(m): + y = A[jj,j ] + z = A[jj,j+1] + A[jj,j ] = y * c + z * s + A[jj,j+1 ] = z * c - y * s + + work[l] = 0 + work[k] = f + S[k] = x + + ########################## + + # Sort singular values into decreasing order (bubble-sort) + + for i in xrange(n): + imax = i + s = ctx.fabs(S[i]) # s is the current maximal element + + for j in xrange(i + 1, n): + c = ctx.fabs(S[j]) + if c > s: + s = c + imax = j + + if imax != i: + # swap singular values + + z = S[i] + S[i] = S[imax] + S[imax] = z + + if calc_u: + for j in xrange(m): + z = A[j,i] + A[j,i] = A[j,imax] + A[j,imax] = z + + if not isinstance(V, bool): + for j in xrange(n): + z = V[i,j] + V[i,j] = V[imax,j] + V[imax,j] = z + + return S + +####################### + +def svd_c_raw(ctx, A, V = False, calc_u = False): + """ + This routine computes the singular value decomposition of a matrix A. + Given A, two unitary matrices U and V are calculated such that + + A = U S V + + where S is a suitable shaped matrix whose off-diagonal elements are zero. + The diagonal elements of S are the singular values of A, i.e. the + squareroots of the eigenvalues of A' A or A A'. Here ' denotes the hermitian + transpose (i.e. transposition and conjugation). Householder bidiagonalization + and a variant of the QR algorithm is used. + + overview of the matrices : + + A : m*n A gets replaced by U + U : m*n U replaces A. If n>m then only the first m*m block of U is + non-zero. column-unitary: U' U = B + here B is a n*n matrix whose first min(m,n) diagonal + elements are 1 and all other elements are zero. + S : n*n diagonal matrix, only the diagonal elements are stored in + the array S. only the first min(m,n) diagonal elements are non-zero. + V : n*n unitary: V V' = V' V = 1 + + parameters: + A (input/output) On input, A contains a complex matrix of shape m*n. + On output, if calc_u is true A contains the column-unitary + matrix U; otherwise A is simply used as workspace and thus destroyed. + + V (input/output) if false, the matrix V is not calculated. otherwise + V must be a matrix of shape n*n. + + calc_u (input) If true, the matrix U is calculated and replaces A. + if false, U is not calculated and A is simply destroyed + + return value: + S an array of length n containing the singular values of A sorted by + decreasing magnitude. only the first min(m,n) elements are non-zero. + + This routine is a python translation of the fortran routine svd.f in the + software library EISPACK (see netlib.org) which itself is based on the + algol procedure svd described in: + - num. math. 14, 403-420(1970) by golub and reinsch. + - wilkinson/reinsch: handbook for auto. comp., vol ii-linear algebra, 134-151(1971). + + """ + + m, n = A.rows, A.cols + + S = ctx.zeros(n, 1) + + # work is a temporary array of size n + work = ctx.zeros(n, 1) + lbeta = ctx.zeros(n, 1) + rbeta = ctx.zeros(n, 1) + dwork = ctx.zeros(n, 1) + + g = scale = anorm = 0 + maxits = 3 * ctx.dps + + for i in xrange(n): # householder reduction to bidiagonal form + dwork[i] = scale * g # dwork are the side-diagonal elements + g = s = scale = 0 + if i < m: + for k in xrange(i, m): + scale += ctx.fabs(ctx.re(A[k,i])) + ctx.fabs(ctx.im(A[k,i])) + if scale != 0: + for k in xrange(i, m): + A[k,i] /= scale + ar = ctx.re(A[k,i]) + ai = ctx.im(A[k,i]) + s += ar * ar + ai * ai + f = A[i,i] + g = -ctx.sqrt(s) + if ctx.re(f) < 0: + beta = -g - ctx.conj(f) + g = -g + else: + beta = -g + ctx.conj(f) + beta /= ctx.conj(beta) + beta += 1 + h = 2 * (ctx.re(f) * g - s) + A[i,i] = f - g + beta /= h + lbeta[i] = (beta / scale) / scale + for j in xrange(i+1, n): + s = 0 + for k in xrange(i, m): + s += ctx.conj(A[k,i]) * A[k,j] + f = beta * s + for k in xrange(i, m): + A[k,j] += f * A[k,i] + for k in xrange(i, m): + A[k,i] *= scale + + S[i] = scale * g # S are the diagonal elements + g = s = scale = 0 + + if i < m and i != n - 1: + for k in xrange(i+1, n): + scale += ctx.fabs(ctx.re(A[i,k])) + ctx.fabs(ctx.im(A[i,k])) + if scale: + for k in xrange(i+1, n): + A[i,k] /= scale + ar = ctx.re(A[i,k]) + ai = ctx.im(A[i,k]) + s += ar * ar + ai * ai + f = A[i,i+1] + g = -ctx.sqrt(s) + if ctx.re(f) < 0: + beta = -g - ctx.conj(f) + g = -g + else: + beta = -g + ctx.conj(f) + + beta /= ctx.conj(beta) + beta += 1 + + h = 2 * (ctx.re(f) * g - s) + A[i,i+1] = f - g + + beta /= h + rbeta[i] = (beta / scale) / scale + + for k in xrange(i+1, n): + work[k] = A[i, k] + + for j in xrange(i+1, m): + s = 0 + for k in xrange(i+1, n): + s += ctx.conj(A[i,k]) * A[j,k] + f = s * beta + for k in xrange(i+1,n): + A[j,k] += f * work[k] + + for k in xrange(i+1, n): + A[i,k] *= scale + + anorm = max(anorm,ctx.fabs(S[i]) + ctx.fabs(dwork[i])) + + if not isinstance(V, bool): + for i in xrange(n-2, -1, -1): # accumulation of right hand transformations + V[i+1,i+1] = 1 + + if dwork[i+1] != 0: + f = ctx.conj(rbeta[i]) + for j in xrange(i+1, n): + V[i,j] = A[i,j] * f + for j in xrange(i+1, n): + s = 0 + for k in xrange(i+1, n): + s += ctx.conj(A[i,k]) * V[j,k] + for k in xrange(i+1, n): + V[j,k] += s * V[i,k] + + for j in xrange(i+1,n): + V[j,i] = V[i,j] = 0 + + V[0,0] = 1 + + if m < n : minnm = m + else : minnm = n + + if calc_u: + for i in xrange(minnm-1, -1, -1): # accumulation of left hand transformations + g = S[i] + for j in xrange(i+1, n): + A[i,j] = 0 + if g != 0: + g = 1 / g + for j in xrange(i+1, n): + s = 0 + for k in xrange(i+1, m): + s += ctx.conj(A[k,i]) * A[k,j] + f = s * ctx.conj(lbeta[i]) + for k in xrange(i, m): + A[k,j] += f * A[k,i] + for j in xrange(i, m): + A[j,i] *= g + else: + for j in xrange(i, m): + A[j,i] = 0 + A[i,i] += 1 + + for k in xrange(n-1, -1, -1): + # diagonalization of the bidiagonal form: + # loop over singular values, and over allowed itations + + its = 0 + while 1: + its += 1 + flag = True + + for l in xrange(k, -1, -1): + nm = l - 1 + + if ctx.fabs(dwork[l]) + anorm == anorm: + flag = False + break + + if ctx.fabs(S[nm]) + anorm == anorm: + break + + if flag: + c = 0 + s = 1 + for i in xrange(l, k+1): + f = s * dwork[i] + dwork[i] *= c + if ctx.fabs(f) + anorm == anorm: + break + g = S[i] + h = ctx.hypot(f, g) + S[i] = h + h = 1 / h + c = g * h + s = -f * h + + if calc_u: + for j in xrange(m): + y = A[j,nm] + z = A[j,i] + A[j,nm]= y * c + z * s + A[j,i] = z * c - y * s + + z = S[k] + + if l == k: # convergence + if z < 0: # singular value is made nonnegative + S[k] = -z + if not isinstance(V, bool): + for j in xrange(n): + V[k,j] = -V[k,j] + break + + if its >= maxits: + raise RuntimeError("svd: no convergence to an eigenvalue after %d iterations" % its) + + x = S[l] # shift from bottom 2 by 2 minor + nm = k-1 + y = S[nm] + g = dwork[nm] + h = dwork[k] + f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2 * h * y) + g = ctx.hypot(f, 1) + if f >=0: f = (( x - z) *( x + z) + h *((y / (f + g)) - h)) / x + else: f = (( x - z) *( x + z) + h *((y / (f - g)) - h)) / x + + c = s = 1 # next qt transformation + + for j in xrange(l, nm + 1): + g = dwork[j+1] + y = S[j+1] + h = s * g + g = c * g + z = ctx.hypot(f, h) + dwork[j] = z + c = f / z + s = h / z + f = x * c + g * s + g = g * c - x * s + h = y * s + y *= c + if not isinstance(V, bool): + for jj in xrange(n): + x = V[j ,jj] + z = V[j+1,jj] + V[j ,jj]= x * c + z * s + V[j+1,jj ]= z * c - x * s + z = ctx.hypot(f, h) + S[j] = z + if z != 0: # rotation can be arbitray if z=0 + z = 1 / z + c = f * z + s = h * z + f = c * g + s * y + x = c * y - s * g + if calc_u: + for jj in xrange(m): + y = A[jj,j ] + z = A[jj,j+1] + A[jj,j ]= y * c + z * s + A[jj,j+1 ]= z * c - y * s + + dwork[l] = 0 + dwork[k] = f + S[k] = x + + ########################## + + # Sort singular values into decreasing order (bubble-sort) + + for i in xrange(n): + imax = i + s = ctx.fabs(S[i]) # s is the current maximal element + + for j in xrange(i + 1, n): + c = ctx.fabs(S[j]) + if c > s: + s = c + imax = j + + if imax != i: + # swap singular values + + z = S[i] + S[i] = S[imax] + S[imax] = z + + if calc_u: + for j in xrange(m): + z = A[j,i] + A[j,i] = A[j,imax] + A[j,imax] = z + + if not isinstance(V, bool): + for j in xrange(n): + z = V[i,j] + V[i,j] = V[imax,j] + V[imax,j] = z + + return S + +################################################################################################## + +@defun +def svd_r(ctx, A, full_matrices = False, compute_uv = True, overwrite_a = False): + """ + This routine computes the singular value decomposition of a matrix A. + Given A, two orthogonal matrices U and V are calculated such that + + A = U S V and U' U = 1 and V V' = 1 + + where S is a suitable shaped matrix whose off-diagonal elements are zero. + Here ' denotes the transpose. The diagonal elements of S are the singular + values of A, i.e. the squareroots of the eigenvalues of A' A or A A'. + + input: + A : a real matrix of shape (m, n) + full_matrices : if true, U and V are of shape (m, m) and (n, n). + if false, U and V are of shape (m, min(m, n)) and (min(m, n), n). + compute_uv : if true, U and V are calculated. if false, only S is calculated. + overwrite_a : if true, allows modification of A which may improve + performance. if false, A is not modified. + + output: + U : an orthogonal matrix: U' U = 1. if full_matrices is true, U is of + shape (m, m). ortherwise it is of shape (m, min(m, n)). + + S : an array of length min(m, n) containing the singular values of A sorted by + decreasing magnitude. + + V : an orthogonal matrix: V V' = 1. if full_matrices is true, V is of + shape (n, n). ortherwise it is of shape (min(m, n), n). + + return value: + + S if compute_uv is false + (U, S, V) if compute_uv is true + + overview of the matrices: + + full_matrices true: + A : m*n + U : m*m U' U = 1 + S as matrix : m*n + V : n*n V V' = 1 + + full_matrices false: + A : m*n + U : m*min(n,m) U' U = 1 + S as matrix : min(m,n)*min(m,n) + V : min(m,n)*n V V' = 1 + + examples: + + >>> from mpmath import mp + >>> A = mp.matrix([[2, -2, -1], [3, 4, -2], [-2, -2, 0]]) + >>> S = mp.svd_r(A, compute_uv = False) + >>> print(S) + [6.0] + [3.0] + [1.0] + + >>> U, S, V = mp.svd_r(A) + >>> print(mp.chop(A - U * mp.diag(S) * V)) + [0.0 0.0 0.0] + [0.0 0.0 0.0] + [0.0 0.0 0.0] + + + see also: svd, svd_c + """ + + m, n = A.rows, A.cols + + if not compute_uv: + if not overwrite_a: + A = A.copy() + S = svd_r_raw(ctx, A, V = False, calc_u = False) + S = S[:min(m,n)] + return S + + if full_matrices and n < m: + V = ctx.zeros(m, m) + A0 = ctx.zeros(m, m) + A0[:,:n] = A + S = svd_r_raw(ctx, A0, V, calc_u = True) + + S = S[:n] + V = V[:n,:n] + + return (A0, S, V) + else: + if not overwrite_a: + A = A.copy() + V = ctx.zeros(n, n) + S = svd_r_raw(ctx, A, V, calc_u = True) + + if n > m: + if full_matrices == False: + V = V[:m,:] + + S = S[:m] + A = A[:,:m] + + return (A, S, V) + +############################## + +@defun +def svd_c(ctx, A, full_matrices = False, compute_uv = True, overwrite_a = False): + """ + This routine computes the singular value decomposition of a matrix A. + Given A, two unitary matrices U and V are calculated such that + + A = U S V and U' U = 1 and V V' = 1 + + where S is a suitable shaped matrix whose off-diagonal elements are zero. + Here ' denotes the hermitian transpose (i.e. transposition and complex + conjugation). The diagonal elements of S are the singular values of A, + i.e. the squareroots of the eigenvalues of A' A or A A'. + + input: + A : a complex matrix of shape (m, n) + full_matrices : if true, U and V are of shape (m, m) and (n, n). + if false, U and V are of shape (m, min(m, n)) and (min(m, n), n). + compute_uv : if true, U and V are calculated. if false, only S is calculated. + overwrite_a : if true, allows modification of A which may improve + performance. if false, A is not modified. + + output: + U : an unitary matrix: U' U = 1. if full_matrices is true, U is of + shape (m, m). ortherwise it is of shape (m, min(m, n)). + + S : an array of length min(m, n) containing the singular values of A sorted by + decreasing magnitude. + + V : an unitary matrix: V V' = 1. if full_matrices is true, V is of + shape (n, n). ortherwise it is of shape (min(m, n), n). + + return value: + + S if compute_uv is false + (U, S, V) if compute_uv is true + + overview of the matrices: + + full_matrices true: + A : m*n + U : m*m U' U = 1 + S as matrix : m*n + V : n*n V V' = 1 + + full_matrices false: + A : m*n + U : m*min(n,m) U' U = 1 + S as matrix : min(m,n)*min(m,n) + V : min(m,n)*n V V' = 1 + + example: + >>> from mpmath import mp + >>> A = mp.matrix([[-2j, -1-3j, -2+2j], [2-2j, -1-3j, 1], [-3+1j,-2j,0]]) + >>> S = mp.svd_c(A, compute_uv = False) + >>> print(mp.chop(S - mp.matrix([mp.sqrt(34), mp.sqrt(15), mp.sqrt(6)]))) + [0.0] + [0.0] + [0.0] + + >>> U, S, V = mp.svd_c(A) + >>> print(mp.chop(A - U * mp.diag(S) * V)) + [0.0 0.0 0.0] + [0.0 0.0 0.0] + [0.0 0.0 0.0] + + see also: svd, svd_r + """ + + m, n = A.rows, A.cols + + if not compute_uv: + if not overwrite_a: + A = A.copy() + S = svd_c_raw(ctx, A, V = False, calc_u = False) + S = S[:min(m,n)] + return S + + if full_matrices and n < m: + V = ctx.zeros(m, m) + A0 = ctx.zeros(m, m) + A0[:,:n] = A + S = svd_c_raw(ctx, A0, V, calc_u = True) + + S = S[:n] + V = V[:n,:n] + + return (A0, S, V) + else: + if not overwrite_a: + A = A.copy() + V = ctx.zeros(n, n) + S = svd_c_raw(ctx, A, V, calc_u = True) + + if n > m: + if full_matrices == False: + V = V[:m,:] + + S = S[:m] + A = A[:,:m] + + return (A, S, V) + +@defun +def svd(ctx, A, full_matrices = False, compute_uv = True, overwrite_a = False): + """ + "svd" is a unified interface for "svd_r" and "svd_c". Depending on + whether A is real or complex the appropriate function is called. + + This routine computes the singular value decomposition of a matrix A. + Given A, two orthogonal (A real) or unitary (A complex) matrices U and V + are calculated such that + + A = U S V and U' U = 1 and V V' = 1 + + where S is a suitable shaped matrix whose off-diagonal elements are zero. + Here ' denotes the hermitian transpose (i.e. transposition and complex + conjugation). The diagonal elements of S are the singular values of A, + i.e. the squareroots of the eigenvalues of A' A or A A'. + + input: + A : a real or complex matrix of shape (m, n) + full_matrices : if true, U and V are of shape (m, m) and (n, n). + if false, U and V are of shape (m, min(m, n)) and (min(m, n), n). + compute_uv : if true, U and V are calculated. if false, only S is calculated. + overwrite_a : if true, allows modification of A which may improve + performance. if false, A is not modified. + + output: + U : an orthogonal or unitary matrix: U' U = 1. if full_matrices is true, U is of + shape (m, m). ortherwise it is of shape (m, min(m, n)). + + S : an array of length min(m, n) containing the singular values of A sorted by + decreasing magnitude. + + V : an orthogonal or unitary matrix: V V' = 1. if full_matrices is true, V is of + shape (n, n). ortherwise it is of shape (min(m, n), n). + + return value: + + S if compute_uv is false + (U, S, V) if compute_uv is true + + overview of the matrices: + + full_matrices true: + A : m*n + U : m*m U' U = 1 + S as matrix : m*n + V : n*n V V' = 1 + + full_matrices false: + A : m*n + U : m*min(n,m) U' U = 1 + S as matrix : min(m,n)*min(m,n) + V : min(m,n)*n V V' = 1 + + examples: + + >>> from mpmath import mp + >>> A = mp.matrix([[2, -2, -1], [3, 4, -2], [-2, -2, 0]]) + >>> S = mp.svd(A, compute_uv = False) + >>> print(S) + [6.0] + [3.0] + [1.0] + + >>> U, S, V = mp.svd(A) + >>> print(mp.chop(A - U * mp.diag(S) * V)) + [0.0 0.0 0.0] + [0.0 0.0 0.0] + [0.0 0.0 0.0] + + see also: svd_r, svd_c + """ + + iscomplex = any(type(x) is ctx.mpc for x in A) + + if iscomplex: + return ctx.svd_c(A, full_matrices = full_matrices, compute_uv = compute_uv, overwrite_a = overwrite_a) + else: + return ctx.svd_r(A, full_matrices = full_matrices, compute_uv = compute_uv, overwrite_a = overwrite_a) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/linalg.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/linalg.py new file mode 100644 index 0000000000000000000000000000000000000000..e2fe643e809822e3d05a52b73c965edb622f9af9 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/linalg.py @@ -0,0 +1,790 @@ +""" +Linear algebra +-------------- + +Linear equations +................ + +Basic linear algebra is implemented; you can for example solve the linear +equation system:: + + x + 2*y = -10 + 3*x + 4*y = 10 + +using ``lu_solve``:: + + >>> from mpmath import * + >>> mp.pretty = False + >>> A = matrix([[1, 2], [3, 4]]) + >>> b = matrix([-10, 10]) + >>> x = lu_solve(A, b) + >>> x + matrix( + [['30.0'], + ['-20.0']]) + +If you don't trust the result, use ``residual`` to calculate the residual ||A*x-b||:: + + >>> residual(A, x, b) + matrix( + [['3.46944695195361e-18'], + ['3.46944695195361e-18']]) + >>> str(eps) + '2.22044604925031e-16' + +As you can see, the solution is quite accurate. The error is caused by the +inaccuracy of the internal floating point arithmetic. Though, it's even smaller +than the current machine epsilon, which basically means you can trust the +result. + +If you need more speed, use NumPy, or ``fp.lu_solve`` for a floating-point computation. + + >>> fp.lu_solve(A, b) # doctest: +ELLIPSIS + matrix(...) + +``lu_solve`` accepts overdetermined systems. It is usually not possible to solve +such systems, so the residual is minimized instead. Internally this is done +using Cholesky decomposition to compute a least squares approximation. This means +that that ``lu_solve`` will square the errors. If you can't afford this, use +``qr_solve`` instead. It is twice as slow but more accurate, and it calculates +the residual automatically. + + +Matrix factorization +.................... + +The function ``lu`` computes an explicit LU factorization of a matrix:: + + >>> P, L, U = lu(matrix([[0,2,3],[4,5,6],[7,8,9]])) + >>> print(P) + [0.0 0.0 1.0] + [1.0 0.0 0.0] + [0.0 1.0 0.0] + >>> print(L) + [ 1.0 0.0 0.0] + [ 0.0 1.0 0.0] + [0.571428571428571 0.214285714285714 1.0] + >>> print(U) + [7.0 8.0 9.0] + [0.0 2.0 3.0] + [0.0 0.0 0.214285714285714] + >>> print(P.T*L*U) + [0.0 2.0 3.0] + [4.0 5.0 6.0] + [7.0 8.0 9.0] + +Interval matrices +----------------- + +Matrices may contain interval elements. This allows one to perform +basic linear algebra operations such as matrix multiplication +and equation solving with rigorous error bounds:: + + >>> a = iv.matrix([['0.1','0.3','1.0'], + ... ['7.1','5.5','4.8'], + ... ['3.2','4.4','5.6']]) + >>> + >>> b = iv.matrix(['4','0.6','0.5']) + >>> c = iv.lu_solve(a, b) + >>> print(c) + [ [5.2582327113062568605927528666, 5.25823271130625686059275702219]] + [[-13.1550493962678375411635581388, -13.1550493962678375411635540152]] + [ [7.42069154774972557628979076189, 7.42069154774972557628979190734]] + >>> print(a*c) + [ [3.99999999999999999999999844904, 4.00000000000000000000000155096]] + [[0.599999999999999999999968898009, 0.600000000000000000000031763736]] + [[0.499999999999999999999979320485, 0.500000000000000000000020679515]] +""" + +# TODO: +# *implement high-level qr() +# *test unitvector +# *iterative solving + +from copy import copy + +from ..libmp.backend import xrange + +class LinearAlgebraMethods(object): + + def LU_decomp(ctx, A, overwrite=False, use_cache=True): + """ + LU-factorization of a n*n matrix using the Gauss algorithm. + Returns L and U in one matrix and the pivot indices. + + Use overwrite to specify whether A will be overwritten with L and U. + """ + if not A.rows == A.cols: + raise ValueError('need n*n matrix') + # get from cache if possible + if use_cache and isinstance(A, ctx.matrix) and A._LU: + return A._LU + if not overwrite: + orig = A + A = A.copy() + tol = ctx.absmin(ctx.mnorm(A,1) * ctx.eps) # each pivot element has to be bigger + n = A.rows + p = [None]*(n - 1) + for j in xrange(n - 1): + # pivoting, choose max(abs(reciprocal row sum)*abs(pivot element)) + biggest = 0 + for k in xrange(j, n): + s = ctx.fsum([ctx.absmin(A[k,l]) for l in xrange(j, n)]) + if ctx.absmin(s) <= tol: + raise ZeroDivisionError('matrix is numerically singular') + current = 1/s * ctx.absmin(A[k,j]) + if current > biggest: # TODO: what if equal? + biggest = current + p[j] = k + # swap rows according to p + ctx.swap_row(A, j, p[j]) + if ctx.absmin(A[j,j]) <= tol: + raise ZeroDivisionError('matrix is numerically singular') + # calculate elimination factors and add rows + for i in xrange(j + 1, n): + A[i,j] /= A[j,j] + for k in xrange(j + 1, n): + A[i,k] -= A[i,j]*A[j,k] + if ctx.absmin(A[n - 1,n - 1]) <= tol: + raise ZeroDivisionError('matrix is numerically singular') + # cache decomposition + if not overwrite and isinstance(orig, ctx.matrix): + orig._LU = (A, p) + return A, p + + def L_solve(ctx, L, b, p=None): + """ + Solve the lower part of a LU factorized matrix for y. + """ + if L.rows != L.cols: + raise RuntimeError("need n*n matrix") + n = L.rows + if len(b) != n: + raise ValueError("Value should be equal to n") + b = copy(b) + if p: # swap b according to p + for k in xrange(0, len(p)): + ctx.swap_row(b, k, p[k]) + # solve + for i in xrange(1, n): + for j in xrange(i): + b[i] -= L[i,j] * b[j] + return b + + def U_solve(ctx, U, y): + """ + Solve the upper part of a LU factorized matrix for x. + """ + if U.rows != U.cols: + raise RuntimeError("need n*n matrix") + n = U.rows + if len(y) != n: + raise ValueError("Value should be equal to n") + x = copy(y) + for i in xrange(n - 1, -1, -1): + for j in xrange(i + 1, n): + x[i] -= U[i,j] * x[j] + x[i] /= U[i,i] + return x + + def lu_solve(ctx, A, b, **kwargs): + """ + Ax = b => x + + Solve a determined or overdetermined linear equations system. + Fast LU decomposition is used, which is less accurate than QR decomposition + (especially for overdetermined systems), but it's twice as efficient. + Use qr_solve if you want more precision or have to solve a very ill- + conditioned system. + + If you specify real=True, it does not check for overdeterminded complex + systems. + """ + prec = ctx.prec + try: + ctx.prec += 10 + # do not overwrite A nor b + A, b = ctx.matrix(A, **kwargs).copy(), ctx.matrix(b, **kwargs).copy() + if A.rows < A.cols: + raise ValueError('cannot solve underdetermined system') + if A.rows > A.cols: + # use least-squares method if overdetermined + # (this increases errors) + AH = A.H + A = AH * A + b = AH * b + if (kwargs.get('real', False) or + not sum(type(i) is ctx.mpc for i in A)): + # TODO: necessary to check also b? + x = ctx.cholesky_solve(A, b) + else: + x = ctx.lu_solve(A, b) + else: + # LU factorization + A, p = ctx.LU_decomp(A) + b = ctx.L_solve(A, b, p) + x = ctx.U_solve(A, b) + finally: + ctx.prec = prec + return x + + def improve_solution(ctx, A, x, b, maxsteps=1): + """ + Improve a solution to a linear equation system iteratively. + + This re-uses the LU decomposition and is thus cheap. + Usually 3 up to 4 iterations are giving the maximal improvement. + """ + if A.rows != A.cols: + raise RuntimeError("need n*n matrix") # TODO: really? + for _ in xrange(maxsteps): + r = ctx.residual(A, x, b) + if ctx.norm(r, 2) < 10*ctx.eps: + break + # this uses cached LU decomposition and is thus cheap + dx = ctx.lu_solve(A, -r) + x += dx + return x + + def lu(ctx, A): + """ + A -> P, L, U + + LU factorisation of a square matrix A. L is the lower, U the upper part. + P is the permutation matrix indicating the row swaps. + + P*A = L*U + + If you need efficiency, use the low-level method LU_decomp instead, it's + much more memory efficient. + """ + # get factorization + A, p = ctx.LU_decomp(A) + n = A.rows + L = ctx.matrix(n) + U = ctx.matrix(n) + for i in xrange(n): + for j in xrange(n): + if i > j: + L[i,j] = A[i,j] + elif i == j: + L[i,j] = 1 + U[i,j] = A[i,j] + else: + U[i,j] = A[i,j] + # calculate permutation matrix + P = ctx.eye(n) + for k in xrange(len(p)): + ctx.swap_row(P, k, p[k]) + return P, L, U + + def unitvector(ctx, n, i): + """ + Return the i-th n-dimensional unit vector. + """ + assert 0 < i <= n, 'this unit vector does not exist' + return [ctx.zero]*(i-1) + [ctx.one] + [ctx.zero]*(n-i) + + def inverse(ctx, A, **kwargs): + """ + Calculate the inverse of a matrix. + + If you want to solve an equation system Ax = b, it's recommended to use + solve(A, b) instead, it's about 3 times more efficient. + """ + prec = ctx.prec + try: + ctx.prec += 10 + # do not overwrite A + A = ctx.matrix(A, **kwargs).copy() + n = A.rows + # get LU factorisation + A, p = ctx.LU_decomp(A) + cols = [] + # calculate unit vectors and solve corresponding system to get columns + for i in xrange(1, n + 1): + e = ctx.unitvector(n, i) + y = ctx.L_solve(A, e, p) + cols.append(ctx.U_solve(A, y)) + # convert columns to matrix + inv = [] + for i in xrange(n): + row = [] + for j in xrange(n): + row.append(cols[j][i]) + inv.append(row) + result = ctx.matrix(inv, **kwargs) + finally: + ctx.prec = prec + return result + + def householder(ctx, A): + """ + (A|b) -> H, p, x, res + + (A|b) is the coefficient matrix with left hand side of an optionally + overdetermined linear equation system. + H and p contain all information about the transformation matrices. + x is the solution, res the residual. + """ + if not isinstance(A, ctx.matrix): + raise TypeError("A should be a type of ctx.matrix") + m = A.rows + n = A.cols + if m < n - 1: + raise RuntimeError("Columns should not be less than rows") + # calculate Householder matrix + p = [] + for j in xrange(0, n - 1): + s = ctx.fsum(abs(A[i,j])**2 for i in xrange(j, m)) + if not abs(s) > ctx.eps: + raise ValueError('matrix is numerically singular') + p.append(-ctx.sign(ctx.re(A[j,j])) * ctx.sqrt(s)) + kappa = ctx.one / (s - p[j] * A[j,j]) + A[j,j] -= p[j] + for k in xrange(j+1, n): + y = ctx.fsum(ctx.conj(A[i,j]) * A[i,k] for i in xrange(j, m)) * kappa + for i in xrange(j, m): + A[i,k] -= A[i,j] * y + # solve Rx = c1 + x = [A[i,n - 1] for i in xrange(n - 1)] + for i in xrange(n - 2, -1, -1): + x[i] -= ctx.fsum(A[i,j] * x[j] for j in xrange(i + 1, n - 1)) + x[i] /= p[i] + # calculate residual + if not m == n - 1: + r = [A[m-1-i, n-1] for i in xrange(m - n + 1)] + else: + # determined system, residual should be 0 + r = [0]*m # maybe a bad idea, changing r[i] will change all elements + return A, p, x, r + + #def qr(ctx, A): + # """ + # A -> Q, R + # + # QR factorisation of a square matrix A using Householder decomposition. + # Q is orthogonal, this leads to very few numerical errors. + # + # A = Q*R + # """ + # H, p, x, res = householder(A) + # TODO: implement this + + def residual(ctx, A, x, b, **kwargs): + """ + Calculate the residual of a solution to a linear equation system. + + r = A*x - b for A*x = b + """ + oldprec = ctx.prec + try: + ctx.prec *= 2 + A, x, b = ctx.matrix(A, **kwargs), ctx.matrix(x, **kwargs), ctx.matrix(b, **kwargs) + return A*x - b + finally: + ctx.prec = oldprec + + def qr_solve(ctx, A, b, norm=None, **kwargs): + """ + Ax = b => x, ||Ax - b|| + + Solve a determined or overdetermined linear equations system and + calculate the norm of the residual (error). + QR decomposition using Householder factorization is applied, which gives very + accurate results even for ill-conditioned matrices. qr_solve is twice as + efficient. + """ + if norm is None: + norm = ctx.norm + prec = ctx.prec + try: + ctx.prec += 10 + # do not overwrite A nor b + A, b = ctx.matrix(A, **kwargs).copy(), ctx.matrix(b, **kwargs).copy() + if A.rows < A.cols: + raise ValueError('cannot solve underdetermined system') + H, p, x, r = ctx.householder(ctx.extend(A, b)) + res = ctx.norm(r) + # calculate residual "manually" for determined systems + if res == 0: + res = ctx.norm(ctx.residual(A, x, b)) + return ctx.matrix(x, **kwargs), res + finally: + ctx.prec = prec + + def cholesky(ctx, A, tol=None): + r""" + Cholesky decomposition of a symmetric positive-definite matrix `A`. + Returns a lower triangular matrix `L` such that `A = L \times L^T`. + More generally, for a complex Hermitian positive-definite matrix, + a Cholesky decomposition satisfying `A = L \times L^H` is returned. + + The Cholesky decomposition can be used to solve linear equation + systems twice as efficiently as LU decomposition, or to + test whether `A` is positive-definite. + + The optional parameter ``tol`` determines the tolerance for + verifying positive-definiteness. + + **Examples** + + Cholesky decomposition of a positive-definite symmetric matrix:: + + >>> from mpmath import * + >>> mp.dps = 25; mp.pretty = True + >>> A = eye(3) + hilbert(3) + >>> nprint(A) + [ 2.0 0.5 0.333333] + [ 0.5 1.33333 0.25] + [0.333333 0.25 1.2] + >>> L = cholesky(A) + >>> nprint(L) + [ 1.41421 0.0 0.0] + [0.353553 1.09924 0.0] + [0.235702 0.15162 1.05899] + >>> chop(A - L*L.T) + [0.0 0.0 0.0] + [0.0 0.0 0.0] + [0.0 0.0 0.0] + + Cholesky decomposition of a Hermitian matrix:: + + >>> A = eye(3) + matrix([[0,0.25j,-0.5j],[-0.25j,0,0],[0.5j,0,0]]) + >>> L = cholesky(A) + >>> nprint(L) + [ 1.0 0.0 0.0] + [(0.0 - 0.25j) (0.968246 + 0.0j) 0.0] + [ (0.0 + 0.5j) (0.129099 + 0.0j) (0.856349 + 0.0j)] + >>> chop(A - L*L.H) + [0.0 0.0 0.0] + [0.0 0.0 0.0] + [0.0 0.0 0.0] + + Attempted Cholesky decomposition of a matrix that is not positive + definite:: + + >>> A = -eye(3) + hilbert(3) + >>> L = cholesky(A) + Traceback (most recent call last): + ... + ValueError: matrix is not positive-definite + + **References** + + 1. [Wikipedia]_ http://en.wikipedia.org/wiki/Cholesky_decomposition + + """ + if not isinstance(A, ctx.matrix): + raise RuntimeError("A should be a type of ctx.matrix") + if not A.rows == A.cols: + raise ValueError('need n*n matrix') + if tol is None: + tol = +ctx.eps + n = A.rows + L = ctx.matrix(n) + for j in xrange(n): + c = ctx.re(A[j,j]) + if abs(c-A[j,j]) > tol: + raise ValueError('matrix is not Hermitian') + s = c - ctx.fsum((L[j,k] for k in xrange(j)), + absolute=True, squared=True) + if s < tol: + raise ValueError('matrix is not positive-definite') + L[j,j] = ctx.sqrt(s) + for i in xrange(j, n): + it1 = (L[i,k] for k in xrange(j)) + it2 = (L[j,k] for k in xrange(j)) + t = ctx.fdot(it1, it2, conjugate=True) + L[i,j] = (A[i,j] - t) / L[j,j] + return L + + def cholesky_solve(ctx, A, b, **kwargs): + """ + Ax = b => x + + Solve a symmetric positive-definite linear equation system. + This is twice as efficient as lu_solve. + + Typical use cases: + * A.T*A + * Hessian matrix + * differential equations + """ + prec = ctx.prec + try: + ctx.prec += 10 + # do not overwrite A nor b + A, b = ctx.matrix(A, **kwargs).copy(), ctx.matrix(b, **kwargs).copy() + if A.rows != A.cols: + raise ValueError('can only solve determined system') + # Cholesky factorization + L = ctx.cholesky(A) + # solve + n = L.rows + if len(b) != n: + raise ValueError("Value should be equal to n") + for i in xrange(n): + b[i] -= ctx.fsum(L[i,j] * b[j] for j in xrange(i)) + b[i] /= L[i,i] + x = ctx.U_solve(L.T, b) + return x + finally: + ctx.prec = prec + + def det(ctx, A): + """ + Calculate the determinant of a matrix. + """ + prec = ctx.prec + try: + # do not overwrite A + A = ctx.matrix(A).copy() + # use LU factorization to calculate determinant + try: + R, p = ctx.LU_decomp(A) + except ZeroDivisionError: + return 0 + z = 1 + for i, e in enumerate(p): + if i != e: + z *= -1 + for i in xrange(A.rows): + z *= R[i,i] + return z + finally: + ctx.prec = prec + + def cond(ctx, A, norm=None): + """ + Calculate the condition number of a matrix using a specified matrix norm. + + The condition number estimates the sensitivity of a matrix to errors. + Example: small input errors for ill-conditioned coefficient matrices + alter the solution of the system dramatically. + + For ill-conditioned matrices it's recommended to use qr_solve() instead + of lu_solve(). This does not help with input errors however, it just avoids + to add additional errors. + + Definition: cond(A) = ||A|| * ||A**-1|| + """ + if norm is None: + norm = lambda x: ctx.mnorm(x,1) + return norm(A) * norm(ctx.inverse(A)) + + def lu_solve_mat(ctx, a, b): + """Solve a * x = b where a and b are matrices.""" + r = ctx.matrix(a.rows, b.cols) + for i in range(b.cols): + c = ctx.lu_solve(a, b.column(i)) + for j in range(len(c)): + r[j, i] = c[j] + return r + + def qr(ctx, A, mode = 'full', edps = 10): + """ + Compute a QR factorization $A = QR$ where + A is an m x n matrix of real or complex numbers where m >= n + + mode has following meanings: + (1) mode = 'raw' returns two matrixes (A, tau) in the + internal format used by LAPACK + (2) mode = 'skinny' returns the leading n columns of Q + and n rows of R + (3) Any other value returns the leading m columns of Q + and m rows of R + + edps is the increase in mp precision used for calculations + + **Examples** + + >>> from mpmath import * + >>> mp.dps = 15 + >>> mp.pretty = True + >>> A = matrix([[1, 2], [3, 4], [1, 1]]) + >>> Q, R = qr(A) + >>> Q + [-0.301511344577764 0.861640436855329 0.408248290463863] + [-0.904534033733291 -0.123091490979333 -0.408248290463863] + [-0.301511344577764 -0.492365963917331 0.816496580927726] + >>> R + [-3.3166247903554 -4.52267016866645] + [ 0.0 0.738548945875996] + [ 0.0 0.0] + >>> Q * R + [1.0 2.0] + [3.0 4.0] + [1.0 1.0] + >>> chop(Q.T * Q) + [1.0 0.0 0.0] + [0.0 1.0 0.0] + [0.0 0.0 1.0] + >>> B = matrix([[1+0j, 2-3j], [3+j, 4+5j]]) + >>> Q, R = qr(B) + >>> nprint(Q) + [ (-0.301511 + 0.0j) (0.0695795 - 0.95092j)] + [(-0.904534 - 0.301511j) (-0.115966 + 0.278318j)] + >>> nprint(R) + [(-3.31662 + 0.0j) (-5.72872 - 2.41209j)] + [ 0.0 (3.91965 + 0.0j)] + >>> Q * R + [(1.0 + 0.0j) (2.0 - 3.0j)] + [(3.0 + 1.0j) (4.0 + 5.0j)] + >>> chop(Q.T * Q.conjugate()) + [1.0 0.0] + [0.0 1.0] + + """ + + # check values before continuing + assert isinstance(A, ctx.matrix) + m = A.rows + n = A.cols + assert n >= 0 + assert m >= n + assert edps >= 0 + + # check for complex data type + cmplx = any(type(x) is ctx.mpc for x in A) + + # temporarily increase the precision and initialize + with ctx.extradps(edps): + tau = ctx.matrix(n,1) + A = A.copy() + + # --------------- + # FACTOR MATRIX A + # --------------- + if cmplx: + one = ctx.mpc('1.0', '0.0') + zero = ctx.mpc('0.0', '0.0') + rzero = ctx.mpf('0.0') + + # main loop to factor A (complex) + for j in xrange(0, n): + alpha = A[j,j] + alphr = ctx.re(alpha) + alphi = ctx.im(alpha) + + if (m-j) >= 2: + xnorm = ctx.fsum( A[i,j]*ctx.conj(A[i,j]) for i in xrange(j+1, m) ) + xnorm = ctx.re( ctx.sqrt(xnorm) ) + else: + xnorm = rzero + + if (xnorm == rzero) and (alphi == rzero): + tau[j] = zero + continue + + if alphr < rzero: + beta = ctx.sqrt(alphr**2 + alphi**2 + xnorm**2) + else: + beta = -ctx.sqrt(alphr**2 + alphi**2 + xnorm**2) + + tau[j] = ctx.mpc( (beta - alphr) / beta, -alphi / beta ) + t = -ctx.conj(tau[j]) + za = one / (alpha - beta) + + for i in xrange(j+1, m): + A[i,j] *= za + + A[j,j] = one + for k in xrange(j+1, n): + y = ctx.fsum(A[i,j] * ctx.conj(A[i,k]) for i in xrange(j, m)) + temp = t * ctx.conj(y) + for i in xrange(j, m): + A[i,k] += A[i,j] * temp + + A[j,j] = ctx.mpc(beta, '0.0') + else: + one = ctx.mpf('1.0') + zero = ctx.mpf('0.0') + + # main loop to factor A (real) + for j in xrange(0, n): + alpha = A[j,j] + + if (m-j) > 2: + xnorm = ctx.fsum( (A[i,j])**2 for i in xrange(j+1, m) ) + xnorm = ctx.sqrt(xnorm) + elif (m-j) == 2: + xnorm = abs( A[m-1,j] ) + else: + xnorm = zero + + if xnorm == zero: + tau[j] = zero + continue + + if alpha < zero: + beta = ctx.sqrt(alpha**2 + xnorm**2) + else: + beta = -ctx.sqrt(alpha**2 + xnorm**2) + + tau[j] = (beta - alpha) / beta + t = -tau[j] + da = one / (alpha - beta) + + for i in xrange(j+1, m): + A[i,j] *= da + + A[j,j] = one + for k in xrange(j+1, n): + y = ctx.fsum( A[i,j] * A[i,k] for i in xrange(j, m) ) + temp = t * y + for i in xrange(j,m): + A[i,k] += A[i,j] * temp + + A[j,j] = beta + + # return factorization in same internal format as LAPACK + if (mode == 'raw') or (mode == 'RAW'): + return A, tau + + # ---------------------------------- + # FORM Q USING BACKWARD ACCUMULATION + # ---------------------------------- + + # form R before the values are overwritten + R = A.copy() + for j in xrange(0, n): + for i in xrange(j+1, m): + R[i,j] = zero + + # set the value of p (number of columns of Q to return) + p = m + if (mode == 'skinny') or (mode == 'SKINNY'): + p = n + + # add columns to A if needed and initialize + A.cols += (p-n) + for j in xrange(0, p): + A[j,j] = one + for i in xrange(0, j): + A[i,j] = zero + + # main loop to form Q + for j in xrange(n-1, -1, -1): + t = -tau[j] + A[j,j] += t + + for k in xrange(j+1, p): + if cmplx: + y = ctx.fsum(A[i,j] * ctx.conj(A[i,k]) for i in xrange(j+1, m)) + temp = t * ctx.conj(y) + else: + y = ctx.fsum(A[i,j] * A[i,k] for i in xrange(j+1, m)) + temp = t * y + A[j,k] = temp + for i in xrange(j+1, m): + A[i,k] += A[i,j] * temp + + for i in xrange(j+1, m): + A[i, j] *= t + + return A, R[0:p,0:n] + + # ------------------ + # END OF FUNCTION QR + # ------------------ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/matrices.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/matrices.py new file mode 100644 index 0000000000000000000000000000000000000000..a97d5a9ca7e173195386dc7cb60860a826ab6a97 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/matrices/matrices.py @@ -0,0 +1,1005 @@ +from ..libmp.backend import xrange +import warnings + +# TODO: interpret list as vectors (for multiplication) + +rowsep = '\n' +colsep = ' ' + +class _matrix(object): + """ + Numerical matrix. + + Specify the dimensions or the data as a nested list. + Elements default to zero. + Use a flat list to create a column vector easily. + + The datatype of the context (mpf for mp, mpi for iv, and float for fp) is used to store the data. + + Creating matrices + ----------------- + + Matrices in mpmath are implemented using dictionaries. Only non-zero values + are stored, so it is cheap to represent sparse matrices. + + The most basic way to create one is to use the ``matrix`` class directly. + You can create an empty matrix specifying the dimensions: + + >>> from mpmath import * + >>> mp.dps = 15 + >>> matrix(2) + matrix( + [['0.0', '0.0'], + ['0.0', '0.0']]) + >>> matrix(2, 3) + matrix( + [['0.0', '0.0', '0.0'], + ['0.0', '0.0', '0.0']]) + + Calling ``matrix`` with one dimension will create a square matrix. + + To access the dimensions of a matrix, use the ``rows`` or ``cols`` keyword: + + >>> A = matrix(3, 2) + >>> A + matrix( + [['0.0', '0.0'], + ['0.0', '0.0'], + ['0.0', '0.0']]) + >>> A.rows + 3 + >>> A.cols + 2 + + You can also change the dimension of an existing matrix. This will set the + new elements to 0. If the new dimension is smaller than before, the + concerning elements are discarded: + + >>> A.rows = 2 + >>> A + matrix( + [['0.0', '0.0'], + ['0.0', '0.0']]) + + Internally ``mpmathify`` is used every time an element is set. This + is done using the syntax A[row,column], counting from 0: + + >>> A = matrix(2) + >>> A[1,1] = 1 + 1j + >>> A + matrix( + [['0.0', '0.0'], + ['0.0', mpc(real='1.0', imag='1.0')]]) + + A more comfortable way to create a matrix lets you use nested lists: + + >>> matrix([[1, 2], [3, 4]]) + matrix( + [['1.0', '2.0'], + ['3.0', '4.0']]) + + Convenient advanced functions are available for creating various standard + matrices, see ``zeros``, ``ones``, ``diag``, ``eye``, ``randmatrix`` and + ``hilbert``. + + Vectors + ....... + + Vectors may also be represented by the ``matrix`` class (with rows = 1 or cols = 1). + For vectors there are some things which make life easier. A column vector can + be created using a flat list, a row vectors using an almost flat nested list:: + + >>> matrix([1, 2, 3]) + matrix( + [['1.0'], + ['2.0'], + ['3.0']]) + >>> matrix([[1, 2, 3]]) + matrix( + [['1.0', '2.0', '3.0']]) + + Optionally vectors can be accessed like lists, using only a single index:: + + >>> x = matrix([1, 2, 3]) + >>> x[1] + mpf('2.0') + >>> x[1,0] + mpf('2.0') + + Other + ..... + + Like you probably expected, matrices can be printed:: + + >>> print randmatrix(3) # doctest:+SKIP + [ 0.782963853573023 0.802057689719883 0.427895717335467] + [0.0541876859348597 0.708243266653103 0.615134039977379] + [ 0.856151514955773 0.544759264818486 0.686210904770947] + + Use ``nstr`` or ``nprint`` to specify the number of digits to print:: + + >>> nprint(randmatrix(5), 3) # doctest:+SKIP + [2.07e-1 1.66e-1 5.06e-1 1.89e-1 8.29e-1] + [6.62e-1 6.55e-1 4.47e-1 4.82e-1 2.06e-2] + [4.33e-1 7.75e-1 6.93e-2 2.86e-1 5.71e-1] + [1.01e-1 2.53e-1 6.13e-1 3.32e-1 2.59e-1] + [1.56e-1 7.27e-2 6.05e-1 6.67e-2 2.79e-1] + + As matrices are mutable, you will need to copy them sometimes:: + + >>> A = matrix(2) + >>> A + matrix( + [['0.0', '0.0'], + ['0.0', '0.0']]) + >>> B = A.copy() + >>> B[0,0] = 1 + >>> B + matrix( + [['1.0', '0.0'], + ['0.0', '0.0']]) + >>> A + matrix( + [['0.0', '0.0'], + ['0.0', '0.0']]) + + Finally, it is possible to convert a matrix to a nested list. This is very useful, + as most Python libraries involving matrices or arrays (namely NumPy or SymPy) + support this format:: + + >>> B.tolist() + [[mpf('1.0'), mpf('0.0')], [mpf('0.0'), mpf('0.0')]] + + + Matrix operations + ----------------- + + You can add and subtract matrices of compatible dimensions:: + + >>> A = matrix([[1, 2], [3, 4]]) + >>> B = matrix([[-2, 4], [5, 9]]) + >>> A + B + matrix( + [['-1.0', '6.0'], + ['8.0', '13.0']]) + >>> A - B + matrix( + [['3.0', '-2.0'], + ['-2.0', '-5.0']]) + >>> A + ones(3) # doctest:+ELLIPSIS + Traceback (most recent call last): + ... + ValueError: incompatible dimensions for addition + + It is possible to multiply or add matrices and scalars. In the latter case the + operation will be done element-wise:: + + >>> A * 2 + matrix( + [['2.0', '4.0'], + ['6.0', '8.0']]) + >>> A / 4 + matrix( + [['0.25', '0.5'], + ['0.75', '1.0']]) + >>> A - 1 + matrix( + [['0.0', '1.0'], + ['2.0', '3.0']]) + + Of course you can perform matrix multiplication, if the dimensions are + compatible, using ``@`` (for Python >= 3.5) or ``*``. For clarity, ``@`` is + recommended (`PEP 465 `), because + the meaning of ``*`` is different in many other Python libraries such as NumPy. + + >>> A @ B # doctest:+SKIP + matrix( + [['8.0', '22.0'], + ['14.0', '48.0']]) + >>> A * B # same as A @ B + matrix( + [['8.0', '22.0'], + ['14.0', '48.0']]) + >>> matrix([[1, 2, 3]]) * matrix([[-6], [7], [-2]]) + matrix( + [['2.0']]) + + .. + COMMENT: TODO: the above "doctest:+SKIP" may be removed as soon as we + have dropped support for Python 3.5 and below. + + You can raise powers of square matrices:: + + >>> A**2 + matrix( + [['7.0', '10.0'], + ['15.0', '22.0']]) + + Negative powers will calculate the inverse:: + + >>> A**-1 + matrix( + [['-2.0', '1.0'], + ['1.5', '-0.5']]) + >>> A * A**-1 + matrix( + [['1.0', '1.0842021724855e-19'], + ['-2.16840434497101e-19', '1.0']]) + + + + Matrix transposition is straightforward:: + + >>> A = ones(2, 3) + >>> A + matrix( + [['1.0', '1.0', '1.0'], + ['1.0', '1.0', '1.0']]) + >>> A.T + matrix( + [['1.0', '1.0'], + ['1.0', '1.0'], + ['1.0', '1.0']]) + + Norms + ..... + + Sometimes you need to know how "large" a matrix or vector is. Due to their + multidimensional nature it's not possible to compare them, but there are + several functions to map a matrix or a vector to a positive real number, the + so called norms. + + For vectors the p-norm is intended, usually the 1-, the 2- and the oo-norm are + used. + + >>> x = matrix([-10, 2, 100]) + >>> norm(x, 1) + mpf('112.0') + >>> norm(x, 2) + mpf('100.5186549850325') + >>> norm(x, inf) + mpf('100.0') + + Please note that the 2-norm is the most used one, though it is more expensive + to calculate than the 1- or oo-norm. + + It is possible to generalize some vector norms to matrix norm:: + + >>> A = matrix([[1, -1000], [100, 50]]) + >>> mnorm(A, 1) + mpf('1050.0') + >>> mnorm(A, inf) + mpf('1001.0') + >>> mnorm(A, 'F') + mpf('1006.2310867787777') + + The last norm (the "Frobenius-norm") is an approximation for the 2-norm, which + is hard to calculate and not available. The Frobenius-norm lacks some + mathematical properties you might expect from a norm. + """ + + def __init__(self, *args, **kwargs): + self.__data = {} + # LU decompostion cache, this is useful when solving the same system + # multiple times, when calculating the inverse and when calculating the + # determinant + self._LU = None + if "force_type" in kwargs: + warnings.warn("The force_type argument was removed, it did not work" + " properly anyway. If you want to force floating-point or" + " interval computations, use the respective methods from `fp`" + " or `mp` instead, e.g., `fp.matrix()` or `iv.matrix()`." + " If you want to truncate values to integer, use .apply(int) instead.") + if isinstance(args[0], (list, tuple)): + if isinstance(args[0][0], (list, tuple)): + # interpret nested list as matrix + A = args[0] + self.__rows = len(A) + self.__cols = len(A[0]) + for i, row in enumerate(A): + for j, a in enumerate(row): + # note: this will call __setitem__ which will call self.ctx.convert() to convert the datatype. + self[i, j] = a + else: + # interpret list as row vector + v = args[0] + self.__rows = len(v) + self.__cols = 1 + for i, e in enumerate(v): + self[i, 0] = e + elif isinstance(args[0], int): + # create empty matrix of given dimensions + if len(args) == 1: + self.__rows = self.__cols = args[0] + else: + if not isinstance(args[1], int): + raise TypeError("expected int") + self.__rows = args[0] + self.__cols = args[1] + elif isinstance(args[0], _matrix): + A = args[0] + self.__rows = A._matrix__rows + self.__cols = A._matrix__cols + for i in xrange(A.__rows): + for j in xrange(A.__cols): + self[i, j] = A[i, j] + elif hasattr(args[0], 'tolist'): + A = self.ctx.matrix(args[0].tolist()) + self.__data = A._matrix__data + self.__rows = A._matrix__rows + self.__cols = A._matrix__cols + else: + raise TypeError('could not interpret given arguments') + + def apply(self, f): + """ + Return a copy of self with the function `f` applied elementwise. + """ + new = self.ctx.matrix(self.__rows, self.__cols) + for i in xrange(self.__rows): + for j in xrange(self.__cols): + new[i,j] = f(self[i,j]) + return new + + def __nstr__(self, n=None, **kwargs): + # Build table of string representations of the elements + res = [] + # Track per-column max lengths for pretty alignment + maxlen = [0] * self.cols + for i in range(self.rows): + res.append([]) + for j in range(self.cols): + if n: + string = self.ctx.nstr(self[i,j], n, **kwargs) + else: + string = str(self[i,j]) + res[-1].append(string) + maxlen[j] = max(len(string), maxlen[j]) + # Patch strings together + for i, row in enumerate(res): + for j, elem in enumerate(row): + # Pad each element up to maxlen so the columns line up + row[j] = elem.rjust(maxlen[j]) + res[i] = "[" + colsep.join(row) + "]" + return rowsep.join(res) + + def __str__(self): + return self.__nstr__() + + def _toliststr(self, avoid_type=False): + """ + Create a list string from a matrix. + + If avoid_type: avoid multiple 'mpf's. + """ + # XXX: should be something like self.ctx._types + typ = self.ctx.mpf + s = '[' + for i in xrange(self.__rows): + s += '[' + for j in xrange(self.__cols): + if not avoid_type or not isinstance(self[i,j], typ): + a = repr(self[i,j]) + else: + a = "'" + str(self[i,j]) + "'" + s += a + ', ' + s = s[:-2] + s += '],\n ' + s = s[:-3] + s += ']' + return s + + def tolist(self): + """ + Convert the matrix to a nested list. + """ + return [[self[i,j] for j in range(self.__cols)] for i in range(self.__rows)] + + def __repr__(self): + if self.ctx.pretty: + return self.__str__() + s = 'matrix(\n' + s += self._toliststr(avoid_type=True) + ')' + return s + + def __get_element(self, key): + ''' + Fast extraction of the i,j element from the matrix + This function is for private use only because is unsafe: + 1. Does not check on the value of key it expects key to be a integer tuple (i,j) + 2. Does not check bounds + ''' + if key in self.__data: + return self.__data[key] + else: + return self.ctx.zero + + def __set_element(self, key, value): + ''' + Fast assignment of the i,j element in the matrix + This function is unsafe: + 1. Does not check on the value of key it expects key to be a integer tuple (i,j) + 2. Does not check bounds + 3. Does not check the value type + 4. Does not reset the LU cache + ''' + if value: # only store non-zeros + self.__data[key] = value + elif key in self.__data: + del self.__data[key] + + + def __getitem__(self, key): + ''' + Getitem function for mp matrix class with slice index enabled + it allows the following assingments + scalar to a slice of the matrix + B = A[:,2:6] + ''' + # Convert vector to matrix indexing + if isinstance(key, int) or isinstance(key,slice): + # only sufficent for vectors + if self.__rows == 1: + key = (0, key) + elif self.__cols == 1: + key = (key, 0) + else: + raise IndexError('insufficient indices for matrix') + + if isinstance(key[0],slice) or isinstance(key[1],slice): + + #Rows + if isinstance(key[0],slice): + #Check bounds + if (key[0].start is None or key[0].start >= 0) and \ + (key[0].stop is None or key[0].stop <= self.__rows+1): + # Generate indices + rows = xrange(*key[0].indices(self.__rows)) + else: + raise IndexError('Row index out of bounds') + else: + # Single row + rows = [key[0]] + + # Columns + if isinstance(key[1],slice): + # Check bounds + if (key[1].start is None or key[1].start >= 0) and \ + (key[1].stop is None or key[1].stop <= self.__cols+1): + # Generate indices + columns = xrange(*key[1].indices(self.__cols)) + else: + raise IndexError('Column index out of bounds') + + else: + # Single column + columns = [key[1]] + + # Create matrix slice + m = self.ctx.matrix(len(rows),len(columns)) + + # Assign elements to the output matrix + for i,x in enumerate(rows): + for j,y in enumerate(columns): + m.__set_element((i,j),self.__get_element((x,y))) + + return m + + else: + # single element extraction + if key[0] >= self.__rows or key[1] >= self.__cols: + raise IndexError('matrix index out of range') + if key in self.__data: + return self.__data[key] + else: + return self.ctx.zero + + def __setitem__(self, key, value): + # setitem function for mp matrix class with slice index enabled + # it allows the following assingments + # scalar to a slice of the matrix + # A[:,2:6] = 2.5 + # submatrix to matrix (the value matrix should be the same size as the slice size) + # A[3,:] = B where A is n x m and B is n x 1 + # Convert vector to matrix indexing + if isinstance(key, int) or isinstance(key,slice): + # only sufficent for vectors + if self.__rows == 1: + key = (0, key) + elif self.__cols == 1: + key = (key, 0) + else: + raise IndexError('insufficient indices for matrix') + # Slice indexing + if isinstance(key[0],slice) or isinstance(key[1],slice): + # Rows + if isinstance(key[0],slice): + # Check bounds + if (key[0].start is None or key[0].start >= 0) and \ + (key[0].stop is None or key[0].stop <= self.__rows+1): + # generate row indices + rows = xrange(*key[0].indices(self.__rows)) + else: + raise IndexError('Row index out of bounds') + else: + # Single row + rows = [key[0]] + # Columns + if isinstance(key[1],slice): + # Check bounds + if (key[1].start is None or key[1].start >= 0) and \ + (key[1].stop is None or key[1].stop <= self.__cols+1): + # Generate column indices + columns = xrange(*key[1].indices(self.__cols)) + else: + raise IndexError('Column index out of bounds') + else: + # Single column + columns = [key[1]] + # Assign slice with a scalar + if isinstance(value,self.ctx.matrix): + # Assign elements to matrix if input and output dimensions match + if len(rows) == value.rows and len(columns) == value.cols: + for i,x in enumerate(rows): + for j,y in enumerate(columns): + self.__set_element((x,y), value.__get_element((i,j))) + else: + raise ValueError('Dimensions do not match') + else: + # Assign slice with scalars + value = self.ctx.convert(value) + for i in rows: + for j in columns: + self.__set_element((i,j), value) + else: + # Single element assingment + # Check bounds + if key[0] >= self.__rows or key[1] >= self.__cols: + raise IndexError('matrix index out of range') + # Convert and store value + value = self.ctx.convert(value) + if value: # only store non-zeros + self.__data[key] = value + elif key in self.__data: + del self.__data[key] + + if self._LU: + self._LU = None + return + + def __iter__(self): + for i in xrange(self.__rows): + for j in xrange(self.__cols): + yield self[i,j] + + def __mul__(self, other): + if isinstance(other, self.ctx.matrix): + # dot multiplication + if self.__cols != other.__rows: + raise ValueError('dimensions not compatible for multiplication') + new = self.ctx.matrix(self.__rows, other.__cols) + self_zero = self.ctx.zero + self_get = self.__data.get + other_zero = other.ctx.zero + other_get = other.__data.get + for i in xrange(self.__rows): + for j in xrange(other.__cols): + new[i, j] = self.ctx.fdot((self_get((i,k), self_zero), other_get((k,j), other_zero)) + for k in xrange(other.__rows)) + return new + else: + # try scalar multiplication + new = self.ctx.matrix(self.__rows, self.__cols) + for i in xrange(self.__rows): + for j in xrange(self.__cols): + new[i, j] = other * self[i, j] + return new + + def __matmul__(self, other): + return self.__mul__(other) + + def __rmul__(self, other): + # assume other is scalar and thus commutative + if isinstance(other, self.ctx.matrix): + raise TypeError("other should not be type of ctx.matrix") + return self.__mul__(other) + + def __pow__(self, other): + # avoid cyclic import problems + #from linalg import inverse + if not isinstance(other, int): + raise ValueError('only integer exponents are supported') + if not self.__rows == self.__cols: + raise ValueError('only powers of square matrices are defined') + n = other + if n == 0: + return self.ctx.eye(self.__rows) + if n < 0: + n = -n + neg = True + else: + neg = False + i = n + y = 1 + z = self.copy() + while i != 0: + if i % 2 == 1: + y = y * z + z = z*z + i = i // 2 + if neg: + y = self.ctx.inverse(y) + return y + + def __div__(self, other): + # assume other is scalar and do element-wise divison + assert not isinstance(other, self.ctx.matrix) + new = self.ctx.matrix(self.__rows, self.__cols) + for i in xrange(self.__rows): + for j in xrange(self.__cols): + new[i,j] = self[i,j] / other + return new + + __truediv__ = __div__ + + def __add__(self, other): + if isinstance(other, self.ctx.matrix): + if not (self.__rows == other.__rows and self.__cols == other.__cols): + raise ValueError('incompatible dimensions for addition') + new = self.ctx.matrix(self.__rows, self.__cols) + for i in xrange(self.__rows): + for j in xrange(self.__cols): + new[i,j] = self[i,j] + other[i,j] + return new + else: + # assume other is scalar and add element-wise + new = self.ctx.matrix(self.__rows, self.__cols) + for i in xrange(self.__rows): + for j in xrange(self.__cols): + new[i,j] += self[i,j] + other + return new + + def __radd__(self, other): + return self.__add__(other) + + def __sub__(self, other): + if isinstance(other, self.ctx.matrix) and not (self.__rows == other.__rows + and self.__cols == other.__cols): + raise ValueError('incompatible dimensions for subtraction') + return self.__add__(other * (-1)) + + def __pos__(self): + """ + +M returns a copy of M, rounded to current working precision. + """ + return (+1) * self + + def __neg__(self): + return (-1) * self + + def __rsub__(self, other): + return -self + other + + def __eq__(self, other): + return self.__rows == other.__rows and self.__cols == other.__cols \ + and self.__data == other.__data + + def __len__(self): + if self.rows == 1: + return self.cols + elif self.cols == 1: + return self.rows + else: + return self.rows # do it like numpy + + def __getrows(self): + return self.__rows + + def __setrows(self, value): + for key in self.__data.copy(): + if key[0] >= value: + del self.__data[key] + self.__rows = value + + rows = property(__getrows, __setrows, doc='number of rows') + + def __getcols(self): + return self.__cols + + def __setcols(self, value): + for key in self.__data.copy(): + if key[1] >= value: + del self.__data[key] + self.__cols = value + + cols = property(__getcols, __setcols, doc='number of columns') + + def transpose(self): + new = self.ctx.matrix(self.__cols, self.__rows) + for i in xrange(self.__rows): + for j in xrange(self.__cols): + new[j,i] = self[i,j] + return new + + T = property(transpose) + + def conjugate(self): + return self.apply(self.ctx.conj) + + def transpose_conj(self): + return self.conjugate().transpose() + + H = property(transpose_conj) + + def copy(self): + new = self.ctx.matrix(self.__rows, self.__cols) + new.__data = self.__data.copy() + return new + + __copy__ = copy + + def column(self, n): + m = self.ctx.matrix(self.rows, 1) + for i in range(self.rows): + m[i] = self[i,n] + return m + +class MatrixMethods(object): + + def __init__(ctx): + # XXX: subclass + ctx.matrix = type('matrix', (_matrix,), {}) + ctx.matrix.ctx = ctx + ctx.matrix.convert = ctx.convert + + def eye(ctx, n, **kwargs): + """ + Create square identity matrix n x n. + """ + A = ctx.matrix(n, **kwargs) + for i in xrange(n): + A[i,i] = 1 + return A + + def diag(ctx, diagonal, **kwargs): + """ + Create square diagonal matrix using given list. + + Example: + >>> from mpmath import diag, mp + >>> mp.pretty = False + >>> diag([1, 2, 3]) + matrix( + [['1.0', '0.0', '0.0'], + ['0.0', '2.0', '0.0'], + ['0.0', '0.0', '3.0']]) + """ + A = ctx.matrix(len(diagonal), **kwargs) + for i in xrange(len(diagonal)): + A[i,i] = diagonal[i] + return A + + def zeros(ctx, *args, **kwargs): + """ + Create matrix m x n filled with zeros. + One given dimension will create square matrix n x n. + + Example: + >>> from mpmath import zeros, mp + >>> mp.pretty = False + >>> zeros(2) + matrix( + [['0.0', '0.0'], + ['0.0', '0.0']]) + """ + if len(args) == 1: + m = n = args[0] + elif len(args) == 2: + m = args[0] + n = args[1] + else: + raise TypeError('zeros expected at most 2 arguments, got %i' % len(args)) + A = ctx.matrix(m, n, **kwargs) + for i in xrange(m): + for j in xrange(n): + A[i,j] = 0 + return A + + def ones(ctx, *args, **kwargs): + """ + Create matrix m x n filled with ones. + One given dimension will create square matrix n x n. + + Example: + >>> from mpmath import ones, mp + >>> mp.pretty = False + >>> ones(2) + matrix( + [['1.0', '1.0'], + ['1.0', '1.0']]) + """ + if len(args) == 1: + m = n = args[0] + elif len(args) == 2: + m = args[0] + n = args[1] + else: + raise TypeError('ones expected at most 2 arguments, got %i' % len(args)) + A = ctx.matrix(m, n, **kwargs) + for i in xrange(m): + for j in xrange(n): + A[i,j] = 1 + return A + + def hilbert(ctx, m, n=None): + """ + Create (pseudo) hilbert matrix m x n. + One given dimension will create hilbert matrix n x n. + + The matrix is very ill-conditioned and symmetric, positive definite if + square. + """ + if n is None: + n = m + A = ctx.matrix(m, n) + for i in xrange(m): + for j in xrange(n): + A[i,j] = ctx.one / (i + j + 1) + return A + + def randmatrix(ctx, m, n=None, min=0, max=1, **kwargs): + """ + Create a random m x n matrix. + + All values are >= min and >> from mpmath import randmatrix + >>> randmatrix(2) # doctest:+SKIP + matrix( + [['0.53491598236191806', '0.57195669543302752'], + ['0.85589992269513615', '0.82444367501382143']]) + """ + if not n: + n = m + A = ctx.matrix(m, n, **kwargs) + for i in xrange(m): + for j in xrange(n): + A[i,j] = ctx.rand() * (max - min) + min + return A + + def swap_row(ctx, A, i, j): + """ + Swap row i with row j. + """ + if i == j: + return + if isinstance(A, ctx.matrix): + for k in xrange(A.cols): + A[i,k], A[j,k] = A[j,k], A[i,k] + elif isinstance(A, list): + A[i], A[j] = A[j], A[i] + else: + raise TypeError('could not interpret type') + + def extend(ctx, A, b): + """ + Extend matrix A with column b and return result. + """ + if not isinstance(A, ctx.matrix): + raise TypeError("A should be a type of ctx.matrix") + if A.rows != len(b): + raise ValueError("Value should be equal to len(b)") + A = A.copy() + A.cols += 1 + for i in xrange(A.rows): + A[i, A.cols-1] = b[i] + return A + + def norm(ctx, x, p=2): + r""" + Gives the entrywise `p`-norm of an iterable *x*, i.e. the vector norm + `\left(\sum_k |x_k|^p\right)^{1/p}`, for any given `1 \le p \le \infty`. + + Special cases: + + If *x* is not iterable, this just returns ``absmax(x)``. + + ``p=1`` gives the sum of absolute values. + + ``p=2`` is the standard Euclidean vector norm. + + ``p=inf`` gives the magnitude of the largest element. + + For *x* a matrix, ``p=2`` is the Frobenius norm. + For operator matrix norms, use :func:`~mpmath.mnorm` instead. + + You can use the string 'inf' as well as float('inf') or mpf('inf') + to specify the infinity norm. + + **Examples** + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = False + >>> x = matrix([-10, 2, 100]) + >>> norm(x, 1) + mpf('112.0') + >>> norm(x, 2) + mpf('100.5186549850325') + >>> norm(x, inf) + mpf('100.0') + + """ + try: + iter(x) + except TypeError: + return ctx.absmax(x) + if type(p) is not int: + p = ctx.convert(p) + if p == ctx.inf: + return max(ctx.absmax(i) for i in x) + elif p == 1: + return ctx.fsum(x, absolute=1) + elif p == 2: + return ctx.sqrt(ctx.fsum(x, absolute=1, squared=1)) + elif p > 1: + return ctx.nthroot(ctx.fsum(abs(i)**p for i in x), p) + else: + raise ValueError('p has to be >= 1') + + def mnorm(ctx, A, p=1): + r""" + Gives the matrix (operator) `p`-norm of A. Currently ``p=1`` and ``p=inf`` + are supported: + + ``p=1`` gives the 1-norm (maximal column sum) + + ``p=inf`` gives the `\infty`-norm (maximal row sum). + You can use the string 'inf' as well as float('inf') or mpf('inf') + + ``p=2`` (not implemented) for a square matrix is the usual spectral + matrix norm, i.e. the largest singular value. + + ``p='f'`` (or 'F', 'fro', 'Frobenius, 'frobenius') gives the + Frobenius norm, which is the elementwise 2-norm. The Frobenius norm is an + approximation of the spectral norm and satisfies + + .. math :: + + \frac{1}{\sqrt{\mathrm{rank}(A)}} \|A\|_F \le \|A\|_2 \le \|A\|_F + + The Frobenius norm lacks some mathematical properties that might + be expected of a norm. + + For general elementwise `p`-norms, use :func:`~mpmath.norm` instead. + + **Examples** + + >>> from mpmath import * + >>> mp.dps = 15; mp.pretty = False + >>> A = matrix([[1, -1000], [100, 50]]) + >>> mnorm(A, 1) + mpf('1050.0') + >>> mnorm(A, inf) + mpf('1001.0') + >>> mnorm(A, 'F') + mpf('1006.2310867787777') + + """ + A = ctx.matrix(A) + if type(p) is not int: + if type(p) is str and 'frobenius'.startswith(p.lower()): + return ctx.norm(A, 2) + p = ctx.convert(p) + m, n = A.rows, A.cols + if p == 1: + return max(ctx.fsum((A[i,j] for i in xrange(m)), absolute=1) for j in xrange(n)) + elif p == ctx.inf: + return max(ctx.fsum((A[i,j] for j in xrange(n)), absolute=1) for i in xrange(m)) + else: + raise NotImplementedError("matrix p-norm for arbitrary p") + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96394064cc6705a3ed2972d0d9a50f3f359b638e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/extratest_gamma.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/extratest_gamma.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae14384c8dd1485a4866f87551f2da5d2ff71cea Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/extratest_gamma.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/extratest_zeta.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/extratest_zeta.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..984d147226928e88f9019fdbb7aec344465cf2f8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/extratest_zeta.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/runtests.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/runtests.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..178725f1d3080226a074261ee0fdf845a78d278c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/runtests.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_calculus.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_calculus.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e7d252f132424fe0edad0ef3f8add9982de301c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_calculus.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_compatibility.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_compatibility.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..287106ade3abfa7ef50a2fa33647749140632d41 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_compatibility.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_convert.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_convert.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a93390cc6b50864f1bb63e1ed722df66a412beea Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_convert.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_division.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_division.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc7d78ff0c7a23a0d1dd836a2b66d25d175b14b7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_division.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_eigen.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_eigen.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfb5624cee716742a95c3bfb56b1e2ad0f4690fb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_eigen.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_eigen_symmetric.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_eigen_symmetric.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0ff5f6d274b13d374b85e8dc61c360137ef2a91 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_eigen_symmetric.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_elliptic.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_elliptic.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..27cbf1f634871a481b16dbe9ceb147b928d22c2c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_elliptic.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_functions.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_functions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1886d177b863d01db550077d97a9a9e815897523 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_functions.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_gammazeta.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_gammazeta.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..607970307df033f4a8773edf06edfde6b71c89eb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_gammazeta.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_hp.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_hp.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..143078c202c60e65b6e49b9b2112e9657c5ddb72 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_hp.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_identify.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_identify.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1475aa5801ee772f694d3bf8cc571b341989ca0e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_identify.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_interval.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_interval.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e7bf75ad271935aaa25cdcfbd5ec995f2f543e7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_interval.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_levin.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_levin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f75a57df9e9d303fd3980e87879f1d52c46d68d9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_levin.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_linalg.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_linalg.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae0f659133a04fae5eb65bd55ed726e8bec2420c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_linalg.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_matrices.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_matrices.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3cf6ee15a8de3390cd95291ebeb32858aa4e7e6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_matrices.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_mpmath.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_mpmath.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f8fac03e6bed7fb601af73c9d23b02a17be8a99 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_mpmath.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_ode.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_ode.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b84283ae79bf17fa0b7f853fa4fc711b74b7e76 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_ode.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_pickle.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_pickle.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25bcc2d4b3c964d98b4a5afe967ef4de35d62ebf Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_pickle.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_power.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_power.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e068108c4ae9baa5859921f7c3e799743174ad67 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_power.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_rootfinding.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_rootfinding.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e3428c978f58e8e41978003e4eba74742a17504 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_rootfinding.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_special.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_special.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb96abda0d9eec2caf43a812063029afce8bb8c3 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_special.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_str.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_str.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9ffd92f272a8249bd49f4f8f575f1d334cc5d8b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_str.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_summation.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_summation.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b3e6df4e60649a95c07183608d0298738e9f7c6d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_summation.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_trig.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_trig.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..927a339f4f748edd35129c727a8ece5d5ea0a72f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_trig.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_visualization.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_visualization.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e040bb35bf26ac67176a5ca9dd498bac2ce295e8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/test_visualization.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/torture.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/torture.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af303dda54ba36bd77078aadca8d88f3b028d6d1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/__pycache__/torture.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_calculus.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_calculus.py new file mode 100644 index 0000000000000000000000000000000000000000..f0a59773d672f0db20bb5072773472a5a3cc1d1f --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_calculus.py @@ -0,0 +1,216 @@ +import pytest +from mpmath import * + +def test_approximation(): + mp.dps = 15 + f = lambda x: cos(2-2*x)/x + p, err = chebyfit(f, [2, 4], 8, error=True) + assert err < 1e-5 + for i in range(10): + x = 2 + i/5. + assert abs(polyval(p, x) - f(x)) < err + +def test_limits(): + mp.dps = 15 + assert limit(lambda x: (x-sin(x))/x**3, 0).ae(mpf(1)/6) + assert limit(lambda n: (1+1/n)**n, inf).ae(e) + +def test_polyval(): + assert polyval([], 3) == 0 + assert polyval([0], 3) == 0 + assert polyval([5], 3) == 5 + # 4x^3 - 2x + 5 + p = [4, 0, -2, 5] + assert polyval(p,4) == 253 + assert polyval(p,4,derivative=True) == (253, 190) + +def test_polyroots(): + p = polyroots([1,-4]) + assert p[0].ae(4) + p, q = polyroots([1,2,3]) + assert p.ae(-1 - sqrt(2)*j) + assert q.ae(-1 + sqrt(2)*j) + #this is not a real test, it only tests a specific case + assert polyroots([1]) == [] + pytest.raises(ValueError, lambda: polyroots([0])) + +def test_polyroots_legendre(): + n = 64 + coeffs = [11975573020964041433067793888190275875, 0, + -190100434726484311252477736051902332000, 0, + 1437919688271127330313741595496589239248, 0, + -6897338342113537600691931230430793911840, 0, + 23556405536185284408974715545252277554280, 0, + -60969520211303089058522793175947071316960, 0, + 124284021969194758465450309166353645376880, 0, + -204721258548015217049921875719981284186016, 0, + 277415422258095841688223780704620656114900, 0, + -313237834141273382807123548182995095192800, 0, + 297432255354328395601259515935229287637200, 0, + -239057700565161140389797367947941296605600, 0, + 163356095386193445933028201431093219347160, 0, + -95158890516229191805647495979277603503200, 0, + 47310254620162038075933656063247634556400, 0, + -20071017111583894941305187420771723751200, 0, + 7255051932731034189479516844750603752850, 0, + -2228176940331017311443863996901733412640, 0, + 579006552594977616773047095969088431600, 0, + -126584428502545713788439446082310831200, 0, + 23112325428835593809686977515028663000, 0, + -3491517141958743235617737161547844000, 0, + 431305058712550634988073414073557200, 0, + -42927166660756742088912492757452000, 0, + 3378527005707706553294038781836500, 0, + -205277590220215081719131470288800, 0, + 9330799555464321896324157740400, 0, + -304114948474392713657972548576, 0, + 6695289961520387531608984680, 0, + -91048139350447232095702560, 0, + 659769125727878493447120, 0, + -1905929106580294155360, 0, + 916312070471295267] + + with mp.workdps(3): + with pytest.raises(mp.NoConvergence): + polyroots(coeffs, maxsteps=5, cleanup=True, error=False, + extraprec=n*10) + + roots = polyroots(coeffs, maxsteps=50, cleanup=True, error=False, + extraprec=n*10) + roots = [str(r) for r in roots] + assert roots == \ + ['-0.999', '-0.996', '-0.991', '-0.983', '-0.973', '-0.961', + '-0.946', '-0.93', '-0.911', '-0.889', '-0.866', '-0.841', + '-0.813', '-0.784', '-0.753', '-0.72', '-0.685', '-0.649', + '-0.611', '-0.572', '-0.531', '-0.489', '-0.446', '-0.402', + '-0.357', '-0.311', '-0.265', '-0.217', '-0.17', '-0.121', + '-0.073', '-0.0243', '0.0243', '0.073', '0.121', '0.17', '0.217', + '0.265', '0.311', '0.357', '0.402', '0.446', '0.489', '0.531', + '0.572', '0.611', '0.649', '0.685', '0.72', '0.753', '0.784', + '0.813', '0.841', '0.866', '0.889', '0.911', '0.93', '0.946', + '0.961', '0.973', '0.983', '0.991', '0.996', '0.999'] + +def test_polyroots_legendre_init(): + extra_prec = 100 + coeffs = [11975573020964041433067793888190275875, 0, + -190100434726484311252477736051902332000, 0, + 1437919688271127330313741595496589239248, 0, + -6897338342113537600691931230430793911840, 0, + 23556405536185284408974715545252277554280, 0, + -60969520211303089058522793175947071316960, 0, + 124284021969194758465450309166353645376880, 0, + -204721258548015217049921875719981284186016, 0, + 277415422258095841688223780704620656114900, 0, + -313237834141273382807123548182995095192800, 0, + 297432255354328395601259515935229287637200, 0, + -239057700565161140389797367947941296605600, 0, + 163356095386193445933028201431093219347160, 0, + -95158890516229191805647495979277603503200, 0, + 47310254620162038075933656063247634556400, 0, + -20071017111583894941305187420771723751200, 0, + 7255051932731034189479516844750603752850, 0, + -2228176940331017311443863996901733412640, 0, + 579006552594977616773047095969088431600, 0, + -126584428502545713788439446082310831200, 0, + 23112325428835593809686977515028663000, 0, + -3491517141958743235617737161547844000, 0, + 431305058712550634988073414073557200, 0, + -42927166660756742088912492757452000, 0, + 3378527005707706553294038781836500, 0, + -205277590220215081719131470288800, 0, + 9330799555464321896324157740400, 0, + -304114948474392713657972548576, 0, + 6695289961520387531608984680, 0, + -91048139350447232095702560, 0, + 659769125727878493447120, 0, + -1905929106580294155360, 0, + 916312070471295267] + + roots_init = matrix(['-0.999', '-0.996', '-0.991', '-0.983', '-0.973', + '-0.961', '-0.946', '-0.93', '-0.911', '-0.889', + '-0.866', '-0.841', '-0.813', '-0.784', '-0.753', + '-0.72', '-0.685', '-0.649', '-0.611', '-0.572', + '-0.531', '-0.489', '-0.446', '-0.402', '-0.357', + '-0.311', '-0.265', '-0.217', '-0.17', '-0.121', + '-0.073', '-0.0243', '0.0243', '0.073', '0.121', + '0.17', '0.217', '0.265', ' 0.311', '0.357', + '0.402', '0.446', '0.489', '0.531', '0.572', + '0.611', '0.649', '0.685', '0.72', '0.753', + '0.784', '0.813', '0.841', '0.866', '0.889', + '0.911', '0.93', '0.946', '0.961', '0.973', + '0.983', '0.991', '0.996', '0.999', '1.0']) + with mp.workdps(2*mp.dps): + roots_exact = polyroots(coeffs, maxsteps=50, cleanup=True, error=False, + extraprec=2*extra_prec) + with pytest.raises(mp.NoConvergence): + polyroots(coeffs, maxsteps=5, cleanup=True, error=False, + extraprec=extra_prec) + roots,err = polyroots(coeffs, maxsteps=5, cleanup=True, error=True, + extraprec=extra_prec,roots_init=roots_init) + assert max(matrix(roots_exact)-matrix(roots).apply(abs)) < err + roots1,err1 = polyroots(coeffs, maxsteps=25, cleanup=True, error=True, + extraprec=extra_prec,roots_init=roots_init[:60]) + assert max(matrix(roots_exact)-matrix(roots1).apply(abs)) < err1 + +def test_pade(): + one = mpf(1) + mp.dps = 20 + N = 10 + a = [one] + k = 1 + for i in range(1, N+1): + k *= i + a.append(one/k) + p, q = pade(a, N//2, N//2) + for x in arange(0, 1, 0.1): + r = polyval(p[::-1], x)/polyval(q[::-1], x) + assert(r.ae(exp(x), 1.0e-10)) + mp.dps = 15 + +def test_fourier(): + mp.dps = 15 + c, s = fourier(lambda x: x+1, [-1, 2], 2) + #plot([lambda x: x+1, lambda x: fourierval((c, s), [-1, 2], x)], [-1, 2]) + assert c[0].ae(1.5) + assert c[1].ae(-3*sqrt(3)/(2*pi)) + assert c[2].ae(3*sqrt(3)/(4*pi)) + assert s[0] == 0 + assert s[1].ae(3/(2*pi)) + assert s[2].ae(3/(4*pi)) + assert fourierval((c, s), [-1, 2], 1).ae(1.9134966715663442) + +def test_differint(): + mp.dps = 15 + assert differint(lambda t: t, 2, -0.5).ae(8*sqrt(2/pi)/3) + +def test_invlap(): + mp.dps = 15 + t = 0.01 + fp = lambda p: 1/(p+1)**2 + ft = lambda t: t*exp(-t) + ftt = ft(t) + assert invertlaplace(fp,t,method='talbot').ae(ftt) + assert invertlaplace(fp,t,method='stehfest').ae(ftt) + assert invertlaplace(fp,t,method='dehoog').ae(ftt) + assert invertlaplace(fp,t,method='cohen').ae(ftt) + t = 1.0 + ftt = ft(t) + assert invertlaplace(fp,t,method='talbot').ae(ftt) + assert invertlaplace(fp,t,method='stehfest').ae(ftt) + assert invertlaplace(fp,t,method='dehoog').ae(ftt) + assert invertlaplace(fp,t,method='cohen').ae(ftt) + + t = 0.01 + fp = lambda p: log(p)/p + ft = lambda t: -euler-log(t) + ftt = ft(t) + assert invertlaplace(fp,t,method='talbot').ae(ftt) + assert invertlaplace(fp,t,method='stehfest').ae(ftt) + assert invertlaplace(fp,t,method='dehoog').ae(ftt) + assert invertlaplace(fp,t,method='cohen').ae(ftt) + t = 1.0 + ftt = ft(t) + assert invertlaplace(fp,t,method='talbot').ae(ftt) + assert invertlaplace(fp,t,method='stehfest').ae(ftt) + assert invertlaplace(fp,t,method='dehoog').ae(ftt) + assert invertlaplace(fp,t,method='cohen').ae(ftt) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_diff.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_diff.py new file mode 100644 index 0000000000000000000000000000000000000000..f5711609da38862eb4fd62c88d35f1704c9425a4 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_diff.py @@ -0,0 +1,61 @@ +from mpmath import * + +def test_diff(): + mp.dps = 15 + assert diff(log, 2.0, n=0).ae(log(2)) + assert diff(cos, 1.0).ae(-sin(1)) + assert diff(abs, 0.0) == 0 + assert diff(abs, 0.0, direction=1) == 1 + assert diff(abs, 0.0, direction=-1) == -1 + assert diff(exp, 1.0).ae(e) + assert diff(exp, 1.0, n=5).ae(e) + assert diff(exp, 2.0, n=5, direction=3*j).ae(e**2) + assert diff(lambda x: x**2, 3.0, method='quad').ae(6) + assert diff(lambda x: 3+x**5, 3.0, n=2, method='quad').ae(540) + assert diff(lambda x: 3+x**5, 3.0, n=2, method='step').ae(540) + assert diffun(sin)(2).ae(cos(2)) + assert diffun(sin, n=2)(2).ae(-sin(2)) + +def test_diffs(): + mp.dps = 15 + assert [chop(d) for d in diffs(sin, 0, 1)] == [0, 1] + assert [chop(d) for d in diffs(sin, 0, 1, method='quad')] == [0, 1] + assert [chop(d) for d in diffs(sin, 0, 2)] == [0, 1, 0] + assert [chop(d) for d in diffs(sin, 0, 2, method='quad')] == [0, 1, 0] + +def test_taylor(): + mp.dps = 15 + # Easy to test since the coefficients are exact in floating-point + assert taylor(sqrt, 1, 4) == [1, 0.5, -0.125, 0.0625, -0.0390625] + +def test_diff_partial(): + mp.dps = 15 + x,y,z = xyz = 2,3,7 + f = lambda x,y,z: 3*x**2 * (y+2)**3 * z**5 + assert diff(f, xyz, (0,0,0)).ae(25210500) + assert diff(f, xyz, (0,0,1)).ae(18007500) + assert diff(f, xyz, (0,0,2)).ae(10290000) + assert diff(f, xyz, (0,1,0)).ae(15126300) + assert diff(f, xyz, (0,1,1)).ae(10804500) + assert diff(f, xyz, (0,1,2)).ae(6174000) + assert diff(f, xyz, (0,2,0)).ae(6050520) + assert diff(f, xyz, (0,2,1)).ae(4321800) + assert diff(f, xyz, (0,2,2)).ae(2469600) + assert diff(f, xyz, (1,0,0)).ae(25210500) + assert diff(f, xyz, (1,0,1)).ae(18007500) + assert diff(f, xyz, (1,0,2)).ae(10290000) + assert diff(f, xyz, (1,1,0)).ae(15126300) + assert diff(f, xyz, (1,1,1)).ae(10804500) + assert diff(f, xyz, (1,1,2)).ae(6174000) + assert diff(f, xyz, (1,2,0)).ae(6050520) + assert diff(f, xyz, (1,2,1)).ae(4321800) + assert diff(f, xyz, (1,2,2)).ae(2469600) + assert diff(f, xyz, (2,0,0)).ae(12605250) + assert diff(f, xyz, (2,0,1)).ae(9003750) + assert diff(f, xyz, (2,0,2)).ae(5145000) + assert diff(f, xyz, (2,1,0)).ae(7563150) + assert diff(f, xyz, (2,1,1)).ae(5402250) + assert diff(f, xyz, (2,1,2)).ae(3087000) + assert diff(f, xyz, (2,2,0)).ae(3025260) + assert diff(f, xyz, (2,2,1)).ae(2160900) + assert diff(f, xyz, (2,2,2)).ae(1234800) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_elliptic.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_elliptic.py new file mode 100644 index 0000000000000000000000000000000000000000..4dddc2df34b8d2fa7f2028b3501e5b7f140d8912 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_elliptic.py @@ -0,0 +1,670 @@ +""" +Limited tests of the elliptic functions module. A full suite of +extensive testing can be found in elliptic_torture_tests.py + +Author of the first version: M.T. Taschuk + +References: + +[1] Abramowitz & Stegun. 'Handbook of Mathematical Functions, 9th Ed.', + (Dover duplicate of 1972 edition) +[2] Whittaker 'A Course of Modern Analysis, 4th Ed.', 1946, + Cambridge University Press + +""" + +import mpmath +import random +import pytest + +from mpmath import * + +def mpc_ae(a, b, eps=eps): + res = True + res = res and a.real.ae(b.real, eps) + res = res and a.imag.ae(b.imag, eps) + return res + +zero = mpf(0) +one = mpf(1) + +jsn = ellipfun('sn') +jcn = ellipfun('cn') +jdn = ellipfun('dn') + +calculate_nome = lambda k: qfrom(k=k) + +def test_ellipfun(): + mp.dps = 15 + assert ellipfun('ss', 0, 0) == 1 + assert ellipfun('cc', 0, 0) == 1 + assert ellipfun('dd', 0, 0) == 1 + assert ellipfun('nn', 0, 0) == 1 + assert ellipfun('sn', 0.25, 0).ae(sin(0.25)) + assert ellipfun('cn', 0.25, 0).ae(cos(0.25)) + assert ellipfun('dn', 0.25, 0).ae(1) + assert ellipfun('ns', 0.25, 0).ae(csc(0.25)) + assert ellipfun('nc', 0.25, 0).ae(sec(0.25)) + assert ellipfun('nd', 0.25, 0).ae(1) + assert ellipfun('sc', 0.25, 0).ae(tan(0.25)) + assert ellipfun('sd', 0.25, 0).ae(sin(0.25)) + assert ellipfun('cd', 0.25, 0).ae(cos(0.25)) + assert ellipfun('cs', 0.25, 0).ae(cot(0.25)) + assert ellipfun('dc', 0.25, 0).ae(sec(0.25)) + assert ellipfun('ds', 0.25, 0).ae(csc(0.25)) + assert ellipfun('sn', 0.25, 1).ae(tanh(0.25)) + assert ellipfun('cn', 0.25, 1).ae(sech(0.25)) + assert ellipfun('dn', 0.25, 1).ae(sech(0.25)) + assert ellipfun('ns', 0.25, 1).ae(coth(0.25)) + assert ellipfun('nc', 0.25, 1).ae(cosh(0.25)) + assert ellipfun('nd', 0.25, 1).ae(cosh(0.25)) + assert ellipfun('sc', 0.25, 1).ae(sinh(0.25)) + assert ellipfun('sd', 0.25, 1).ae(sinh(0.25)) + assert ellipfun('cd', 0.25, 1).ae(1) + assert ellipfun('cs', 0.25, 1).ae(csch(0.25)) + assert ellipfun('dc', 0.25, 1).ae(1) + assert ellipfun('ds', 0.25, 1).ae(csch(0.25)) + assert ellipfun('sn', 0.25, 0.5).ae(0.24615967096986145833) + assert ellipfun('cn', 0.25, 0.5).ae(0.96922928989378439337) + assert ellipfun('dn', 0.25, 0.5).ae(0.98473484156599474563) + assert ellipfun('ns', 0.25, 0.5).ae(4.0624038700573130369) + assert ellipfun('nc', 0.25, 0.5).ae(1.0317476065024692949) + assert ellipfun('nd', 0.25, 0.5).ae(1.0155017958029488665) + assert ellipfun('sc', 0.25, 0.5).ae(0.25397465134058993408) + assert ellipfun('sd', 0.25, 0.5).ae(0.24997558792415733063) + assert ellipfun('cd', 0.25, 0.5).ae(0.98425408443195497052) + assert ellipfun('cs', 0.25, 0.5).ae(3.9374008182374110826) + assert ellipfun('dc', 0.25, 0.5).ae(1.0159978158253033913) + assert ellipfun('ds', 0.25, 0.5).ae(4.0003906313579720593) + + + + +def test_calculate_nome(): + mp.dps = 100 + + q = calculate_nome(zero) + assert(q == zero) + + mp.dps = 25 + # used Mathematica's EllipticNomeQ[m] + math1 = [(mpf(1)/10, mpf('0.006584651553858370274473060')), + (mpf(2)/10, mpf('0.01394285727531826872146409')), + (mpf(3)/10, mpf('0.02227743615715350822901627')), + (mpf(4)/10, mpf('0.03188334731336317755064299')), + (mpf(5)/10, mpf('0.04321391826377224977441774')), + (mpf(6)/10, mpf('0.05702025781460967637754953')), + (mpf(7)/10, mpf('0.07468994353717944761143751')), + (mpf(8)/10, mpf('0.09927369733882489703607378')), + (mpf(9)/10, mpf('0.1401731269542615524091055')), + (mpf(9)/10, mpf('0.1401731269542615524091055'))] + + for i in math1: + m = i[0] + q = calculate_nome(sqrt(m)) + assert q.ae(i[1]) + + mp.dps = 15 + +def test_jtheta(): + mp.dps = 25 + + z = q = zero + for n in range(1,5): + value = jtheta(n, z, q) + assert(value == (n-1)//2) + + for q in [one, mpf(2)]: + for n in range(1,5): + pytest.raises(ValueError, lambda: jtheta(n, z, q)) + + z = one/10 + q = one/11 + + # Mathematical N[EllipticTheta[1, 1/10, 1/11], 25] + res = mpf('0.1069552990104042681962096') + result = jtheta(1, z, q) + assert(result.ae(res)) + + # Mathematica N[EllipticTheta[2, 1/10, 1/11], 25] + res = mpf('1.101385760258855791140606') + result = jtheta(2, z, q) + assert(result.ae(res)) + + # Mathematica N[EllipticTheta[3, 1/10, 1/11], 25] + res = mpf('1.178319743354331061795905') + result = jtheta(3, z, q) + assert(result.ae(res)) + + # Mathematica N[EllipticTheta[4, 1/10, 1/11], 25] + res = mpf('0.8219318954665153577314573') + result = jtheta(4, z, q) + assert(result.ae(res)) + + # test for sin zeros for jtheta(1, z, q) + # test for cos zeros for jtheta(2, z, q) + z1 = pi + z2 = pi/2 + for i in range(10): + qstring = str(random.random()) + q = mpf(qstring) + result = jtheta(1, z1, q) + assert(result.ae(0)) + result = jtheta(2, z2, q) + assert(result.ae(0)) + mp.dps = 15 + + +def test_jtheta_issue_79(): + # near the circle of covergence |q| = 1 the convergence slows + # down; for |q| > Q_LIM the theta functions raise ValueError + mp.dps = 30 + mp.dps += 30 + q = mpf(6)/10 - one/10**6 - mpf(8)/10 * j + mp.dps -= 30 + # Mathematica run first + # N[EllipticTheta[3, 1, 6/10 - 10^-6 - 8/10*I], 2000] + # then it works: + # N[EllipticTheta[3, 1, 6/10 - 10^-6 - 8/10*I], 30] + res = mpf('32.0031009628901652627099524264') + \ + mpf('16.6153027998236087899308935624') * j + result = jtheta(3, 1, q) + # check that for abs(q) > Q_LIM a ValueError exception is raised + mp.dps += 30 + q = mpf(6)/10 - one/10**7 - mpf(8)/10 * j + mp.dps -= 30 + pytest.raises(ValueError, lambda: jtheta(3, 1, q)) + + # bug reported in issue 79 + mp.dps = 100 + z = (1+j)/3 + q = mpf(368983957219251)/10**15 + mpf(636363636363636)/10**15 * j + # Mathematica N[EllipticTheta[1, z, q], 35] + res = mpf('2.4439389177990737589761828991467471') + \ + mpf('0.5446453005688226915290954851851490') *j + mp.dps = 30 + result = jtheta(1, z, q) + assert(result.ae(res)) + mp.dps = 80 + z = 3 + 4*j + q = 0.5 + 0.5*j + r1 = jtheta(1, z, q) + mp.dps = 15 + r2 = jtheta(1, z, q) + assert r1.ae(r2) + mp.dps = 80 + z = 3 + j + q1 = exp(j*3) + # longer test + # for n in range(1, 6) + for n in range(1, 2): + mp.dps = 80 + q = q1*(1 - mpf(1)/10**n) + r1 = jtheta(1, z, q) + mp.dps = 15 + r2 = jtheta(1, z, q) + assert r1.ae(r2) + mp.dps = 15 + # issue 79 about high derivatives + assert jtheta(3, 4.5, 0.25, 9).ae(1359.04892680683) + assert jtheta(3, 4.5, 0.25, 50).ae(-6.14832772630905e+33) + mp.dps = 50 + r = jtheta(3, 4.5, 0.25, 9) + assert r.ae('1359.048926806828939547859396600218966947753213803') + r = jtheta(3, 4.5, 0.25, 50) + assert r.ae('-6148327726309051673317975084654262.4119215720343656') + +def test_jtheta_identities(): + """ + Tests the some of the jacobi identidies found in Abramowitz, + Sec. 16.28, Pg. 576. The identities are tested to 1 part in 10^98. + """ + mp.dps = 110 + eps1 = ldexp(eps, 30) + + for i in range(10): + qstring = str(random.random()) + q = mpf(qstring) + + zstring = str(10*random.random()) + z = mpf(zstring) + # Abramowitz 16.28.1 + # v_1(z, q)**2 * v_4(0, q)**2 = v_3(z, q)**2 * v_2(0, q)**2 + # - v_2(z, q)**2 * v_3(0, q)**2 + term1 = (jtheta(1, z, q)**2) * (jtheta(4, zero, q)**2) + term2 = (jtheta(3, z, q)**2) * (jtheta(2, zero, q)**2) + term3 = (jtheta(2, z, q)**2) * (jtheta(3, zero, q)**2) + equality = term1 - term2 + term3 + assert(equality.ae(0, eps1)) + + zstring = str(100*random.random()) + z = mpf(zstring) + # Abramowitz 16.28.2 + # v_2(z, q)**2 * v_4(0, q)**2 = v_4(z, q)**2 * v_2(0, q)**2 + # - v_1(z, q)**2 * v_3(0, q)**2 + term1 = (jtheta(2, z, q)**2) * (jtheta(4, zero, q)**2) + term2 = (jtheta(4, z, q)**2) * (jtheta(2, zero, q)**2) + term3 = (jtheta(1, z, q)**2) * (jtheta(3, zero, q)**2) + equality = term1 - term2 + term3 + assert(equality.ae(0, eps1)) + + # Abramowitz 16.28.3 + # v_3(z, q)**2 * v_4(0, q)**2 = v_4(z, q)**2 * v_3(0, q)**2 + # - v_1(z, q)**2 * v_2(0, q)**2 + term1 = (jtheta(3, z, q)**2) * (jtheta(4, zero, q)**2) + term2 = (jtheta(4, z, q)**2) * (jtheta(3, zero, q)**2) + term3 = (jtheta(1, z, q)**2) * (jtheta(2, zero, q)**2) + equality = term1 - term2 + term3 + assert(equality.ae(0, eps1)) + + # Abramowitz 16.28.4 + # v_4(z, q)**2 * v_4(0, q)**2 = v_3(z, q)**2 * v_3(0, q)**2 + # - v_2(z, q)**2 * v_2(0, q)**2 + term1 = (jtheta(4, z, q)**2) * (jtheta(4, zero, q)**2) + term2 = (jtheta(3, z, q)**2) * (jtheta(3, zero, q)**2) + term3 = (jtheta(2, z, q)**2) * (jtheta(2, zero, q)**2) + equality = term1 - term2 + term3 + assert(equality.ae(0, eps1)) + + # Abramowitz 16.28.5 + # v_2(0, q)**4 + v_4(0, q)**4 == v_3(0, q)**4 + term1 = (jtheta(2, zero, q))**4 + term2 = (jtheta(4, zero, q))**4 + term3 = (jtheta(3, zero, q))**4 + equality = term1 + term2 - term3 + assert(equality.ae(0, eps1)) + mp.dps = 15 + +def test_jtheta_complex(): + mp.dps = 30 + z = mpf(1)/4 + j/8 + q = mpf(1)/3 + j/7 + # Mathematica N[EllipticTheta[1, 1/4 + I/8, 1/3 + I/7], 35] + res = mpf('0.31618034835986160705729105731678285') + \ + mpf('0.07542013825835103435142515194358975') * j + r = jtheta(1, z, q) + assert(mpc_ae(r, res)) + + # Mathematica N[EllipticTheta[2, 1/4 + I/8, 1/3 + I/7], 35] + res = mpf('1.6530986428239765928634711417951828') + \ + mpf('0.2015344864707197230526742145361455') * j + r = jtheta(2, z, q) + assert(mpc_ae(r, res)) + + # Mathematica N[EllipticTheta[3, 1/4 + I/8, 1/3 + I/7], 35] + res = mpf('1.6520564411784228184326012700348340') + \ + mpf('0.1998129119671271328684690067401823') * j + r = jtheta(3, z, q) + assert(mpc_ae(r, res)) + + # Mathematica N[EllipticTheta[4, 1/4 + I/8, 1/3 + I/7], 35] + res = mpf('0.37619082382228348252047624089973824') - \ + mpf('0.15623022130983652972686227200681074') * j + r = jtheta(4, z, q) + assert(mpc_ae(r, res)) + + # check some theta function identities + mp.dos = 100 + z = mpf(1)/4 + j/8 + q = mpf(1)/3 + j/7 + mp.dps += 10 + a = [0,0, jtheta(2, 0, q), jtheta(3, 0, q), jtheta(4, 0, q)] + t = [0, jtheta(1, z, q), jtheta(2, z, q), jtheta(3, z, q), jtheta(4, z, q)] + r = [(t[2]*a[4])**2 - (t[4]*a[2])**2 + (t[1] *a[3])**2, + (t[3]*a[4])**2 - (t[4]*a[3])**2 + (t[1] *a[2])**2, + (t[1]*a[4])**2 - (t[3]*a[2])**2 + (t[2] *a[3])**2, + (t[4]*a[4])**2 - (t[3]*a[3])**2 + (t[2] *a[2])**2, + a[2]**4 + a[4]**4 - a[3]**4] + mp.dps -= 10 + for x in r: + assert(mpc_ae(x, mpc(0))) + mp.dps = 15 + +def test_djtheta(): + mp.dps = 30 + + z = one/7 + j/3 + q = one/8 + j/5 + # Mathematica N[EllipticThetaPrime[1, 1/7 + I/3, 1/8 + I/5], 35] + res = mpf('1.5555195883277196036090928995803201') - \ + mpf('0.02439761276895463494054149673076275') * j + result = jtheta(1, z, q, 1) + assert(mpc_ae(result, res)) + + # Mathematica N[EllipticThetaPrime[2, 1/7 + I/3, 1/8 + I/5], 35] + res = mpf('0.19825296689470982332701283509685662') - \ + mpf('0.46038135182282106983251742935250009') * j + result = jtheta(2, z, q, 1) + assert(mpc_ae(result, res)) + + # Mathematica N[EllipticThetaPrime[3, 1/7 + I/3, 1/8 + I/5], 35] + res = mpf('0.36492498415476212680896699407390026') - \ + mpf('0.57743812698666990209897034525640369') * j + result = jtheta(3, z, q, 1) + assert(mpc_ae(result, res)) + + # Mathematica N[EllipticThetaPrime[4, 1/7 + I/3, 1/8 + I/5], 35] + res = mpf('-0.38936892528126996010818803742007352') + \ + mpf('0.66549886179739128256269617407313625') * j + result = jtheta(4, z, q, 1) + assert(mpc_ae(result, res)) + + for i in range(10): + q = (one*random.random() + j*random.random())/2 + # identity in Wittaker, Watson &21.41 + a = jtheta(1, 0, q, 1) + b = jtheta(2, 0, q)*jtheta(3, 0, q)*jtheta(4, 0, q) + assert(a.ae(b)) + + # test higher derivatives + mp.dps = 20 + for q,z in [(one/3, one/5), (one/3 + j/8, one/5), + (one/3, one/5 + j/8), (one/3 + j/7, one/5 + j/8)]: + for n in [1, 2, 3, 4]: + r = jtheta(n, z, q, 2) + r1 = diff(lambda zz: jtheta(n, zz, q), z, n=2) + assert r.ae(r1) + r = jtheta(n, z, q, 3) + r1 = diff(lambda zz: jtheta(n, zz, q), z, n=3) + assert r.ae(r1) + + # identity in Wittaker, Watson &21.41 + q = one/3 + z = zero + a = [0]*5 + a[1] = jtheta(1, z, q, 3)/jtheta(1, z, q, 1) + for n in [2,3,4]: + a[n] = jtheta(n, z, q, 2)/jtheta(n, z, q) + equality = a[2] + a[3] + a[4] - a[1] + assert(equality.ae(0)) + mp.dps = 15 + +def test_jsn(): + """ + Test some special cases of the sn(z, q) function. + """ + mp.dps = 100 + + # trival case + result = jsn(zero, zero) + assert(result == zero) + + # Abramowitz Table 16.5 + # + # sn(0, m) = 0 + + for i in range(10): + qstring = str(random.random()) + q = mpf(qstring) + + equality = jsn(zero, q) + assert(equality.ae(0)) + + # Abramowitz Table 16.6.1 + # + # sn(z, 0) = sin(z), m == 0 + # + # sn(z, 1) = tanh(z), m == 1 + # + # It would be nice to test these, but I find that they run + # in to numerical trouble. I'm currently treating as a boundary + # case for sn function. + + mp.dps = 25 + arg = one/10 + #N[JacobiSN[1/10, 2^-100], 25] + res = mpf('0.09983341664682815230681420') + m = ldexp(one, -100) + result = jsn(arg, m) + assert(result.ae(res)) + + # N[JacobiSN[1/10, 1/10], 25] + res = mpf('0.09981686718599080096451168') + result = jsn(arg, arg) + assert(result.ae(res)) + mp.dps = 15 + +def test_jcn(): + """ + Test some special cases of the cn(z, q) function. + """ + mp.dps = 100 + + # Abramowitz Table 16.5 + # cn(0, q) = 1 + qstring = str(random.random()) + q = mpf(qstring) + cn = jcn(zero, q) + assert(cn.ae(one)) + + # Abramowitz Table 16.6.2 + # + # cn(u, 0) = cos(u), m == 0 + # + # cn(u, 1) = sech(z), m == 1 + # + # It would be nice to test these, but I find that they run + # in to numerical trouble. I'm currently treating as a boundary + # case for cn function. + + mp.dps = 25 + arg = one/10 + m = ldexp(one, -100) + #N[JacobiCN[1/10, 2^-100], 25] + res = mpf('0.9950041652780257660955620') + result = jcn(arg, m) + assert(result.ae(res)) + + # N[JacobiCN[1/10, 1/10], 25] + res = mpf('0.9950058256237368748520459') + result = jcn(arg, arg) + assert(result.ae(res)) + mp.dps = 15 + +def test_jdn(): + """ + Test some special cases of the dn(z, q) function. + """ + mp.dps = 100 + + # Abramowitz Table 16.5 + # dn(0, q) = 1 + mstring = str(random.random()) + m = mpf(mstring) + + dn = jdn(zero, m) + assert(dn.ae(one)) + + mp.dps = 25 + # N[JacobiDN[1/10, 1/10], 25] + res = mpf('0.9995017055025556219713297') + arg = one/10 + result = jdn(arg, arg) + assert(result.ae(res)) + mp.dps = 15 + + +def test_sn_cn_dn_identities(): + """ + Tests the some of the jacobi elliptic function identities found + on Mathworld. Haven't found in Abramowitz. + """ + mp.dps = 100 + N = 5 + for i in range(N): + qstring = str(random.random()) + q = mpf(qstring) + zstring = str(100*random.random()) + z = mpf(zstring) + + # MathWorld + # sn(z, q)**2 + cn(z, q)**2 == 1 + term1 = jsn(z, q)**2 + term2 = jcn(z, q)**2 + equality = one - term1 - term2 + assert(equality.ae(0)) + + # MathWorld + # k**2 * sn(z, m)**2 + dn(z, m)**2 == 1 + for i in range(N): + mstring = str(random.random()) + m = mpf(qstring) + k = m.sqrt() + zstring = str(10*random.random()) + z = mpf(zstring) + term1 = k**2 * jsn(z, m)**2 + term2 = jdn(z, m)**2 + equality = one - term1 - term2 + assert(equality.ae(0)) + + + for i in range(N): + mstring = str(random.random()) + m = mpf(mstring) + k = m.sqrt() + zstring = str(random.random()) + z = mpf(zstring) + + # MathWorld + # k**2 * cn(z, m)**2 + (1 - k**2) = dn(z, m)**2 + term1 = k**2 * jcn(z, m)**2 + term2 = 1 - k**2 + term3 = jdn(z, m)**2 + equality = term3 - term1 - term2 + assert(equality.ae(0)) + + K = ellipk(k**2) + # Abramowitz Table 16.5 + # sn(K, m) = 1; K is K(k), first complete elliptic integral + r = jsn(K, m) + assert(r.ae(one)) + + # Abramowitz Table 16.5 + # cn(K, q) = 0; K is K(k), first complete elliptic integral + equality = jcn(K, m) + assert(equality.ae(0)) + + # Abramowitz Table 16.6.3 + # dn(z, 0) = 1, m == 0 + z = m + value = jdn(z, zero) + assert(value.ae(one)) + + mp.dps = 15 + +def test_sn_cn_dn_complex(): + mp.dps = 30 + # N[JacobiSN[1/4 + I/8, 1/3 + I/7], 35] in Mathematica + res = mpf('0.2495674401066275492326652143537') + \ + mpf('0.12017344422863833381301051702823') * j + u = mpf(1)/4 + j/8 + m = mpf(1)/3 + j/7 + r = jsn(u, m) + assert(mpc_ae(r, res)) + + #N[JacobiCN[1/4 + I/8, 1/3 + I/7], 35] + res = mpf('0.9762691700944007312693721148331') - \ + mpf('0.0307203994181623243583169154824')*j + r = jcn(u, m) + #assert r.real.ae(res.real) + #assert r.imag.ae(res.imag) + assert(mpc_ae(r, res)) + + #N[JacobiDN[1/4 + I/8, 1/3 + I/7], 35] + res = mpf('0.99639490163039577560547478589753039') - \ + mpf('0.01346296520008176393432491077244994')*j + r = jdn(u, m) + assert(mpc_ae(r, res)) + mp.dps = 15 + +def test_elliptic_integrals(): + # Test cases from Carlson's paper + mp.dps = 15 + assert elliprd(0,2,1).ae(1.7972103521033883112) + assert elliprd(2,3,4).ae(0.16510527294261053349) + assert elliprd(j,-j,2).ae(0.65933854154219768919) + assert elliprd(0,j,-j).ae(1.2708196271909686299 + 2.7811120159520578777j) + assert elliprd(0,j-1,j).ae(-1.8577235439239060056 - 0.96193450888838559989j) + assert elliprd(-2-j,-j,-1+j).ae(1.8249027393703805305 - 1.2218475784827035855j) + # extra test cases + assert elliprg(0,0,0) == 0 + assert elliprg(0,0,16).ae(2) + assert elliprg(0,16,0).ae(2) + assert elliprg(16,0,0).ae(2) + assert elliprg(1,4,0).ae(1.2110560275684595248036) + assert elliprg(1,0,4).ae(1.2110560275684595248036) + assert elliprg(0,4,1).ae(1.2110560275684595248036) + # should be symmetric -- fixes a bug present in the paper + x,y,z = 1,1j,-1+1j + assert elliprg(x,y,z).ae(0.64139146875812627545 + 0.58085463774808290907j) + assert elliprg(x,z,y).ae(0.64139146875812627545 + 0.58085463774808290907j) + assert elliprg(y,x,z).ae(0.64139146875812627545 + 0.58085463774808290907j) + assert elliprg(y,z,x).ae(0.64139146875812627545 + 0.58085463774808290907j) + assert elliprg(z,x,y).ae(0.64139146875812627545 + 0.58085463774808290907j) + assert elliprg(z,y,x).ae(0.64139146875812627545 + 0.58085463774808290907j) + + for n in [5, 15, 30, 60, 100]: + mp.dps = n + assert elliprf(1,2,0).ae('1.3110287771460599052324197949455597068413774757158115814084108519003952935352071251151477664807145467230678763') + assert elliprf(0.5,1,0).ae('1.854074677301371918433850347195260046217598823521766905585928045056021776838119978357271861650371897277771871') + assert elliprf(j,-j,0).ae('1.854074677301371918433850347195260046217598823521766905585928045056021776838119978357271861650371897277771871') + assert elliprf(j-1,j,0).ae(mpc('0.79612586584233913293056938229563057846592264089185680214929401744498956943287031832657642790719940442165621412', + '-1.2138566698364959864300942567386038975419875860741507618279563735753073152507112254567291141460317931258599889')) + assert elliprf(2,3,4).ae('0.58408284167715170669284916892566789240351359699303216166309375305508295130412919665541330837704050454472379308') + assert elliprf(j,-j,2).ae('1.0441445654064360931078658361850779139591660747973017593275012615517220315993723776182276555339288363064476126') + assert elliprf(j-1,j,1-j).ae(mpc('0.93912050218619371196624617169781141161485651998254431830645241993282941057500174238125105410055253623847335313', + '-0.53296252018635269264859303449447908970360344322834582313172115220559316331271520508208025270300138589669326136')) + assert elliprc(0,0.25).ae(+pi) + assert elliprc(2.25,2).ae(+ln2) + assert elliprc(0,j).ae(mpc('1.1107207345395915617539702475151734246536554223439225557713489017391086982748684776438317336911913093408525532', + '-1.1107207345395915617539702475151734246536554223439225557713489017391086982748684776438317336911913093408525532')) + assert elliprc(-j,j).ae(mpc('1.2260849569072198222319655083097718755633725139745941606203839524036426936825652935738621522906572884239069297', + '-0.34471136988767679699935618332997956653521218571295874986708834375026550946053920574015526038040124556716711353')) + assert elliprc(0.25,-2).ae(ln2/3) + assert elliprc(j,-1).ae(mpc('0.77778596920447389875196055840799837589537035343923012237628610795937014001905822029050288316217145443865649819', + '0.1983248499342877364755170948292130095921681309577950696116251029742793455964385947473103628983664877025779304')) + assert elliprj(0,1,2,3).ae('0.77688623778582332014190282640545501102298064276022952731669118325952563819813258230708177398475643634103990878') + assert elliprj(2,3,4,5).ae('0.14297579667156753833233879421985774801466647854232626336218889885463800128817976132826443904216546421431528308') + assert elliprj(2,3,4,-1+j).ae(mpc('0.13613945827770535203521374457913768360237593025944342652613569368333226052158214183059386307242563164036672709', + '-0.38207561624427164249600936454845112611060375760094156571007648297226090050927156176977091273224510621553615189')) + assert elliprj(j,-j,0,2).ae('1.6490011662710884518243257224860232300246792717163891216346170272567376981346412066066050103935109581019055806') + assert elliprj(-1+j,-1-j,1,2).ae('0.94148358841220238083044612133767270187474673547917988681610772381758628963408843935027667916713866133196845063') + assert elliprj(j,-j,0,1-j).ae(mpc('1.8260115229009316249372594065790946657011067182850435297162034335356430755397401849070610280860044610878657501', + '1.2290661908643471500163617732957042849283739403009556715926326841959667290840290081010472716420690899886276961')) + assert elliprj(-1+j,-1-j,1,-3+j).ae(mpc('-0.61127970812028172123588152373622636829986597243716610650831553882054127570542477508023027578037045504958619422', + '-1.0684038390006807880182112972232562745485871763154040245065581157751693730095703406209466903752930797510491155')) + assert elliprj(-1+j,-2-j,-j,-1+j).ae(mpc('1.8249027393703805304622013339009022294368078659619988943515764258335975852685224202567854526307030593012768954', + '-1.2218475784827035854568450371590419833166777535029296025352291308244564398645467465067845461070602841312456831')) + + assert elliprg(0,16,16).ae(+pi) + assert elliprg(2,3,4).ae('1.7255030280692277601061148835701141842692457170470456590515892070736643637303053506944907685301315299153040991') + assert elliprg(0,j,-j).ae('0.42360654239698954330324956174109581824072295516347109253028968632986700241706737986160014699730561497106114281') + assert elliprg(j-1,j,0).ae(mpc('0.44660591677018372656731970402124510811555212083508861036067729944477855594654762496407405328607219895053798354', + '0.70768352357515390073102719507612395221369717586839400605901402910893345301718731499237159587077682267374159282')) + assert elliprg(-j,j-1,j).ae(mpc('0.36023392184473309033675652092928695596803358846377334894215349632203382573844427952830064383286995172598964266', + '0.40348623401722113740956336997761033878615232917480045914551915169013722542827052849476969199578321834819903921')) + assert elliprg(0, mpf('0.0796'), 4).ae('1.0284758090288040009838871385180217366569777284430590125081211090574701293154645750017813190805144572673802094') + mp.dps = 15 + + # more test cases for the branch of ellippi / elliprj + assert elliprj(-1-0.5j, -10-6j, -10-3j, -5+10j).ae(0.128470516743927699 + 0.102175950778504625j, abs_eps=1e-8) + assert elliprj(1.987, 4.463 - 1.614j, 0, -3.965).ae(-0.341575118513811305 - 0.394703757004268486j, abs_eps=1e-8) + assert elliprj(0.3068, -4.037+0.632j, 1.654, -0.9609).ae(-1.14735199581485639 - 0.134450158867472264j, abs_eps=1e-8) + assert elliprj(0.3068, -4.037-0.632j, 1.654, -0.9609).ae(1.758765901861727 - 0.161002343366626892j, abs_eps=1e-5) + assert elliprj(0.3068, -4.037+0.0632j, 1.654, -0.9609).ae(-1.17157627949475577 - 0.069182614173988811j, abs_eps=1e-8) + assert elliprj(0.3068, -4.037+0.00632j, 1.654, -0.9609).ae(-1.17337595670549633 - 0.0623069224526925j, abs_eps=1e-8) + + # these require accurate integration + assert elliprj(0.3068, -4.037-0.0632j, 1.654, -0.9609).ae(1.77940452391261626 + 0.0388711305592447234j) + assert elliprj(0.3068, -4.037-0.00632j, 1.654, -0.9609).ae(1.77806722756403055 + 0.0592749824572262329j) + # issue #571 + assert ellippi(2.1 + 0.94j, 2.3 + 0.98j, 2.5 + 0.01j).ae(-0.40652414240811963438 + 2.1547659461404749309j) + + assert ellippi(2.0-1.0j, 2.0+1.0j).ae(1.8578723151271115 - 1.18642180609983531j) + assert ellippi(2.0-0.5j, 0.5+1.0j).ae(0.936761970766645807 - 1.61876787838890786j) + assert ellippi(2.0, 1.0+1.0j).ae(0.999881420735506708 - 2.4139272867045391j) + assert ellippi(2.0+1.0j, 2.0-1.0j).ae(1.8578723151271115 + 1.18642180609983531j) + assert ellippi(2.0+1.0j, 2.0).ae(2.78474654927885845 + 2.02204728966993314j) + +def test_issue_238(): + assert isnan(qfrom(m=nan)) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_fp.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_fp.py new file mode 100644 index 0000000000000000000000000000000000000000..99f3759c3071c4d55e0481472f3d16c1f5df1fef --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_fp.py @@ -0,0 +1,1671 @@ +""" +Easy-to-use test-generating code: + +cases = ''' +exp 2.25 +log 2.25 +''' + +from mpmath import * +mp.dps = 20 +for test in cases.splitlines(): + if not test: + continue + words = test.split() + fname = words[0] + args = words[1:] + argstr = ", ".join(args) + testline = "%s(%s)" % (fname, argstr) + ans = str(eval(testline)) + print " assert ae(fp.%s, %s)" % (testline, ans) + +""" + +from mpmath import fp + +def ae(x, y, tol=1e-12): + if x == y: + return True + return abs(x-y) <= tol*abs(y) + +def test_conj(): + assert fp.conj(4) == 4 + assert fp.conj(3+4j) == 3-4j + assert fp.fdot([1,2],[3,2+1j], conjugate=True) == 7-2j + +def test_fp_number_parts(): + assert ae(fp.arg(3), 0.0) + assert ae(fp.arg(-3), 3.1415926535897932385) + assert ae(fp.arg(3j), 1.5707963267948966192) + assert ae(fp.arg(-3j), -1.5707963267948966192) + assert ae(fp.arg(2+3j), 0.98279372324732906799) + assert ae(fp.arg(-1-1j), -2.3561944901923449288) + assert ae(fp.re(2.5), 2.5) + assert ae(fp.re(2.5+3j), 2.5) + assert ae(fp.im(2.5), 0.0) + assert ae(fp.im(2.5+3j), 3.0) + assert ae(fp.floor(2.5), 2.0) + assert ae(fp.floor(2), 2.0) + assert ae(fp.floor(2.0+0j), (2.0 + 0.0j)) + assert ae(fp.floor(-1.5-0.5j), (-2.0 - 1.0j)) + assert ae(fp.ceil(2.5), 3.0) + assert ae(fp.ceil(2), 2.0) + assert ae(fp.ceil(2.0+0j), (2.0 + 0.0j)) + assert ae(fp.ceil(-1.5-0.5j), (-1.0 + 0.0j)) + +def test_fp_cospi_sinpi(): + assert ae(fp.sinpi(0), 0.0) + assert ae(fp.sinpi(0.25), 0.7071067811865475244) + assert ae(fp.sinpi(0.5), 1.0) + assert ae(fp.sinpi(0.75), 0.7071067811865475244) + assert ae(fp.sinpi(1), 0.0) + assert ae(fp.sinpi(1.25), -0.7071067811865475244) + assert ae(fp.sinpi(1.5), -1.0) + assert ae(fp.sinpi(1.75), -0.7071067811865475244) + assert ae(fp.sinpi(2), 0.0) + assert ae(fp.sinpi(2.25), 0.7071067811865475244) + assert ae(fp.sinpi(0+3j), (0.0 + 6195.8238636085899556j)) + assert ae(fp.sinpi(0.25+3j), (4381.1091260582448033 + 4381.1090689950686908j)) + assert ae(fp.sinpi(0.5+3j), (6195.8239443081075259 + 0.0j)) + assert ae(fp.sinpi(0.75+3j), (4381.1091260582448033 - 4381.1090689950686908j)) + assert ae(fp.sinpi(1+3j), (0.0 - 6195.8238636085899556j)) + assert ae(fp.sinpi(1.25+3j), (-4381.1091260582448033 - 4381.1090689950686908j)) + assert ae(fp.sinpi(1.5+3j), (-6195.8239443081075259 + 0.0j)) + assert ae(fp.sinpi(1.75+3j), (-4381.1091260582448033 + 4381.1090689950686908j)) + assert ae(fp.sinpi(2+3j), (0.0 + 6195.8238636085899556j)) + assert ae(fp.sinpi(2.25+3j), (4381.1091260582448033 + 4381.1090689950686908j)) + assert ae(fp.sinpi(-0.75), -0.7071067811865475244) + assert ae(fp.sinpi(-1e-10), -3.1415926535897933529e-10) + assert ae(fp.sinpi(1e-10), 3.1415926535897933529e-10) + assert ae(fp.sinpi(1e-10+1e-10j), (3.141592653589793353e-10 + 3.1415926535897933528e-10j)) + assert ae(fp.sinpi(1e-10-1e-10j), (3.141592653589793353e-10 - 3.1415926535897933528e-10j)) + assert ae(fp.sinpi(-1e-10+1e-10j), (-3.141592653589793353e-10 + 3.1415926535897933528e-10j)) + assert ae(fp.sinpi(-1e-10-1e-10j), (-3.141592653589793353e-10 - 3.1415926535897933528e-10j)) + assert ae(fp.cospi(0), 1.0) + assert ae(fp.cospi(0.25), 0.7071067811865475244) + assert ae(fp.cospi(0.5), 0.0) + assert ae(fp.cospi(0.75), -0.7071067811865475244) + assert ae(fp.cospi(1), -1.0) + assert ae(fp.cospi(1.25), -0.7071067811865475244) + assert ae(fp.cospi(1.5), 0.0) + assert ae(fp.cospi(1.75), 0.7071067811865475244) + assert ae(fp.cospi(2), 1.0) + assert ae(fp.cospi(2.25), 0.7071067811865475244) + assert ae(fp.cospi(0+3j), (6195.8239443081075259 + 0.0j)) + assert ae(fp.cospi(0.25+3j), (4381.1091260582448033 - 4381.1090689950686908j)) + assert ae(fp.cospi(0.5+3j), (0.0 - 6195.8238636085899556j)) + assert ae(fp.cospi(0.75+3j), (-4381.1091260582448033 - 4381.1090689950686908j)) + assert ae(fp.cospi(1+3j), (-6195.8239443081075259 + 0.0j)) + assert ae(fp.cospi(1.25+3j), (-4381.1091260582448033 + 4381.1090689950686908j)) + assert ae(fp.cospi(1.5+3j), (0.0 + 6195.8238636085899556j)) + assert ae(fp.cospi(1.75+3j), (4381.1091260582448033 + 4381.1090689950686908j)) + assert ae(fp.cospi(2+3j), (6195.8239443081075259 + 0.0j)) + assert ae(fp.cospi(2.25+3j), (4381.1091260582448033 - 4381.1090689950686908j)) + assert ae(fp.cospi(-0.75), -0.7071067811865475244) + assert ae(fp.sinpi(-0.7), -0.80901699437494750611) + assert ae(fp.cospi(-0.7), -0.5877852522924730163) + assert ae(fp.cospi(-3+2j), (-267.74676148374822225 + 0.0j)) + assert ae(fp.sinpi(-3+2j), (0.0 - 267.74489404101651426j)) + assert ae(fp.sinpi(-0.7+2j), (-216.6116802292079471 - 157.37650009392034693j)) + assert ae(fp.cospi(-0.7+2j), (-157.37759774921754565 + 216.61016943630197336j)) + +def test_fp_expj(): + assert ae(fp.expj(0), (1.0 + 0.0j)) + assert ae(fp.expj(1), (0.5403023058681397174 + 0.84147098480789650665j)) + assert ae(fp.expj(2), (-0.416146836547142387 + 0.9092974268256816954j)) + assert ae(fp.expj(0.75), (0.73168886887382088631 + 0.68163876002333416673j)) + assert ae(fp.expj(2+3j), (-0.020718731002242879378 + 0.045271253156092975488j)) + assert ae(fp.expjpi(0), (1.0 + 0.0j)) + assert ae(fp.expjpi(1), (-1.0 + 0.0j)) + assert ae(fp.expjpi(2), (1.0 + 0.0j)) + assert ae(fp.expjpi(0.75), (-0.7071067811865475244 + 0.7071067811865475244j)) + assert ae(fp.expjpi(2+3j), (0.000080699517570304599239 + 0.0j)) + +def test_fp_bernoulli(): + assert ae(fp.bernoulli(0), 1.0) + assert ae(fp.bernoulli(1), -0.5) + assert ae(fp.bernoulli(2), 0.16666666666666666667) + assert ae(fp.bernoulli(10), 0.075757575757575757576) + assert ae(fp.bernoulli(11), 0.0) + +def test_fp_gamma(): + assert ae(fp.gamma(1), 1.0) + assert ae(fp.gamma(1.5), 0.88622692545275801365) + assert ae(fp.gamma(10), 362880.0) + assert ae(fp.gamma(-0.5), -3.5449077018110320546) + assert ae(fp.gamma(-7.1), 0.0016478244570263333622) + assert ae(fp.gamma(12.3), 83385367.899970000963) + assert ae(fp.gamma(2+0j), (1.0 + 0.0j)) + assert ae(fp.gamma(-2.5+0j), (-0.94530872048294188123 + 0.0j)) + assert ae(fp.gamma(3+4j), (0.0052255384713692141947 - 0.17254707929430018772j)) + assert ae(fp.gamma(-3-4j), (0.00001460997305874775607 - 0.000020760733311509070396j)) + assert ae(fp.fac(0), 1.0) + assert ae(fp.fac(1), 1.0) + assert ae(fp.fac(20), 2432902008176640000.0) + assert ae(fp.fac(-3.5), -0.94530872048294188123) + assert ae(fp.fac(2+3j), (-0.44011340763700171113 - 0.06363724312631702183j)) + assert ae(fp.loggamma(1.0), 0.0) + assert ae(fp.loggamma(2.0), 0.0) + assert ae(fp.loggamma(3.0), 0.69314718055994530942) + assert ae(fp.loggamma(7.25), 7.0521854507385394449) + assert ae(fp.loggamma(1000.0), 5905.2204232091812118) + assert ae(fp.loggamma(1e50), 1.1412925464970229298e+52) + assert ae(fp.loggamma(1e25+1e25j), (5.6125802751733671621e+26 + 5.7696599078528568383e+26j)) + assert ae(fp.loggamma(3+4j), (-1.7566267846037841105 + 4.7426644380346579282j)) + assert ae(fp.loggamma(-0.5), (1.2655121234846453965 - 3.1415926535897932385j)) + assert ae(fp.loggamma(-1.25), (1.3664317612369762346 - 6.2831853071795864769j)) + assert ae(fp.loggamma(-2.75), (0.0044878975359557733115 - 9.4247779607693797154j)) + assert ae(fp.loggamma(-3.5), (-1.3090066849930420464 - 12.566370614359172954j)) + assert ae(fp.loggamma(-4.5), (-2.8130840817693161197 - 15.707963267948966192j)) + assert ae(fp.loggamma(-2+3j), (-6.776523813485657093 - 4.568791367260286402j)) + assert ae(fp.loggamma(-1000.3), (-5912.8440347785205041 - 3144.7342462433830317j)) + assert ae(fp.loggamma(-100-100j), (-632.35117666833135562 - 158.37641469650352462j)) + assert ae(fp.loggamma(1e-10), 23.025850929882735237) + assert ae(fp.loggamma(-1e-10), (23.02585092999817837 - 3.1415926535897932385j)) + assert ae(fp.loggamma(1e-10j), (23.025850929940456804 - 1.5707963268526181857j)) + assert ae(fp.loggamma(1e-10j-1e-10), (22.679277339718205716 - 2.3561944902500664954j)) + +def test_fp_psi(): + assert ae(fp.psi(0, 3.7), 1.1671535393615114409) + assert ae(fp.psi(0, 0.5), -1.9635100260214234794) + assert ae(fp.psi(0, 1), -0.57721566490153286061) + assert ae(fp.psi(0, -2.5), 1.1031566406452431872) + assert ae(fp.psi(0, 12.9), 2.5179671503279156347) + assert ae(fp.psi(0, 100), 4.6001618527380874002) + assert ae(fp.psi(0, 2500.3), 7.8239660143238547877) + assert ae(fp.psi(0, 1e40), 92.103403719761827391) + assert ae(fp.psi(0, 1e200), 460.51701859880913677) + assert ae(fp.psi(0, 3.7+0j), (1.1671535393615114409 + 0.0j)) + assert ae(fp.psi(1, 3), 0.39493406684822643647) + assert ae(fp.psi(3, 2+3j), (-0.05383196209159972116 + 0.0076890935247364805218j)) + assert ae(fp.psi(4, -0.5+1j), (1.2719531355492328195 - 18.211833410936276774j)) + assert ae(fp.harmonic(0), 0.0) + assert ae(fp.harmonic(1), 1.0) + assert ae(fp.harmonic(2), 1.5) + assert ae(fp.harmonic(100), 5.1873775176396202608) + assert ae(fp.harmonic(-2.5), 1.2803723055467760478) + assert ae(fp.harmonic(2+3j), (1.9390425294578375875 + 0.87336044981834544043j)) + assert ae(fp.harmonic(-5-4j), (2.3725754822349437733 - 2.4160904444801621j)) + +def test_fp_zeta(): + assert ae(fp.zeta(1e100), 1.0) + assert ae(fp.zeta(3), 1.2020569031595942854) + assert ae(fp.zeta(2+0j), (1.6449340668482264365 + 0.0j)) + assert ae(fp.zeta(0.93), -13.713619351638164784) + assert ae(fp.zeta(1.74), 1.9796863545771774095) + assert ae(fp.zeta(0.0), -0.5) + assert ae(fp.zeta(-1.0), -0.083333333333333333333) + assert ae(fp.zeta(-2.0), 0.0) + assert ae(fp.zeta(-3.0), 0.0083333333333333333333) + assert ae(fp.zeta(-500.0), 0.0) + assert ae(fp.zeta(-7.4), 0.0036537321227995882447) + assert ae(fp.zeta(2.1), 1.5602165335033620158) + assert ae(fp.zeta(26.9), 1.0000000079854809935) + assert ae(fp.zeta(26), 1.0000000149015548284) + assert ae(fp.zeta(27), 1.0000000074507117898) + assert ae(fp.zeta(28), 1.0000000037253340248) + assert ae(fp.zeta(27.1), 1.000000006951755045) + assert ae(fp.zeta(32.7), 1.0000000001433243232) + assert ae(fp.zeta(100), 1.0) + assert ae(fp.altzeta(3.5), 0.92755357777394803511) + assert ae(fp.altzeta(1), 0.69314718055994530942) + assert ae(fp.altzeta(2), 0.82246703342411321824) + assert ae(fp.altzeta(0), 0.5) + assert ae(fp.zeta(-2+3j, 1), (0.13297115587929864827 + 0.12305330040458776494j)) + assert ae(fp.zeta(-2+3j, 5), (18.384866151867576927 - 11.377015110597711009j)) + assert ae(fp.zeta(1.0000000001), 9999999173.1735741337) + assert ae(fp.zeta(0.9999999999), -9999999172.0191428039) + assert ae(fp.zeta(1+0.000000001j), (0.57721566490153286061 - 999999999.99999993765j)) + assert ae(fp.primezeta(2.5+4j), (-0.16922458243438033385 - 0.010847965298387727811j)) + assert ae(fp.primezeta(4), 0.076993139764246844943) + assert ae(fp.riemannr(3.7), 2.3034079839110855717) + assert ae(fp.riemannr(8), 3.9011860449341499474) + assert ae(fp.riemannr(3+4j), (2.2369653314259991796 + 1.6339943856990281694j)) + +def test_fp_hyp2f1(): + assert ae(fp.hyp2f1(1, (3,2), 3.25, 5.0), (-0.46600275923108143059 - 0.74393667908854842325j)) + assert ae(fp.hyp2f1(1+1j, (3,2), 3.25, 5.0), (-5.9208875603806515987 - 2.3813557707889590686j)) + assert ae(fp.hyp2f1(1+1j, (3,2), 3.25, 2+3j), (0.17174552030925080445 + 0.19589781970539389999j)) + +def test_fp_erf(): + assert fp.erf(2) == fp.erf(2.0) == fp.erf(2.0+0.0j) + assert fp.erf(fp.inf) == 1.0 + assert fp.erf(fp.ninf) == -1.0 + assert ae(fp.erf(0), 0.0) + assert ae(fp.erf(-0), -0.0) + assert ae(fp.erf(0.3), 0.32862675945912741619) + assert ae(fp.erf(-0.3), -0.32862675945912741619) + assert ae(fp.erf(0.9), 0.79690821242283213966) + assert ae(fp.erf(-0.9), -0.79690821242283213966) + assert ae(fp.erf(1.0), 0.84270079294971486934) + assert ae(fp.erf(-1.0), -0.84270079294971486934) + assert ae(fp.erf(1.1), 0.88020506957408172966) + assert ae(fp.erf(-1.1), -0.88020506957408172966) + assert ae(fp.erf(8.5), 1.0) + assert ae(fp.erf(-8.5), -1.0) + assert ae(fp.erf(9.1), 1.0) + assert ae(fp.erf(-9.1), -1.0) + assert ae(fp.erf(20.0), 1.0) + assert ae(fp.erf(-20.0), -1.0) + assert ae(fp.erf(10000.0), 1.0) + assert ae(fp.erf(-10000.0), -1.0) + assert ae(fp.erf(1e+50), 1.0) + assert ae(fp.erf(-1e+50), -1.0) + assert ae(fp.erf(1j), 1.650425758797542876j) + assert ae(fp.erf(-1j), -1.650425758797542876j) + assert ae(fp.erf((2+3j)), (-20.829461427614568389 + 8.6873182714701631444j)) + assert ae(fp.erf(-(2+3j)), -(-20.829461427614568389 + 8.6873182714701631444j)) + assert ae(fp.erf((8+9j)), (-1072004.2525062051158 + 364149.91954310255423j)) + assert ae(fp.erf(-(8+9j)), -(-1072004.2525062051158 + 364149.91954310255423j)) + assert fp.erfc(fp.inf) == 0.0 + assert fp.erfc(fp.ninf) == 2.0 + assert fp.erfc(0) == 1 + assert fp.erfc(-0.0) == 1 + assert fp.erfc(0+0j) == 1 + assert ae(fp.erfc(0.3), 0.67137324054087258381) + assert ae(fp.erfc(-0.3), 1.3286267594591274162) + assert ae(fp.erfc(0.9), 0.20309178757716786034) + assert ae(fp.erfc(-0.9), 1.7969082124228321397) + assert ae(fp.erfc(1.0), 0.15729920705028513066) + assert ae(fp.erfc(-1.0), 1.8427007929497148693) + assert ae(fp.erfc(1.1), 0.11979493042591827034) + assert ae(fp.erfc(-1.1), 1.8802050695740817297) + assert ae(fp.erfc(8.5), 2.7623240713337714461e-33) + assert ae(fp.erfc(-8.5), 2.0) + assert ae(fp.erfc(9.1), 6.6969004279886077452e-38) + assert ae(fp.erfc(-9.1), 2.0) + assert ae(fp.erfc(20.0), 5.3958656116079009289e-176) + assert ae(fp.erfc(-20.0), 2.0) + assert ae(fp.erfc(10000.0), 0.0) + assert ae(fp.erfc(-10000.0), 2.0) + assert ae(fp.erfc(1e+50), 0.0) + assert ae(fp.erfc(-1e+50), 2.0) + assert ae(fp.erfc(1j), (1.0 - 1.650425758797542876j)) + assert ae(fp.erfc(-1j), (1.0 + 1.650425758797542876j)) + assert ae(fp.erfc((2+3j)), (21.829461427614568389 - 8.6873182714701631444j), 1e-13) + assert ae(fp.erfc(-(2+3j)), (-19.829461427614568389 + 8.6873182714701631444j), 1e-13) + assert ae(fp.erfc((8+9j)), (1072005.2525062051158 - 364149.91954310255423j)) + assert ae(fp.erfc(-(8+9j)), (-1072003.2525062051158 + 364149.91954310255423j)) + assert ae(fp.erfc(20+0j), (5.3958656116079009289e-176 + 0.0j)) + +def test_fp_lambertw(): + assert ae(fp.lambertw(0.0), 0.0) + assert ae(fp.lambertw(1.0), 0.567143290409783873) + assert ae(fp.lambertw(7.5), 1.5662309537823875394) + assert ae(fp.lambertw(-0.25), -0.35740295618138890307) + assert ae(fp.lambertw(-10.0), (1.3699809685212708156 + 2.140194527074713196j)) + assert ae(fp.lambertw(0+0j), (0.0 + 0.0j)) + assert ae(fp.lambertw(4+0j), (1.2021678731970429392 + 0.0j)) + assert ae(fp.lambertw(1000.5), 5.2500227450408980127) + assert ae(fp.lambertw(1e100), 224.84310644511850156) + assert ae(fp.lambertw(-1000.0), (5.1501630246362515223 + 2.6641981432905204596j)) + assert ae(fp.lambertw(1e-10), 9.9999999990000003645e-11) + assert ae(fp.lambertw(1e-10j), (1.0000000000000000728e-20 + 1.0000000000000000364e-10j)) + assert ae(fp.lambertw(3+4j), (1.2815618061237758782 + 0.53309522202097107131j)) + assert ae(fp.lambertw(-3-4j), (1.0750730665692549276 - 1.3251023817343588823j)) + assert ae(fp.lambertw(10000+1000j), (7.2361526563371602186 + 0.087567810943839352034j)) + assert ae(fp.lambertw(0.0, -1), -fp.inf) + assert ae(fp.lambertw(1.0, -1), (-1.5339133197935745079 - 4.3751851530618983855j)) + assert ae(fp.lambertw(7.5, -1), (0.44125668415098614999 - 4.8039842008452390179j)) + assert ae(fp.lambertw(-0.25, -1), -2.1532923641103496492) + assert ae(fp.lambertw(-10.0, -1), (1.3699809685212708156 - 2.140194527074713196j)) + assert ae(fp.lambertw(0+0j, -1), -fp.inf) + assert ae(fp.lambertw(4+0j, -1), (-0.15730793189620765317 - 4.6787800704666656212j)) + assert ae(fp.lambertw(1000.5, -1), (4.9153765415404024736 - 5.4465682700815159569j)) + assert ae(fp.lambertw(1e100, -1), (224.84272130101601052 - 6.2553713838167244141j)) + assert ae(fp.lambertw(-1000.0, -1), (5.1501630246362515223 - 2.6641981432905204596j)) + assert ae(fp.lambertw(1e-10, -1), (-26.303186778379041521 - 3.2650939117038283975j)) + assert ae(fp.lambertw(1e-10j, -1), (-26.297238779529035028 - 1.6328071613455765135j)) + assert ae(fp.lambertw(3+4j, -1), (0.25856740686699741676 - 3.8521166861614355895j)) + assert ae(fp.lambertw(-3-4j, -1), (-0.32028750204310768396 - 6.8801677192091972343j)) + assert ae(fp.lambertw(10000+1000j, -1), (7.0255308742285435567 - 5.5177506835734067601j)) + assert ae(fp.lambertw(0.0, 2), -fp.inf) + assert ae(fp.lambertw(1.0, 2), (-2.4015851048680028842 + 10.776299516115070898j)) + assert ae(fp.lambertw(7.5, 2), (-0.38003357962843791529 + 10.960916473368746184j)) + assert ae(fp.lambertw(-0.25, 2), (-4.0558735269061511898 + 13.852334658567271386j)) + assert ae(fp.lambertw(-10.0, 2), (-0.34479123764318858696 + 14.112740596763592363j)) + assert ae(fp.lambertw(0+0j, 2), -fp.inf) + assert ae(fp.lambertw(4+0j, 2), (-1.0070343323804262788 + 10.903476551861683082j)) + assert ae(fp.lambertw(1000.5, 2), (4.4076185165459395295 + 11.365524591091402177j)) + assert ae(fp.lambertw(1e100, 2), (224.84156762724875878 + 12.510785262632255672j)) + assert ae(fp.lambertw(-1000.0, 2), (4.1984245610246530756 + 14.420478573754313845j)) + assert ae(fp.lambertw(1e-10, 2), (-26.362258095445866488 + 9.7800247407031482519j)) + assert ae(fp.lambertw(1e-10j, 2), (-26.384250801683084252 + 11.403535950607739763j)) + assert ae(fp.lambertw(3+4j, 2), (-0.86554679943333993562 + 11.849956798331992027j)) + assert ae(fp.lambertw(-3-4j, 2), (-0.55792273874679112639 + 8.7173627024159324811j)) + assert ae(fp.lambertw(10000+1000j, 2), (6.6223802254585662734 + 11.61348646825020766j)) + +def test_fp_stress_ei_e1(): + # Can be tightened on recent Pythons with more accurate math/cmath + ATOL = 1e-13 + PTOL = 1e-12 + v = fp.e1(1.1641532182693481445e-10) + assert ae(v, 22.296641293693077672, tol=ATOL) + assert type(v) is float + v = fp.e1(0.25) + assert ae(v, 1.0442826344437381945, tol=ATOL) + assert type(v) is float + v = fp.e1(1.0) + assert ae(v, 0.21938393439552027368, tol=ATOL) + assert type(v) is float + v = fp.e1(2.0) + assert ae(v, 0.048900510708061119567, tol=ATOL) + assert type(v) is float + v = fp.e1(5.0) + assert ae(v, 0.0011482955912753257973, tol=ATOL) + assert type(v) is float + v = fp.e1(20.0) + assert ae(v, 9.8355252906498816904e-11, tol=ATOL) + assert type(v) is float + v = fp.e1(30.0) + assert ae(v, 3.0215520106888125448e-15, tol=ATOL) + assert type(v) is float + v = fp.e1(40.0) + assert ae(v, 1.0367732614516569722e-19, tol=ATOL) + assert type(v) is float + v = fp.e1(50.0) + assert ae(v, 3.7832640295504590187e-24, tol=ATOL) + assert type(v) is float + v = fp.e1(80.0) + assert ae(v, 2.2285432586884729112e-37, tol=ATOL) + assert type(v) is float + v = fp.e1((1.1641532182693481445e-10 + 0.0j)) + assert ae(v, (22.296641293693077672 + 0.0j), tol=ATOL) + assert ae(v.real, 22.296641293693077672, tol=PTOL) + assert v.imag == 0 + v = fp.e1((0.25 + 0.0j)) + assert ae(v, (1.0442826344437381945 + 0.0j), tol=ATOL) + assert ae(v.real, 1.0442826344437381945, tol=PTOL) + assert v.imag == 0 + v = fp.e1((1.0 + 0.0j)) + assert ae(v, (0.21938393439552027368 + 0.0j), tol=ATOL) + assert ae(v.real, 0.21938393439552027368, tol=PTOL) + assert v.imag == 0 + v = fp.e1((2.0 + 0.0j)) + assert ae(v, (0.048900510708061119567 + 0.0j), tol=ATOL) + assert ae(v.real, 0.048900510708061119567, tol=PTOL) + assert v.imag == 0 + v = fp.e1((5.0 + 0.0j)) + assert ae(v, (0.0011482955912753257973 + 0.0j), tol=ATOL) + assert ae(v.real, 0.0011482955912753257973, tol=PTOL) + assert v.imag == 0 + v = fp.e1((20.0 + 0.0j)) + assert ae(v, (9.8355252906498816904e-11 + 0.0j), tol=ATOL) + assert ae(v.real, 9.8355252906498816904e-11, tol=PTOL) + assert v.imag == 0 + v = fp.e1((30.0 + 0.0j)) + assert ae(v, (3.0215520106888125448e-15 + 0.0j), tol=ATOL) + assert ae(v.real, 3.0215520106888125448e-15, tol=PTOL) + assert v.imag == 0 + v = fp.e1((40.0 + 0.0j)) + assert ae(v, (1.0367732614516569722e-19 + 0.0j), tol=ATOL) + assert ae(v.real, 1.0367732614516569722e-19, tol=PTOL) + assert v.imag == 0 + v = fp.e1((50.0 + 0.0j)) + assert ae(v, (3.7832640295504590187e-24 + 0.0j), tol=ATOL) + assert ae(v.real, 3.7832640295504590187e-24, tol=PTOL) + assert v.imag == 0 + v = fp.e1((80.0 + 0.0j)) + assert ae(v, (2.2285432586884729112e-37 + 0.0j), tol=ATOL) + assert ae(v.real, 2.2285432586884729112e-37, tol=PTOL) + assert v.imag == 0 + v = fp.e1((4.6566128730773925781e-10 + 1.1641532182693481445e-10j)) + assert ae(v, (20.880034622014215597 - 0.24497866301044883237j), tol=ATOL) + assert ae(v.real, 20.880034622014215597, tol=PTOL) + assert ae(v.imag, -0.24497866301044883237, tol=PTOL) + v = fp.e1((1.0 + 0.25j)) + assert ae(v, (0.19731063945004229095 - 0.087366045774299963672j), tol=ATOL) + assert ae(v.real, 0.19731063945004229095, tol=PTOL) + assert ae(v.imag, -0.087366045774299963672, tol=PTOL) + v = fp.e1((4.0 + 1.0j)) + assert ae(v, (0.0013106173980145506944 - 0.0034542480199350626699j), tol=ATOL) + assert ae(v.real, 0.0013106173980145506944, tol=PTOL) + assert ae(v.imag, -0.0034542480199350626699, tol=PTOL) + v = fp.e1((8.0 + 2.0j)) + assert ae(v, (-0.000022278049065270225945 - 0.000029191940456521555288j), tol=ATOL) + assert ae(v.real, -0.000022278049065270225945, tol=PTOL) + assert ae(v.imag, -0.000029191940456521555288, tol=PTOL) + v = fp.e1((20.0 + 5.0j)) + assert ae(v, (4.7711374515765346894e-11 + 8.2902652405126947359e-11j), tol=ATOL) + assert ae(v.real, 4.7711374515765346894e-11, tol=PTOL) + assert ae(v.imag, 8.2902652405126947359e-11, tol=PTOL) + v = fp.e1((80.0 + 20.0j)) + assert ae(v, (3.8353473865788235787e-38 - 2.129247592349605139e-37j), tol=ATOL) + assert ae(v.real, 3.8353473865788235787e-38, tol=PTOL) + assert ae(v.imag, -2.129247592349605139e-37, tol=PTOL) + v = fp.e1((120.0 + 30.0j)) + assert ae(v, (2.3836002337480334716e-55 + 5.6704043587126198306e-55j), tol=ATOL) + assert ae(v.real, 2.3836002337480334716e-55, tol=PTOL) + assert ae(v.imag, 5.6704043587126198306e-55, tol=PTOL) + v = fp.e1((160.0 + 40.0j)) + assert ae(v, (-1.6238022898654510661e-72 - 1.104172355572287367e-72j), tol=ATOL) + assert ae(v.real, -1.6238022898654510661e-72, tol=PTOL) + assert ae(v.imag, -1.104172355572287367e-72, tol=PTOL) + v = fp.e1((200.0 + 50.0j)) + assert ae(v, (6.6800061461666228487e-90 + 1.4473816083541016115e-91j), tol=ATOL) + assert ae(v.real, 6.6800061461666228487e-90, tol=PTOL) + assert ae(v.imag, 1.4473816083541016115e-91, tol=PTOL) + v = fp.e1((320.0 + 80.0j)) + assert ae(v, (4.2737871527778786157e-143 + 3.1789935525785660314e-142j), tol=ATOL) + assert ae(v.real, 4.2737871527778786157e-143, tol=PTOL) + assert ae(v.imag, 3.1789935525785660314e-142, tol=PTOL) + v = fp.e1((1.1641532182693481445e-10 + 1.1641532182693481445e-10j)) + assert ae(v, (21.950067703413105017 - 0.7853981632810329878j), tol=ATOL) + assert ae(v.real, 21.950067703413105017, tol=PTOL) + assert ae(v.imag, -0.7853981632810329878, tol=PTOL) + v = fp.e1((0.25 + 0.25j)) + assert ae(v, (0.71092525792923287894 - 0.56491812441304194711j), tol=ATOL) + assert ae(v.real, 0.71092525792923287894, tol=PTOL) + assert ae(v.imag, -0.56491812441304194711, tol=PTOL) + v = fp.e1((1.0 + 1.0j)) + assert ae(v, (0.00028162445198141832551 - 0.17932453503935894015j), tol=ATOL) + assert ae(v.real, 0.00028162445198141832551, tol=PTOL) + assert ae(v.imag, -0.17932453503935894015, tol=PTOL) + v = fp.e1((2.0 + 2.0j)) + assert ae(v, (-0.033767089606562004246 - 0.018599414169750541925j), tol=ATOL) + assert ae(v.real, -0.033767089606562004246, tol=PTOL) + assert ae(v.imag, -0.018599414169750541925, tol=PTOL) + v = fp.e1((5.0 + 5.0j)) + assert ae(v, (0.0007266506660356393891 + 0.00047102780163522245054j), tol=ATOL) + assert ae(v.real, 0.0007266506660356393891, tol=PTOL) + assert ae(v.imag, 0.00047102780163522245054, tol=PTOL) + v = fp.e1((20.0 + 20.0j)) + assert ae(v, (-2.3824537449367396579e-11 - 6.6969873156525615158e-11j), tol=ATOL) + assert ae(v.real, -2.3824537449367396579e-11, tol=PTOL) + assert ae(v.imag, -6.6969873156525615158e-11, tol=PTOL) + v = fp.e1((30.0 + 30.0j)) + assert ae(v, (1.7316045841744061617e-15 + 1.3065678019487308689e-15j), tol=ATOL) + assert ae(v.real, 1.7316045841744061617e-15, tol=PTOL) + assert ae(v.imag, 1.3065678019487308689e-15, tol=PTOL) + v = fp.e1((40.0 + 40.0j)) + assert ae(v, (-7.4001043002899232182e-20 - 4.991847855336816304e-21j), tol=ATOL) + assert ae(v.real, -7.4001043002899232182e-20, tol=PTOL) + assert ae(v.imag, -4.991847855336816304e-21, tol=PTOL) + v = fp.e1((50.0 + 50.0j)) + assert ae(v, (2.3566128324644641219e-24 - 1.3188326726201614778e-24j), tol=ATOL) + assert ae(v.real, 2.3566128324644641219e-24, tol=PTOL) + assert ae(v.imag, -1.3188326726201614778e-24, tol=PTOL) + v = fp.e1((80.0 + 80.0j)) + assert ae(v, (9.8279750572186526673e-38 + 1.243952841288868831e-37j), tol=ATOL) + assert ae(v.real, 9.8279750572186526673e-38, tol=PTOL) + assert ae(v.imag, 1.243952841288868831e-37, tol=PTOL) + v = fp.e1((1.1641532182693481445e-10 + 4.6566128730773925781e-10j)) + assert ae(v, (20.880034621664969632 - 1.3258176632023711778j), tol=ATOL) + assert ae(v.real, 20.880034621664969632, tol=PTOL) + assert ae(v.imag, -1.3258176632023711778, tol=PTOL) + v = fp.e1((0.25 + 1.0j)) + assert ae(v, (-0.16868306393667788761 - 0.4858011885947426971j), tol=ATOL) + assert ae(v.real, -0.16868306393667788761, tol=PTOL) + assert ae(v.imag, -0.4858011885947426971, tol=PTOL) + v = fp.e1((1.0 + 4.0j)) + assert ae(v, (0.03373591813926547318 + 0.073523452241083821877j), tol=ATOL) + assert ae(v.real, 0.03373591813926547318, tol=PTOL) + assert ae(v.imag, 0.073523452241083821877, tol=PTOL) + v = fp.e1((2.0 + 8.0j)) + assert ae(v, (-0.015392833434733785143 - 0.0031747121557605415914j), tol=ATOL) + assert ae(v.real, -0.015392833434733785143, tol=PTOL) + assert ae(v.imag, -0.0031747121557605415914, tol=PTOL) + v = fp.e1((5.0 + 20.0j)) + assert ae(v, (-0.00024419662286542966525 - 0.00021008322966152755674j), tol=ATOL) + assert ae(v.real, -0.00024419662286542966525, tol=PTOL) + assert ae(v.imag, -0.00021008322966152755674, tol=PTOL) + v = fp.e1((20.0 + 80.0j)) + assert ae(v, (2.3255552781051330088e-11 + 8.9463918891349438007e-12j), tol=ATOL) + assert ae(v.real, 2.3255552781051330088e-11, tol=PTOL) + assert ae(v.imag, 8.9463918891349438007e-12, tol=PTOL) + v = fp.e1((30.0 + 120.0j)) + assert ae(v, (-2.7068919097124652332e-16 - 7.0477762411705130239e-16j), tol=ATOL) + assert ae(v.real, -2.7068919097124652332e-16, tol=PTOL) + assert ae(v.imag, -7.0477762411705130239e-16, tol=PTOL) + v = fp.e1((40.0 + 160.0j)) + assert ae(v, (-1.1695597827678024687e-20 + 2.2907401455645736661e-20j), tol=ATOL) + assert ae(v.real, -1.1695597827678024687e-20, tol=PTOL) + assert ae(v.imag, 2.2907401455645736661e-20, tol=PTOL) + v = fp.e1((50.0 + 200.0j)) + assert ae(v, (9.0323746914410162531e-25 - 2.3950601790033530935e-25j), tol=ATOL) + assert ae(v.real, 9.0323746914410162531e-25, tol=PTOL) + assert ae(v.imag, -2.3950601790033530935e-25, tol=PTOL) + v = fp.e1((80.0 + 320.0j)) + assert ae(v, (3.4819106748728063576e-38 - 4.215653005615772724e-38j), tol=ATOL) + assert ae(v.real, 3.4819106748728063576e-38, tol=PTOL) + assert ae(v.imag, -4.215653005615772724e-38, tol=PTOL) + v = fp.e1((0.0 + 1.1641532182693481445e-10j)) + assert ae(v, (22.29664129357666235 - 1.5707963266784812974j), tol=ATOL) + assert ae(v.real, 22.29664129357666235, tol=PTOL) + assert ae(v.imag, -1.5707963266784812974, tol=PTOL) + v = fp.e1((0.0 + 0.25j)) + assert ae(v, (0.82466306258094565309 - 1.3216627564751394551j), tol=ATOL) + assert ae(v.real, 0.82466306258094565309, tol=PTOL) + assert ae(v.imag, -1.3216627564751394551, tol=PTOL) + v = fp.e1((0.0 + 1.0j)) + assert ae(v, (-0.33740392290096813466 - 0.62471325642771360429j), tol=ATOL) + assert ae(v.real, -0.33740392290096813466, tol=PTOL) + assert ae(v.imag, -0.62471325642771360429, tol=PTOL) + v = fp.e1((0.0 + 2.0j)) + assert ae(v, (-0.4229808287748649957 + 0.034616650007798229345j), tol=ATOL) + assert ae(v.real, -0.4229808287748649957, tol=PTOL) + assert ae(v.imag, 0.034616650007798229345, tol=PTOL) + v = fp.e1((0.0 + 5.0j)) + assert ae(v, (0.19002974965664387862 - 0.020865081850222481957j), tol=ATOL) + assert ae(v.real, 0.19002974965664387862, tol=PTOL) + assert ae(v.imag, -0.020865081850222481957, tol=PTOL) + v = fp.e1((0.0 + 20.0j)) + assert ae(v, (-0.04441982084535331654 - 0.022554625751456779068j), tol=ATOL) + assert ae(v.real, -0.04441982084535331654, tol=PTOL) + assert ae(v.imag, -0.022554625751456779068, tol=PTOL) + v = fp.e1((0.0 + 30.0j)) + assert ae(v, (0.033032417282071143779 - 0.0040397867645455082476j), tol=ATOL) + assert ae(v.real, 0.033032417282071143779, tol=PTOL) + assert ae(v.imag, -0.0040397867645455082476, tol=PTOL) + v = fp.e1((0.0 + 40.0j)) + assert ae(v, (-0.019020007896208766962 + 0.016188792559887887544j), tol=ATOL) + assert ae(v.real, -0.019020007896208766962, tol=PTOL) + assert ae(v.imag, 0.016188792559887887544, tol=PTOL) + v = fp.e1((0.0 + 50.0j)) + assert ae(v, (0.0056283863241163054402 - 0.019179254308960724503j), tol=ATOL) + assert ae(v.real, 0.0056283863241163054402, tol=PTOL) + assert ae(v.imag, -0.019179254308960724503, tol=PTOL) + v = fp.e1((0.0 + 80.0j)) + assert ae(v, (0.012402501155070958192 + 0.0015345601175906961199j), tol=ATOL) + assert ae(v.real, 0.012402501155070958192, tol=PTOL) + assert ae(v.imag, 0.0015345601175906961199, tol=PTOL) + v = fp.e1((-1.1641532182693481445e-10 + 4.6566128730773925781e-10j)) + assert ae(v, (20.880034621432138988 - 1.8157749894560994861j), tol=ATOL) + assert ae(v.real, 20.880034621432138988, tol=PTOL) + assert ae(v.imag, -1.8157749894560994861, tol=PTOL) + v = fp.e1((-0.25 + 1.0j)) + assert ae(v, (-0.59066621214766308594 - 0.74474454765205036972j), tol=ATOL) + assert ae(v.real, -0.59066621214766308594, tol=PTOL) + assert ae(v.imag, -0.74474454765205036972, tol=PTOL) + v = fp.e1((-1.0 + 4.0j)) + assert ae(v, (0.49739047283060471093 + 0.41543605404038863174j), tol=ATOL) + assert ae(v.real, 0.49739047283060471093, tol=PTOL) + assert ae(v.imag, 0.41543605404038863174, tol=PTOL) + v = fp.e1((-2.0 + 8.0j)) + assert ae(v, (-0.8705211147733730969 + 0.24099328498605539667j), tol=ATOL) + assert ae(v.real, -0.8705211147733730969, tol=PTOL) + assert ae(v.imag, 0.24099328498605539667, tol=PTOL) + v = fp.e1((-5.0 + 20.0j)) + assert ae(v, (-7.0789514293925893007 - 1.6102177171960790536j), tol=ATOL) + assert ae(v.real, -7.0789514293925893007, tol=PTOL) + assert ae(v.imag, -1.6102177171960790536, tol=PTOL) + v = fp.e1((-20.0 + 80.0j)) + assert ae(v, (5855431.4907298084434 - 720920.93315409165707j), tol=ATOL) + assert ae(v.real, 5855431.4907298084434, tol=PTOL) + assert ae(v.imag, -720920.93315409165707, tol=PTOL) + v = fp.e1((-30.0 + 120.0j)) + assert ae(v, (-65402491644.703470747 - 56697658399.657460294j), tol=ATOL) + assert ae(v.real, -65402491644.703470747, tol=PTOL) + assert ae(v.imag, -56697658399.657460294, tol=PTOL) + v = fp.e1((-40.0 + 160.0j)) + assert ae(v, (25504929379604.776769 + 1429035198630573.2463j), tol=ATOL) + assert ae(v.real, 25504929379604.776769, tol=PTOL) + assert ae(v.imag, 1429035198630573.2463, tol=PTOL) + v = fp.e1((-50.0 + 200.0j)) + assert ae(v, (18437746526988116954.0 - 17146362239046152345.0j), tol=ATOL) + assert ae(v.real, 18437746526988116954.0, tol=PTOL) + assert ae(v.imag, -17146362239046152345.0, tol=PTOL) + v = fp.e1((-80.0 + 320.0j)) + assert ae(v, (3.3464697299634526706e+31 - 1.6473152633843023919e+32j), tol=ATOL) + assert ae(v.real, 3.3464697299634526706e+31, tol=PTOL) + assert ae(v.imag, -1.6473152633843023919e+32, tol=PTOL) + v = fp.e1((-4.6566128730773925781e-10 + 1.1641532182693481445e-10j)) + assert ae(v, (20.880034621082893023 - 2.8966139903465137624j), tol=ATOL) + assert ae(v.real, 20.880034621082893023, tol=PTOL) + assert ae(v.imag, -2.8966139903465137624, tol=PTOL) + v = fp.e1((-1.0 + 0.25j)) + assert ae(v, (-1.8942716983721074932 - 2.4689102827070540799j), tol=ATOL) + assert ae(v.real, -1.8942716983721074932, tol=PTOL) + assert ae(v.imag, -2.4689102827070540799, tol=PTOL) + v = fp.e1((-4.0 + 1.0j)) + assert ae(v, (-14.806699492675420438 + 9.1384225230837893776j), tol=ATOL) + assert ae(v.real, -14.806699492675420438, tol=PTOL) + assert ae(v.imag, 9.1384225230837893776, tol=PTOL) + v = fp.e1((-8.0 + 2.0j)) + assert ae(v, (54.633252667426386294 + 413.20318163814670688j), tol=ATOL) + assert ae(v.real, 54.633252667426386294, tol=PTOL) + assert ae(v.imag, 413.20318163814670688, tol=PTOL) + v = fp.e1((-20.0 + 5.0j)) + assert ae(v, (-711836.97165402624643 - 24745250.939695900956j), tol=ATOL) + assert ae(v.real, -711836.97165402624643, tol=PTOL) + assert ae(v.imag, -24745250.939695900956, tol=PTOL) + v = fp.e1((-80.0 + 20.0j)) + assert ae(v, (-4.2139911108612653091e+32 + 5.3367124741918251637e+32j), tol=ATOL) + assert ae(v.real, -4.2139911108612653091e+32, tol=PTOL) + assert ae(v.imag, 5.3367124741918251637e+32, tol=PTOL) + v = fp.e1((-120.0 + 30.0j)) + assert ae(v, (9.7760616203707508892e+48 - 1.058257682317195792e+50j), tol=ATOL) + assert ae(v.real, 9.7760616203707508892e+48, tol=PTOL) + assert ae(v.imag, -1.058257682317195792e+50, tol=PTOL) + v = fp.e1((-160.0 + 40.0j)) + assert ae(v, (8.7065541466623638861e+66 + 1.6577106725141739889e+67j), tol=ATOL) + assert ae(v.real, 8.7065541466623638861e+66, tol=PTOL) + assert ae(v.imag, 1.6577106725141739889e+67, tol=PTOL) + v = fp.e1((-200.0 + 50.0j)) + assert ae(v, (-3.070744996327018106e+84 - 1.7243244846769415903e+84j), tol=ATOL) + assert ae(v.real, -3.070744996327018106e+84, tol=PTOL) + assert ae(v.imag, -1.7243244846769415903e+84, tol=PTOL) + v = fp.e1((-320.0 + 80.0j)) + assert ae(v, (9.9960598637998647276e+135 - 2.6855081527595608863e+136j), tol=ATOL) + assert ae(v.real, 9.9960598637998647276e+135, tol=PTOL) + assert ae(v.imag, -2.6855081527595608863e+136, tol=PTOL) + v = fp.e1(-1.1641532182693481445e-10) + assert ae(v, (22.296641293460247028 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, 22.296641293460247028, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1(-0.25) + assert ae(v, (0.54254326466191372953 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, 0.54254326466191372953, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1(-1.0) + assert ae(v, (-1.8951178163559367555 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -1.8951178163559367555, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1(-2.0) + assert ae(v, (-4.9542343560018901634 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -4.9542343560018901634, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1(-5.0) + assert ae(v, (-40.185275355803177455 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -40.185275355803177455, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1(-20.0) + assert ae(v, (-25615652.66405658882 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -25615652.66405658882, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1(-30.0) + assert ae(v, (-368973209407.27419706 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -368973209407.27419706, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1(-40.0) + assert ae(v, (-6039718263611241.5784 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -6039718263611241.5784, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1(-50.0) + assert ae(v, (-1.0585636897131690963e+20 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -1.0585636897131690963e+20, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1(-80.0) + assert ae(v, (-7.0146000049047999696e+32 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -7.0146000049047999696e+32, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1((-1.1641532182693481445e-10 + 0.0j)) + assert ae(v, (22.296641293460247028 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, 22.296641293460247028, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1((-0.25 + 0.0j)) + assert ae(v, (0.54254326466191372953 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, 0.54254326466191372953, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1((-1.0 + 0.0j)) + assert ae(v, (-1.8951178163559367555 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -1.8951178163559367555, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1((-2.0 + 0.0j)) + assert ae(v, (-4.9542343560018901634 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -4.9542343560018901634, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1((-5.0 + 0.0j)) + assert ae(v, (-40.185275355803177455 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -40.185275355803177455, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1((-20.0 + 0.0j)) + assert ae(v, (-25615652.66405658882 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -25615652.66405658882, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1((-30.0 + 0.0j)) + assert ae(v, (-368973209407.27419706 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -368973209407.27419706, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1((-40.0 + 0.0j)) + assert ae(v, (-6039718263611241.5784 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -6039718263611241.5784, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1((-50.0 + 0.0j)) + assert ae(v, (-1.0585636897131690963e+20 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -1.0585636897131690963e+20, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1((-80.0 + 0.0j)) + assert ae(v, (-7.0146000049047999696e+32 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -7.0146000049047999696e+32, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.e1((-4.6566128730773925781e-10 - 1.1641532182693481445e-10j)) + assert ae(v, (20.880034621082893023 + 2.8966139903465137624j), tol=ATOL) + assert ae(v.real, 20.880034621082893023, tol=PTOL) + assert ae(v.imag, 2.8966139903465137624, tol=PTOL) + v = fp.e1((-1.0 - 0.25j)) + assert ae(v, (-1.8942716983721074932 + 2.4689102827070540799j), tol=ATOL) + assert ae(v.real, -1.8942716983721074932, tol=PTOL) + assert ae(v.imag, 2.4689102827070540799, tol=PTOL) + v = fp.e1((-4.0 - 1.0j)) + assert ae(v, (-14.806699492675420438 - 9.1384225230837893776j), tol=ATOL) + assert ae(v.real, -14.806699492675420438, tol=PTOL) + assert ae(v.imag, -9.1384225230837893776, tol=PTOL) + v = fp.e1((-8.0 - 2.0j)) + assert ae(v, (54.633252667426386294 - 413.20318163814670688j), tol=ATOL) + assert ae(v.real, 54.633252667426386294, tol=PTOL) + assert ae(v.imag, -413.20318163814670688, tol=PTOL) + v = fp.e1((-20.0 - 5.0j)) + assert ae(v, (-711836.97165402624643 + 24745250.939695900956j), tol=ATOL) + assert ae(v.real, -711836.97165402624643, tol=PTOL) + assert ae(v.imag, 24745250.939695900956, tol=PTOL) + v = fp.e1((-80.0 - 20.0j)) + assert ae(v, (-4.2139911108612653091e+32 - 5.3367124741918251637e+32j), tol=ATOL) + assert ae(v.real, -4.2139911108612653091e+32, tol=PTOL) + assert ae(v.imag, -5.3367124741918251637e+32, tol=PTOL) + v = fp.e1((-120.0 - 30.0j)) + assert ae(v, (9.7760616203707508892e+48 + 1.058257682317195792e+50j), tol=ATOL) + assert ae(v.real, 9.7760616203707508892e+48, tol=PTOL) + assert ae(v.imag, 1.058257682317195792e+50, tol=PTOL) + v = fp.e1((-160.0 - 40.0j)) + assert ae(v, (8.7065541466623638861e+66 - 1.6577106725141739889e+67j), tol=ATOL) + assert ae(v.real, 8.7065541466623638861e+66, tol=PTOL) + assert ae(v.imag, -1.6577106725141739889e+67, tol=PTOL) + v = fp.e1((-200.0 - 50.0j)) + assert ae(v, (-3.070744996327018106e+84 + 1.7243244846769415903e+84j), tol=ATOL) + assert ae(v.real, -3.070744996327018106e+84, tol=PTOL) + assert ae(v.imag, 1.7243244846769415903e+84, tol=PTOL) + v = fp.e1((-320.0 - 80.0j)) + assert ae(v, (9.9960598637998647276e+135 + 2.6855081527595608863e+136j), tol=ATOL) + assert ae(v.real, 9.9960598637998647276e+135, tol=PTOL) + assert ae(v.imag, 2.6855081527595608863e+136, tol=PTOL) + v = fp.e1((-1.1641532182693481445e-10 - 1.1641532182693481445e-10j)) + assert ae(v, (21.950067703180274374 + 2.356194490075929607j), tol=ATOL) + assert ae(v.real, 21.950067703180274374, tol=PTOL) + assert ae(v.imag, 2.356194490075929607, tol=PTOL) + v = fp.e1((-0.25 - 0.25j)) + assert ae(v, (0.21441047326710323254 + 2.0732153554307936389j), tol=ATOL) + assert ae(v.real, 0.21441047326710323254, tol=PTOL) + assert ae(v.imag, 2.0732153554307936389, tol=PTOL) + v = fp.e1((-1.0 - 1.0j)) + assert ae(v, (-1.7646259855638540684 + 0.7538228020792708192j), tol=ATOL) + assert ae(v.real, -1.7646259855638540684, tol=PTOL) + assert ae(v.imag, 0.7538228020792708192, tol=PTOL) + v = fp.e1((-2.0 - 2.0j)) + assert ae(v, (-1.8920781621855474089 - 2.1753697842428647236j), tol=ATOL) + assert ae(v.real, -1.8920781621855474089, tol=PTOL) + assert ae(v.imag, -2.1753697842428647236, tol=PTOL) + v = fp.e1((-5.0 - 5.0j)) + assert ae(v, (13.470936071475245856 + 18.464085049321024206j), tol=ATOL) + assert ae(v.real, 13.470936071475245856, tol=PTOL) + assert ae(v.imag, 18.464085049321024206, tol=PTOL) + v = fp.e1((-20.0 - 20.0j)) + assert ae(v, (-16589317.398788971896 - 5831702.3296441771206j), tol=ATOL) + assert ae(v.real, -16589317.398788971896, tol=PTOL) + assert ae(v.imag, -5831702.3296441771206, tol=PTOL) + v = fp.e1((-30.0 - 30.0j)) + assert ae(v, (154596484273.69322527 + 204179357837.41389696j), tol=ATOL) + assert ae(v.real, 154596484273.69322527, tol=PTOL) + assert ae(v.imag, 204179357837.41389696, tol=PTOL) + v = fp.e1((-40.0 - 40.0j)) + assert ae(v, (-287512180321448.45408 - 4203502407932314.974j), tol=ATOL) + assert ae(v.real, -287512180321448.45408, tol=PTOL) + assert ae(v.imag, -4203502407932314.974, tol=PTOL) + v = fp.e1((-50.0 - 50.0j)) + assert ae(v, (-36128528616649268826.0 + 64648801861338741963.0j), tol=ATOL) + assert ae(v.real, -36128528616649268826.0, tol=PTOL) + assert ae(v.imag, 64648801861338741963.0, tol=PTOL) + v = fp.e1((-80.0 - 80.0j)) + assert ae(v, (3.8674816337930010217e+32 + 3.0540709639658071041e+32j), tol=ATOL) + assert ae(v.real, 3.8674816337930010217e+32, tol=PTOL) + assert ae(v.imag, 3.0540709639658071041e+32, tol=PTOL) + v = fp.e1((-1.1641532182693481445e-10 - 4.6566128730773925781e-10j)) + assert ae(v, (20.880034621432138988 + 1.8157749894560994861j), tol=ATOL) + assert ae(v.real, 20.880034621432138988, tol=PTOL) + assert ae(v.imag, 1.8157749894560994861, tol=PTOL) + v = fp.e1((-0.25 - 1.0j)) + assert ae(v, (-0.59066621214766308594 + 0.74474454765205036972j), tol=ATOL) + assert ae(v.real, -0.59066621214766308594, tol=PTOL) + assert ae(v.imag, 0.74474454765205036972, tol=PTOL) + v = fp.e1((-1.0 - 4.0j)) + assert ae(v, (0.49739047283060471093 - 0.41543605404038863174j), tol=ATOL) + assert ae(v.real, 0.49739047283060471093, tol=PTOL) + assert ae(v.imag, -0.41543605404038863174, tol=PTOL) + v = fp.e1((-2.0 - 8.0j)) + assert ae(v, (-0.8705211147733730969 - 0.24099328498605539667j), tol=ATOL) + assert ae(v.real, -0.8705211147733730969, tol=PTOL) + assert ae(v.imag, -0.24099328498605539667, tol=PTOL) + v = fp.e1((-5.0 - 20.0j)) + assert ae(v, (-7.0789514293925893007 + 1.6102177171960790536j), tol=ATOL) + assert ae(v.real, -7.0789514293925893007, tol=PTOL) + assert ae(v.imag, 1.6102177171960790536, tol=PTOL) + v = fp.e1((-20.0 - 80.0j)) + assert ae(v, (5855431.4907298084434 + 720920.93315409165707j), tol=ATOL) + assert ae(v.real, 5855431.4907298084434, tol=PTOL) + assert ae(v.imag, 720920.93315409165707, tol=PTOL) + v = fp.e1((-30.0 - 120.0j)) + assert ae(v, (-65402491644.703470747 + 56697658399.657460294j), tol=ATOL) + assert ae(v.real, -65402491644.703470747, tol=PTOL) + assert ae(v.imag, 56697658399.657460294, tol=PTOL) + v = fp.e1((-40.0 - 160.0j)) + assert ae(v, (25504929379604.776769 - 1429035198630573.2463j), tol=ATOL) + assert ae(v.real, 25504929379604.776769, tol=PTOL) + assert ae(v.imag, -1429035198630573.2463, tol=PTOL) + v = fp.e1((-50.0 - 200.0j)) + assert ae(v, (18437746526988116954.0 + 17146362239046152345.0j), tol=ATOL) + assert ae(v.real, 18437746526988116954.0, tol=PTOL) + assert ae(v.imag, 17146362239046152345.0, tol=PTOL) + v = fp.e1((-80.0 - 320.0j)) + assert ae(v, (3.3464697299634526706e+31 + 1.6473152633843023919e+32j), tol=ATOL) + assert ae(v.real, 3.3464697299634526706e+31, tol=PTOL) + assert ae(v.imag, 1.6473152633843023919e+32, tol=PTOL) + v = fp.e1((0.0 - 1.1641532182693481445e-10j)) + assert ae(v, (22.29664129357666235 + 1.5707963266784812974j), tol=ATOL) + assert ae(v.real, 22.29664129357666235, tol=PTOL) + assert ae(v.imag, 1.5707963266784812974, tol=PTOL) + v = fp.e1((0.0 - 0.25j)) + assert ae(v, (0.82466306258094565309 + 1.3216627564751394551j), tol=ATOL) + assert ae(v.real, 0.82466306258094565309, tol=PTOL) + assert ae(v.imag, 1.3216627564751394551, tol=PTOL) + v = fp.e1((0.0 - 1.0j)) + assert ae(v, (-0.33740392290096813466 + 0.62471325642771360429j), tol=ATOL) + assert ae(v.real, -0.33740392290096813466, tol=PTOL) + assert ae(v.imag, 0.62471325642771360429, tol=PTOL) + v = fp.e1((0.0 - 2.0j)) + assert ae(v, (-0.4229808287748649957 - 0.034616650007798229345j), tol=ATOL) + assert ae(v.real, -0.4229808287748649957, tol=PTOL) + assert ae(v.imag, -0.034616650007798229345, tol=PTOL) + v = fp.e1((0.0 - 5.0j)) + assert ae(v, (0.19002974965664387862 + 0.020865081850222481957j), tol=ATOL) + assert ae(v.real, 0.19002974965664387862, tol=PTOL) + assert ae(v.imag, 0.020865081850222481957, tol=PTOL) + v = fp.e1((0.0 - 20.0j)) + assert ae(v, (-0.04441982084535331654 + 0.022554625751456779068j), tol=ATOL) + assert ae(v.real, -0.04441982084535331654, tol=PTOL) + assert ae(v.imag, 0.022554625751456779068, tol=PTOL) + v = fp.e1((0.0 - 30.0j)) + assert ae(v, (0.033032417282071143779 + 0.0040397867645455082476j), tol=ATOL) + assert ae(v.real, 0.033032417282071143779, tol=PTOL) + assert ae(v.imag, 0.0040397867645455082476, tol=PTOL) + v = fp.e1((0.0 - 40.0j)) + assert ae(v, (-0.019020007896208766962 - 0.016188792559887887544j), tol=ATOL) + assert ae(v.real, -0.019020007896208766962, tol=PTOL) + assert ae(v.imag, -0.016188792559887887544, tol=PTOL) + v = fp.e1((0.0 - 50.0j)) + assert ae(v, (0.0056283863241163054402 + 0.019179254308960724503j), tol=ATOL) + assert ae(v.real, 0.0056283863241163054402, tol=PTOL) + assert ae(v.imag, 0.019179254308960724503, tol=PTOL) + v = fp.e1((0.0 - 80.0j)) + assert ae(v, (0.012402501155070958192 - 0.0015345601175906961199j), tol=ATOL) + assert ae(v.real, 0.012402501155070958192, tol=PTOL) + assert ae(v.imag, -0.0015345601175906961199, tol=PTOL) + v = fp.e1((1.1641532182693481445e-10 - 4.6566128730773925781e-10j)) + assert ae(v, (20.880034621664969632 + 1.3258176632023711778j), tol=ATOL) + assert ae(v.real, 20.880034621664969632, tol=PTOL) + assert ae(v.imag, 1.3258176632023711778, tol=PTOL) + v = fp.e1((0.25 - 1.0j)) + assert ae(v, (-0.16868306393667788761 + 0.4858011885947426971j), tol=ATOL) + assert ae(v.real, -0.16868306393667788761, tol=PTOL) + assert ae(v.imag, 0.4858011885947426971, tol=PTOL) + v = fp.e1((1.0 - 4.0j)) + assert ae(v, (0.03373591813926547318 - 0.073523452241083821877j), tol=ATOL) + assert ae(v.real, 0.03373591813926547318, tol=PTOL) + assert ae(v.imag, -0.073523452241083821877, tol=PTOL) + v = fp.e1((2.0 - 8.0j)) + assert ae(v, (-0.015392833434733785143 + 0.0031747121557605415914j), tol=ATOL) + assert ae(v.real, -0.015392833434733785143, tol=PTOL) + assert ae(v.imag, 0.0031747121557605415914, tol=PTOL) + v = fp.e1((5.0 - 20.0j)) + assert ae(v, (-0.00024419662286542966525 + 0.00021008322966152755674j), tol=ATOL) + assert ae(v.real, -0.00024419662286542966525, tol=PTOL) + assert ae(v.imag, 0.00021008322966152755674, tol=PTOL) + v = fp.e1((20.0 - 80.0j)) + assert ae(v, (2.3255552781051330088e-11 - 8.9463918891349438007e-12j), tol=ATOL) + assert ae(v.real, 2.3255552781051330088e-11, tol=PTOL) + assert ae(v.imag, -8.9463918891349438007e-12, tol=PTOL) + v = fp.e1((30.0 - 120.0j)) + assert ae(v, (-2.7068919097124652332e-16 + 7.0477762411705130239e-16j), tol=ATOL) + assert ae(v.real, -2.7068919097124652332e-16, tol=PTOL) + assert ae(v.imag, 7.0477762411705130239e-16, tol=PTOL) + v = fp.e1((40.0 - 160.0j)) + assert ae(v, (-1.1695597827678024687e-20 - 2.2907401455645736661e-20j), tol=ATOL) + assert ae(v.real, -1.1695597827678024687e-20, tol=PTOL) + assert ae(v.imag, -2.2907401455645736661e-20, tol=PTOL) + v = fp.e1((50.0 - 200.0j)) + assert ae(v, (9.0323746914410162531e-25 + 2.3950601790033530935e-25j), tol=ATOL) + assert ae(v.real, 9.0323746914410162531e-25, tol=PTOL) + assert ae(v.imag, 2.3950601790033530935e-25, tol=PTOL) + v = fp.e1((80.0 - 320.0j)) + assert ae(v, (3.4819106748728063576e-38 + 4.215653005615772724e-38j), tol=ATOL) + assert ae(v.real, 3.4819106748728063576e-38, tol=PTOL) + assert ae(v.imag, 4.215653005615772724e-38, tol=PTOL) + v = fp.e1((1.1641532182693481445e-10 - 1.1641532182693481445e-10j)) + assert ae(v, (21.950067703413105017 + 0.7853981632810329878j), tol=ATOL) + assert ae(v.real, 21.950067703413105017, tol=PTOL) + assert ae(v.imag, 0.7853981632810329878, tol=PTOL) + v = fp.e1((0.25 - 0.25j)) + assert ae(v, (0.71092525792923287894 + 0.56491812441304194711j), tol=ATOL) + assert ae(v.real, 0.71092525792923287894, tol=PTOL) + assert ae(v.imag, 0.56491812441304194711, tol=PTOL) + v = fp.e1((1.0 - 1.0j)) + assert ae(v, (0.00028162445198141832551 + 0.17932453503935894015j), tol=ATOL) + assert ae(v.real, 0.00028162445198141832551, tol=PTOL) + assert ae(v.imag, 0.17932453503935894015, tol=PTOL) + v = fp.e1((2.0 - 2.0j)) + assert ae(v, (-0.033767089606562004246 + 0.018599414169750541925j), tol=ATOL) + assert ae(v.real, -0.033767089606562004246, tol=PTOL) + assert ae(v.imag, 0.018599414169750541925, tol=PTOL) + v = fp.e1((5.0 - 5.0j)) + assert ae(v, (0.0007266506660356393891 - 0.00047102780163522245054j), tol=ATOL) + assert ae(v.real, 0.0007266506660356393891, tol=PTOL) + assert ae(v.imag, -0.00047102780163522245054, tol=PTOL) + v = fp.e1((20.0 - 20.0j)) + assert ae(v, (-2.3824537449367396579e-11 + 6.6969873156525615158e-11j), tol=ATOL) + assert ae(v.real, -2.3824537449367396579e-11, tol=PTOL) + assert ae(v.imag, 6.6969873156525615158e-11, tol=PTOL) + v = fp.e1((30.0 - 30.0j)) + assert ae(v, (1.7316045841744061617e-15 - 1.3065678019487308689e-15j), tol=ATOL) + assert ae(v.real, 1.7316045841744061617e-15, tol=PTOL) + assert ae(v.imag, -1.3065678019487308689e-15, tol=PTOL) + v = fp.e1((40.0 - 40.0j)) + assert ae(v, (-7.4001043002899232182e-20 + 4.991847855336816304e-21j), tol=ATOL) + assert ae(v.real, -7.4001043002899232182e-20, tol=PTOL) + assert ae(v.imag, 4.991847855336816304e-21, tol=PTOL) + v = fp.e1((50.0 - 50.0j)) + assert ae(v, (2.3566128324644641219e-24 + 1.3188326726201614778e-24j), tol=ATOL) + assert ae(v.real, 2.3566128324644641219e-24, tol=PTOL) + assert ae(v.imag, 1.3188326726201614778e-24, tol=PTOL) + v = fp.e1((80.0 - 80.0j)) + assert ae(v, (9.8279750572186526673e-38 - 1.243952841288868831e-37j), tol=ATOL) + assert ae(v.real, 9.8279750572186526673e-38, tol=PTOL) + assert ae(v.imag, -1.243952841288868831e-37, tol=PTOL) + v = fp.e1((4.6566128730773925781e-10 - 1.1641532182693481445e-10j)) + assert ae(v, (20.880034622014215597 + 0.24497866301044883237j), tol=ATOL) + assert ae(v.real, 20.880034622014215597, tol=PTOL) + assert ae(v.imag, 0.24497866301044883237, tol=PTOL) + v = fp.e1((1.0 - 0.25j)) + assert ae(v, (0.19731063945004229095 + 0.087366045774299963672j), tol=ATOL) + assert ae(v.real, 0.19731063945004229095, tol=PTOL) + assert ae(v.imag, 0.087366045774299963672, tol=PTOL) + v = fp.e1((4.0 - 1.0j)) + assert ae(v, (0.0013106173980145506944 + 0.0034542480199350626699j), tol=ATOL) + assert ae(v.real, 0.0013106173980145506944, tol=PTOL) + assert ae(v.imag, 0.0034542480199350626699, tol=PTOL) + v = fp.e1((8.0 - 2.0j)) + assert ae(v, (-0.000022278049065270225945 + 0.000029191940456521555288j), tol=ATOL) + assert ae(v.real, -0.000022278049065270225945, tol=PTOL) + assert ae(v.imag, 0.000029191940456521555288, tol=PTOL) + v = fp.e1((20.0 - 5.0j)) + assert ae(v, (4.7711374515765346894e-11 - 8.2902652405126947359e-11j), tol=ATOL) + assert ae(v.real, 4.7711374515765346894e-11, tol=PTOL) + assert ae(v.imag, -8.2902652405126947359e-11, tol=PTOL) + v = fp.e1((80.0 - 20.0j)) + assert ae(v, (3.8353473865788235787e-38 + 2.129247592349605139e-37j), tol=ATOL) + assert ae(v.real, 3.8353473865788235787e-38, tol=PTOL) + assert ae(v.imag, 2.129247592349605139e-37, tol=PTOL) + v = fp.e1((120.0 - 30.0j)) + assert ae(v, (2.3836002337480334716e-55 - 5.6704043587126198306e-55j), tol=ATOL) + assert ae(v.real, 2.3836002337480334716e-55, tol=PTOL) + assert ae(v.imag, -5.6704043587126198306e-55, tol=PTOL) + v = fp.e1((160.0 - 40.0j)) + assert ae(v, (-1.6238022898654510661e-72 + 1.104172355572287367e-72j), tol=ATOL) + assert ae(v.real, -1.6238022898654510661e-72, tol=PTOL) + assert ae(v.imag, 1.104172355572287367e-72, tol=PTOL) + v = fp.e1((200.0 - 50.0j)) + assert ae(v, (6.6800061461666228487e-90 - 1.4473816083541016115e-91j), tol=ATOL) + assert ae(v.real, 6.6800061461666228487e-90, tol=PTOL) + assert ae(v.imag, -1.4473816083541016115e-91, tol=PTOL) + v = fp.e1((320.0 - 80.0j)) + assert ae(v, (4.2737871527778786157e-143 - 3.1789935525785660314e-142j), tol=ATOL) + assert ae(v.real, 4.2737871527778786157e-143, tol=PTOL) + assert ae(v.imag, -3.1789935525785660314e-142, tol=PTOL) + v = fp.ei(1.1641532182693481445e-10) + assert ae(v, -22.296641293460247028, tol=ATOL) + assert type(v) is float + v = fp.ei(0.25) + assert ae(v, -0.54254326466191372953, tol=ATOL) + assert type(v) is float + v = fp.ei(1.0) + assert ae(v, 1.8951178163559367555, tol=ATOL) + assert type(v) is float + v = fp.ei(2.0) + assert ae(v, 4.9542343560018901634, tol=ATOL) + assert type(v) is float + v = fp.ei(5.0) + assert ae(v, 40.185275355803177455, tol=ATOL) + assert type(v) is float + v = fp.ei(20.0) + assert ae(v, 25615652.66405658882, tol=ATOL) + assert type(v) is float + v = fp.ei(30.0) + assert ae(v, 368973209407.27419706, tol=ATOL) + assert type(v) is float + v = fp.ei(40.0) + assert ae(v, 6039718263611241.5784, tol=ATOL) + assert type(v) is float + v = fp.ei(50.0) + assert ae(v, 1.0585636897131690963e+20, tol=ATOL) + assert type(v) is float + v = fp.ei(80.0) + assert ae(v, 7.0146000049047999696e+32, tol=ATOL) + assert type(v) is float + v = fp.ei((1.1641532182693481445e-10 + 0.0j)) + assert ae(v, (-22.296641293460247028 + 0.0j), tol=ATOL) + assert ae(v.real, -22.296641293460247028, tol=PTOL) + assert v.imag == 0 + v = fp.ei((0.25 + 0.0j)) + assert ae(v, (-0.54254326466191372953 + 0.0j), tol=ATOL) + assert ae(v.real, -0.54254326466191372953, tol=PTOL) + assert v.imag == 0 + v = fp.ei((1.0 + 0.0j)) + assert ae(v, (1.8951178163559367555 + 0.0j), tol=ATOL) + assert ae(v.real, 1.8951178163559367555, tol=PTOL) + assert v.imag == 0 + v = fp.ei((2.0 + 0.0j)) + assert ae(v, (4.9542343560018901634 + 0.0j), tol=ATOL) + assert ae(v.real, 4.9542343560018901634, tol=PTOL) + assert v.imag == 0 + v = fp.ei((5.0 + 0.0j)) + assert ae(v, (40.185275355803177455 + 0.0j), tol=ATOL) + assert ae(v.real, 40.185275355803177455, tol=PTOL) + assert v.imag == 0 + v = fp.ei((20.0 + 0.0j)) + assert ae(v, (25615652.66405658882 + 0.0j), tol=ATOL) + assert ae(v.real, 25615652.66405658882, tol=PTOL) + assert v.imag == 0 + v = fp.ei((30.0 + 0.0j)) + assert ae(v, (368973209407.27419706 + 0.0j), tol=ATOL) + assert ae(v.real, 368973209407.27419706, tol=PTOL) + assert v.imag == 0 + v = fp.ei((40.0 + 0.0j)) + assert ae(v, (6039718263611241.5784 + 0.0j), tol=ATOL) + assert ae(v.real, 6039718263611241.5784, tol=PTOL) + assert v.imag == 0 + v = fp.ei((50.0 + 0.0j)) + assert ae(v, (1.0585636897131690963e+20 + 0.0j), tol=ATOL) + assert ae(v.real, 1.0585636897131690963e+20, tol=PTOL) + assert v.imag == 0 + v = fp.ei((80.0 + 0.0j)) + assert ae(v, (7.0146000049047999696e+32 + 0.0j), tol=ATOL) + assert ae(v.real, 7.0146000049047999696e+32, tol=PTOL) + assert v.imag == 0 + v = fp.ei((4.6566128730773925781e-10 + 1.1641532182693481445e-10j)) + assert ae(v, (-20.880034621082893023 + 0.24497866324327947603j), tol=ATOL) + assert ae(v.real, -20.880034621082893023, tol=PTOL) + assert ae(v.imag, 0.24497866324327947603, tol=PTOL) + v = fp.ei((1.0 + 0.25j)) + assert ae(v, (1.8942716983721074932 + 0.67268237088273915854j), tol=ATOL) + assert ae(v.real, 1.8942716983721074932, tol=PTOL) + assert ae(v.imag, 0.67268237088273915854, tol=PTOL) + v = fp.ei((4.0 + 1.0j)) + assert ae(v, (14.806699492675420438 + 12.280015176673582616j), tol=ATOL) + assert ae(v.real, 14.806699492675420438, tol=PTOL) + assert ae(v.imag, 12.280015176673582616, tol=PTOL) + v = fp.ei((8.0 + 2.0j)) + assert ae(v, (-54.633252667426386294 + 416.34477429173650012j), tol=ATOL) + assert ae(v.real, -54.633252667426386294, tol=PTOL) + assert ae(v.imag, 416.34477429173650012, tol=PTOL) + v = fp.ei((20.0 + 5.0j)) + assert ae(v, (711836.97165402624643 - 24745247.798103247366j), tol=ATOL) + assert ae(v.real, 711836.97165402624643, tol=PTOL) + assert ae(v.imag, -24745247.798103247366, tol=PTOL) + v = fp.ei((80.0 + 20.0j)) + assert ae(v, (4.2139911108612653091e+32 + 5.3367124741918251637e+32j), tol=ATOL) + assert ae(v.real, 4.2139911108612653091e+32, tol=PTOL) + assert ae(v.imag, 5.3367124741918251637e+32, tol=PTOL) + v = fp.ei((120.0 + 30.0j)) + assert ae(v, (-9.7760616203707508892e+48 - 1.058257682317195792e+50j), tol=ATOL) + assert ae(v.real, -9.7760616203707508892e+48, tol=PTOL) + assert ae(v.imag, -1.058257682317195792e+50, tol=PTOL) + v = fp.ei((160.0 + 40.0j)) + assert ae(v, (-8.7065541466623638861e+66 + 1.6577106725141739889e+67j), tol=ATOL) + assert ae(v.real, -8.7065541466623638861e+66, tol=PTOL) + assert ae(v.imag, 1.6577106725141739889e+67, tol=PTOL) + v = fp.ei((200.0 + 50.0j)) + assert ae(v, (3.070744996327018106e+84 - 1.7243244846769415903e+84j), tol=ATOL) + assert ae(v.real, 3.070744996327018106e+84, tol=PTOL) + assert ae(v.imag, -1.7243244846769415903e+84, tol=PTOL) + v = fp.ei((320.0 + 80.0j)) + assert ae(v, (-9.9960598637998647276e+135 - 2.6855081527595608863e+136j), tol=ATOL) + assert ae(v.real, -9.9960598637998647276e+135, tol=PTOL) + assert ae(v.imag, -2.6855081527595608863e+136, tol=PTOL) + v = fp.ei((1.1641532182693481445e-10 + 1.1641532182693481445e-10j)) + assert ae(v, (-21.950067703180274374 + 0.78539816351386363145j), tol=ATOL) + assert ae(v.real, -21.950067703180274374, tol=PTOL) + assert ae(v.imag, 0.78539816351386363145, tol=PTOL) + v = fp.ei((0.25 + 0.25j)) + assert ae(v, (-0.21441047326710323254 + 1.0683772981589995996j), tol=ATOL) + assert ae(v.real, -0.21441047326710323254, tol=PTOL) + assert ae(v.imag, 1.0683772981589995996, tol=PTOL) + v = fp.ei((1.0 + 1.0j)) + assert ae(v, (1.7646259855638540684 + 2.3877698515105224193j), tol=ATOL) + assert ae(v.real, 1.7646259855638540684, tol=PTOL) + assert ae(v.imag, 2.3877698515105224193, tol=PTOL) + v = fp.ei((2.0 + 2.0j)) + assert ae(v, (1.8920781621855474089 + 5.3169624378326579621j), tol=ATOL) + assert ae(v.real, 1.8920781621855474089, tol=PTOL) + assert ae(v.imag, 5.3169624378326579621, tol=PTOL) + v = fp.ei((5.0 + 5.0j)) + assert ae(v, (-13.470936071475245856 - 15.322492395731230968j), tol=ATOL) + assert ae(v.real, -13.470936071475245856, tol=PTOL) + assert ae(v.imag, -15.322492395731230968, tol=PTOL) + v = fp.ei((20.0 + 20.0j)) + assert ae(v, (16589317.398788971896 + 5831705.4712368307104j), tol=ATOL) + assert ae(v.real, 16589317.398788971896, tol=PTOL) + assert ae(v.imag, 5831705.4712368307104, tol=PTOL) + v = fp.ei((30.0 + 30.0j)) + assert ae(v, (-154596484273.69322527 - 204179357834.2723043j), tol=ATOL) + assert ae(v.real, -154596484273.69322527, tol=PTOL) + assert ae(v.imag, -204179357834.2723043, tol=PTOL) + v = fp.ei((40.0 + 40.0j)) + assert ae(v, (287512180321448.45408 + 4203502407932318.1156j), tol=ATOL) + assert ae(v.real, 287512180321448.45408, tol=PTOL) + assert ae(v.imag, 4203502407932318.1156, tol=PTOL) + v = fp.ei((50.0 + 50.0j)) + assert ae(v, (36128528616649268826.0 - 64648801861338741960.0j), tol=ATOL) + assert ae(v.real, 36128528616649268826.0, tol=PTOL) + assert ae(v.imag, -64648801861338741960.0, tol=PTOL) + v = fp.ei((80.0 + 80.0j)) + assert ae(v, (-3.8674816337930010217e+32 - 3.0540709639658071041e+32j), tol=ATOL) + assert ae(v.real, -3.8674816337930010217e+32, tol=PTOL) + assert ae(v.imag, -3.0540709639658071041e+32, tol=PTOL) + v = fp.ei((1.1641532182693481445e-10 + 4.6566128730773925781e-10j)) + assert ae(v, (-20.880034621432138988 + 1.3258176641336937524j), tol=ATOL) + assert ae(v.real, -20.880034621432138988, tol=PTOL) + assert ae(v.imag, 1.3258176641336937524, tol=PTOL) + v = fp.ei((0.25 + 1.0j)) + assert ae(v, (0.59066621214766308594 + 2.3968481059377428687j), tol=ATOL) + assert ae(v.real, 0.59066621214766308594, tol=PTOL) + assert ae(v.imag, 2.3968481059377428687, tol=PTOL) + v = fp.ei((1.0 + 4.0j)) + assert ae(v, (-0.49739047283060471093 + 3.5570287076301818702j), tol=ATOL) + assert ae(v.real, -0.49739047283060471093, tol=PTOL) + assert ae(v.imag, 3.5570287076301818702, tol=PTOL) + v = fp.ei((2.0 + 8.0j)) + assert ae(v, (0.8705211147733730969 + 3.3825859385758486351j), tol=ATOL) + assert ae(v.real, 0.8705211147733730969, tol=PTOL) + assert ae(v.imag, 3.3825859385758486351, tol=PTOL) + v = fp.ei((5.0 + 20.0j)) + assert ae(v, (7.0789514293925893007 + 1.5313749363937141849j), tol=ATOL) + assert ae(v.real, 7.0789514293925893007, tol=PTOL) + assert ae(v.imag, 1.5313749363937141849, tol=PTOL) + v = fp.ei((20.0 + 80.0j)) + assert ae(v, (-5855431.4907298084434 - 720917.79156143806727j), tol=ATOL) + assert ae(v.real, -5855431.4907298084434, tol=PTOL) + assert ae(v.imag, -720917.79156143806727, tol=PTOL) + v = fp.ei((30.0 + 120.0j)) + assert ae(v, (65402491644.703470747 - 56697658396.51586764j), tol=ATOL) + assert ae(v.real, 65402491644.703470747, tol=PTOL) + assert ae(v.imag, -56697658396.51586764, tol=PTOL) + v = fp.ei((40.0 + 160.0j)) + assert ae(v, (-25504929379604.776769 + 1429035198630576.3879j), tol=ATOL) + assert ae(v.real, -25504929379604.776769, tol=PTOL) + assert ae(v.imag, 1429035198630576.3879, tol=PTOL) + v = fp.ei((50.0 + 200.0j)) + assert ae(v, (-18437746526988116954.0 - 17146362239046152342.0j), tol=ATOL) + assert ae(v.real, -18437746526988116954.0, tol=PTOL) + assert ae(v.imag, -17146362239046152342.0, tol=PTOL) + v = fp.ei((80.0 + 320.0j)) + assert ae(v, (-3.3464697299634526706e+31 - 1.6473152633843023919e+32j), tol=ATOL) + assert ae(v.real, -3.3464697299634526706e+31, tol=PTOL) + assert ae(v.imag, -1.6473152633843023919e+32, tol=PTOL) + v = fp.ei((0.0 + 1.1641532182693481445e-10j)) + assert ae(v, (-22.29664129357666235 + 1.5707963269113119411j), tol=ATOL) + assert ae(v.real, -22.29664129357666235, tol=PTOL) + assert ae(v.imag, 1.5707963269113119411, tol=PTOL) + v = fp.ei((0.0 + 0.25j)) + assert ae(v, (-0.82466306258094565309 + 1.8199298971146537833j), tol=ATOL) + assert ae(v.real, -0.82466306258094565309, tol=PTOL) + assert ae(v.imag, 1.8199298971146537833, tol=PTOL) + v = fp.ei((0.0 + 1.0j)) + assert ae(v, (0.33740392290096813466 + 2.5168793971620796342j), tol=ATOL) + assert ae(v.real, 0.33740392290096813466, tol=PTOL) + assert ae(v.imag, 2.5168793971620796342, tol=PTOL) + v = fp.ei((0.0 + 2.0j)) + assert ae(v, (0.4229808287748649957 + 3.1762093035975914678j), tol=ATOL) + assert ae(v.real, 0.4229808287748649957, tol=PTOL) + assert ae(v.imag, 3.1762093035975914678, tol=PTOL) + v = fp.ei((0.0 + 5.0j)) + assert ae(v, (-0.19002974965664387862 + 3.1207275717395707565j), tol=ATOL) + assert ae(v.real, -0.19002974965664387862, tol=PTOL) + assert ae(v.imag, 3.1207275717395707565, tol=PTOL) + v = fp.ei((0.0 + 20.0j)) + assert ae(v, (0.04441982084535331654 + 3.1190380278383364594j), tol=ATOL) + assert ae(v.real, 0.04441982084535331654, tol=PTOL) + assert ae(v.imag, 3.1190380278383364594, tol=PTOL) + v = fp.ei((0.0 + 30.0j)) + assert ae(v, (-0.033032417282071143779 + 3.1375528668252477302j), tol=ATOL) + assert ae(v.real, -0.033032417282071143779, tol=PTOL) + assert ae(v.imag, 3.1375528668252477302, tol=PTOL) + v = fp.ei((0.0 + 40.0j)) + assert ae(v, (0.019020007896208766962 + 3.157781446149681126j), tol=ATOL) + assert ae(v.real, 0.019020007896208766962, tol=PTOL) + assert ae(v.imag, 3.157781446149681126, tol=PTOL) + v = fp.ei((0.0 + 50.0j)) + assert ae(v, (-0.0056283863241163054402 + 3.122413399280832514j), tol=ATOL) + assert ae(v.real, -0.0056283863241163054402, tol=PTOL) + assert ae(v.imag, 3.122413399280832514, tol=PTOL) + v = fp.ei((0.0 + 80.0j)) + assert ae(v, (-0.012402501155070958192 + 3.1431272137073839346j), tol=ATOL) + assert ae(v.real, -0.012402501155070958192, tol=PTOL) + assert ae(v.imag, 3.1431272137073839346, tol=PTOL) + v = fp.ei((-1.1641532182693481445e-10 + 4.6566128730773925781e-10j)) + assert ae(v, (-20.880034621664969632 + 1.8157749903874220607j), tol=ATOL) + assert ae(v.real, -20.880034621664969632, tol=PTOL) + assert ae(v.imag, 1.8157749903874220607, tol=PTOL) + v = fp.ei((-0.25 + 1.0j)) + assert ae(v, (0.16868306393667788761 + 2.6557914649950505414j), tol=ATOL) + assert ae(v.real, 0.16868306393667788761, tol=PTOL) + assert ae(v.imag, 2.6557914649950505414, tol=PTOL) + v = fp.ei((-1.0 + 4.0j)) + assert ae(v, (-0.03373591813926547318 + 3.2151161058308770603j), tol=ATOL) + assert ae(v.real, -0.03373591813926547318, tol=PTOL) + assert ae(v.imag, 3.2151161058308770603, tol=PTOL) + v = fp.ei((-2.0 + 8.0j)) + assert ae(v, (0.015392833434733785143 + 3.1384179414340326969j), tol=ATOL) + assert ae(v.real, 0.015392833434733785143, tol=PTOL) + assert ae(v.imag, 3.1384179414340326969, tol=PTOL) + v = fp.ei((-5.0 + 20.0j)) + assert ae(v, (0.00024419662286542966525 + 3.1413825703601317109j), tol=ATOL) + assert ae(v.real, 0.00024419662286542966525, tol=PTOL) + assert ae(v.imag, 3.1413825703601317109, tol=PTOL) + v = fp.ei((-20.0 + 80.0j)) + assert ae(v, (-2.3255552781051330088e-11 + 3.1415926535987396304j), tol=ATOL) + assert ae(v.real, -2.3255552781051330088e-11, tol=PTOL) + assert ae(v.imag, 3.1415926535987396304, tol=PTOL) + v = fp.ei((-30.0 + 120.0j)) + assert ae(v, (2.7068919097124652332e-16 + 3.1415926535897925337j), tol=ATOL) + assert ae(v.real, 2.7068919097124652332e-16, tol=PTOL) + assert ae(v.imag, 3.1415926535897925337, tol=PTOL) + v = fp.ei((-40.0 + 160.0j)) + assert ae(v, (1.1695597827678024687e-20 + 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, 1.1695597827678024687e-20, tol=PTOL) + assert ae(v.imag, 3.1415926535897932385, tol=PTOL) + v = fp.ei((-50.0 + 200.0j)) + assert ae(v, (-9.0323746914410162531e-25 + 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -9.0323746914410162531e-25, tol=PTOL) + assert ae(v.imag, 3.1415926535897932385, tol=PTOL) + v = fp.ei((-80.0 + 320.0j)) + assert ae(v, (-3.4819106748728063576e-38 + 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -3.4819106748728063576e-38, tol=PTOL) + assert ae(v.imag, 3.1415926535897932385, tol=PTOL) + v = fp.ei((-4.6566128730773925781e-10 + 1.1641532182693481445e-10j)) + assert ae(v, (-20.880034622014215597 + 2.8966139905793444061j), tol=ATOL) + assert ae(v.real, -20.880034622014215597, tol=PTOL) + assert ae(v.imag, 2.8966139905793444061, tol=PTOL) + v = fp.ei((-1.0 + 0.25j)) + assert ae(v, (-0.19731063945004229095 + 3.0542266078154932748j), tol=ATOL) + assert ae(v.real, -0.19731063945004229095, tol=PTOL) + assert ae(v.imag, 3.0542266078154932748, tol=PTOL) + v = fp.ei((-4.0 + 1.0j)) + assert ae(v, (-0.0013106173980145506944 + 3.1381384055698581758j), tol=ATOL) + assert ae(v.real, -0.0013106173980145506944, tol=PTOL) + assert ae(v.imag, 3.1381384055698581758, tol=PTOL) + v = fp.ei((-8.0 + 2.0j)) + assert ae(v, (0.000022278049065270225945 + 3.1415634616493367169j), tol=ATOL) + assert ae(v.real, 0.000022278049065270225945, tol=PTOL) + assert ae(v.imag, 3.1415634616493367169, tol=PTOL) + v = fp.ei((-20.0 + 5.0j)) + assert ae(v, (-4.7711374515765346894e-11 + 3.1415926536726958909j), tol=ATOL) + assert ae(v.real, -4.7711374515765346894e-11, tol=PTOL) + assert ae(v.imag, 3.1415926536726958909, tol=PTOL) + v = fp.ei((-80.0 + 20.0j)) + assert ae(v, (-3.8353473865788235787e-38 + 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -3.8353473865788235787e-38, tol=PTOL) + assert ae(v.imag, 3.1415926535897932385, tol=PTOL) + v = fp.ei((-120.0 + 30.0j)) + assert ae(v, (-2.3836002337480334716e-55 + 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -2.3836002337480334716e-55, tol=PTOL) + assert ae(v.imag, 3.1415926535897932385, tol=PTOL) + v = fp.ei((-160.0 + 40.0j)) + assert ae(v, (1.6238022898654510661e-72 + 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, 1.6238022898654510661e-72, tol=PTOL) + assert ae(v.imag, 3.1415926535897932385, tol=PTOL) + v = fp.ei((-200.0 + 50.0j)) + assert ae(v, (-6.6800061461666228487e-90 + 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -6.6800061461666228487e-90, tol=PTOL) + assert ae(v.imag, 3.1415926535897932385, tol=PTOL) + v = fp.ei((-320.0 + 80.0j)) + assert ae(v, (-4.2737871527778786157e-143 + 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -4.2737871527778786157e-143, tol=PTOL) + assert ae(v.imag, 3.1415926535897932385, tol=PTOL) + v = fp.ei(-1.1641532182693481445e-10) + assert ae(v, -22.296641293693077672, tol=ATOL) + assert type(v) is float + v = fp.ei(-0.25) + assert ae(v, -1.0442826344437381945, tol=ATOL) + assert type(v) is float + v = fp.ei(-1.0) + assert ae(v, -0.21938393439552027368, tol=ATOL) + assert type(v) is float + v = fp.ei(-2.0) + assert ae(v, -0.048900510708061119567, tol=ATOL) + assert type(v) is float + v = fp.ei(-5.0) + assert ae(v, -0.0011482955912753257973, tol=ATOL) + assert type(v) is float + v = fp.ei(-20.0) + assert ae(v, -9.8355252906498816904e-11, tol=ATOL) + assert type(v) is float + v = fp.ei(-30.0) + assert ae(v, -3.0215520106888125448e-15, tol=ATOL) + assert type(v) is float + v = fp.ei(-40.0) + assert ae(v, -1.0367732614516569722e-19, tol=ATOL) + assert type(v) is float + v = fp.ei(-50.0) + assert ae(v, -3.7832640295504590187e-24, tol=ATOL) + assert type(v) is float + v = fp.ei(-80.0) + assert ae(v, -2.2285432586884729112e-37, tol=ATOL) + assert type(v) is float + v = fp.ei((-1.1641532182693481445e-10 + 0.0j)) + assert ae(v, (-22.296641293693077672 + 0.0j), tol=ATOL) + assert ae(v.real, -22.296641293693077672, tol=PTOL) + assert v.imag == 0 + v = fp.ei((-0.25 + 0.0j)) + assert ae(v, (-1.0442826344437381945 + 0.0j), tol=ATOL) + assert ae(v.real, -1.0442826344437381945, tol=PTOL) + assert v.imag == 0 + v = fp.ei((-1.0 + 0.0j)) + assert ae(v, (-0.21938393439552027368 + 0.0j), tol=ATOL) + assert ae(v.real, -0.21938393439552027368, tol=PTOL) + assert v.imag == 0 + v = fp.ei((-2.0 + 0.0j)) + assert ae(v, (-0.048900510708061119567 + 0.0j), tol=ATOL) + assert ae(v.real, -0.048900510708061119567, tol=PTOL) + assert v.imag == 0 + v = fp.ei((-5.0 + 0.0j)) + assert ae(v, (-0.0011482955912753257973 + 0.0j), tol=ATOL) + assert ae(v.real, -0.0011482955912753257973, tol=PTOL) + assert v.imag == 0 + v = fp.ei((-20.0 + 0.0j)) + assert ae(v, (-9.8355252906498816904e-11 + 0.0j), tol=ATOL) + assert ae(v.real, -9.8355252906498816904e-11, tol=PTOL) + assert v.imag == 0 + v = fp.ei((-30.0 + 0.0j)) + assert ae(v, (-3.0215520106888125448e-15 + 0.0j), tol=ATOL) + assert ae(v.real, -3.0215520106888125448e-15, tol=PTOL) + assert v.imag == 0 + v = fp.ei((-40.0 + 0.0j)) + assert ae(v, (-1.0367732614516569722e-19 + 0.0j), tol=ATOL) + assert ae(v.real, -1.0367732614516569722e-19, tol=PTOL) + assert v.imag == 0 + v = fp.ei((-50.0 + 0.0j)) + assert ae(v, (-3.7832640295504590187e-24 + 0.0j), tol=ATOL) + assert ae(v.real, -3.7832640295504590187e-24, tol=PTOL) + assert v.imag == 0 + v = fp.ei((-80.0 + 0.0j)) + assert ae(v, (-2.2285432586884729112e-37 + 0.0j), tol=ATOL) + assert ae(v.real, -2.2285432586884729112e-37, tol=PTOL) + assert v.imag == 0 + v = fp.ei((-4.6566128730773925781e-10 - 1.1641532182693481445e-10j)) + assert ae(v, (-20.880034622014215597 - 2.8966139905793444061j), tol=ATOL) + assert ae(v.real, -20.880034622014215597, tol=PTOL) + assert ae(v.imag, -2.8966139905793444061, tol=PTOL) + v = fp.ei((-1.0 - 0.25j)) + assert ae(v, (-0.19731063945004229095 - 3.0542266078154932748j), tol=ATOL) + assert ae(v.real, -0.19731063945004229095, tol=PTOL) + assert ae(v.imag, -3.0542266078154932748, tol=PTOL) + v = fp.ei((-4.0 - 1.0j)) + assert ae(v, (-0.0013106173980145506944 - 3.1381384055698581758j), tol=ATOL) + assert ae(v.real, -0.0013106173980145506944, tol=PTOL) + assert ae(v.imag, -3.1381384055698581758, tol=PTOL) + v = fp.ei((-8.0 - 2.0j)) + assert ae(v, (0.000022278049065270225945 - 3.1415634616493367169j), tol=ATOL) + assert ae(v.real, 0.000022278049065270225945, tol=PTOL) + assert ae(v.imag, -3.1415634616493367169, tol=PTOL) + v = fp.ei((-20.0 - 5.0j)) + assert ae(v, (-4.7711374515765346894e-11 - 3.1415926536726958909j), tol=ATOL) + assert ae(v.real, -4.7711374515765346894e-11, tol=PTOL) + assert ae(v.imag, -3.1415926536726958909, tol=PTOL) + v = fp.ei((-80.0 - 20.0j)) + assert ae(v, (-3.8353473865788235787e-38 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -3.8353473865788235787e-38, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.ei((-120.0 - 30.0j)) + assert ae(v, (-2.3836002337480334716e-55 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -2.3836002337480334716e-55, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.ei((-160.0 - 40.0j)) + assert ae(v, (1.6238022898654510661e-72 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, 1.6238022898654510661e-72, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.ei((-200.0 - 50.0j)) + assert ae(v, (-6.6800061461666228487e-90 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -6.6800061461666228487e-90, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.ei((-320.0 - 80.0j)) + assert ae(v, (-4.2737871527778786157e-143 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -4.2737871527778786157e-143, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.ei((-1.1641532182693481445e-10 - 1.1641532182693481445e-10j)) + assert ae(v, (-21.950067703413105017 - 2.3561944903087602507j), tol=ATOL) + assert ae(v.real, -21.950067703413105017, tol=PTOL) + assert ae(v.imag, -2.3561944903087602507, tol=PTOL) + v = fp.ei((-0.25 - 0.25j)) + assert ae(v, (-0.71092525792923287894 - 2.5766745291767512913j), tol=ATOL) + assert ae(v.real, -0.71092525792923287894, tol=PTOL) + assert ae(v.imag, -2.5766745291767512913, tol=PTOL) + v = fp.ei((-1.0 - 1.0j)) + assert ae(v, (-0.00028162445198141832551 - 2.9622681185504342983j), tol=ATOL) + assert ae(v.real, -0.00028162445198141832551, tol=PTOL) + assert ae(v.imag, -2.9622681185504342983, tol=PTOL) + v = fp.ei((-2.0 - 2.0j)) + assert ae(v, (0.033767089606562004246 - 3.1229932394200426965j), tol=ATOL) + assert ae(v.real, 0.033767089606562004246, tol=PTOL) + assert ae(v.imag, -3.1229932394200426965, tol=PTOL) + v = fp.ei((-5.0 - 5.0j)) + assert ae(v, (-0.0007266506660356393891 - 3.1420636813914284609j), tol=ATOL) + assert ae(v.real, -0.0007266506660356393891, tol=PTOL) + assert ae(v.imag, -3.1420636813914284609, tol=PTOL) + v = fp.ei((-20.0 - 20.0j)) + assert ae(v, (2.3824537449367396579e-11 - 3.1415926535228233653j), tol=ATOL) + assert ae(v.real, 2.3824537449367396579e-11, tol=PTOL) + assert ae(v.imag, -3.1415926535228233653, tol=PTOL) + v = fp.ei((-30.0 - 30.0j)) + assert ae(v, (-1.7316045841744061617e-15 - 3.141592653589794545j), tol=ATOL) + assert ae(v.real, -1.7316045841744061617e-15, tol=PTOL) + assert ae(v.imag, -3.141592653589794545, tol=PTOL) + v = fp.ei((-40.0 - 40.0j)) + assert ae(v, (7.4001043002899232182e-20 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, 7.4001043002899232182e-20, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.ei((-50.0 - 50.0j)) + assert ae(v, (-2.3566128324644641219e-24 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -2.3566128324644641219e-24, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.ei((-80.0 - 80.0j)) + assert ae(v, (-9.8279750572186526673e-38 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -9.8279750572186526673e-38, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.ei((-1.1641532182693481445e-10 - 4.6566128730773925781e-10j)) + assert ae(v, (-20.880034621664969632 - 1.8157749903874220607j), tol=ATOL) + assert ae(v.real, -20.880034621664969632, tol=PTOL) + assert ae(v.imag, -1.8157749903874220607, tol=PTOL) + v = fp.ei((-0.25 - 1.0j)) + assert ae(v, (0.16868306393667788761 - 2.6557914649950505414j), tol=ATOL) + assert ae(v.real, 0.16868306393667788761, tol=PTOL) + assert ae(v.imag, -2.6557914649950505414, tol=PTOL) + v = fp.ei((-1.0 - 4.0j)) + assert ae(v, (-0.03373591813926547318 - 3.2151161058308770603j), tol=ATOL) + assert ae(v.real, -0.03373591813926547318, tol=PTOL) + assert ae(v.imag, -3.2151161058308770603, tol=PTOL) + v = fp.ei((-2.0 - 8.0j)) + assert ae(v, (0.015392833434733785143 - 3.1384179414340326969j), tol=ATOL) + assert ae(v.real, 0.015392833434733785143, tol=PTOL) + assert ae(v.imag, -3.1384179414340326969, tol=PTOL) + v = fp.ei((-5.0 - 20.0j)) + assert ae(v, (0.00024419662286542966525 - 3.1413825703601317109j), tol=ATOL) + assert ae(v.real, 0.00024419662286542966525, tol=PTOL) + assert ae(v.imag, -3.1413825703601317109, tol=PTOL) + v = fp.ei((-20.0 - 80.0j)) + assert ae(v, (-2.3255552781051330088e-11 - 3.1415926535987396304j), tol=ATOL) + assert ae(v.real, -2.3255552781051330088e-11, tol=PTOL) + assert ae(v.imag, -3.1415926535987396304, tol=PTOL) + v = fp.ei((-30.0 - 120.0j)) + assert ae(v, (2.7068919097124652332e-16 - 3.1415926535897925337j), tol=ATOL) + assert ae(v.real, 2.7068919097124652332e-16, tol=PTOL) + assert ae(v.imag, -3.1415926535897925337, tol=PTOL) + v = fp.ei((-40.0 - 160.0j)) + assert ae(v, (1.1695597827678024687e-20 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, 1.1695597827678024687e-20, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.ei((-50.0 - 200.0j)) + assert ae(v, (-9.0323746914410162531e-25 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -9.0323746914410162531e-25, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.ei((-80.0 - 320.0j)) + assert ae(v, (-3.4819106748728063576e-38 - 3.1415926535897932385j), tol=ATOL) + assert ae(v.real, -3.4819106748728063576e-38, tol=PTOL) + assert ae(v.imag, -3.1415926535897932385, tol=PTOL) + v = fp.ei((0.0 - 1.1641532182693481445e-10j)) + assert ae(v, (-22.29664129357666235 - 1.5707963269113119411j), tol=ATOL) + assert ae(v.real, -22.29664129357666235, tol=PTOL) + assert ae(v.imag, -1.5707963269113119411, tol=PTOL) + v = fp.ei((0.0 - 0.25j)) + assert ae(v, (-0.82466306258094565309 - 1.8199298971146537833j), tol=ATOL) + assert ae(v.real, -0.82466306258094565309, tol=PTOL) + assert ae(v.imag, -1.8199298971146537833, tol=PTOL) + v = fp.ei((0.0 - 1.0j)) + assert ae(v, (0.33740392290096813466 - 2.5168793971620796342j), tol=ATOL) + assert ae(v.real, 0.33740392290096813466, tol=PTOL) + assert ae(v.imag, -2.5168793971620796342, tol=PTOL) + v = fp.ei((0.0 - 2.0j)) + assert ae(v, (0.4229808287748649957 - 3.1762093035975914678j), tol=ATOL) + assert ae(v.real, 0.4229808287748649957, tol=PTOL) + assert ae(v.imag, -3.1762093035975914678, tol=PTOL) + v = fp.ei((0.0 - 5.0j)) + assert ae(v, (-0.19002974965664387862 - 3.1207275717395707565j), tol=ATOL) + assert ae(v.real, -0.19002974965664387862, tol=PTOL) + assert ae(v.imag, -3.1207275717395707565, tol=PTOL) + v = fp.ei((0.0 - 20.0j)) + assert ae(v, (0.04441982084535331654 - 3.1190380278383364594j), tol=ATOL) + assert ae(v.real, 0.04441982084535331654, tol=PTOL) + assert ae(v.imag, -3.1190380278383364594, tol=PTOL) + v = fp.ei((0.0 - 30.0j)) + assert ae(v, (-0.033032417282071143779 - 3.1375528668252477302j), tol=ATOL) + assert ae(v.real, -0.033032417282071143779, tol=PTOL) + assert ae(v.imag, -3.1375528668252477302, tol=PTOL) + v = fp.ei((0.0 - 40.0j)) + assert ae(v, (0.019020007896208766962 - 3.157781446149681126j), tol=ATOL) + assert ae(v.real, 0.019020007896208766962, tol=PTOL) + assert ae(v.imag, -3.157781446149681126, tol=PTOL) + v = fp.ei((0.0 - 50.0j)) + assert ae(v, (-0.0056283863241163054402 - 3.122413399280832514j), tol=ATOL) + assert ae(v.real, -0.0056283863241163054402, tol=PTOL) + assert ae(v.imag, -3.122413399280832514, tol=PTOL) + v = fp.ei((0.0 - 80.0j)) + assert ae(v, (-0.012402501155070958192 - 3.1431272137073839346j), tol=ATOL) + assert ae(v.real, -0.012402501155070958192, tol=PTOL) + assert ae(v.imag, -3.1431272137073839346, tol=PTOL) + v = fp.ei((1.1641532182693481445e-10 - 4.6566128730773925781e-10j)) + assert ae(v, (-20.880034621432138988 - 1.3258176641336937524j), tol=ATOL) + assert ae(v.real, -20.880034621432138988, tol=PTOL) + assert ae(v.imag, -1.3258176641336937524, tol=PTOL) + v = fp.ei((0.25 - 1.0j)) + assert ae(v, (0.59066621214766308594 - 2.3968481059377428687j), tol=ATOL) + assert ae(v.real, 0.59066621214766308594, tol=PTOL) + assert ae(v.imag, -2.3968481059377428687, tol=PTOL) + v = fp.ei((1.0 - 4.0j)) + assert ae(v, (-0.49739047283060471093 - 3.5570287076301818702j), tol=ATOL) + assert ae(v.real, -0.49739047283060471093, tol=PTOL) + assert ae(v.imag, -3.5570287076301818702, tol=PTOL) + v = fp.ei((2.0 - 8.0j)) + assert ae(v, (0.8705211147733730969 - 3.3825859385758486351j), tol=ATOL) + assert ae(v.real, 0.8705211147733730969, tol=PTOL) + assert ae(v.imag, -3.3825859385758486351, tol=PTOL) + v = fp.ei((5.0 - 20.0j)) + assert ae(v, (7.0789514293925893007 - 1.5313749363937141849j), tol=ATOL) + assert ae(v.real, 7.0789514293925893007, tol=PTOL) + assert ae(v.imag, -1.5313749363937141849, tol=PTOL) + v = fp.ei((20.0 - 80.0j)) + assert ae(v, (-5855431.4907298084434 + 720917.79156143806727j), tol=ATOL) + assert ae(v.real, -5855431.4907298084434, tol=PTOL) + assert ae(v.imag, 720917.79156143806727, tol=PTOL) + v = fp.ei((30.0 - 120.0j)) + assert ae(v, (65402491644.703470747 + 56697658396.51586764j), tol=ATOL) + assert ae(v.real, 65402491644.703470747, tol=PTOL) + assert ae(v.imag, 56697658396.51586764, tol=PTOL) + v = fp.ei((40.0 - 160.0j)) + assert ae(v, (-25504929379604.776769 - 1429035198630576.3879j), tol=ATOL) + assert ae(v.real, -25504929379604.776769, tol=PTOL) + assert ae(v.imag, -1429035198630576.3879, tol=PTOL) + v = fp.ei((50.0 - 200.0j)) + assert ae(v, (-18437746526988116954.0 + 17146362239046152342.0j), tol=ATOL) + assert ae(v.real, -18437746526988116954.0, tol=PTOL) + assert ae(v.imag, 17146362239046152342.0, tol=PTOL) + v = fp.ei((80.0 - 320.0j)) + assert ae(v, (-3.3464697299634526706e+31 + 1.6473152633843023919e+32j), tol=ATOL) + assert ae(v.real, -3.3464697299634526706e+31, tol=PTOL) + assert ae(v.imag, 1.6473152633843023919e+32, tol=PTOL) + v = fp.ei((1.1641532182693481445e-10 - 1.1641532182693481445e-10j)) + assert ae(v, (-21.950067703180274374 - 0.78539816351386363145j), tol=ATOL) + assert ae(v.real, -21.950067703180274374, tol=PTOL) + assert ae(v.imag, -0.78539816351386363145, tol=PTOL) + v = fp.ei((0.25 - 0.25j)) + assert ae(v, (-0.21441047326710323254 - 1.0683772981589995996j), tol=ATOL) + assert ae(v.real, -0.21441047326710323254, tol=PTOL) + assert ae(v.imag, -1.0683772981589995996, tol=PTOL) + v = fp.ei((1.0 - 1.0j)) + assert ae(v, (1.7646259855638540684 - 2.3877698515105224193j), tol=ATOL) + assert ae(v.real, 1.7646259855638540684, tol=PTOL) + assert ae(v.imag, -2.3877698515105224193, tol=PTOL) + v = fp.ei((2.0 - 2.0j)) + assert ae(v, (1.8920781621855474089 - 5.3169624378326579621j), tol=ATOL) + assert ae(v.real, 1.8920781621855474089, tol=PTOL) + assert ae(v.imag, -5.3169624378326579621, tol=PTOL) + v = fp.ei((5.0 - 5.0j)) + assert ae(v, (-13.470936071475245856 + 15.322492395731230968j), tol=ATOL) + assert ae(v.real, -13.470936071475245856, tol=PTOL) + assert ae(v.imag, 15.322492395731230968, tol=PTOL) + v = fp.ei((20.0 - 20.0j)) + assert ae(v, (16589317.398788971896 - 5831705.4712368307104j), tol=ATOL) + assert ae(v.real, 16589317.398788971896, tol=PTOL) + assert ae(v.imag, -5831705.4712368307104, tol=PTOL) + v = fp.ei((30.0 - 30.0j)) + assert ae(v, (-154596484273.69322527 + 204179357834.2723043j), tol=ATOL) + assert ae(v.real, -154596484273.69322527, tol=PTOL) + assert ae(v.imag, 204179357834.2723043, tol=PTOL) + v = fp.ei((40.0 - 40.0j)) + assert ae(v, (287512180321448.45408 - 4203502407932318.1156j), tol=ATOL) + assert ae(v.real, 287512180321448.45408, tol=PTOL) + assert ae(v.imag, -4203502407932318.1156, tol=PTOL) + v = fp.ei((50.0 - 50.0j)) + assert ae(v, (36128528616649268826.0 + 64648801861338741960.0j), tol=ATOL) + assert ae(v.real, 36128528616649268826.0, tol=PTOL) + assert ae(v.imag, 64648801861338741960.0, tol=PTOL) + v = fp.ei((80.0 - 80.0j)) + assert ae(v, (-3.8674816337930010217e+32 + 3.0540709639658071041e+32j), tol=ATOL) + assert ae(v.real, -3.8674816337930010217e+32, tol=PTOL) + assert ae(v.imag, 3.0540709639658071041e+32, tol=PTOL) + v = fp.ei((4.6566128730773925781e-10 - 1.1641532182693481445e-10j)) + assert ae(v, (-20.880034621082893023 - 0.24497866324327947603j), tol=ATOL) + assert ae(v.real, -20.880034621082893023, tol=PTOL) + assert ae(v.imag, -0.24497866324327947603, tol=PTOL) + v = fp.ei((1.0 - 0.25j)) + assert ae(v, (1.8942716983721074932 - 0.67268237088273915854j), tol=ATOL) + assert ae(v.real, 1.8942716983721074932, tol=PTOL) + assert ae(v.imag, -0.67268237088273915854, tol=PTOL) + v = fp.ei((4.0 - 1.0j)) + assert ae(v, (14.806699492675420438 - 12.280015176673582616j), tol=ATOL) + assert ae(v.real, 14.806699492675420438, tol=PTOL) + assert ae(v.imag, -12.280015176673582616, tol=PTOL) + v = fp.ei((8.0 - 2.0j)) + assert ae(v, (-54.633252667426386294 - 416.34477429173650012j), tol=ATOL) + assert ae(v.real, -54.633252667426386294, tol=PTOL) + assert ae(v.imag, -416.34477429173650012, tol=PTOL) + v = fp.ei((20.0 - 5.0j)) + assert ae(v, (711836.97165402624643 + 24745247.798103247366j), tol=ATOL) + assert ae(v.real, 711836.97165402624643, tol=PTOL) + assert ae(v.imag, 24745247.798103247366, tol=PTOL) + v = fp.ei((80.0 - 20.0j)) + assert ae(v, (4.2139911108612653091e+32 - 5.3367124741918251637e+32j), tol=ATOL) + assert ae(v.real, 4.2139911108612653091e+32, tol=PTOL) + assert ae(v.imag, -5.3367124741918251637e+32, tol=PTOL) + v = fp.ei((120.0 - 30.0j)) + assert ae(v, (-9.7760616203707508892e+48 + 1.058257682317195792e+50j), tol=ATOL) + assert ae(v.real, -9.7760616203707508892e+48, tol=PTOL) + assert ae(v.imag, 1.058257682317195792e+50, tol=PTOL) + v = fp.ei((160.0 - 40.0j)) + assert ae(v, (-8.7065541466623638861e+66 - 1.6577106725141739889e+67j), tol=ATOL) + assert ae(v.real, -8.7065541466623638861e+66, tol=PTOL) + assert ae(v.imag, -1.6577106725141739889e+67, tol=PTOL) + v = fp.ei((200.0 - 50.0j)) + assert ae(v, (3.070744996327018106e+84 + 1.7243244846769415903e+84j), tol=ATOL) + assert ae(v.real, 3.070744996327018106e+84, tol=PTOL) + assert ae(v.imag, 1.7243244846769415903e+84, tol=PTOL) + v = fp.ei((320.0 - 80.0j)) + assert ae(v, (-9.9960598637998647276e+135 + 2.6855081527595608863e+136j), tol=ATOL) + assert ae(v.real, -9.9960598637998647276e+135, tol=PTOL) + assert ae(v.imag, 2.6855081527595608863e+136, tol=PTOL) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_ode.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_ode.py new file mode 100644 index 0000000000000000000000000000000000000000..6b6dbffa79cfd4ca6dbf14f8591296ee48b16682 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_ode.py @@ -0,0 +1,73 @@ +#from mpmath.calculus import ODE_step_euler, ODE_step_rk4, odeint, arange +from mpmath import odefun, cos, sin, mpf, sinc, mp + +''' +solvers = [ODE_step_euler, ODE_step_rk4] + +def test_ode1(): + """ + Let's solve: + + x'' + w**2 * x = 0 + + i.e. x1 = x, x2 = x1': + + x1' = x2 + x2' = -x1 + """ + def derivs((x1, x2), t): + return x2, -x1 + + for solver in solvers: + t = arange(0, 3.1415926, 0.005) + sol = odeint(derivs, (0., 1.), t, solver) + x1 = [a[0] for a in sol] + x2 = [a[1] for a in sol] + # the result is x1 = sin(t), x2 = cos(t) + # let's just check the end points for t = pi + assert abs(x1[-1]) < 1e-2 + assert abs(x2[-1] - (-1)) < 1e-2 + +def test_ode2(): + """ + Let's solve: + + x' - x = 0 + + i.e. x = exp(x) + + """ + def derivs((x), t): + return x + + for solver in solvers: + t = arange(0, 1, 1e-3) + sol = odeint(derivs, (1.,), t, solver) + x = [a[0] for a in sol] + # the result is x = exp(t) + # let's just check the end point for t = 1, i.e. x = e + assert abs(x[-1] - 2.718281828) < 1e-2 +''' + +def test_odefun_rational(): + mp.dps = 15 + # A rational function + f = lambda t: 1/(1+mpf(t)**2) + g = odefun(lambda x, y: [-2*x*y[0]**2], 0, [f(0)]) + assert f(2).ae(g(2)[0]) + +def test_odefun_sinc_large(): + mp.dps = 15 + # Sinc function; test for large x + f = sinc + g = odefun(lambda x, y: [(cos(x)-y[0])/x], 1, [f(1)], tol=0.01, degree=5) + assert abs(f(100) - g(100)[0])/f(100) < 0.01 + +def test_odefun_harmonic(): + mp.dps = 15 + # Harmonic oscillator + f = odefun(lambda x, y: [-y[1], y[0]], 0, [1, 0]) + for x in [0, 1, 2.5, 8, 3.7]: # we go back to 3.7 to check caching + c, s = f(x) + assert c.ae(cos(x)) + assert s.ae(sin(x)) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_trig.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_trig.py new file mode 100644 index 0000000000000000000000000000000000000000..c70a2a0ff4c44c784404ecdb15357d5b91a992d6 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/mpmath/tests/test_trig.py @@ -0,0 +1,136 @@ +from mpmath import * +from mpmath.libmp import * + +def test_trig_misc_hard(): + mp.prec = 53 + # Worst-case input for an IEEE double, from a paper by Kahan + x = ldexp(6381956970095103,797) + assert cos(x) == mpf('-4.6871659242546277e-19') + assert sin(x) == 1 + + mp.prec = 150 + a = mpf(10**50) + mp.prec = 53 + assert sin(a).ae(-0.7896724934293100827) + assert cos(a).ae(-0.6135286082336635622) + + # Check relative accuracy close to x = zero + assert sin(1e-100) == 1e-100 # when rounding to nearest + assert sin(1e-6).ae(9.999999999998333e-007, rel_eps=2e-15, abs_eps=0) + assert sin(1e-6j).ae(1.0000000000001666e-006j, rel_eps=2e-15, abs_eps=0) + assert sin(-1e-6j).ae(-1.0000000000001666e-006j, rel_eps=2e-15, abs_eps=0) + assert cos(1e-100) == 1 + assert cos(1e-6).ae(0.9999999999995) + assert cos(-1e-6j).ae(1.0000000000005) + assert tan(1e-100) == 1e-100 + assert tan(1e-6).ae(1.0000000000003335e-006, rel_eps=2e-15, abs_eps=0) + assert tan(1e-6j).ae(9.9999999999966644e-007j, rel_eps=2e-15, abs_eps=0) + assert tan(-1e-6j).ae(-9.9999999999966644e-007j, rel_eps=2e-15, abs_eps=0) + +def test_trig_near_zero(): + mp.dps = 15 + + for r in [round_nearest, round_down, round_up, round_floor, round_ceiling]: + assert sin(0, rounding=r) == 0 + assert cos(0, rounding=r) == 1 + + a = mpf('1e-100') + b = mpf('-1e-100') + + assert sin(a, rounding=round_nearest) == a + assert sin(a, rounding=round_down) < a + assert sin(a, rounding=round_floor) < a + assert sin(a, rounding=round_up) >= a + assert sin(a, rounding=round_ceiling) >= a + assert sin(b, rounding=round_nearest) == b + assert sin(b, rounding=round_down) > b + assert sin(b, rounding=round_floor) <= b + assert sin(b, rounding=round_up) <= b + assert sin(b, rounding=round_ceiling) > b + + assert cos(a, rounding=round_nearest) == 1 + assert cos(a, rounding=round_down) < 1 + assert cos(a, rounding=round_floor) < 1 + assert cos(a, rounding=round_up) == 1 + assert cos(a, rounding=round_ceiling) == 1 + assert cos(b, rounding=round_nearest) == 1 + assert cos(b, rounding=round_down) < 1 + assert cos(b, rounding=round_floor) < 1 + assert cos(b, rounding=round_up) == 1 + assert cos(b, rounding=round_ceiling) == 1 + + +def test_trig_near_n_pi(): + + mp.dps = 15 + a = [n*pi for n in [1, 2, 6, 11, 100, 1001, 10000, 100001]] + mp.dps = 135 + a.append(10**100 * pi) + mp.dps = 15 + + assert sin(a[0]) == mpf('1.2246467991473531772e-16') + assert sin(a[1]) == mpf('-2.4492935982947063545e-16') + assert sin(a[2]) == mpf('-7.3478807948841190634e-16') + assert sin(a[3]) == mpf('4.8998251578625894243e-15') + assert sin(a[4]) == mpf('1.9643867237284719452e-15') + assert sin(a[5]) == mpf('-8.8632615209684813458e-15') + assert sin(a[6]) == mpf('-4.8568235395684898392e-13') + assert sin(a[7]) == mpf('3.9087342299491231029e-11') + assert sin(a[8]) == mpf('-1.369235466754566993528e-36') + + r = round_nearest + assert cos(a[0], rounding=r) == -1 + assert cos(a[1], rounding=r) == 1 + assert cos(a[2], rounding=r) == 1 + assert cos(a[3], rounding=r) == -1 + assert cos(a[4], rounding=r) == 1 + assert cos(a[5], rounding=r) == -1 + assert cos(a[6], rounding=r) == 1 + assert cos(a[7], rounding=r) == -1 + assert cos(a[8], rounding=r) == 1 + + r = round_up + assert cos(a[0], rounding=r) == -1 + assert cos(a[1], rounding=r) == 1 + assert cos(a[2], rounding=r) == 1 + assert cos(a[3], rounding=r) == -1 + assert cos(a[4], rounding=r) == 1 + assert cos(a[5], rounding=r) == -1 + assert cos(a[6], rounding=r) == 1 + assert cos(a[7], rounding=r) == -1 + assert cos(a[8], rounding=r) == 1 + + r = round_down + assert cos(a[0], rounding=r) > -1 + assert cos(a[1], rounding=r) < 1 + assert cos(a[2], rounding=r) < 1 + assert cos(a[3], rounding=r) > -1 + assert cos(a[4], rounding=r) < 1 + assert cos(a[5], rounding=r) > -1 + assert cos(a[6], rounding=r) < 1 + assert cos(a[7], rounding=r) > -1 + assert cos(a[8], rounding=r) < 1 + + r = round_floor + assert cos(a[0], rounding=r) == -1 + assert cos(a[1], rounding=r) < 1 + assert cos(a[2], rounding=r) < 1 + assert cos(a[3], rounding=r) == -1 + assert cos(a[4], rounding=r) < 1 + assert cos(a[5], rounding=r) == -1 + assert cos(a[6], rounding=r) < 1 + assert cos(a[7], rounding=r) == -1 + assert cos(a[8], rounding=r) < 1 + + r = round_ceiling + assert cos(a[0], rounding=r) > -1 + assert cos(a[1], rounding=r) == 1 + assert cos(a[2], rounding=r) == 1 + assert cos(a[3], rounding=r) > -1 + assert cos(a[4], rounding=r) == 1 + assert cos(a[5], rounding=r) > -1 + assert cos(a[6], rounding=r) == 1 + assert cos(a[7], rounding=r) > -1 + assert cos(a[8], rounding=r) == 1 + + mp.dps = 15 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/chains.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/chains.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab619cd7f903fb2e50ab39929a5af7055430c025 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/chains.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/hybrid.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/hybrid.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0bb074ad499c6aa2e741e6a33e18cf0c5c54885d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/hybrid.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/similarity.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/similarity.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..642e425fb7c673794eff44a1c643c7c87005623f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/similarity.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/wiener.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/wiener.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9288295577b4998535e06c26e148727b5f8d0e14 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/__pycache__/wiener.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d84a9e2b3f6fff0f4cc6fccb847285e113bed370 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/base_test.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/base_test.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d270b614a623b459193eb6cc65e5406683a41f77 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/base_test.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_connectivity.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_connectivity.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..899e7bb86d94fc573873e1e8ca6bcd9019c4e898 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_connectivity.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_correlation.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_correlation.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..04b0d7f414bcb46af82b3f9648032b7e3df0ebe8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_correlation.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_mixing.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_mixing.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1768d18943dbb19c693aca3be6bf4bcb61e13af Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_mixing.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_pairs.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_pairs.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4e04a306d63ea200bf8a91090a1f8018d48251b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/tests/__pycache__/test_pairs.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39fb483498ed4a47571c35d5cb72a4635ac56a41 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/boykovkolmogorov.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/boykovkolmogorov.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0c125715e6a36e63a9967fc268db2702e17af037 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/boykovkolmogorov.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/capacityscaling.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/capacityscaling.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ccb643fabda729833d957204057daf5b5e6bb18 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/capacityscaling.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/dinitz_alg.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/dinitz_alg.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..efa30cacbc0de4366a64805009a9e796274a3118 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/dinitz_alg.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/edmondskarp.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/edmondskarp.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ed879572fdf464fb5591fff4234b922c1d0fe5c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/edmondskarp.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/gomory_hu.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/gomory_hu.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab0cc5a048bca5164d9a9bad7eec903f992ab935 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/gomory_hu.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/maxflow.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/maxflow.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f6c01e891eb5afed9645909eb0afd799a71ade1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/maxflow.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/mincost.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/mincost.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e715ec52c774e507a5cbf1a39ca41edf705276bd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/mincost.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/networksimplex.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/networksimplex.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..78601cd1e7dae5087b5efde646c53728ca6ec39d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/networksimplex.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/preflowpush.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/preflowpush.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6febdacb7f83b33c2a1af558560b70a1c442e526 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/preflowpush.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/shortestaugmentingpath.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/shortestaugmentingpath.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37c2241ea6e0b8bc63be721130e15214a0f45b18 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/shortestaugmentingpath.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/utils.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aad677b4cdc666c7b48dadbfba29ab8772b9ba9c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/__pycache__/utils.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f2c1f93c6328209430110521df61f8d33a7485f0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_gomory_hu.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_gomory_hu.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc56d569c9ebac7e06464e4f4fbbda94a9dc7b00 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_gomory_hu.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_maxflow.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_maxflow.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb5742d711f04cf2d558dfdd737be74f9f2f1582 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_maxflow.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_maxflow_large_graph.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_maxflow_large_graph.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6de1bf02df163a4b515ceb820174c09ce54b929 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_maxflow_large_graph.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_mincost.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_mincost.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb5bdc4b35b440181c9bb708e9d933ed68d72114 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_mincost.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_networksimplex.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_networksimplex.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e04f4391ea4fa94c3eeacbc5e75e06c37f72a56d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/__pycache__/test_networksimplex.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_gomory_hu.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_gomory_hu.py new file mode 100644 index 0000000000000000000000000000000000000000..1649ec82c719226e9caa68268d8953f7cae6ef74 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_gomory_hu.py @@ -0,0 +1,128 @@ +from itertools import combinations + +import pytest + +import networkx as nx +from networkx.algorithms.flow import ( + boykov_kolmogorov, + dinitz, + edmonds_karp, + preflow_push, + shortest_augmenting_path, +) + +flow_funcs = [ + boykov_kolmogorov, + dinitz, + edmonds_karp, + preflow_push, + shortest_augmenting_path, +] + + +class TestGomoryHuTree: + def minimum_edge_weight(self, T, u, v): + path = nx.shortest_path(T, u, v, weight="weight") + return min((T[u][v]["weight"], (u, v)) for (u, v) in zip(path, path[1:])) + + def compute_cutset(self, G, T_orig, edge): + T = T_orig.copy() + T.remove_edge(*edge) + U, V = list(nx.connected_components(T)) + cutset = set() + for x, nbrs in ((n, G[n]) for n in U): + cutset.update((x, y) for y in nbrs if y in V) + return cutset + + def test_default_flow_function_karate_club_graph(self): + G = nx.karate_club_graph() + nx.set_edge_attributes(G, 1, "capacity") + T = nx.gomory_hu_tree(G) + assert nx.is_tree(T) + for u, v in combinations(G, 2): + cut_value, edge = self.minimum_edge_weight(T, u, v) + assert nx.minimum_cut_value(G, u, v) == cut_value + + def test_karate_club_graph(self): + G = nx.karate_club_graph() + nx.set_edge_attributes(G, 1, "capacity") + for flow_func in flow_funcs: + T = nx.gomory_hu_tree(G, flow_func=flow_func) + assert nx.is_tree(T) + for u, v in combinations(G, 2): + cut_value, edge = self.minimum_edge_weight(T, u, v) + assert nx.minimum_cut_value(G, u, v) == cut_value + + def test_davis_southern_women_graph(self): + G = nx.davis_southern_women_graph() + nx.set_edge_attributes(G, 1, "capacity") + for flow_func in flow_funcs: + T = nx.gomory_hu_tree(G, flow_func=flow_func) + assert nx.is_tree(T) + for u, v in combinations(G, 2): + cut_value, edge = self.minimum_edge_weight(T, u, v) + assert nx.minimum_cut_value(G, u, v) == cut_value + + def test_florentine_families_graph(self): + G = nx.florentine_families_graph() + nx.set_edge_attributes(G, 1, "capacity") + for flow_func in flow_funcs: + T = nx.gomory_hu_tree(G, flow_func=flow_func) + assert nx.is_tree(T) + for u, v in combinations(G, 2): + cut_value, edge = self.minimum_edge_weight(T, u, v) + assert nx.minimum_cut_value(G, u, v) == cut_value + + @pytest.mark.slow + def test_les_miserables_graph_cutset(self): + G = nx.les_miserables_graph() + nx.set_edge_attributes(G, 1, "capacity") + for flow_func in flow_funcs: + T = nx.gomory_hu_tree(G, flow_func=flow_func) + assert nx.is_tree(T) + for u, v in combinations(G, 2): + cut_value, edge = self.minimum_edge_weight(T, u, v) + assert nx.minimum_cut_value(G, u, v) == cut_value + + def test_karate_club_graph_cutset(self): + G = nx.karate_club_graph() + nx.set_edge_attributes(G, 1, "capacity") + T = nx.gomory_hu_tree(G) + assert nx.is_tree(T) + u, v = 0, 33 + cut_value, edge = self.minimum_edge_weight(T, u, v) + cutset = self.compute_cutset(G, T, edge) + assert cut_value == len(cutset) + + def test_wikipedia_example(self): + # Example from https://en.wikipedia.org/wiki/Gomory%E2%80%93Hu_tree + G = nx.Graph() + G.add_weighted_edges_from( + ( + (0, 1, 1), + (0, 2, 7), + (1, 2, 1), + (1, 3, 3), + (1, 4, 2), + (2, 4, 4), + (3, 4, 1), + (3, 5, 6), + (4, 5, 2), + ) + ) + for flow_func in flow_funcs: + T = nx.gomory_hu_tree(G, capacity="weight", flow_func=flow_func) + assert nx.is_tree(T) + for u, v in combinations(G, 2): + cut_value, edge = self.minimum_edge_weight(T, u, v) + assert nx.minimum_cut_value(G, u, v, capacity="weight") == cut_value + + def test_directed_raises(self): + with pytest.raises(nx.NetworkXNotImplemented): + G = nx.DiGraph() + T = nx.gomory_hu_tree(G) + + def test_empty_raises(self): + with pytest.raises(nx.NetworkXError): + G = nx.empty_graph() + T = nx.gomory_hu_tree(G) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_maxflow.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_maxflow.py new file mode 100644 index 0000000000000000000000000000000000000000..d7305a7b6320ef1b55c682386cd7320f33a78994 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_maxflow.py @@ -0,0 +1,573 @@ +"""Maximum flow algorithms test suite.""" + +import pytest + +import networkx as nx +from networkx.algorithms.flow import ( + boykov_kolmogorov, + build_flow_dict, + build_residual_network, + dinitz, + edmonds_karp, + preflow_push, + shortest_augmenting_path, +) + +flow_funcs = { + boykov_kolmogorov, + dinitz, + edmonds_karp, + preflow_push, + shortest_augmenting_path, +} + +max_min_funcs = {nx.maximum_flow, nx.minimum_cut} +flow_value_funcs = {nx.maximum_flow_value, nx.minimum_cut_value} +interface_funcs = max_min_funcs | flow_value_funcs +all_funcs = flow_funcs | interface_funcs + + +def compute_cutset(G, partition): + reachable, non_reachable = partition + cutset = set() + for u, nbrs in ((n, G[n]) for n in reachable): + cutset.update((u, v) for v in nbrs if v in non_reachable) + return cutset + + +def validate_flows(G, s, t, flowDict, solnValue, capacity, flow_func): + errmsg = f"Assertion failed in function: {flow_func.__name__}" + assert set(G) == set(flowDict), errmsg + for u in G: + assert set(G[u]) == set(flowDict[u]), errmsg + excess = {u: 0 for u in flowDict} + for u in flowDict: + for v, flow in flowDict[u].items(): + if capacity in G[u][v]: + assert flow <= G[u][v][capacity] + assert flow >= 0, errmsg + excess[u] -= flow + excess[v] += flow + for u, exc in excess.items(): + if u == s: + assert exc == -solnValue, errmsg + elif u == t: + assert exc == solnValue, errmsg + else: + assert exc == 0, errmsg + + +def validate_cuts(G, s, t, solnValue, partition, capacity, flow_func): + errmsg = f"Assertion failed in function: {flow_func.__name__}" + assert all(n in G for n in partition[0]), errmsg + assert all(n in G for n in partition[1]), errmsg + cutset = compute_cutset(G, partition) + assert all(G.has_edge(u, v) for (u, v) in cutset), errmsg + assert solnValue == sum(G[u][v][capacity] for (u, v) in cutset), errmsg + H = G.copy() + H.remove_edges_from(cutset) + if not G.is_directed(): + assert not nx.is_connected(H), errmsg + else: + assert not nx.is_strongly_connected(H), errmsg + + +def compare_flows_and_cuts(G, s, t, solnValue, capacity="capacity"): + for flow_func in flow_funcs: + errmsg = f"Assertion failed in function: {flow_func.__name__}" + R = flow_func(G, s, t, capacity) + # Test both legacy and new implementations. + flow_value = R.graph["flow_value"] + flow_dict = build_flow_dict(G, R) + assert flow_value == solnValue, errmsg + validate_flows(G, s, t, flow_dict, solnValue, capacity, flow_func) + # Minimum cut + cut_value, partition = nx.minimum_cut( + G, s, t, capacity=capacity, flow_func=flow_func + ) + validate_cuts(G, s, t, solnValue, partition, capacity, flow_func) + + +class TestMaxflowMinCutCommon: + def test_graph1(self): + # Trivial undirected graph + G = nx.Graph() + G.add_edge(1, 2, capacity=1.0) + + # solution flows + # {1: {2: 1.0}, 2: {1: 1.0}} + + compare_flows_and_cuts(G, 1, 2, 1.0) + + def test_graph2(self): + # A more complex undirected graph + # adapted from https://web.archive.org/web/20220815055650/https://www.topcoder.com/thrive/articles/Maximum%20Flow:%20Part%20One + G = nx.Graph() + G.add_edge("x", "a", capacity=3.0) + G.add_edge("x", "b", capacity=1.0) + G.add_edge("a", "c", capacity=3.0) + G.add_edge("b", "c", capacity=5.0) + G.add_edge("b", "d", capacity=4.0) + G.add_edge("d", "e", capacity=2.0) + G.add_edge("c", "y", capacity=2.0) + G.add_edge("e", "y", capacity=3.0) + + # H + # { + # "x": {"a": 3, "b": 1}, + # "a": {"c": 3, "x": 3}, + # "b": {"c": 1, "d": 2, "x": 1}, + # "c": {"a": 3, "b": 1, "y": 2}, + # "d": {"b": 2, "e": 2}, + # "e": {"d": 2, "y": 2}, + # "y": {"c": 2, "e": 2}, + # } + + compare_flows_and_cuts(G, "x", "y", 4.0) + + def test_digraph1(self): + # The classic directed graph example + G = nx.DiGraph() + G.add_edge("a", "b", capacity=1000.0) + G.add_edge("a", "c", capacity=1000.0) + G.add_edge("b", "c", capacity=1.0) + G.add_edge("b", "d", capacity=1000.0) + G.add_edge("c", "d", capacity=1000.0) + + # H + # { + # "a": {"b": 1000.0, "c": 1000.0}, + # "b": {"c": 0, "d": 1000.0}, + # "c": {"d": 1000.0}, + # "d": {}, + # } + + compare_flows_and_cuts(G, "a", "d", 2000.0) + + def test_digraph2(self): + # An example in which some edges end up with zero flow. + G = nx.DiGraph() + G.add_edge("s", "b", capacity=2) + G.add_edge("s", "c", capacity=1) + G.add_edge("c", "d", capacity=1) + G.add_edge("d", "a", capacity=1) + G.add_edge("b", "a", capacity=2) + G.add_edge("a", "t", capacity=2) + + # H + # { + # "s": {"b": 2, "c": 0}, + # "c": {"d": 0}, + # "d": {"a": 0}, + # "b": {"a": 2}, + # "a": {"t": 2}, + # "t": {}, + # } + + compare_flows_and_cuts(G, "s", "t", 2) + + def test_digraph3(self): + # A directed graph example from Cormen et al. + G = nx.DiGraph() + G.add_edge("s", "v1", capacity=16.0) + G.add_edge("s", "v2", capacity=13.0) + G.add_edge("v1", "v2", capacity=10.0) + G.add_edge("v2", "v1", capacity=4.0) + G.add_edge("v1", "v3", capacity=12.0) + G.add_edge("v3", "v2", capacity=9.0) + G.add_edge("v2", "v4", capacity=14.0) + G.add_edge("v4", "v3", capacity=7.0) + G.add_edge("v3", "t", capacity=20.0) + G.add_edge("v4", "t", capacity=4.0) + + # H + # { + # "s": {"v1": 12.0, "v2": 11.0}, + # "v2": {"v1": 0, "v4": 11.0}, + # "v1": {"v2": 0, "v3": 12.0}, + # "v3": {"v2": 0, "t": 19.0}, + # "v4": {"v3": 7.0, "t": 4.0}, + # "t": {}, + # } + + compare_flows_and_cuts(G, "s", "t", 23.0) + + def test_digraph4(self): + # A more complex directed graph + # from https://web.archive.org/web/20220815055650/https://www.topcoder.com/thrive/articles/Maximum%20Flow:%20Part%20One + G = nx.DiGraph() + G.add_edge("x", "a", capacity=3.0) + G.add_edge("x", "b", capacity=1.0) + G.add_edge("a", "c", capacity=3.0) + G.add_edge("b", "c", capacity=5.0) + G.add_edge("b", "d", capacity=4.0) + G.add_edge("d", "e", capacity=2.0) + G.add_edge("c", "y", capacity=2.0) + G.add_edge("e", "y", capacity=3.0) + + # H + # { + # "x": {"a": 2.0, "b": 1.0}, + # "a": {"c": 2.0}, + # "b": {"c": 0, "d": 1.0}, + # "c": {"y": 2.0}, + # "d": {"e": 1.0}, + # "e": {"y": 1.0}, + # "y": {}, + # } + + compare_flows_and_cuts(G, "x", "y", 3.0) + + def test_wikipedia_dinitz_example(self): + # Nice example from https://en.wikipedia.org/wiki/Dinic's_algorithm + G = nx.DiGraph() + G.add_edge("s", 1, capacity=10) + G.add_edge("s", 2, capacity=10) + G.add_edge(1, 3, capacity=4) + G.add_edge(1, 4, capacity=8) + G.add_edge(1, 2, capacity=2) + G.add_edge(2, 4, capacity=9) + G.add_edge(3, "t", capacity=10) + G.add_edge(4, 3, capacity=6) + G.add_edge(4, "t", capacity=10) + + # solution flows + # { + # 1: {2: 0, 3: 4, 4: 6}, + # 2: {4: 9}, + # 3: {"t": 9}, + # 4: {3: 5, "t": 10}, + # "s": {1: 10, 2: 9}, + # "t": {}, + # } + + compare_flows_and_cuts(G, "s", "t", 19) + + def test_optional_capacity(self): + # Test optional capacity parameter. + G = nx.DiGraph() + G.add_edge("x", "a", spam=3.0) + G.add_edge("x", "b", spam=1.0) + G.add_edge("a", "c", spam=3.0) + G.add_edge("b", "c", spam=5.0) + G.add_edge("b", "d", spam=4.0) + G.add_edge("d", "e", spam=2.0) + G.add_edge("c", "y", spam=2.0) + G.add_edge("e", "y", spam=3.0) + + # solution flows + # { + # "x": {"a": 2.0, "b": 1.0}, + # "a": {"c": 2.0}, + # "b": {"c": 0, "d": 1.0}, + # "c": {"y": 2.0}, + # "d": {"e": 1.0}, + # "e": {"y": 1.0}, + # "y": {}, + # } + solnValue = 3.0 + s = "x" + t = "y" + + compare_flows_and_cuts(G, s, t, solnValue, capacity="spam") + + def test_digraph_infcap_edges(self): + # DiGraph with infinite capacity edges + G = nx.DiGraph() + G.add_edge("s", "a") + G.add_edge("s", "b", capacity=30) + G.add_edge("a", "c", capacity=25) + G.add_edge("b", "c", capacity=12) + G.add_edge("a", "t", capacity=60) + G.add_edge("c", "t") + + # H + # { + # "s": {"a": 85, "b": 12}, + # "a": {"c": 25, "t": 60}, + # "b": {"c": 12}, + # "c": {"t": 37}, + # "t": {}, + # } + + compare_flows_and_cuts(G, "s", "t", 97) + + # DiGraph with infinite capacity digon + G = nx.DiGraph() + G.add_edge("s", "a", capacity=85) + G.add_edge("s", "b", capacity=30) + G.add_edge("a", "c") + G.add_edge("c", "a") + G.add_edge("b", "c", capacity=12) + G.add_edge("a", "t", capacity=60) + G.add_edge("c", "t", capacity=37) + + # H + # { + # "s": {"a": 85, "b": 12}, + # "a": {"c": 25, "t": 60}, + # "c": {"a": 0, "t": 37}, + # "b": {"c": 12}, + # "t": {}, + # } + + compare_flows_and_cuts(G, "s", "t", 97) + + def test_digraph_infcap_path(self): + # Graph with infinite capacity (s, t)-path + G = nx.DiGraph() + G.add_edge("s", "a") + G.add_edge("s", "b", capacity=30) + G.add_edge("a", "c") + G.add_edge("b", "c", capacity=12) + G.add_edge("a", "t", capacity=60) + G.add_edge("c", "t") + + for flow_func in all_funcs: + pytest.raises(nx.NetworkXUnbounded, flow_func, G, "s", "t") + + def test_graph_infcap_edges(self): + # Undirected graph with infinite capacity edges + G = nx.Graph() + G.add_edge("s", "a") + G.add_edge("s", "b", capacity=30) + G.add_edge("a", "c", capacity=25) + G.add_edge("b", "c", capacity=12) + G.add_edge("a", "t", capacity=60) + G.add_edge("c", "t") + + # H + # { + # "s": {"a": 85, "b": 12}, + # "a": {"c": 25, "s": 85, "t": 60}, + # "b": {"c": 12, "s": 12}, + # "c": {"a": 25, "b": 12, "t": 37}, + # "t": {"a": 60, "c": 37}, + # } + + compare_flows_and_cuts(G, "s", "t", 97) + + def test_digraph5(self): + # From ticket #429 by mfrasca. + G = nx.DiGraph() + G.add_edge("s", "a", capacity=2) + G.add_edge("s", "b", capacity=2) + G.add_edge("a", "b", capacity=5) + G.add_edge("a", "t", capacity=1) + G.add_edge("b", "a", capacity=1) + G.add_edge("b", "t", capacity=3) + # flow solution + # { + # "a": {"b": 1, "t": 1}, + # "b": {"a": 0, "t": 3}, + # "s": {"a": 2, "b": 2}, + # "t": {}, + # } + compare_flows_and_cuts(G, "s", "t", 4) + + def test_disconnected(self): + G = nx.Graph() + G.add_weighted_edges_from([(0, 1, 1), (1, 2, 1), (2, 3, 1)], weight="capacity") + G.remove_node(1) + assert nx.maximum_flow_value(G, 0, 3) == 0 + # flow solution + # {0: {}, 2: {3: 0}, 3: {2: 0}} + compare_flows_and_cuts(G, 0, 3, 0) + + def test_source_target_not_in_graph(self): + G = nx.Graph() + G.add_weighted_edges_from([(0, 1, 1), (1, 2, 1), (2, 3, 1)], weight="capacity") + G.remove_node(0) + for flow_func in all_funcs: + pytest.raises(nx.NetworkXError, flow_func, G, 0, 3) + G.add_weighted_edges_from([(0, 1, 1), (1, 2, 1), (2, 3, 1)], weight="capacity") + G.remove_node(3) + for flow_func in all_funcs: + pytest.raises(nx.NetworkXError, flow_func, G, 0, 3) + + def test_source_target_coincide(self): + G = nx.Graph() + G.add_node(0) + for flow_func in all_funcs: + pytest.raises(nx.NetworkXError, flow_func, G, 0, 0) + + def test_multigraphs_raise(self): + G = nx.MultiGraph() + M = nx.MultiDiGraph() + G.add_edges_from([(0, 1), (1, 0)], capacity=True) + for flow_func in all_funcs: + pytest.raises(nx.NetworkXError, flow_func, G, 0, 0) + + +class TestMaxFlowMinCutInterface: + def setup_method(self): + G = nx.DiGraph() + G.add_edge("x", "a", capacity=3.0) + G.add_edge("x", "b", capacity=1.0) + G.add_edge("a", "c", capacity=3.0) + G.add_edge("b", "c", capacity=5.0) + G.add_edge("b", "d", capacity=4.0) + G.add_edge("d", "e", capacity=2.0) + G.add_edge("c", "y", capacity=2.0) + G.add_edge("e", "y", capacity=3.0) + self.G = G + H = nx.DiGraph() + H.add_edge(0, 1, capacity=1.0) + H.add_edge(1, 2, capacity=1.0) + self.H = H + + def test_flow_func_not_callable(self): + elements = ["this_should_be_callable", 10, {1, 2, 3}] + G = nx.Graph() + G.add_weighted_edges_from([(0, 1, 1), (1, 2, 1), (2, 3, 1)], weight="capacity") + for flow_func in interface_funcs: + for element in elements: + pytest.raises(nx.NetworkXError, flow_func, G, 0, 1, flow_func=element) + pytest.raises(nx.NetworkXError, flow_func, G, 0, 1, flow_func=element) + + def test_flow_func_parameters(self): + G = self.G + fv = 3.0 + for interface_func in interface_funcs: + for flow_func in flow_funcs: + errmsg = ( + f"Assertion failed in function: {flow_func.__name__} " + f"in interface {interface_func.__name__}" + ) + result = interface_func(G, "x", "y", flow_func=flow_func) + if interface_func in max_min_funcs: + result = result[0] + assert fv == result, errmsg + + def test_minimum_cut_no_cutoff(self): + G = self.G + pytest.raises( + nx.NetworkXError, + nx.minimum_cut, + G, + "x", + "y", + flow_func=preflow_push, + cutoff=1.0, + ) + pytest.raises( + nx.NetworkXError, + nx.minimum_cut_value, + G, + "x", + "y", + flow_func=preflow_push, + cutoff=1.0, + ) + + def test_kwargs(self): + G = self.H + fv = 1.0 + to_test = ( + (shortest_augmenting_path, {"two_phase": True}), + (preflow_push, {"global_relabel_freq": 5}), + ) + for interface_func in interface_funcs: + for flow_func, kwargs in to_test: + errmsg = ( + f"Assertion failed in function: {flow_func.__name__} " + f"in interface {interface_func.__name__}" + ) + result = interface_func(G, 0, 2, flow_func=flow_func, **kwargs) + if interface_func in max_min_funcs: + result = result[0] + assert fv == result, errmsg + + def test_kwargs_default_flow_func(self): + G = self.H + for interface_func in interface_funcs: + pytest.raises( + nx.NetworkXError, interface_func, G, 0, 1, global_relabel_freq=2 + ) + + def test_reusing_residual(self): + G = self.G + fv = 3.0 + s, t = "x", "y" + R = build_residual_network(G, "capacity") + for interface_func in interface_funcs: + for flow_func in flow_funcs: + errmsg = ( + f"Assertion failed in function: {flow_func.__name__} " + f"in interface {interface_func.__name__}" + ) + for i in range(3): + result = interface_func( + G, "x", "y", flow_func=flow_func, residual=R + ) + if interface_func in max_min_funcs: + result = result[0] + assert fv == result, errmsg + + +# Tests specific to one algorithm +def test_preflow_push_global_relabel_freq(): + G = nx.DiGraph() + G.add_edge(1, 2, capacity=1) + R = preflow_push(G, 1, 2, global_relabel_freq=None) + assert R.graph["flow_value"] == 1 + pytest.raises(nx.NetworkXError, preflow_push, G, 1, 2, global_relabel_freq=-1) + + +def test_preflow_push_makes_enough_space(): + # From ticket #1542 + G = nx.DiGraph() + nx.add_path(G, [0, 1, 3], capacity=1) + nx.add_path(G, [1, 2, 3], capacity=1) + R = preflow_push(G, 0, 3, value_only=False) + assert R.graph["flow_value"] == 1 + + +def test_shortest_augmenting_path_two_phase(): + k = 5 + p = 1000 + G = nx.DiGraph() + for i in range(k): + G.add_edge("s", (i, 0), capacity=1) + nx.add_path(G, ((i, j) for j in range(p)), capacity=1) + G.add_edge((i, p - 1), "t", capacity=1) + R = shortest_augmenting_path(G, "s", "t", two_phase=True) + assert R.graph["flow_value"] == k + R = shortest_augmenting_path(G, "s", "t", two_phase=False) + assert R.graph["flow_value"] == k + + +class TestCutoff: + def test_cutoff(self): + k = 5 + p = 1000 + G = nx.DiGraph() + for i in range(k): + G.add_edge("s", (i, 0), capacity=2) + nx.add_path(G, ((i, j) for j in range(p)), capacity=2) + G.add_edge((i, p - 1), "t", capacity=2) + R = shortest_augmenting_path(G, "s", "t", two_phase=True, cutoff=k) + assert k <= R.graph["flow_value"] <= (2 * k) + R = shortest_augmenting_path(G, "s", "t", two_phase=False, cutoff=k) + assert k <= R.graph["flow_value"] <= (2 * k) + R = edmonds_karp(G, "s", "t", cutoff=k) + assert k <= R.graph["flow_value"] <= (2 * k) + R = dinitz(G, "s", "t", cutoff=k) + assert k <= R.graph["flow_value"] <= (2 * k) + R = boykov_kolmogorov(G, "s", "t", cutoff=k) + assert k <= R.graph["flow_value"] <= (2 * k) + + def test_complete_graph_cutoff(self): + G = nx.complete_graph(5) + nx.set_edge_attributes(G, {(u, v): 1 for u, v in G.edges()}, "capacity") + for flow_func in [ + shortest_augmenting_path, + edmonds_karp, + dinitz, + boykov_kolmogorov, + ]: + for cutoff in [3, 2, 1]: + result = nx.maximum_flow_value( + G, 0, 4, flow_func=flow_func, cutoff=cutoff + ) + assert cutoff == result, f"cutoff error in {flow_func.__name__}" diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_maxflow_large_graph.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_maxflow_large_graph.py new file mode 100644 index 0000000000000000000000000000000000000000..6165da891b4b30704cc1c2697cf719ef080163ee --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_maxflow_large_graph.py @@ -0,0 +1,155 @@ +"""Maximum flow algorithms test suite on large graphs.""" + +import bz2 +import importlib.resources +import pickle + +import pytest + +import networkx as nx +from networkx.algorithms.flow import ( + boykov_kolmogorov, + build_flow_dict, + build_residual_network, + dinitz, + edmonds_karp, + preflow_push, + shortest_augmenting_path, +) + +flow_funcs = [ + boykov_kolmogorov, + dinitz, + edmonds_karp, + preflow_push, + shortest_augmenting_path, +] + + +def gen_pyramid(N): + # This graph admits a flow of value 1 for which every arc is at + # capacity (except the arcs incident to the sink which have + # infinite capacity). + G = nx.DiGraph() + + for i in range(N - 1): + cap = 1.0 / (i + 2) + for j in range(i + 1): + G.add_edge((i, j), (i + 1, j), capacity=cap) + cap = 1.0 / (i + 1) - cap + G.add_edge((i, j), (i + 1, j + 1), capacity=cap) + cap = 1.0 / (i + 2) - cap + + for j in range(N): + G.add_edge((N - 1, j), "t") + + return G + + +def read_graph(name): + fname = ( + importlib.resources.files("networkx.algorithms.flow.tests") + / f"{name}.gpickle.bz2" + ) + + with bz2.BZ2File(fname, "rb") as f: + G = pickle.load(f) + return G + + +def validate_flows(G, s, t, soln_value, R, flow_func): + flow_value = R.graph["flow_value"] + flow_dict = build_flow_dict(G, R) + errmsg = f"Assertion failed in function: {flow_func.__name__}" + assert soln_value == flow_value, errmsg + assert set(G) == set(flow_dict), errmsg + for u in G: + assert set(G[u]) == set(flow_dict[u]), errmsg + excess = {u: 0 for u in flow_dict} + for u in flow_dict: + for v, flow in flow_dict[u].items(): + assert flow <= G[u][v].get("capacity", float("inf")), errmsg + assert flow >= 0, errmsg + excess[u] -= flow + excess[v] += flow + for u, exc in excess.items(): + if u == s: + assert exc == -soln_value, errmsg + elif u == t: + assert exc == soln_value, errmsg + else: + assert exc == 0, errmsg + + +class TestMaxflowLargeGraph: + def test_complete_graph(self): + N = 50 + G = nx.complete_graph(N) + nx.set_edge_attributes(G, 5, "capacity") + R = build_residual_network(G, "capacity") + kwargs = {"residual": R} + + for flow_func in flow_funcs: + kwargs["flow_func"] = flow_func + errmsg = f"Assertion failed in function: {flow_func.__name__}" + flow_value = nx.maximum_flow_value(G, 1, 2, **kwargs) + assert flow_value == 5 * (N - 1), errmsg + + def test_pyramid(self): + N = 10 + # N = 100 # this gives a graph with 5051 nodes + G = gen_pyramid(N) + R = build_residual_network(G, "capacity") + kwargs = {"residual": R} + + for flow_func in flow_funcs: + kwargs["flow_func"] = flow_func + errmsg = f"Assertion failed in function: {flow_func.__name__}" + flow_value = nx.maximum_flow_value(G, (0, 0), "t", **kwargs) + assert flow_value == pytest.approx(1.0, abs=1e-7) + + def test_gl1(self): + G = read_graph("gl1") + s = 1 + t = len(G) + R = build_residual_network(G, "capacity") + kwargs = {"residual": R} + + # do one flow_func to save time + flow_func = flow_funcs[0] + validate_flows(G, s, t, 156545, flow_func(G, s, t, **kwargs), flow_func) + + # for flow_func in flow_funcs: + # validate_flows(G, s, t, 156545, flow_func(G, s, t, **kwargs), + # flow_func) + + @pytest.mark.slow + def test_gw1(self): + G = read_graph("gw1") + s = 1 + t = len(G) + R = build_residual_network(G, "capacity") + kwargs = {"residual": R} + + for flow_func in flow_funcs: + validate_flows(G, s, t, 1202018, flow_func(G, s, t, **kwargs), flow_func) + + def test_wlm3(self): + G = read_graph("wlm3") + s = 1 + t = len(G) + R = build_residual_network(G, "capacity") + kwargs = {"residual": R} + + # do one flow_func to save time + flow_func = flow_funcs[0] + validate_flows(G, s, t, 11875108, flow_func(G, s, t, **kwargs), flow_func) + + # for flow_func in flow_funcs: + # validate_flows(G, s, t, 11875108, flow_func(G, s, t, **kwargs), + # flow_func) + + def test_preflow_push_global_relabel(self): + G = read_graph("gw1") + R = preflow_push(G, 1, len(G), global_relabel_freq=50) + assert R.graph["flow_value"] == 1202018 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_mincost.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_mincost.py new file mode 100644 index 0000000000000000000000000000000000000000..edc6262213300b3853419b2604e49722c418934a --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_mincost.py @@ -0,0 +1,475 @@ +import bz2 +import importlib.resources +import pickle + +import pytest + +import networkx as nx + + +class TestMinCostFlow: + def test_simple_digraph(self): + G = nx.DiGraph() + G.add_node("a", demand=-5) + G.add_node("d", demand=5) + G.add_edge("a", "b", weight=3, capacity=4) + G.add_edge("a", "c", weight=6, capacity=10) + G.add_edge("b", "d", weight=1, capacity=9) + G.add_edge("c", "d", weight=2, capacity=5) + flowCost, H = nx.network_simplex(G) + soln = {"a": {"b": 4, "c": 1}, "b": {"d": 4}, "c": {"d": 1}, "d": {}} + assert flowCost == 24 + assert nx.min_cost_flow_cost(G) == 24 + assert H == soln + assert nx.min_cost_flow(G) == soln + assert nx.cost_of_flow(G, H) == 24 + + flowCost, H = nx.capacity_scaling(G) + assert flowCost == 24 + assert nx.cost_of_flow(G, H) == 24 + assert H == soln + + def test_negcycle_infcap(self): + G = nx.DiGraph() + G.add_node("s", demand=-5) + G.add_node("t", demand=5) + G.add_edge("s", "a", weight=1, capacity=3) + G.add_edge("a", "b", weight=3) + G.add_edge("c", "a", weight=-6) + G.add_edge("b", "d", weight=1) + G.add_edge("d", "c", weight=-2) + G.add_edge("d", "t", weight=1, capacity=3) + pytest.raises(nx.NetworkXUnfeasible, nx.network_simplex, G) + pytest.raises(nx.NetworkXUnbounded, nx.capacity_scaling, G) + + def test_sum_demands_not_zero(self): + G = nx.DiGraph() + G.add_node("s", demand=-5) + G.add_node("t", demand=4) + G.add_edge("s", "a", weight=1, capacity=3) + G.add_edge("a", "b", weight=3) + G.add_edge("a", "c", weight=-6) + G.add_edge("b", "d", weight=1) + G.add_edge("c", "d", weight=-2) + G.add_edge("d", "t", weight=1, capacity=3) + pytest.raises(nx.NetworkXUnfeasible, nx.network_simplex, G) + pytest.raises(nx.NetworkXUnfeasible, nx.capacity_scaling, G) + + def test_no_flow_satisfying_demands(self): + G = nx.DiGraph() + G.add_node("s", demand=-5) + G.add_node("t", demand=5) + G.add_edge("s", "a", weight=1, capacity=3) + G.add_edge("a", "b", weight=3) + G.add_edge("a", "c", weight=-6) + G.add_edge("b", "d", weight=1) + G.add_edge("c", "d", weight=-2) + G.add_edge("d", "t", weight=1, capacity=3) + pytest.raises(nx.NetworkXUnfeasible, nx.network_simplex, G) + pytest.raises(nx.NetworkXUnfeasible, nx.capacity_scaling, G) + + def test_transshipment(self): + G = nx.DiGraph() + G.add_node("a", demand=1) + G.add_node("b", demand=-2) + G.add_node("c", demand=-2) + G.add_node("d", demand=3) + G.add_node("e", demand=-4) + G.add_node("f", demand=-4) + G.add_node("g", demand=3) + G.add_node("h", demand=2) + G.add_node("r", demand=3) + G.add_edge("a", "c", weight=3) + G.add_edge("r", "a", weight=2) + G.add_edge("b", "a", weight=9) + G.add_edge("r", "c", weight=0) + G.add_edge("b", "r", weight=-6) + G.add_edge("c", "d", weight=5) + G.add_edge("e", "r", weight=4) + G.add_edge("e", "f", weight=3) + G.add_edge("h", "b", weight=4) + G.add_edge("f", "d", weight=7) + G.add_edge("f", "h", weight=12) + G.add_edge("g", "d", weight=12) + G.add_edge("f", "g", weight=-1) + G.add_edge("h", "g", weight=-10) + flowCost, H = nx.network_simplex(G) + soln = { + "a": {"c": 0}, + "b": {"a": 0, "r": 2}, + "c": {"d": 3}, + "d": {}, + "e": {"r": 3, "f": 1}, + "f": {"d": 0, "g": 3, "h": 2}, + "g": {"d": 0}, + "h": {"b": 0, "g": 0}, + "r": {"a": 1, "c": 1}, + } + assert flowCost == 41 + assert nx.min_cost_flow_cost(G) == 41 + assert H == soln + assert nx.min_cost_flow(G) == soln + assert nx.cost_of_flow(G, H) == 41 + + flowCost, H = nx.capacity_scaling(G) + assert flowCost == 41 + assert nx.cost_of_flow(G, H) == 41 + assert H == soln + + def test_max_flow_min_cost(self): + G = nx.DiGraph() + G.add_edge("s", "a", bandwidth=6) + G.add_edge("s", "c", bandwidth=10, cost=10) + G.add_edge("a", "b", cost=6) + G.add_edge("b", "d", bandwidth=8, cost=7) + G.add_edge("c", "d", cost=10) + G.add_edge("d", "t", bandwidth=5, cost=5) + soln = { + "s": {"a": 5, "c": 0}, + "a": {"b": 5}, + "b": {"d": 5}, + "c": {"d": 0}, + "d": {"t": 5}, + "t": {}, + } + flow = nx.max_flow_min_cost(G, "s", "t", capacity="bandwidth", weight="cost") + assert flow == soln + assert nx.cost_of_flow(G, flow, weight="cost") == 90 + + G.add_edge("t", "s", cost=-100) + flowCost, flow = nx.capacity_scaling(G, capacity="bandwidth", weight="cost") + G.remove_edge("t", "s") + assert flowCost == -410 + assert flow["t"]["s"] == 5 + del flow["t"]["s"] + assert flow == soln + assert nx.cost_of_flow(G, flow, weight="cost") == 90 + + def test_digraph1(self): + # From Bradley, S. P., Hax, A. C. and Magnanti, T. L. Applied + # Mathematical Programming. Addison-Wesley, 1977. + G = nx.DiGraph() + G.add_node(1, demand=-20) + G.add_node(4, demand=5) + G.add_node(5, demand=15) + G.add_edges_from( + [ + (1, 2, {"capacity": 15, "weight": 4}), + (1, 3, {"capacity": 8, "weight": 4}), + (2, 3, {"weight": 2}), + (2, 4, {"capacity": 4, "weight": 2}), + (2, 5, {"capacity": 10, "weight": 6}), + (3, 4, {"capacity": 15, "weight": 1}), + (3, 5, {"capacity": 5, "weight": 3}), + (4, 5, {"weight": 2}), + (5, 3, {"capacity": 4, "weight": 1}), + ] + ) + flowCost, H = nx.network_simplex(G) + soln = { + 1: {2: 12, 3: 8}, + 2: {3: 8, 4: 4, 5: 0}, + 3: {4: 11, 5: 5}, + 4: {5: 10}, + 5: {3: 0}, + } + assert flowCost == 150 + assert nx.min_cost_flow_cost(G) == 150 + assert H == soln + assert nx.min_cost_flow(G) == soln + assert nx.cost_of_flow(G, H) == 150 + + flowCost, H = nx.capacity_scaling(G) + assert flowCost == 150 + assert H == soln + assert nx.cost_of_flow(G, H) == 150 + + def test_digraph2(self): + # Example from ticket #430 from mfrasca. Original source: + # http://www.cs.princeton.edu/courses/archive/spr03/cs226/lectures/mincost.4up.pdf, slide 11. + G = nx.DiGraph() + G.add_edge("s", 1, capacity=12) + G.add_edge("s", 2, capacity=6) + G.add_edge("s", 3, capacity=14) + G.add_edge(1, 2, capacity=11, weight=4) + G.add_edge(2, 3, capacity=9, weight=6) + G.add_edge(1, 4, capacity=5, weight=5) + G.add_edge(1, 5, capacity=2, weight=12) + G.add_edge(2, 5, capacity=4, weight=4) + G.add_edge(2, 6, capacity=2, weight=6) + G.add_edge(3, 6, capacity=31, weight=3) + G.add_edge(4, 5, capacity=18, weight=4) + G.add_edge(5, 6, capacity=9, weight=5) + G.add_edge(4, "t", capacity=3) + G.add_edge(5, "t", capacity=7) + G.add_edge(6, "t", capacity=22) + flow = nx.max_flow_min_cost(G, "s", "t") + soln = { + 1: {2: 6, 4: 5, 5: 1}, + 2: {3: 6, 5: 4, 6: 2}, + 3: {6: 20}, + 4: {5: 2, "t": 3}, + 5: {6: 0, "t": 7}, + 6: {"t": 22}, + "s": {1: 12, 2: 6, 3: 14}, + "t": {}, + } + assert flow == soln + + G.add_edge("t", "s", weight=-100) + flowCost, flow = nx.capacity_scaling(G) + G.remove_edge("t", "s") + assert flow["t"]["s"] == 32 + assert flowCost == -3007 + del flow["t"]["s"] + assert flow == soln + assert nx.cost_of_flow(G, flow) == 193 + + def test_digraph3(self): + """Combinatorial Optimization: Algorithms and Complexity, + Papadimitriou Steiglitz at page 140 has an example, 7.1, but that + admits multiple solutions, so I alter it a bit. From ticket #430 + by mfrasca.""" + + G = nx.DiGraph() + G.add_edge("s", "a") + G["s"]["a"].update({0: 2, 1: 4}) + G.add_edge("s", "b") + G["s"]["b"].update({0: 2, 1: 1}) + G.add_edge("a", "b") + G["a"]["b"].update({0: 5, 1: 2}) + G.add_edge("a", "t") + G["a"]["t"].update({0: 1, 1: 5}) + G.add_edge("b", "a") + G["b"]["a"].update({0: 1, 1: 3}) + G.add_edge("b", "t") + G["b"]["t"].update({0: 3, 1: 2}) + + "PS.ex.7.1: testing main function" + sol = nx.max_flow_min_cost(G, "s", "t", capacity=0, weight=1) + flow = sum(v for v in sol["s"].values()) + assert 4 == flow + assert 23 == nx.cost_of_flow(G, sol, weight=1) + assert sol["s"] == {"a": 2, "b": 2} + assert sol["a"] == {"b": 1, "t": 1} + assert sol["b"] == {"a": 0, "t": 3} + assert sol["t"] == {} + + G.add_edge("t", "s") + G["t"]["s"].update({1: -100}) + flowCost, sol = nx.capacity_scaling(G, capacity=0, weight=1) + G.remove_edge("t", "s") + flow = sum(v for v in sol["s"].values()) + assert 4 == flow + assert sol["t"]["s"] == 4 + assert flowCost == -377 + del sol["t"]["s"] + assert sol["s"] == {"a": 2, "b": 2} + assert sol["a"] == {"b": 1, "t": 1} + assert sol["b"] == {"a": 0, "t": 3} + assert sol["t"] == {} + assert nx.cost_of_flow(G, sol, weight=1) == 23 + + def test_zero_capacity_edges(self): + """Address issue raised in ticket #617 by arv.""" + G = nx.DiGraph() + G.add_edges_from( + [ + (1, 2, {"capacity": 1, "weight": 1}), + (1, 5, {"capacity": 1, "weight": 1}), + (2, 3, {"capacity": 0, "weight": 1}), + (2, 5, {"capacity": 1, "weight": 1}), + (5, 3, {"capacity": 2, "weight": 1}), + (5, 4, {"capacity": 0, "weight": 1}), + (3, 4, {"capacity": 2, "weight": 1}), + ] + ) + G.nodes[1]["demand"] = -1 + G.nodes[2]["demand"] = -1 + G.nodes[4]["demand"] = 2 + + flowCost, H = nx.network_simplex(G) + soln = {1: {2: 0, 5: 1}, 2: {3: 0, 5: 1}, 3: {4: 2}, 4: {}, 5: {3: 2, 4: 0}} + assert flowCost == 6 + assert nx.min_cost_flow_cost(G) == 6 + assert H == soln + assert nx.min_cost_flow(G) == soln + assert nx.cost_of_flow(G, H) == 6 + + flowCost, H = nx.capacity_scaling(G) + assert flowCost == 6 + assert H == soln + assert nx.cost_of_flow(G, H) == 6 + + def test_digon(self): + """Check if digons are handled properly. Taken from ticket + #618 by arv.""" + nodes = [(1, {}), (2, {"demand": -4}), (3, {"demand": 4})] + edges = [ + (1, 2, {"capacity": 3, "weight": 600000}), + (2, 1, {"capacity": 2, "weight": 0}), + (2, 3, {"capacity": 5, "weight": 714285}), + (3, 2, {"capacity": 2, "weight": 0}), + ] + G = nx.DiGraph(edges) + G.add_nodes_from(nodes) + flowCost, H = nx.network_simplex(G) + soln = {1: {2: 0}, 2: {1: 0, 3: 4}, 3: {2: 0}} + assert flowCost == 2857140 + assert nx.min_cost_flow_cost(G) == 2857140 + assert H == soln + assert nx.min_cost_flow(G) == soln + assert nx.cost_of_flow(G, H) == 2857140 + + flowCost, H = nx.capacity_scaling(G) + assert flowCost == 2857140 + assert H == soln + assert nx.cost_of_flow(G, H) == 2857140 + + def test_deadend(self): + """Check if one-node cycles are handled properly. Taken from ticket + #2906 from @sshraven.""" + G = nx.DiGraph() + + G.add_nodes_from(range(5), demand=0) + G.nodes[4]["demand"] = -13 + G.nodes[3]["demand"] = 13 + + G.add_edges_from([(0, 2), (0, 3), (2, 1)], capacity=20, weight=0.1) + pytest.raises(nx.NetworkXUnfeasible, nx.min_cost_flow, G) + + def test_infinite_capacity_neg_digon(self): + """An infinite capacity negative cost digon results in an unbounded + instance.""" + nodes = [(1, {}), (2, {"demand": -4}), (3, {"demand": 4})] + edges = [ + (1, 2, {"weight": -600}), + (2, 1, {"weight": 0}), + (2, 3, {"capacity": 5, "weight": 714285}), + (3, 2, {"capacity": 2, "weight": 0}), + ] + G = nx.DiGraph(edges) + G.add_nodes_from(nodes) + pytest.raises(nx.NetworkXUnbounded, nx.network_simplex, G) + pytest.raises(nx.NetworkXUnbounded, nx.capacity_scaling, G) + + def test_finite_capacity_neg_digon(self): + """The digon should receive the maximum amount of flow it can handle. + Taken from ticket #749 by @chuongdo.""" + G = nx.DiGraph() + G.add_edge("a", "b", capacity=1, weight=-1) + G.add_edge("b", "a", capacity=1, weight=-1) + min_cost = -2 + assert nx.min_cost_flow_cost(G) == min_cost + + flowCost, H = nx.capacity_scaling(G) + assert flowCost == -2 + assert H == {"a": {"b": 1}, "b": {"a": 1}} + assert nx.cost_of_flow(G, H) == -2 + + def test_multidigraph(self): + """Multidigraphs are acceptable.""" + G = nx.MultiDiGraph() + G.add_weighted_edges_from([(1, 2, 1), (2, 3, 2)], weight="capacity") + flowCost, H = nx.network_simplex(G) + assert flowCost == 0 + assert H == {1: {2: {0: 0}}, 2: {3: {0: 0}}, 3: {}} + + flowCost, H = nx.capacity_scaling(G) + assert flowCost == 0 + assert H == {1: {2: {0: 0}}, 2: {3: {0: 0}}, 3: {}} + + def test_negative_selfloops(self): + """Negative selfloops should cause an exception if uncapacitated and + always be saturated otherwise. + """ + G = nx.DiGraph() + G.add_edge(1, 1, weight=-1) + pytest.raises(nx.NetworkXUnbounded, nx.network_simplex, G) + pytest.raises(nx.NetworkXUnbounded, nx.capacity_scaling, G) + G[1][1]["capacity"] = 2 + flowCost, H = nx.network_simplex(G) + assert flowCost == -2 + assert H == {1: {1: 2}} + flowCost, H = nx.capacity_scaling(G) + assert flowCost == -2 + assert H == {1: {1: 2}} + + G = nx.MultiDiGraph() + G.add_edge(1, 1, "x", weight=-1) + G.add_edge(1, 1, "y", weight=1) + pytest.raises(nx.NetworkXUnbounded, nx.network_simplex, G) + pytest.raises(nx.NetworkXUnbounded, nx.capacity_scaling, G) + G[1][1]["x"]["capacity"] = 2 + flowCost, H = nx.network_simplex(G) + assert flowCost == -2 + assert H == {1: {1: {"x": 2, "y": 0}}} + flowCost, H = nx.capacity_scaling(G) + assert flowCost == -2 + assert H == {1: {1: {"x": 2, "y": 0}}} + + def test_bone_shaped(self): + # From #1283 + G = nx.DiGraph() + G.add_node(0, demand=-4) + G.add_node(1, demand=2) + G.add_node(2, demand=2) + G.add_node(3, demand=4) + G.add_node(4, demand=-2) + G.add_node(5, demand=-2) + G.add_edge(0, 1, capacity=4) + G.add_edge(0, 2, capacity=4) + G.add_edge(4, 3, capacity=4) + G.add_edge(5, 3, capacity=4) + G.add_edge(0, 3, capacity=0) + flowCost, H = nx.network_simplex(G) + assert flowCost == 0 + assert H == {0: {1: 2, 2: 2, 3: 0}, 1: {}, 2: {}, 3: {}, 4: {3: 2}, 5: {3: 2}} + flowCost, H = nx.capacity_scaling(G) + assert flowCost == 0 + assert H == {0: {1: 2, 2: 2, 3: 0}, 1: {}, 2: {}, 3: {}, 4: {3: 2}, 5: {3: 2}} + + def test_exceptions(self): + G = nx.Graph() + pytest.raises(nx.NetworkXNotImplemented, nx.network_simplex, G) + pytest.raises(nx.NetworkXNotImplemented, nx.capacity_scaling, G) + G = nx.MultiGraph() + pytest.raises(nx.NetworkXNotImplemented, nx.network_simplex, G) + pytest.raises(nx.NetworkXNotImplemented, nx.capacity_scaling, G) + G = nx.DiGraph() + pytest.raises(nx.NetworkXError, nx.network_simplex, G) + # pytest.raises(nx.NetworkXError, nx.capacity_scaling, G) + G.add_node(0, demand=float("inf")) + pytest.raises(nx.NetworkXError, nx.network_simplex, G) + pytest.raises(nx.NetworkXUnfeasible, nx.capacity_scaling, G) + G.nodes[0]["demand"] = 0 + G.add_node(1, demand=0) + G.add_edge(0, 1, weight=-float("inf")) + pytest.raises(nx.NetworkXError, nx.network_simplex, G) + pytest.raises(nx.NetworkXUnfeasible, nx.capacity_scaling, G) + G[0][1]["weight"] = 0 + G.add_edge(0, 0, weight=float("inf")) + pytest.raises(nx.NetworkXError, nx.network_simplex, G) + # pytest.raises(nx.NetworkXError, nx.capacity_scaling, G) + G[0][0]["weight"] = 0 + G[0][1]["capacity"] = -1 + pytest.raises(nx.NetworkXUnfeasible, nx.network_simplex, G) + # pytest.raises(nx.NetworkXUnfeasible, nx.capacity_scaling, G) + G[0][1]["capacity"] = 0 + G[0][0]["capacity"] = -1 + pytest.raises(nx.NetworkXUnfeasible, nx.network_simplex, G) + # pytest.raises(nx.NetworkXUnfeasible, nx.capacity_scaling, G) + + def test_large(self): + fname = ( + importlib.resources.files("networkx.algorithms.flow.tests") + / "netgen-2.gpickle.bz2" + ) + with bz2.BZ2File(fname, "rb") as f: + G = pickle.load(f) + flowCost, flowDict = nx.network_simplex(G) + assert 6749969302 == flowCost + assert 6749969302 == nx.cost_of_flow(G, flowDict) + flowCost, flowDict = nx.capacity_scaling(G) + assert 6749969302 == flowCost + assert 6749969302 == nx.cost_of_flow(G, flowDict) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_networksimplex.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_networksimplex.py new file mode 100644 index 0000000000000000000000000000000000000000..9a37fc6e9a41579fb9555b27710f3e5298d9d321 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/flow/tests/test_networksimplex.py @@ -0,0 +1,481 @@ +import bz2 +import importlib.resources +import pickle + +import pytest + +import networkx as nx + + +@pytest.fixture +def simple_flow_graph(): + G = nx.DiGraph() + G.add_node("a", demand=0) + G.add_node("b", demand=-5) + G.add_node("c", demand=50000000) + G.add_node("d", demand=-49999995) + G.add_edge("a", "b", weight=3, capacity=4) + G.add_edge("a", "c", weight=6, capacity=10) + G.add_edge("b", "d", weight=1, capacity=9) + G.add_edge("c", "d", weight=2, capacity=5) + return G + + +@pytest.fixture +def simple_no_flow_graph(): + G = nx.DiGraph() + G.add_node("s", demand=-5) + G.add_node("t", demand=5) + G.add_edge("s", "a", weight=1, capacity=3) + G.add_edge("a", "b", weight=3) + G.add_edge("a", "c", weight=-6) + G.add_edge("b", "d", weight=1) + G.add_edge("c", "d", weight=-2) + G.add_edge("d", "t", weight=1, capacity=3) + return G + + +def get_flowcost_from_flowdict(G, flowDict): + """Returns flow cost calculated from flow dictionary""" + flowCost = 0 + for u in flowDict: + for v in flowDict[u]: + flowCost += flowDict[u][v] * G[u][v]["weight"] + return flowCost + + +def test_infinite_demand_raise(simple_flow_graph): + G = simple_flow_graph + inf = float("inf") + node_name = "a" + nx.set_node_attributes(G, {node_name: {"demand": inf}}) + with pytest.raises( + nx.NetworkXError, + match=f"node '{node_name}' has infinite demand", + ): + nx.network_simplex(G) + + +def test_neg_infinite_demand_raise(simple_flow_graph): + G = simple_flow_graph + inf = float("inf") + node_name = "a" + nx.set_node_attributes(G, {node_name: {"demand": -inf}}) + with pytest.raises( + nx.NetworkXError, + match=f"node '{node_name}' has infinite demand", + ): + nx.network_simplex(G) + + +def test_infinite_weight_raise(simple_flow_graph): + G = simple_flow_graph + inf = float("inf") + nx.set_edge_attributes( + G, {("a", "b"): {"weight": inf}, ("b", "d"): {"weight": inf}} + ) + with pytest.raises( + nx.NetworkXError, + match=r"edge .* has infinite weight", + ): + nx.network_simplex(G) + + +def test_nonzero_net_demand_raise(simple_flow_graph): + G = simple_flow_graph + nx.set_node_attributes(G, {"b": {"demand": -4}}) + with pytest.raises( + nx.NetworkXUnfeasible, + match="total node demand is not zero", + ): + nx.network_simplex(G) + + +def test_negative_capacity_raise(simple_flow_graph): + G = simple_flow_graph + nx.set_edge_attributes(G, {("a", "b"): {"weight": 1}, ("b", "d"): {"capacity": -9}}) + with pytest.raises( + nx.NetworkXUnfeasible, + match=r"edge .* has negative capacity", + ): + nx.network_simplex(G) + + +def test_no_flow_satisfying_demands(simple_no_flow_graph): + G = simple_no_flow_graph + with pytest.raises( + nx.NetworkXUnfeasible, + match="no flow satisfies all node demands", + ): + nx.network_simplex(G) + + +def test_sum_demands_not_zero(simple_no_flow_graph): + G = simple_no_flow_graph + nx.set_node_attributes(G, {"t": {"demand": 4}}) + with pytest.raises( + nx.NetworkXUnfeasible, + match="total node demand is not zero", + ): + nx.network_simplex(G) + + +def test_google_or_tools_example(): + """ + https://developers.google.com/optimization/flow/mincostflow + """ + G = nx.DiGraph() + start_nodes = [0, 0, 1, 1, 1, 2, 2, 3, 4] + end_nodes = [1, 2, 2, 3, 4, 3, 4, 4, 2] + capacities = [15, 8, 20, 4, 10, 15, 4, 20, 5] + unit_costs = [4, 4, 2, 2, 6, 1, 3, 2, 3] + supplies = [20, 0, 0, -5, -15] + answer = 150 + + for i in range(len(supplies)): + G.add_node(i, demand=(-1) * supplies[i]) # supplies are negative of demand + + for i in range(len(start_nodes)): + G.add_edge( + start_nodes[i], end_nodes[i], weight=unit_costs[i], capacity=capacities[i] + ) + + flowCost, flowDict = nx.network_simplex(G) + assert flowCost == answer + assert flowCost == get_flowcost_from_flowdict(G, flowDict) + + +def test_google_or_tools_example2(): + """ + https://developers.google.com/optimization/flow/mincostflow + """ + G = nx.DiGraph() + start_nodes = [0, 0, 1, 1, 1, 2, 2, 3, 4, 3] + end_nodes = [1, 2, 2, 3, 4, 3, 4, 4, 2, 5] + capacities = [15, 8, 20, 4, 10, 15, 4, 20, 5, 10] + unit_costs = [4, 4, 2, 2, 6, 1, 3, 2, 3, 4] + supplies = [23, 0, 0, -5, -15, -3] + answer = 183 + + for i in range(len(supplies)): + G.add_node(i, demand=(-1) * supplies[i]) # supplies are negative of demand + + for i in range(len(start_nodes)): + G.add_edge( + start_nodes[i], end_nodes[i], weight=unit_costs[i], capacity=capacities[i] + ) + + flowCost, flowDict = nx.network_simplex(G) + assert flowCost == answer + assert flowCost == get_flowcost_from_flowdict(G, flowDict) + + +def test_large(): + fname = ( + importlib.resources.files("networkx.algorithms.flow.tests") + / "netgen-2.gpickle.bz2" + ) + + with bz2.BZ2File(fname, "rb") as f: + G = pickle.load(f) + flowCost, flowDict = nx.network_simplex(G) + assert 6749969302 == flowCost + assert 6749969302 == nx.cost_of_flow(G, flowDict) + + +def test_simple_digraph(): + G = nx.DiGraph() + G.add_node("a", demand=-5) + G.add_node("d", demand=5) + G.add_edge("a", "b", weight=3, capacity=4) + G.add_edge("a", "c", weight=6, capacity=10) + G.add_edge("b", "d", weight=1, capacity=9) + G.add_edge("c", "d", weight=2, capacity=5) + flowCost, H = nx.network_simplex(G) + soln = {"a": {"b": 4, "c": 1}, "b": {"d": 4}, "c": {"d": 1}, "d": {}} + assert flowCost == 24 + assert nx.min_cost_flow_cost(G) == 24 + assert H == soln + + +def test_negcycle_infcap(): + G = nx.DiGraph() + G.add_node("s", demand=-5) + G.add_node("t", demand=5) + G.add_edge("s", "a", weight=1, capacity=3) + G.add_edge("a", "b", weight=3) + G.add_edge("c", "a", weight=-6) + G.add_edge("b", "d", weight=1) + G.add_edge("d", "c", weight=-2) + G.add_edge("d", "t", weight=1, capacity=3) + pytest.raises(nx.NetworkXUnfeasible, nx.network_simplex, G) + + +def test_transshipment(): + G = nx.DiGraph() + G.add_node("a", demand=1) + G.add_node("b", demand=-2) + G.add_node("c", demand=-2) + G.add_node("d", demand=3) + G.add_node("e", demand=-4) + G.add_node("f", demand=-4) + G.add_node("g", demand=3) + G.add_node("h", demand=2) + G.add_node("r", demand=3) + G.add_edge("a", "c", weight=3) + G.add_edge("r", "a", weight=2) + G.add_edge("b", "a", weight=9) + G.add_edge("r", "c", weight=0) + G.add_edge("b", "r", weight=-6) + G.add_edge("c", "d", weight=5) + G.add_edge("e", "r", weight=4) + G.add_edge("e", "f", weight=3) + G.add_edge("h", "b", weight=4) + G.add_edge("f", "d", weight=7) + G.add_edge("f", "h", weight=12) + G.add_edge("g", "d", weight=12) + G.add_edge("f", "g", weight=-1) + G.add_edge("h", "g", weight=-10) + flowCost, H = nx.network_simplex(G) + soln = { + "a": {"c": 0}, + "b": {"a": 0, "r": 2}, + "c": {"d": 3}, + "d": {}, + "e": {"r": 3, "f": 1}, + "f": {"d": 0, "g": 3, "h": 2}, + "g": {"d": 0}, + "h": {"b": 0, "g": 0}, + "r": {"a": 1, "c": 1}, + } + assert flowCost == 41 + assert H == soln + + +def test_digraph1(): + # From Bradley, S. P., Hax, A. C. and Magnanti, T. L. Applied + # Mathematical Programming. Addison-Wesley, 1977. + G = nx.DiGraph() + G.add_node(1, demand=-20) + G.add_node(4, demand=5) + G.add_node(5, demand=15) + G.add_edges_from( + [ + (1, 2, {"capacity": 15, "weight": 4}), + (1, 3, {"capacity": 8, "weight": 4}), + (2, 3, {"weight": 2}), + (2, 4, {"capacity": 4, "weight": 2}), + (2, 5, {"capacity": 10, "weight": 6}), + (3, 4, {"capacity": 15, "weight": 1}), + (3, 5, {"capacity": 5, "weight": 3}), + (4, 5, {"weight": 2}), + (5, 3, {"capacity": 4, "weight": 1}), + ] + ) + flowCost, H = nx.network_simplex(G) + soln = { + 1: {2: 12, 3: 8}, + 2: {3: 8, 4: 4, 5: 0}, + 3: {4: 11, 5: 5}, + 4: {5: 10}, + 5: {3: 0}, + } + assert flowCost == 150 + assert nx.min_cost_flow_cost(G) == 150 + assert H == soln + + +def test_zero_capacity_edges(): + """Address issue raised in ticket #617 by arv.""" + G = nx.DiGraph() + G.add_edges_from( + [ + (1, 2, {"capacity": 1, "weight": 1}), + (1, 5, {"capacity": 1, "weight": 1}), + (2, 3, {"capacity": 0, "weight": 1}), + (2, 5, {"capacity": 1, "weight": 1}), + (5, 3, {"capacity": 2, "weight": 1}), + (5, 4, {"capacity": 0, "weight": 1}), + (3, 4, {"capacity": 2, "weight": 1}), + ] + ) + G.nodes[1]["demand"] = -1 + G.nodes[2]["demand"] = -1 + G.nodes[4]["demand"] = 2 + + flowCost, H = nx.network_simplex(G) + soln = {1: {2: 0, 5: 1}, 2: {3: 0, 5: 1}, 3: {4: 2}, 4: {}, 5: {3: 2, 4: 0}} + assert flowCost == 6 + assert nx.min_cost_flow_cost(G) == 6 + assert H == soln + + +def test_digon(): + """Check if digons are handled properly. Taken from ticket + #618 by arv.""" + nodes = [(1, {}), (2, {"demand": -4}), (3, {"demand": 4})] + edges = [ + (1, 2, {"capacity": 3, "weight": 600000}), + (2, 1, {"capacity": 2, "weight": 0}), + (2, 3, {"capacity": 5, "weight": 714285}), + (3, 2, {"capacity": 2, "weight": 0}), + ] + G = nx.DiGraph(edges) + G.add_nodes_from(nodes) + flowCost, H = nx.network_simplex(G) + soln = {1: {2: 0}, 2: {1: 0, 3: 4}, 3: {2: 0}} + assert flowCost == 2857140 + + +def test_deadend(): + """Check if one-node cycles are handled properly. Taken from ticket + #2906 from @sshraven.""" + G = nx.DiGraph() + + G.add_nodes_from(range(5), demand=0) + G.nodes[4]["demand"] = -13 + G.nodes[3]["demand"] = 13 + + G.add_edges_from([(0, 2), (0, 3), (2, 1)], capacity=20, weight=0.1) + pytest.raises(nx.NetworkXUnfeasible, nx.network_simplex, G) + + +def test_infinite_capacity_neg_digon(): + """An infinite capacity negative cost digon results in an unbounded + instance.""" + nodes = [(1, {}), (2, {"demand": -4}), (3, {"demand": 4})] + edges = [ + (1, 2, {"weight": -600}), + (2, 1, {"weight": 0}), + (2, 3, {"capacity": 5, "weight": 714285}), + (3, 2, {"capacity": 2, "weight": 0}), + ] + G = nx.DiGraph(edges) + G.add_nodes_from(nodes) + pytest.raises(nx.NetworkXUnbounded, nx.network_simplex, G) + + +def test_multidigraph(): + """Multidigraphs are acceptable.""" + G = nx.MultiDiGraph() + G.add_weighted_edges_from([(1, 2, 1), (2, 3, 2)], weight="capacity") + flowCost, H = nx.network_simplex(G) + assert flowCost == 0 + assert H == {1: {2: {0: 0}}, 2: {3: {0: 0}}, 3: {}} + + +def test_negative_selfloops(): + """Negative selfloops should cause an exception if uncapacitated and + always be saturated otherwise. + """ + G = nx.DiGraph() + G.add_edge(1, 1, weight=-1) + pytest.raises(nx.NetworkXUnbounded, nx.network_simplex, G) + + G[1][1]["capacity"] = 2 + flowCost, H = nx.network_simplex(G) + assert flowCost == -2 + assert H == {1: {1: 2}} + + G = nx.MultiDiGraph() + G.add_edge(1, 1, "x", weight=-1) + G.add_edge(1, 1, "y", weight=1) + pytest.raises(nx.NetworkXUnbounded, nx.network_simplex, G) + + G[1][1]["x"]["capacity"] = 2 + flowCost, H = nx.network_simplex(G) + assert flowCost == -2 + assert H == {1: {1: {"x": 2, "y": 0}}} + + +def test_bone_shaped(): + # From #1283 + G = nx.DiGraph() + G.add_node(0, demand=-4) + G.add_node(1, demand=2) + G.add_node(2, demand=2) + G.add_node(3, demand=4) + G.add_node(4, demand=-2) + G.add_node(5, demand=-2) + G.add_edge(0, 1, capacity=4) + G.add_edge(0, 2, capacity=4) + G.add_edge(4, 3, capacity=4) + G.add_edge(5, 3, capacity=4) + G.add_edge(0, 3, capacity=0) + flowCost, H = nx.network_simplex(G) + assert flowCost == 0 + assert H == {0: {1: 2, 2: 2, 3: 0}, 1: {}, 2: {}, 3: {}, 4: {3: 2}, 5: {3: 2}} + + +def test_graphs_type_exceptions(): + G = nx.Graph() + pytest.raises(nx.NetworkXNotImplemented, nx.network_simplex, G) + G = nx.MultiGraph() + pytest.raises(nx.NetworkXNotImplemented, nx.network_simplex, G) + G = nx.DiGraph() + pytest.raises(nx.NetworkXError, nx.network_simplex, G) + + +@pytest.fixture() +def faux_inf_example(): + """Base test graph for probing faux_infinity bound. See gh-7562""" + G = nx.DiGraph() + + # Add nodes with demands + G.add_node("s0", demand=-4) + G.add_node("s1", demand=-4) + G.add_node("ns", demand=0) + G.add_node("nc", demand=0) + G.add_node("c0", demand=4) + G.add_node("c1", demand=4) + + # Uniformly weighted edges + G.add_edge("s0", "ns", weight=1) + G.add_edge("s1", "ns", weight=1) + G.add_edge("ns", "nc", weight=1) + G.add_edge("nc", "c0", weight=1) + G.add_edge("nc", "c1", weight=1) + + return G + + +@pytest.mark.parametrize("large_capacity", [True, False]) +@pytest.mark.parametrize("large_demand", [True, False]) +@pytest.mark.parametrize("large_weight", [True, False]) +def test_network_simplex_faux_infinity( + faux_inf_example, large_capacity, large_demand, large_weight +): + """network_simplex should not raise an exception as a result of faux_infinity + for these cases. See gh-7562""" + G = faux_inf_example + lv = 1_000_000_000 + + # Modify the base graph with combinations of large values for capacity, + # demand, and weight to probe faux_inifity + if large_capacity: + G["s0"]["ns"]["capacity"] = lv + if large_demand: + G.nodes["s0"]["demand"] = -lv + G.nodes["c1"]["demand"] = lv + if large_weight: + G["s1"]["ns"]["weight"] = lv + + # Execute without raising + fc, fd = nx.network_simplex(G) + + +def test_network_simplex_unbounded_flow(): + G = nx.DiGraph() + # Add nodes + G.add_node("A") + G.add_node("B") + G.add_node("C") + + # Add edges forming a negative cycle + G.add_weighted_edges_from([("A", "B", -5), ("B", "C", -5), ("C", "A", -5)]) + + with pytest.raises( + nx.NetworkXUnbounded, + match="negative cycle with infinite capacity found", + ): + nx.network_simplex(G) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6374292cd2b7727759b9e0cb3238dda6103cb719 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/__pycache__/hits_alg.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/__pycache__/hits_alg.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..38e7d22ed3886b88f9c7b73be0ea0a8c01de44c5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/__pycache__/hits_alg.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/__pycache__/pagerank_alg.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/__pycache__/pagerank_alg.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..47144ea95aa5a828f9a5e903ea35a358812910da Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/__pycache__/pagerank_alg.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dec4d3a5b9279f07543c5d274ed2f097e165f754 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/__pycache__/test_hits.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/__pycache__/test_hits.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6fea5739987a57b9d872960c561ecb57b3f13695 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/__pycache__/test_hits.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/__pycache__/test_pagerank.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/__pycache__/test_pagerank.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a59cbf4fedb83abfbc267e48a0e78baed56c0b7d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/__pycache__/test_pagerank.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/test_hits.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/test_hits.py new file mode 100644 index 0000000000000000000000000000000000000000..f048f0af06500e0a42488bcd4c4ce122f24203ab --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/test_hits.py @@ -0,0 +1,77 @@ +import pytest + +import networkx as nx +from networkx.algorithms.link_analysis.hits_alg import ( + _hits_numpy, + _hits_python, + _hits_scipy, +) + +np = pytest.importorskip("numpy") +sp = pytest.importorskip("scipy") + +# Example from +# A. Langville and C. Meyer, "A survey of eigenvector methods of web +# information retrieval." http://citeseer.ist.psu.edu/713792.html + + +class TestHITS: + @classmethod + def setup_class(cls): + G = nx.DiGraph() + + edges = [(1, 3), (1, 5), (2, 1), (3, 5), (5, 4), (5, 3), (6, 5)] + + G.add_edges_from(edges, weight=1) + cls.G = G + cls.G.a = dict( + zip(sorted(G), [0.000000, 0.000000, 0.366025, 0.133975, 0.500000, 0.000000]) + ) + cls.G.h = dict( + zip(sorted(G), [0.366025, 0.000000, 0.211325, 0.000000, 0.211325, 0.211325]) + ) + + def test_hits_numpy(self): + G = self.G + h, a = _hits_numpy(G) + for n in G: + assert h[n] == pytest.approx(G.h[n], abs=1e-4) + for n in G: + assert a[n] == pytest.approx(G.a[n], abs=1e-4) + + @pytest.mark.parametrize("hits_alg", (nx.hits, _hits_python, _hits_scipy)) + def test_hits(self, hits_alg): + G = self.G + h, a = hits_alg(G, tol=1.0e-08) + for n in G: + assert h[n] == pytest.approx(G.h[n], abs=1e-4) + for n in G: + assert a[n] == pytest.approx(G.a[n], abs=1e-4) + nstart = {i: 1.0 / 2 for i in G} + h, a = hits_alg(G, nstart=nstart) + for n in G: + assert h[n] == pytest.approx(G.h[n], abs=1e-4) + for n in G: + assert a[n] == pytest.approx(G.a[n], abs=1e-4) + + def test_empty(self): + G = nx.Graph() + assert nx.hits(G) == ({}, {}) + assert _hits_numpy(G) == ({}, {}) + assert _hits_python(G) == ({}, {}) + assert _hits_scipy(G) == ({}, {}) + + def test_hits_not_convergent(self): + G = nx.path_graph(50) + with pytest.raises(nx.PowerIterationFailedConvergence): + _hits_scipy(G, max_iter=1) + with pytest.raises(nx.PowerIterationFailedConvergence): + _hits_python(G, max_iter=1) + with pytest.raises(nx.PowerIterationFailedConvergence): + _hits_scipy(G, max_iter=0) + with pytest.raises(nx.PowerIterationFailedConvergence): + _hits_python(G, max_iter=0) + with pytest.raises(nx.PowerIterationFailedConvergence): + nx.hits(G, max_iter=0) + with pytest.raises(nx.PowerIterationFailedConvergence): + nx.hits(G, max_iter=1) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/test_pagerank.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/test_pagerank.py new file mode 100644 index 0000000000000000000000000000000000000000..fb084236735ceea9c31e77670bd01e427da963ca --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/link_analysis/tests/test_pagerank.py @@ -0,0 +1,213 @@ +import random + +import pytest + +import networkx as nx +from networkx.algorithms.link_analysis.pagerank_alg import ( + _pagerank_numpy, + _pagerank_python, + _pagerank_scipy, +) +from networkx.classes.tests import dispatch_interface + +np = pytest.importorskip("numpy") +pytest.importorskip("scipy") + +# Example from +# A. Langville and C. Meyer, "A survey of eigenvector methods of web +# information retrieval." http://citeseer.ist.psu.edu/713792.html + + +class TestPageRank: + @classmethod + def setup_class(cls): + G = nx.DiGraph() + edges = [ + (1, 2), + (1, 3), + # 2 is a dangling node + (3, 1), + (3, 2), + (3, 5), + (4, 5), + (4, 6), + (5, 4), + (5, 6), + (6, 4), + ] + G.add_edges_from(edges) + cls.G = G + cls.G.pagerank = dict( + zip( + sorted(G), + [ + 0.03721197, + 0.05395735, + 0.04150565, + 0.37508082, + 0.20599833, + 0.28624589, + ], + ) + ) + cls.dangling_node_index = 1 + cls.dangling_edges = {1: 2, 2: 3, 3: 0, 4: 0, 5: 0, 6: 0} + cls.G.dangling_pagerank = dict( + zip( + sorted(G), + [0.10844518, 0.18618601, 0.0710892, 0.2683668, 0.15919783, 0.20671497], + ) + ) + + @pytest.mark.parametrize("alg", (nx.pagerank, _pagerank_python)) + def test_pagerank(self, alg): + G = self.G + p = alg(G, alpha=0.9, tol=1.0e-08) + for n in G: + assert p[n] == pytest.approx(G.pagerank[n], abs=1e-4) + + nstart = {n: random.random() for n in G} + p = alg(G, alpha=0.9, tol=1.0e-08, nstart=nstart) + for n in G: + assert p[n] == pytest.approx(G.pagerank[n], abs=1e-4) + + @pytest.mark.parametrize("alg", (nx.pagerank, _pagerank_python)) + def test_pagerank_max_iter(self, alg): + with pytest.raises(nx.PowerIterationFailedConvergence): + alg(self.G, max_iter=0) + + def test_numpy_pagerank(self): + G = self.G + p = _pagerank_numpy(G, alpha=0.9) + for n in G: + assert p[n] == pytest.approx(G.pagerank[n], abs=1e-4) + + def test_google_matrix(self): + G = self.G + M = nx.google_matrix(G, alpha=0.9, nodelist=sorted(G)) + _, ev = np.linalg.eig(M.T) + p = ev[:, 0] / ev[:, 0].sum() + for a, b in zip(p, self.G.pagerank.values()): + assert a == pytest.approx(b, abs=1e-7) + + @pytest.mark.parametrize("alg", (nx.pagerank, _pagerank_python, _pagerank_numpy)) + def test_personalization(self, alg): + G = nx.complete_graph(4) + personalize = {0: 1, 1: 1, 2: 4, 3: 4} + answer = { + 0: 0.23246732615667579, + 1: 0.23246732615667579, + 2: 0.267532673843324, + 3: 0.2675326738433241, + } + p = alg(G, alpha=0.85, personalization=personalize) + for n in G: + assert p[n] == pytest.approx(answer[n], abs=1e-4) + + @pytest.mark.parametrize("alg", (nx.pagerank, _pagerank_python, nx.google_matrix)) + def test_zero_personalization_vector(self, alg): + G = nx.complete_graph(4) + personalize = {0: 0, 1: 0, 2: 0, 3: 0} + pytest.raises(ZeroDivisionError, alg, G, personalization=personalize) + + @pytest.mark.parametrize("alg", (nx.pagerank, _pagerank_python)) + def test_one_nonzero_personalization_value(self, alg): + G = nx.complete_graph(4) + personalize = {0: 0, 1: 0, 2: 0, 3: 1} + answer = { + 0: 0.22077931820379187, + 1: 0.22077931820379187, + 2: 0.22077931820379187, + 3: 0.3376620453886241, + } + p = alg(G, alpha=0.85, personalization=personalize) + for n in G: + assert p[n] == pytest.approx(answer[n], abs=1e-4) + + @pytest.mark.parametrize("alg", (nx.pagerank, _pagerank_python)) + def test_incomplete_personalization(self, alg): + G = nx.complete_graph(4) + personalize = {3: 1} + answer = { + 0: 0.22077931820379187, + 1: 0.22077931820379187, + 2: 0.22077931820379187, + 3: 0.3376620453886241, + } + p = alg(G, alpha=0.85, personalization=personalize) + for n in G: + assert p[n] == pytest.approx(answer[n], abs=1e-4) + + def test_dangling_matrix(self): + """ + Tests that the google_matrix doesn't change except for the dangling + nodes. + """ + G = self.G + dangling = self.dangling_edges + dangling_sum = sum(dangling.values()) + M1 = nx.google_matrix(G, personalization=dangling) + M2 = nx.google_matrix(G, personalization=dangling, dangling=dangling) + for i in range(len(G)): + for j in range(len(G)): + if i == self.dangling_node_index and (j + 1) in dangling: + assert M2[i, j] == pytest.approx( + dangling[j + 1] / dangling_sum, abs=1e-4 + ) + else: + assert M2[i, j] == pytest.approx(M1[i, j], abs=1e-4) + + @pytest.mark.parametrize("alg", (nx.pagerank, _pagerank_python, _pagerank_numpy)) + def test_dangling_pagerank(self, alg): + pr = alg(self.G, dangling=self.dangling_edges) + for n in self.G: + assert pr[n] == pytest.approx(self.G.dangling_pagerank[n], abs=1e-4) + + def test_empty(self): + G = nx.Graph() + assert nx.pagerank(G) == {} + assert _pagerank_python(G) == {} + assert _pagerank_numpy(G) == {} + assert nx.google_matrix(G).shape == (0, 0) + + @pytest.mark.parametrize("alg", (nx.pagerank, _pagerank_python)) + def test_multigraph(self, alg): + G = nx.MultiGraph() + G.add_edges_from([(1, 2), (1, 2), (1, 2), (2, 3), (2, 3), ("3", 3), ("3", 3)]) + answer = { + 1: 0.21066048614468322, + 2: 0.3395308825985378, + 3: 0.28933951385531687, + "3": 0.16046911740146227, + } + p = alg(G) + for n in G: + assert p[n] == pytest.approx(answer[n], abs=1e-4) + + +class TestPageRankScipy(TestPageRank): + def test_scipy_pagerank(self): + G = self.G + p = _pagerank_scipy(G, alpha=0.9, tol=1.0e-08) + for n in G: + assert p[n] == pytest.approx(G.pagerank[n], abs=1e-4) + personalize = {n: random.random() for n in G} + p = _pagerank_scipy(G, alpha=0.9, tol=1.0e-08, personalization=personalize) + + nstart = {n: random.random() for n in G} + p = _pagerank_scipy(G, alpha=0.9, tol=1.0e-08, nstart=nstart) + for n in G: + assert p[n] == pytest.approx(G.pagerank[n], abs=1e-4) + + def test_scipy_pagerank_max_iter(self): + with pytest.raises(nx.PowerIterationFailedConvergence): + _pagerank_scipy(self.G, max_iter=0) + + def test_dangling_scipy_pagerank(self): + pr = _pagerank_scipy(self.G, dangling=self.dangling_edges) + for n in self.G: + assert pr[n] == pytest.approx(self.G.dangling_pagerank[n], abs=1e-4) + + def test_empty_scipy(self): + G = nx.Graph() + assert _pagerank_scipy(G) == {} diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a57b15f34e71eda4150ae9c4677f7eb0581d1971 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_all.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_all.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d7fbdc8eba565ff9c0a2d3e659f9119560c3b94 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_all.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_binary.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_binary.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83081db76de3e7088f587a78d4f2c62df3b6f661 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_binary.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_product.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_product.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b0128788e77b4b24cff694085a5e746bbb89092 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_product.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_unary.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_unary.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c7f4bb33fbe59a31d3ee1676e3c4a42c27aa734a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/operators/tests/__pycache__/test_unary.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/shortest_paths/tests/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/shortest_paths/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/shortest_paths/tests/test_dense.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/shortest_paths/tests/test_dense.py new file mode 100644 index 0000000000000000000000000000000000000000..6923bfef856c83bd3e65573b97fe96ff16cdbc71 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/shortest_paths/tests/test_dense.py @@ -0,0 +1,212 @@ +import pytest + +import networkx as nx + + +class TestFloyd: + @classmethod + def setup_class(cls): + pass + + def test_floyd_warshall_predecessor_and_distance(self): + XG = nx.DiGraph() + XG.add_weighted_edges_from( + [ + ("s", "u", 10), + ("s", "x", 5), + ("u", "v", 1), + ("u", "x", 2), + ("v", "y", 1), + ("x", "u", 3), + ("x", "v", 5), + ("x", "y", 2), + ("y", "s", 7), + ("y", "v", 6), + ] + ) + path, dist = nx.floyd_warshall_predecessor_and_distance(XG) + assert dist["s"]["v"] == 9 + assert path["s"]["v"] == "u" + assert dist == { + "y": {"y": 0, "x": 12, "s": 7, "u": 15, "v": 6}, + "x": {"y": 2, "x": 0, "s": 9, "u": 3, "v": 4}, + "s": {"y": 7, "x": 5, "s": 0, "u": 8, "v": 9}, + "u": {"y": 2, "x": 2, "s": 9, "u": 0, "v": 1}, + "v": {"y": 1, "x": 13, "s": 8, "u": 16, "v": 0}, + } + + GG = XG.to_undirected() + # make sure we get lower weight + # to_undirected might choose either edge with weight 2 or weight 3 + GG["u"]["x"]["weight"] = 2 + path, dist = nx.floyd_warshall_predecessor_and_distance(GG) + assert dist["s"]["v"] == 8 + # skip this test, could be alternate path s-u-v + # assert_equal(path['s']['v'],'y') + + G = nx.DiGraph() # no weights + G.add_edges_from( + [ + ("s", "u"), + ("s", "x"), + ("u", "v"), + ("u", "x"), + ("v", "y"), + ("x", "u"), + ("x", "v"), + ("x", "y"), + ("y", "s"), + ("y", "v"), + ] + ) + path, dist = nx.floyd_warshall_predecessor_and_distance(G) + assert dist["s"]["v"] == 2 + # skip this test, could be alternate path s-u-v + # assert_equal(path['s']['v'],'x') + + # alternate interface + dist = nx.floyd_warshall(G) + assert dist["s"]["v"] == 2 + + # floyd_warshall_predecessor_and_distance returns + # dicts-of-defautdicts + # make sure we don't get empty dictionary + XG = nx.DiGraph() + XG.add_weighted_edges_from( + [("v", "x", 5.0), ("y", "x", 5.0), ("v", "y", 6.0), ("x", "u", 2.0)] + ) + path, dist = nx.floyd_warshall_predecessor_and_distance(XG) + inf = float("inf") + assert dist == { + "v": {"v": 0, "x": 5.0, "y": 6.0, "u": 7.0}, + "x": {"x": 0, "u": 2.0, "v": inf, "y": inf}, + "y": {"y": 0, "x": 5.0, "v": inf, "u": 7.0}, + "u": {"u": 0, "v": inf, "x": inf, "y": inf}, + } + assert path == { + "v": {"x": "v", "y": "v", "u": "x"}, + "x": {"u": "x"}, + "y": {"x": "y", "u": "x"}, + } + + def test_reconstruct_path(self): + with pytest.raises(KeyError): + XG = nx.DiGraph() + XG.add_weighted_edges_from( + [ + ("s", "u", 10), + ("s", "x", 5), + ("u", "v", 1), + ("u", "x", 2), + ("v", "y", 1), + ("x", "u", 3), + ("x", "v", 5), + ("x", "y", 2), + ("y", "s", 7), + ("y", "v", 6), + ] + ) + predecessors, _ = nx.floyd_warshall_predecessor_and_distance(XG) + + path = nx.reconstruct_path("s", "v", predecessors) + assert path == ["s", "x", "u", "v"] + + path = nx.reconstruct_path("s", "s", predecessors) + assert path == [] + + # this part raises the keyError + nx.reconstruct_path("1", "2", predecessors) + + def test_cycle(self): + path, dist = nx.floyd_warshall_predecessor_and_distance(nx.cycle_graph(7)) + assert dist[0][3] == 3 + assert path[0][3] == 2 + assert dist[0][4] == 3 + + def test_weighted(self): + XG3 = nx.Graph() + XG3.add_weighted_edges_from( + [[0, 1, 2], [1, 2, 12], [2, 3, 1], [3, 4, 5], [4, 5, 1], [5, 0, 10]] + ) + path, dist = nx.floyd_warshall_predecessor_and_distance(XG3) + assert dist[0][3] == 15 + assert path[0][3] == 2 + + def test_weighted2(self): + XG4 = nx.Graph() + XG4.add_weighted_edges_from( + [ + [0, 1, 2], + [1, 2, 2], + [2, 3, 1], + [3, 4, 1], + [4, 5, 1], + [5, 6, 1], + [6, 7, 1], + [7, 0, 1], + ] + ) + path, dist = nx.floyd_warshall_predecessor_and_distance(XG4) + assert dist[0][2] == 4 + assert path[0][2] == 1 + + def test_weight_parameter(self): + XG4 = nx.Graph() + XG4.add_edges_from( + [ + (0, 1, {"heavy": 2}), + (1, 2, {"heavy": 2}), + (2, 3, {"heavy": 1}), + (3, 4, {"heavy": 1}), + (4, 5, {"heavy": 1}), + (5, 6, {"heavy": 1}), + (6, 7, {"heavy": 1}), + (7, 0, {"heavy": 1}), + ] + ) + path, dist = nx.floyd_warshall_predecessor_and_distance(XG4, weight="heavy") + assert dist[0][2] == 4 + assert path[0][2] == 1 + + def test_zero_distance(self): + XG = nx.DiGraph() + XG.add_weighted_edges_from( + [ + ("s", "u", 10), + ("s", "x", 5), + ("u", "v", 1), + ("u", "x", 2), + ("v", "y", 1), + ("x", "u", 3), + ("x", "v", 5), + ("x", "y", 2), + ("y", "s", 7), + ("y", "v", 6), + ] + ) + path, dist = nx.floyd_warshall_predecessor_and_distance(XG) + + for u in XG: + assert dist[u][u] == 0 + + GG = XG.to_undirected() + # make sure we get lower weight + # to_undirected might choose either edge with weight 2 or weight 3 + GG["u"]["x"]["weight"] = 2 + path, dist = nx.floyd_warshall_predecessor_and_distance(GG) + + for u in GG: + dist[u][u] = 0 + + def test_zero_weight(self): + G = nx.DiGraph() + edges = [(1, 2, -2), (2, 3, -4), (1, 5, 1), (5, 4, 0), (4, 3, -5), (2, 5, -7)] + G.add_weighted_edges_from(edges) + dist = nx.floyd_warshall(G) + assert dist[1][3] == -14 + + G = nx.MultiDiGraph() + edges.append((2, 5, -7)) + G.add_weighted_edges_from(edges) + dist = nx.floyd_warshall(G) + assert dist[1][3] == -14 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/shortest_paths/tests/test_dense_numpy.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/shortest_paths/tests/test_dense_numpy.py new file mode 100644 index 0000000000000000000000000000000000000000..6eb95a5280bd74d8b88cfc3049f020e7ee187a51 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/shortest_paths/tests/test_dense_numpy.py @@ -0,0 +1,88 @@ +import pytest + +import networkx as nx + +np = pytest.importorskip("numpy") + + +def test_cycle_numpy(): + dist = nx.floyd_warshall_numpy(nx.cycle_graph(7)) + assert dist[0, 3] == 3 + assert dist[0, 4] == 3 + + +def test_weighted_numpy_three_edges(): + XG3 = nx.Graph() + XG3.add_weighted_edges_from( + [[0, 1, 2], [1, 2, 12], [2, 3, 1], [3, 4, 5], [4, 5, 1], [5, 0, 10]] + ) + dist = nx.floyd_warshall_numpy(XG3) + assert dist[0, 3] == 15 + + +def test_weighted_numpy_two_edges(): + XG4 = nx.Graph() + XG4.add_weighted_edges_from( + [ + [0, 1, 2], + [1, 2, 2], + [2, 3, 1], + [3, 4, 1], + [4, 5, 1], + [5, 6, 1], + [6, 7, 1], + [7, 0, 1], + ] + ) + dist = nx.floyd_warshall_numpy(XG4) + assert dist[0, 2] == 4 + + +def test_weight_parameter_numpy(): + XG4 = nx.Graph() + XG4.add_edges_from( + [ + (0, 1, {"heavy": 2}), + (1, 2, {"heavy": 2}), + (2, 3, {"heavy": 1}), + (3, 4, {"heavy": 1}), + (4, 5, {"heavy": 1}), + (5, 6, {"heavy": 1}), + (6, 7, {"heavy": 1}), + (7, 0, {"heavy": 1}), + ] + ) + dist = nx.floyd_warshall_numpy(XG4, weight="heavy") + assert dist[0, 2] == 4 + + +def test_directed_cycle_numpy(): + G = nx.DiGraph() + nx.add_cycle(G, [0, 1, 2, 3]) + pred, dist = nx.floyd_warshall_predecessor_and_distance(G) + D = nx.utils.dict_to_numpy_array(dist) + np.testing.assert_equal(nx.floyd_warshall_numpy(G), D) + + +def test_zero_weight(): + G = nx.DiGraph() + edges = [(1, 2, -2), (2, 3, -4), (1, 5, 1), (5, 4, 0), (4, 3, -5), (2, 5, -7)] + G.add_weighted_edges_from(edges) + dist = nx.floyd_warshall_numpy(G) + assert int(np.min(dist)) == -14 + + G = nx.MultiDiGraph() + edges.append((2, 5, -7)) + G.add_weighted_edges_from(edges) + dist = nx.floyd_warshall_numpy(G) + assert int(np.min(dist)) == -14 + + +def test_nodelist(): + G = nx.path_graph(7) + dist = nx.floyd_warshall_numpy(G, nodelist=[3, 5, 4, 6, 2, 1, 0]) + assert dist[0, 3] == 3 + assert dist[0, 1] == 2 + assert dist[6, 2] == 4 + pytest.raises(nx.NetworkXError, nx.floyd_warshall_numpy, G, [1, 3]) + pytest.raises(nx.NetworkXError, nx.floyd_warshall_numpy, G, list(range(9))) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/shortest_paths/tests/test_generic.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/shortest_paths/tests/test_generic.py new file mode 100644 index 0000000000000000000000000000000000000000..09f6953d4bce83d79db2f424c5645c65cb6e2234 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/shortest_paths/tests/test_generic.py @@ -0,0 +1,511 @@ +import pytest + +import networkx as nx + + +def validate_grid_path(r, c, s, t, p): + assert isinstance(p, list) + assert p[0] == s + assert p[-1] == t + s = ((s - 1) // c, (s - 1) % c) + t = ((t - 1) // c, (t - 1) % c) + assert len(p) == abs(t[0] - s[0]) + abs(t[1] - s[1]) + 1 + p = [((u - 1) // c, (u - 1) % c) for u in p] + for u in p: + assert 0 <= u[0] < r + assert 0 <= u[1] < c + for u, v in zip(p[:-1], p[1:]): + assert (abs(v[0] - u[0]), abs(v[1] - u[1])) in [(0, 1), (1, 0)] + + +class TestGenericPath: + @classmethod + def setup_class(cls): + from networkx import convert_node_labels_to_integers as cnlti + + cls.grid = cnlti(nx.grid_2d_graph(4, 4), first_label=1, ordering="sorted") + cls.cycle = nx.cycle_graph(7) + cls.directed_cycle = nx.cycle_graph(7, create_using=nx.DiGraph()) + cls.neg_weights = nx.DiGraph() + cls.neg_weights.add_edge(0, 1, weight=1) + cls.neg_weights.add_edge(0, 2, weight=3) + cls.neg_weights.add_edge(1, 3, weight=1) + cls.neg_weights.add_edge(2, 3, weight=-2) + + def test_sentinel_trick_all_algorithms(self): + def reconstruct_path(pred, source, target): + path = [target] + while path[-1] != source: + path.append(pred[path[-1]]) + return list(reversed(path)) + + # Build the test graph inline + G = nx.Graph() + G.add_edge("A", "B", weight=1) + G.add_edge("B", "C", weight=1) + G.add_edge("C", "D", weight=1) + G.add_edge("D", "E", weight=1) + + source = "A" + targets = {"C", "D", "E"} + expected_target = "C" # A-B-C is closest + + sentinel = "_sentinel_" + G.add_node(sentinel) + for t in targets: + G.add_edge(t, sentinel, weight=0) + + # shortest_path: Dijkstra (default) + path = nx.shortest_path(G, source=source, target=sentinel, weight="weight") + assert path[-2] == expected_target + + # shortest_path: Bellman-Ford + path = nx.shortest_path( + G, source=source, target=sentinel, weight="weight", method="bellman-ford" + ) + assert path[-2] == expected_target + + # shortest_path: Unweighted (BFS) + path = nx.shortest_path(G, source=source, target=sentinel, weight=None) + assert path[-2] == expected_target + + # bidirectional_dijkstra + _, path = nx.bidirectional_dijkstra(G, source, sentinel, weight="weight") + assert path[-2] == expected_target + + # goldberg_radzik + pred, _ = nx.goldberg_radzik(G, source, weight="weight") + path = reconstruct_path(pred, source, sentinel) + assert path[-2] == expected_target + + # astar_path with zero heuristic + path = nx.astar_path( + G, source, sentinel, heuristic=lambda u, v: 0, weight="weight" + ) + assert path[-2] == expected_target + + # johnson (all-pairs shortest paths) + paths = nx.johnson(G, weight="weight") + assert paths[source][sentinel][-2] == expected_target + + # floyd_warshall_predecessor_and_distance + pred, _ = nx.floyd_warshall_predecessor_and_distance(G, weight="weight") + path = reconstruct_path(pred[source], source, sentinel) + assert path[-2] == expected_target + + def test_shortest_path(self): + assert nx.shortest_path(self.cycle, 0, 3) == [0, 1, 2, 3] + assert nx.shortest_path(self.cycle, 0, 4) == [0, 6, 5, 4] + validate_grid_path(4, 4, 1, 12, nx.shortest_path(self.grid, 1, 12)) + assert nx.shortest_path(self.directed_cycle, 0, 3) == [0, 1, 2, 3] + # now with weights + assert nx.shortest_path(self.cycle, 0, 3, weight="weight") == [0, 1, 2, 3] + assert nx.shortest_path(self.cycle, 0, 4, weight="weight") == [0, 6, 5, 4] + validate_grid_path( + 4, 4, 1, 12, nx.shortest_path(self.grid, 1, 12, weight="weight") + ) + assert nx.shortest_path(self.directed_cycle, 0, 3, weight="weight") == [ + 0, + 1, + 2, + 3, + ] + # weights and method specified + assert nx.shortest_path( + self.directed_cycle, 0, 3, weight="weight", method="dijkstra" + ) == [0, 1, 2, 3] + assert nx.shortest_path( + self.directed_cycle, 0, 3, weight="weight", method="bellman-ford" + ) == [0, 1, 2, 3] + # when Dijkstra's will probably (depending on precise implementation) + # incorrectly return [0, 1, 3] instead + assert nx.shortest_path( + self.neg_weights, 0, 3, weight="weight", method="bellman-ford" + ) == [0, 2, 3] + # confirm bad method rejection + pytest.raises(ValueError, nx.shortest_path, self.cycle, method="SPAM") + # confirm absent source rejection + pytest.raises(nx.NodeNotFound, nx.shortest_path, self.cycle, 8) + + def test_shortest_path_target(self): + answer = {0: [0, 1], 1: [1], 2: [2, 1]} + sp = nx.shortest_path(nx.path_graph(3), target=1) + assert sp == answer + # with weights + sp = nx.shortest_path(nx.path_graph(3), target=1, weight="weight") + assert sp == answer + # weights and method specified + sp = nx.shortest_path( + nx.path_graph(3), target=1, weight="weight", method="dijkstra" + ) + assert sp == answer + sp = nx.shortest_path( + nx.path_graph(3), target=1, weight="weight", method="bellman-ford" + ) + assert sp == answer + + def test_shortest_path_length(self): + assert nx.shortest_path_length(self.cycle, 0, 3) == 3 + assert nx.shortest_path_length(self.grid, 1, 12) == 5 + assert nx.shortest_path_length(self.directed_cycle, 0, 4) == 4 + # now with weights + assert nx.shortest_path_length(self.cycle, 0, 3, weight="weight") == 3 + assert nx.shortest_path_length(self.grid, 1, 12, weight="weight") == 5 + assert nx.shortest_path_length(self.directed_cycle, 0, 4, weight="weight") == 4 + # weights and method specified + assert ( + nx.shortest_path_length( + self.cycle, 0, 3, weight="weight", method="dijkstra" + ) + == 3 + ) + assert ( + nx.shortest_path_length( + self.cycle, 0, 3, weight="weight", method="bellman-ford" + ) + == 3 + ) + # confirm bad method rejection + pytest.raises(ValueError, nx.shortest_path_length, self.cycle, method="SPAM") + # confirm absent source rejection + pytest.raises(nx.NodeNotFound, nx.shortest_path_length, self.cycle, 8) + + def test_shortest_path_length_target(self): + answer = {0: 1, 1: 0, 2: 1} + sp = nx.shortest_path_length(nx.path_graph(3), target=1) + assert sp == answer + # with weights + sp = nx.shortest_path_length(nx.path_graph(3), target=1, weight="weight") + assert sp == answer + # weights and method specified + sp = nx.shortest_path_length( + nx.path_graph(3), target=1, weight="weight", method="dijkstra" + ) + assert sp == answer + sp = nx.shortest_path_length( + nx.path_graph(3), target=1, weight="weight", method="bellman-ford" + ) + assert sp == answer + + def test_single_source_shortest_path(self): + p = nx.shortest_path(self.cycle, 0) + assert p[3] == [0, 1, 2, 3] + assert p == nx.single_source_shortest_path(self.cycle, 0) + p = nx.shortest_path(self.grid, 1) + validate_grid_path(4, 4, 1, 12, p[12]) + # now with weights + p = nx.shortest_path(self.cycle, 0, weight="weight") + assert p[3] == [0, 1, 2, 3] + assert p == nx.single_source_dijkstra_path(self.cycle, 0) + p = nx.shortest_path(self.grid, 1, weight="weight") + validate_grid_path(4, 4, 1, 12, p[12]) + # weights and method specified + p = nx.shortest_path(self.cycle, 0, method="dijkstra", weight="weight") + assert p[3] == [0, 1, 2, 3] + assert p == nx.single_source_shortest_path(self.cycle, 0) + p = nx.shortest_path(self.cycle, 0, method="bellman-ford", weight="weight") + assert p[3] == [0, 1, 2, 3] + assert p == nx.single_source_shortest_path(self.cycle, 0) + + def test_single_source_shortest_path_length(self): + ans = nx.shortest_path_length(self.cycle, 0) + assert ans == {0: 0, 1: 1, 2: 2, 3: 3, 4: 3, 5: 2, 6: 1} + assert ans == nx.single_source_shortest_path_length(self.cycle, 0) + ans = nx.shortest_path_length(self.grid, 1) + assert ans[16] == 6 + # now with weights + ans = nx.shortest_path_length(self.cycle, 0, weight="weight") + assert ans == {0: 0, 1: 1, 2: 2, 3: 3, 4: 3, 5: 2, 6: 1} + assert ans == nx.single_source_dijkstra_path_length(self.cycle, 0) + ans = nx.shortest_path_length(self.grid, 1, weight="weight") + assert ans[16] == 6 + # weights and method specified + ans = dict( + nx.shortest_path_length(self.cycle, 0, weight="weight", method="dijkstra") + ) + assert ans == {0: 0, 1: 1, 2: 2, 3: 3, 4: 3, 5: 2, 6: 1} + assert ans == nx.single_source_dijkstra_path_length(self.cycle, 0) + ans = dict( + nx.shortest_path_length( + self.cycle, 0, weight="weight", method="bellman-ford" + ) + ) + assert ans == {0: 0, 1: 1, 2: 2, 3: 3, 4: 3, 5: 2, 6: 1} + assert ans == nx.single_source_bellman_ford_path_length(self.cycle, 0) + + def test_single_source_all_shortest_paths(self): + cycle_ans = {0: [[0]], 1: [[0, 1]], 2: [[0, 1, 2], [0, 3, 2]], 3: [[0, 3]]} + ans = dict(nx.single_source_all_shortest_paths(nx.cycle_graph(4), 0)) + assert sorted(ans[2]) == cycle_ans[2] + ans = dict(nx.single_source_all_shortest_paths(self.grid, 1)) + grid_ans = [ + [1, 2, 3, 7, 11], + [1, 2, 6, 7, 11], + [1, 2, 6, 10, 11], + [1, 5, 6, 7, 11], + [1, 5, 6, 10, 11], + [1, 5, 9, 10, 11], + ] + assert sorted(ans[11]) == grid_ans + ans = dict( + nx.single_source_all_shortest_paths(nx.cycle_graph(4), 0, weight="weight") + ) + assert sorted(ans[2]) == cycle_ans[2] + ans = dict( + nx.single_source_all_shortest_paths( + nx.cycle_graph(4), 0, method="bellman-ford", weight="weight" + ) + ) + assert sorted(ans[2]) == cycle_ans[2] + ans = dict(nx.single_source_all_shortest_paths(self.grid, 1, weight="weight")) + assert sorted(ans[11]) == grid_ans + ans = dict( + nx.single_source_all_shortest_paths( + self.grid, 1, method="bellman-ford", weight="weight" + ) + ) + assert sorted(ans[11]) == grid_ans + G = nx.cycle_graph(4) + G.add_node(4) + ans = dict(nx.single_source_all_shortest_paths(G, 0)) + assert sorted(ans[2]) == [[0, 1, 2], [0, 3, 2]] + ans = dict(nx.single_source_all_shortest_paths(G, 4)) + assert sorted(ans[4]) == [[4]] + + def test_all_pairs_shortest_path(self): + # shortest_path w/o source and target returns a generator instead of + # a dict beginning in version 3.5. Only the first call needed changed here. + p = dict(nx.shortest_path(self.cycle)) + assert p[0][3] == [0, 1, 2, 3] + assert p == dict(nx.all_pairs_shortest_path(self.cycle)) + p = dict(nx.shortest_path(self.grid)) + validate_grid_path(4, 4, 1, 12, p[1][12]) + # now with weights + p = dict(nx.shortest_path(self.cycle, weight="weight")) + assert p[0][3] == [0, 1, 2, 3] + assert p == dict(nx.all_pairs_dijkstra_path(self.cycle)) + p = dict(nx.shortest_path(self.grid, weight="weight")) + validate_grid_path(4, 4, 1, 12, p[1][12]) + # weights and method specified + p = dict(nx.shortest_path(self.cycle, weight="weight", method="dijkstra")) + assert p[0][3] == [0, 1, 2, 3] + assert p == dict(nx.all_pairs_dijkstra_path(self.cycle)) + p = dict(nx.shortest_path(self.cycle, weight="weight", method="bellman-ford")) + assert p[0][3] == [0, 1, 2, 3] + assert p == dict(nx.all_pairs_bellman_ford_path(self.cycle)) + + def test_all_pairs_shortest_path_length(self): + ans = dict(nx.shortest_path_length(self.cycle)) + assert ans[0] == {0: 0, 1: 1, 2: 2, 3: 3, 4: 3, 5: 2, 6: 1} + assert ans == dict(nx.all_pairs_shortest_path_length(self.cycle)) + ans = dict(nx.shortest_path_length(self.grid)) + assert ans[1][16] == 6 + # now with weights + ans = dict(nx.shortest_path_length(self.cycle, weight="weight")) + assert ans[0] == {0: 0, 1: 1, 2: 2, 3: 3, 4: 3, 5: 2, 6: 1} + assert ans == dict(nx.all_pairs_dijkstra_path_length(self.cycle)) + ans = dict(nx.shortest_path_length(self.grid, weight="weight")) + assert ans[1][16] == 6 + # weights and method specified + ans = dict( + nx.shortest_path_length(self.cycle, weight="weight", method="dijkstra") + ) + assert ans[0] == {0: 0, 1: 1, 2: 2, 3: 3, 4: 3, 5: 2, 6: 1} + assert ans == dict(nx.all_pairs_dijkstra_path_length(self.cycle)) + ans = dict( + nx.shortest_path_length(self.cycle, weight="weight", method="bellman-ford") + ) + assert ans[0] == {0: 0, 1: 1, 2: 2, 3: 3, 4: 3, 5: 2, 6: 1} + assert ans == dict(nx.all_pairs_bellman_ford_path_length(self.cycle)) + + def test_all_pairs_all_shortest_paths(self): + ans = dict(nx.all_pairs_all_shortest_paths(nx.cycle_graph(4))) + assert sorted(ans[1][3]) == [[1, 0, 3], [1, 2, 3]] + ans = dict(nx.all_pairs_all_shortest_paths(nx.cycle_graph(4)), weight="weight") + assert sorted(ans[1][3]) == [[1, 0, 3], [1, 2, 3]] + ans = dict( + nx.all_pairs_all_shortest_paths(nx.cycle_graph(4)), + method="bellman-ford", + weight="weight", + ) + assert sorted(ans[1][3]) == [[1, 0, 3], [1, 2, 3]] + G = nx.cycle_graph(4) + G.add_node(4) + ans = dict(nx.all_pairs_all_shortest_paths(G)) + assert sorted(ans[4][4]) == [[4]] + + def test_has_path(self): + G = nx.Graph() + nx.add_path(G, range(3)) + nx.add_path(G, range(3, 5)) + assert nx.has_path(G, 0, 2) + assert not nx.has_path(G, 0, 4) + + def test_has_path_singleton(self): + G = nx.empty_graph(1) + assert nx.has_path(G, 0, 0) + + def test_all_shortest_paths(self): + G = nx.Graph() + nx.add_path(G, [0, 1, 2, 3]) + nx.add_path(G, [0, 10, 20, 3]) + assert [[0, 1, 2, 3], [0, 10, 20, 3]] == sorted(nx.all_shortest_paths(G, 0, 3)) + # with weights + G = nx.Graph() + nx.add_path(G, [0, 1, 2, 3]) + nx.add_path(G, [0, 10, 20, 3]) + assert [[0, 1, 2, 3], [0, 10, 20, 3]] == sorted( + nx.all_shortest_paths(G, 0, 3, weight="weight") + ) + # weights and method specified + G = nx.Graph() + nx.add_path(G, [0, 1, 2, 3]) + nx.add_path(G, [0, 10, 20, 3]) + assert [[0, 1, 2, 3], [0, 10, 20, 3]] == sorted( + nx.all_shortest_paths(G, 0, 3, weight="weight", method="dijkstra") + ) + G = nx.Graph() + nx.add_path(G, [0, 1, 2, 3]) + nx.add_path(G, [0, 10, 20, 3]) + assert [[0, 1, 2, 3], [0, 10, 20, 3]] == sorted( + nx.all_shortest_paths(G, 0, 3, weight="weight", method="bellman-ford") + ) + + def test_all_shortest_paths_raise(self): + with pytest.raises(nx.NetworkXNoPath): + G = nx.path_graph(4) + G.add_node(4) + list(nx.all_shortest_paths(G, 0, 4)) + + def test_bad_method(self): + with pytest.raises(ValueError): + G = nx.path_graph(2) + list(nx.all_shortest_paths(G, 0, 1, weight="weight", method="SPAM")) + + def test_single_source_all_shortest_paths_bad_method(self): + with pytest.raises(ValueError): + G = nx.path_graph(2) + dict( + nx.single_source_all_shortest_paths( + G, 0, weight="weight", method="SPAM" + ) + ) + + def test_all_shortest_paths_zero_weight_edge(self): + g = nx.Graph() + nx.add_path(g, [0, 1, 3]) + nx.add_path(g, [0, 1, 2, 3]) + g.edges[1, 2]["weight"] = 0 + paths30d = list( + nx.all_shortest_paths(g, 3, 0, weight="weight", method="dijkstra") + ) + paths03d = list( + nx.all_shortest_paths(g, 0, 3, weight="weight", method="dijkstra") + ) + paths30b = list( + nx.all_shortest_paths(g, 3, 0, weight="weight", method="bellman-ford") + ) + paths03b = list( + nx.all_shortest_paths(g, 0, 3, weight="weight", method="bellman-ford") + ) + assert sorted(paths03d) == sorted(p[::-1] for p in paths30d) + assert sorted(paths03d) == sorted(p[::-1] for p in paths30b) + assert sorted(paths03b) == sorted(p[::-1] for p in paths30b) + + +class TestAverageShortestPathLength: + def test_cycle_graph(self): + ans = nx.average_shortest_path_length(nx.cycle_graph(7)) + assert ans == pytest.approx(2, abs=1e-7) + + def test_path_graph(self): + ans = nx.average_shortest_path_length(nx.path_graph(5)) + assert ans == pytest.approx(2, abs=1e-7) + + def test_weighted(self): + G = nx.Graph() + nx.add_cycle(G, range(7), weight=2) + ans = nx.average_shortest_path_length(G, weight="weight") + assert ans == pytest.approx(4, abs=1e-7) + G = nx.Graph() + nx.add_path(G, range(5), weight=2) + ans = nx.average_shortest_path_length(G, weight="weight") + assert ans == pytest.approx(4, abs=1e-7) + + def test_specified_methods(self): + G = nx.Graph() + nx.add_cycle(G, range(7), weight=2) + ans = nx.average_shortest_path_length(G, weight="weight", method="dijkstra") + assert ans == pytest.approx(4, abs=1e-7) + ans = nx.average_shortest_path_length(G, weight="weight", method="bellman-ford") + assert ans == pytest.approx(4, abs=1e-7) + ans = nx.average_shortest_path_length( + G, weight="weight", method="floyd-warshall" + ) + assert ans == pytest.approx(4, abs=1e-7) + + G = nx.Graph() + nx.add_path(G, range(5), weight=2) + ans = nx.average_shortest_path_length(G, weight="weight", method="dijkstra") + assert ans == pytest.approx(4, abs=1e-7) + ans = nx.average_shortest_path_length(G, weight="weight", method="bellman-ford") + assert ans == pytest.approx(4, abs=1e-7) + ans = nx.average_shortest_path_length( + G, weight="weight", method="floyd-warshall" + ) + assert ans == pytest.approx(4, abs=1e-7) + + def test_directed_not_strongly_connected(self): + G = nx.DiGraph([(0, 1)]) + with pytest.raises(nx.NetworkXError, match="Graph is not strongly connected"): + nx.average_shortest_path_length(G) + + def test_undirected_not_connected(self): + g = nx.Graph() + g.add_nodes_from(range(3)) + g.add_edge(0, 1) + pytest.raises(nx.NetworkXError, nx.average_shortest_path_length, g) + + def test_trivial_graph(self): + """Tests that the trivial graph has average path length zero, + since there is exactly one path of length zero in the trivial + graph. + + For more information, see issue #1960. + + """ + G = nx.trivial_graph() + assert nx.average_shortest_path_length(G) == 0 + + def test_null_graph(self): + with pytest.raises(nx.NetworkXPointlessConcept): + nx.average_shortest_path_length(nx.null_graph()) + + def test_bad_method(self): + with pytest.raises(ValueError): + G = nx.path_graph(2) + nx.average_shortest_path_length(G, weight="weight", method="SPAM") + + +class TestAverageShortestPathLengthNumpy: + @classmethod + def setup_class(cls): + global np + import pytest + + np = pytest.importorskip("numpy") + + def test_specified_methods_numpy(self): + G = nx.Graph() + nx.add_cycle(G, range(7), weight=2) + ans = nx.average_shortest_path_length( + G, weight="weight", method="floyd-warshall-numpy" + ) + np.testing.assert_almost_equal(ans, 4) + + G = nx.Graph() + nx.add_path(G, range(5), weight=2) + ans = nx.average_shortest_path_length( + G, weight="weight", method="floyd-warshall-numpy" + ) + np.testing.assert_almost_equal(ans, 4) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..67ddfe4a54cab0ce062f0808ff103a0d5b49b977 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/beamsearch.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/beamsearch.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2707fbb613c3e99a6638f8a82a880db4b7dc530 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/beamsearch.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/breadth_first_search.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/breadth_first_search.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98427dfc622309bdca9eb6da61116b336885ea99 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/breadth_first_search.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/depth_first_search.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/depth_first_search.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d597c0670c651f7e82aefc55408bd13cd65cdaa9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/depth_first_search.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/edgebfs.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/edgebfs.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f3bf65e8984e19c0ab672f5c6a52121250d2d08 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/edgebfs.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/edgedfs.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/edgedfs.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..85307799f47aef90653e14c1327fb03e80524cd2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/__pycache__/edgedfs.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..413cf80cd7e4eeafbf84bb9fee6bc0eb9bbe3147 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/test_bfs.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/test_bfs.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0928ad8c02492630eac64c9782dde6a8afaf337c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/test_bfs.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/test_edgebfs.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/test_edgebfs.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..274a647a3e49a8182c8f2628e8da4c208545b433 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/test_edgebfs.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/test_edgedfs.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/test_edgedfs.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0b9a0a5d287c64e18d4b2452396142a19847376 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/__pycache__/test_edgedfs.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_beamsearch.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_beamsearch.py new file mode 100644 index 0000000000000000000000000000000000000000..049f116b62fb595977d5ed94d01b9c15baf17fb3 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_beamsearch.py @@ -0,0 +1,25 @@ +"""Unit tests for the beam search functions.""" + +import pytest + +import networkx as nx + + +def test_narrow(): + """Tests that a narrow beam width may cause an incomplete search.""" + # In this search, we enqueue only the neighbor 3 at the first + # step, then only the neighbor 2 at the second step. Once at + # node 2, the search chooses node 3, since it has a higher value + # than node 1, but node 3 has already been visited, so the + # search terminates. + G = nx.cycle_graph(4) + edges = nx.bfs_beam_edges(G, source=0, value=lambda n: n, width=1) + assert list(edges) == [(0, 3), (3, 2)] + + +@pytest.mark.parametrize("width", (2, None)) +def test_wide(width): + """All nodes are searched when `width` is None or >= max degree""" + G = nx.cycle_graph(4) + edges = nx.bfs_beam_edges(G, source=0, value=lambda n: n, width=width) + assert list(edges) == [(0, 3), (0, 1), (3, 2)] diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_bfs.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_bfs.py new file mode 100644 index 0000000000000000000000000000000000000000..7f4f37a31c4d6a780f084047b492ad52b8d04fae --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_bfs.py @@ -0,0 +1,203 @@ +from functools import partial + +import pytest + +import networkx as nx + + +class TestBFS: + @classmethod + def setup_class(cls): + # simple graph + G = nx.Graph() + G.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4)]) + cls.G = G + + def test_successor(self): + assert dict(nx.bfs_successors(self.G, source=0)) == {0: [1], 1: [2, 3], 2: [4]} + + def test_predecessor(self): + assert dict(nx.bfs_predecessors(self.G, source=0)) == {1: 0, 2: 1, 3: 1, 4: 2} + + def test_bfs_tree(self): + T = nx.bfs_tree(self.G, source=0) + assert sorted(T.nodes()) == sorted(self.G.nodes()) + assert sorted(T.edges()) == [(0, 1), (1, 2), (1, 3), (2, 4)] + + def test_bfs_edges(self): + edges = nx.bfs_edges(self.G, source=0) + assert list(edges) == [(0, 1), (1, 2), (1, 3), (2, 4)] + + def test_bfs_edges_reverse(self): + D = nx.DiGraph() + D.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4)]) + edges = nx.bfs_edges(D, source=4, reverse=True) + assert list(edges) == [(4, 2), (4, 3), (2, 1), (1, 0)] + + def test_bfs_edges_sorting(self): + D = nx.DiGraph() + D.add_edges_from([(0, 1), (0, 2), (1, 4), (1, 3), (2, 5)]) + sort_desc = partial(sorted, reverse=True) + edges_asc = nx.bfs_edges(D, source=0, sort_neighbors=sorted) + edges_desc = nx.bfs_edges(D, source=0, sort_neighbors=sort_desc) + assert list(edges_asc) == [(0, 1), (0, 2), (1, 3), (1, 4), (2, 5)] + assert list(edges_desc) == [(0, 2), (0, 1), (2, 5), (1, 4), (1, 3)] + + def test_bfs_tree_isolates(self): + G = nx.Graph() + G.add_node(1) + G.add_node(2) + T = nx.bfs_tree(G, source=1) + assert sorted(T.nodes()) == [1] + assert sorted(T.edges()) == [] + + def test_bfs_layers(self): + expected = { + 0: [0], + 1: [1], + 2: [2, 3], + 3: [4], + } + for sources in [0, [0], (i for i in [0]), [0, 0]]: + assert dict(enumerate(nx.bfs_layers(self.G, sources))) == expected + + def test_bfs_layers_missing_source(self): + with pytest.raises(nx.NetworkXError): + next(nx.bfs_layers(self.G, sources="abc")) + with pytest.raises(nx.NetworkXError): + next(nx.bfs_layers(self.G, sources=["abc"])) + + def test_descendants_at_distance(self): + for distance, descendants in enumerate([{0}, {1}, {2, 3}, {4}]): + assert nx.descendants_at_distance(self.G, 0, distance) == descendants + + def test_descendants_at_distance_missing_source(self): + with pytest.raises(nx.NetworkXError): + nx.descendants_at_distance(self.G, "abc", 0) + + def test_bfs_labeled_edges_directed(self): + D = nx.cycle_graph(5, create_using=nx.DiGraph) + expected = [ + (0, 1, "tree"), + (1, 2, "tree"), + (2, 3, "tree"), + (3, 4, "tree"), + (4, 0, "reverse"), + ] + answer = list(nx.bfs_labeled_edges(D, 0)) + assert expected == answer + + D.add_edge(4, 4) + expected.append((4, 4, "level")) + answer = list(nx.bfs_labeled_edges(D, 0)) + assert expected == answer + + D.add_edge(0, 2) + D.add_edge(1, 5) + D.add_edge(2, 5) + D.remove_edge(4, 4) + expected = [ + (0, 1, "tree"), + (0, 2, "tree"), + (1, 2, "level"), + (1, 5, "tree"), + (2, 3, "tree"), + (2, 5, "forward"), + (3, 4, "tree"), + (4, 0, "reverse"), + ] + answer = list(nx.bfs_labeled_edges(D, 0)) + assert expected == answer + + G = D.to_undirected() + G.add_edge(4, 4) + expected = [ + (0, 1, "tree"), + (0, 2, "tree"), + (0, 4, "tree"), + (1, 2, "level"), + (1, 5, "tree"), + (2, 3, "tree"), + (2, 5, "forward"), + (4, 3, "forward"), + (4, 4, "level"), + ] + answer = list(nx.bfs_labeled_edges(G, 0)) + assert expected == answer + + +class TestBreadthLimitedSearch: + @classmethod + def setup_class(cls): + # a tree + G = nx.Graph() + nx.add_path(G, [0, 1, 2, 3, 4, 5, 6]) + nx.add_path(G, [2, 7, 8, 9, 10]) + cls.G = G + # a disconnected graph + D = nx.Graph() + D.add_edges_from([(0, 1), (2, 3)]) + nx.add_path(D, [2, 7, 8, 9, 10]) + cls.D = D + + def test_limited_bfs_successor(self): + assert dict(nx.bfs_successors(self.G, source=1, depth_limit=3)) == { + 1: [0, 2], + 2: [3, 7], + 3: [4], + 7: [8], + } + result = { + n: sorted(s) for n, s in nx.bfs_successors(self.D, source=7, depth_limit=2) + } + assert result == {8: [9], 2: [3], 7: [2, 8]} + + def test_limited_bfs_predecessor(self): + assert dict(nx.bfs_predecessors(self.G, source=1, depth_limit=3)) == { + 0: 1, + 2: 1, + 3: 2, + 4: 3, + 7: 2, + 8: 7, + } + assert dict(nx.bfs_predecessors(self.D, source=7, depth_limit=2)) == { + 2: 7, + 3: 2, + 8: 7, + 9: 8, + } + + def test_limited_bfs_tree(self): + T = nx.bfs_tree(self.G, source=3, depth_limit=1) + assert sorted(T.edges()) == [(3, 2), (3, 4)] + + def test_limited_bfs_edges(self): + edges = nx.bfs_edges(self.G, source=9, depth_limit=4) + assert list(edges) == [(9, 8), (9, 10), (8, 7), (7, 2), (2, 1), (2, 3)] + + def test_limited_bfs_layers(self): + assert dict(enumerate(nx.bfs_layers(self.G, sources=[0]))) == { + 0: [0], + 1: [1], + 2: [2], + 3: [3, 7], + 4: [4, 8], + 5: [5, 9], + 6: [6, 10], + } + assert dict(enumerate(nx.bfs_layers(self.D, sources=2))) == { + 0: [2], + 1: [3, 7], + 2: [8], + 3: [9], + 4: [10], + } + + def test_limited_descendants_at_distance(self): + for distance, descendants in enumerate( + [{0}, {1}, {2}, {3, 7}, {4, 8}, {5, 9}, {6, 10}] + ): + assert nx.descendants_at_distance(self.G, 0, distance) == descendants + for distance, descendants in enumerate([{2}, {3, 7}, {8}, {9}, {10}]): + assert nx.descendants_at_distance(self.D, 2, distance) == descendants diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_dfs.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_dfs.py new file mode 100644 index 0000000000000000000000000000000000000000..292de05a083861d6cca44bbaa72ea422358d376e --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_dfs.py @@ -0,0 +1,307 @@ +import networkx as nx + + +class TestDFS: + @classmethod + def setup_class(cls): + # simple graph + G = nx.Graph() + G.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 4), (3, 0), (0, 4)]) + cls.G = G + # simple graph, disconnected + D = nx.Graph() + D.add_edges_from([(0, 1), (2, 3)]) + cls.D = D + + def test_preorder_nodes(self): + assert list(nx.dfs_preorder_nodes(self.G, source=0)) == [0, 1, 2, 4, 3] + assert list(nx.dfs_preorder_nodes(self.D)) == [0, 1, 2, 3] + assert list(nx.dfs_preorder_nodes(self.D, source=2)) == [2, 3] + + def test_postorder_nodes(self): + assert list(nx.dfs_postorder_nodes(self.G, source=0)) == [4, 2, 3, 1, 0] + assert list(nx.dfs_postorder_nodes(self.D)) == [1, 0, 3, 2] + assert list(nx.dfs_postorder_nodes(self.D, source=0)) == [1, 0] + + def test_successor(self): + assert nx.dfs_successors(self.G, source=0) == {0: [1], 1: [2, 3], 2: [4]} + assert nx.dfs_successors(self.G, source=1) == {0: [3, 4], 1: [0], 4: [2]} + assert nx.dfs_successors(self.D) == {0: [1], 2: [3]} + assert nx.dfs_successors(self.D, source=1) == {1: [0]} + + def test_predecessor(self): + assert nx.dfs_predecessors(self.G, source=0) == {1: 0, 2: 1, 3: 1, 4: 2} + assert nx.dfs_predecessors(self.D) == {1: 0, 3: 2} + + def test_dfs_tree(self): + exp_nodes = sorted(self.G.nodes()) + exp_edges = [(0, 1), (1, 2), (1, 3), (2, 4)] + # Search from first node + T = nx.dfs_tree(self.G, source=0) + assert sorted(T.nodes()) == exp_nodes + assert sorted(T.edges()) == exp_edges + # Check source=None + T = nx.dfs_tree(self.G, source=None) + assert sorted(T.nodes()) == exp_nodes + assert sorted(T.edges()) == exp_edges + # Check source=None is the default + T = nx.dfs_tree(self.G) + assert sorted(T.nodes()) == exp_nodes + assert sorted(T.edges()) == exp_edges + + def test_dfs_edges(self): + edges = nx.dfs_edges(self.G, source=0) + assert list(edges) == [(0, 1), (1, 2), (2, 4), (1, 3)] + edges = nx.dfs_edges(self.D) + assert list(edges) == [(0, 1), (2, 3)] + + def test_dfs_edges_sorting(self): + G = nx.Graph([(0, 1), (1, 2), (1, 3), (2, 4), (3, 0), (0, 4)]) + edges_asc = nx.dfs_edges(G, source=0, sort_neighbors=sorted) + edges_desc = nx.dfs_edges( + G, source=0, sort_neighbors=lambda x: sorted(x, reverse=True) + ) + assert list(edges_asc) == [(0, 1), (1, 2), (2, 4), (1, 3)] + assert list(edges_desc) == [(0, 4), (4, 2), (2, 1), (1, 3)] + + def test_dfs_labeled_edges(self): + edges = list(nx.dfs_labeled_edges(self.G, source=0)) + forward = [(u, v) for (u, v, d) in edges if d == "forward"] + assert forward == [(0, 0), (0, 1), (1, 2), (2, 4), (1, 3)] + assert edges == [ + (0, 0, "forward"), + (0, 1, "forward"), + (1, 0, "nontree"), + (1, 2, "forward"), + (2, 1, "nontree"), + (2, 4, "forward"), + (4, 2, "nontree"), + (4, 0, "nontree"), + (2, 4, "reverse"), + (1, 2, "reverse"), + (1, 3, "forward"), + (3, 1, "nontree"), + (3, 0, "nontree"), + (1, 3, "reverse"), + (0, 1, "reverse"), + (0, 3, "nontree"), + (0, 4, "nontree"), + (0, 0, "reverse"), + ] + + def test_dfs_labeled_edges_sorting(self): + G = nx.Graph([(0, 1), (1, 2), (1, 3), (2, 4), (3, 0), (0, 4)]) + edges_asc = nx.dfs_labeled_edges(G, source=0, sort_neighbors=sorted) + edges_desc = nx.dfs_labeled_edges( + G, source=0, sort_neighbors=lambda x: sorted(x, reverse=True) + ) + assert list(edges_asc) == [ + (0, 0, "forward"), + (0, 1, "forward"), + (1, 0, "nontree"), + (1, 2, "forward"), + (2, 1, "nontree"), + (2, 4, "forward"), + (4, 0, "nontree"), + (4, 2, "nontree"), + (2, 4, "reverse"), + (1, 2, "reverse"), + (1, 3, "forward"), + (3, 0, "nontree"), + (3, 1, "nontree"), + (1, 3, "reverse"), + (0, 1, "reverse"), + (0, 3, "nontree"), + (0, 4, "nontree"), + (0, 0, "reverse"), + ] + assert list(edges_desc) == [ + (0, 0, "forward"), + (0, 4, "forward"), + (4, 2, "forward"), + (2, 4, "nontree"), + (2, 1, "forward"), + (1, 3, "forward"), + (3, 1, "nontree"), + (3, 0, "nontree"), + (1, 3, "reverse"), + (1, 2, "nontree"), + (1, 0, "nontree"), + (2, 1, "reverse"), + (4, 2, "reverse"), + (4, 0, "nontree"), + (0, 4, "reverse"), + (0, 3, "nontree"), + (0, 1, "nontree"), + (0, 0, "reverse"), + ] + + def test_dfs_labeled_disconnected_edges(self): + edges = list(nx.dfs_labeled_edges(self.D)) + forward = [(u, v) for (u, v, d) in edges if d == "forward"] + assert forward == [(0, 0), (0, 1), (2, 2), (2, 3)] + assert edges == [ + (0, 0, "forward"), + (0, 1, "forward"), + (1, 0, "nontree"), + (0, 1, "reverse"), + (0, 0, "reverse"), + (2, 2, "forward"), + (2, 3, "forward"), + (3, 2, "nontree"), + (2, 3, "reverse"), + (2, 2, "reverse"), + ] + + def test_dfs_tree_isolates(self): + G = nx.Graph() + G.add_node(1) + G.add_node(2) + T = nx.dfs_tree(G, source=1) + assert sorted(T.nodes()) == [1] + assert sorted(T.edges()) == [] + T = nx.dfs_tree(G, source=None) + assert sorted(T.nodes()) == [1, 2] + assert sorted(T.edges()) == [] + + +class TestDepthLimitedSearch: + @classmethod + def setup_class(cls): + # a tree + G = nx.Graph() + nx.add_path(G, [0, 1, 2, 3, 4, 5, 6]) + nx.add_path(G, [2, 7, 8, 9, 10]) + cls.G = G + # a disconnected graph + D = nx.Graph() + D.add_edges_from([(0, 1), (2, 3)]) + nx.add_path(D, [2, 7, 8, 9, 10]) + cls.D = D + + def test_dls_preorder_nodes(self): + assert list(nx.dfs_preorder_nodes(self.G, source=0, depth_limit=2)) == [0, 1, 2] + assert list(nx.dfs_preorder_nodes(self.D, source=1, depth_limit=2)) == ([1, 0]) + + def test_dls_postorder_nodes(self): + assert list(nx.dfs_postorder_nodes(self.G, source=3, depth_limit=3)) == [ + 1, + 7, + 2, + 5, + 4, + 3, + ] + assert list(nx.dfs_postorder_nodes(self.D, source=2, depth_limit=2)) == ( + [3, 7, 2] + ) + + def test_dls_successor(self): + result = nx.dfs_successors(self.G, source=4, depth_limit=3) + assert {n: set(v) for n, v in result.items()} == { + 2: {1, 7}, + 3: {2}, + 4: {3, 5}, + 5: {6}, + } + result = nx.dfs_successors(self.D, source=7, depth_limit=2) + assert {n: set(v) for n, v in result.items()} == {8: {9}, 2: {3}, 7: {8, 2}} + + def test_dls_predecessor(self): + assert nx.dfs_predecessors(self.G, source=0, depth_limit=3) == { + 1: 0, + 2: 1, + 3: 2, + 7: 2, + } + assert nx.dfs_predecessors(self.D, source=2, depth_limit=3) == { + 8: 7, + 9: 8, + 3: 2, + 7: 2, + } + + def test_dls_tree(self): + T = nx.dfs_tree(self.G, source=3, depth_limit=1) + assert sorted(T.edges()) == [(3, 2), (3, 4)] + + def test_dls_edges(self): + edges = nx.dfs_edges(self.G, source=9, depth_limit=4) + assert list(edges) == [(9, 8), (8, 7), (7, 2), (2, 1), (2, 3), (9, 10)] + + def test_dls_labeled_edges_depth_1(self): + edges = list(nx.dfs_labeled_edges(self.G, source=5, depth_limit=1)) + forward = [(u, v) for (u, v, d) in edges if d == "forward"] + assert forward == [(5, 5), (5, 4), (5, 6)] + # Note: reverse-depth_limit edge types were not reported before gh-6240 + assert edges == [ + (5, 5, "forward"), + (5, 4, "forward"), + (5, 4, "reverse-depth_limit"), + (5, 6, "forward"), + (5, 6, "reverse-depth_limit"), + (5, 5, "reverse"), + ] + + def test_dls_labeled_edges_depth_2(self): + edges = list(nx.dfs_labeled_edges(self.G, source=6, depth_limit=2)) + forward = [(u, v) for (u, v, d) in edges if d == "forward"] + assert forward == [(6, 6), (6, 5), (5, 4)] + assert edges == [ + (6, 6, "forward"), + (6, 5, "forward"), + (5, 4, "forward"), + (5, 4, "reverse-depth_limit"), + (5, 6, "nontree"), + (6, 5, "reverse"), + (6, 6, "reverse"), + ] + + def test_dls_labeled_disconnected_edges(self): + edges = list(nx.dfs_labeled_edges(self.D, depth_limit=1)) + assert edges == [ + (0, 0, "forward"), + (0, 1, "forward"), + (0, 1, "reverse-depth_limit"), + (0, 0, "reverse"), + (2, 2, "forward"), + (2, 3, "forward"), + (2, 3, "reverse-depth_limit"), + (2, 7, "forward"), + (2, 7, "reverse-depth_limit"), + (2, 2, "reverse"), + (8, 8, "forward"), + (8, 7, "nontree"), + (8, 9, "forward"), + (8, 9, "reverse-depth_limit"), + (8, 8, "reverse"), + (10, 10, "forward"), + (10, 9, "nontree"), + (10, 10, "reverse"), + ] + # large depth_limit has no impact + edges = list(nx.dfs_labeled_edges(self.D, depth_limit=19)) + assert edges == [ + (0, 0, "forward"), + (0, 1, "forward"), + (1, 0, "nontree"), + (0, 1, "reverse"), + (0, 0, "reverse"), + (2, 2, "forward"), + (2, 3, "forward"), + (3, 2, "nontree"), + (2, 3, "reverse"), + (2, 7, "forward"), + (7, 2, "nontree"), + (7, 8, "forward"), + (8, 7, "nontree"), + (8, 9, "forward"), + (9, 8, "nontree"), + (9, 10, "forward"), + (10, 9, "nontree"), + (9, 10, "reverse"), + (8, 9, "reverse"), + (7, 8, "reverse"), + (2, 7, "reverse"), + (2, 2, "reverse"), + ] diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_edgebfs.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_edgebfs.py new file mode 100644 index 0000000000000000000000000000000000000000..1bf3fae0bd067dd548281e3382a6125f6e50ee22 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_edgebfs.py @@ -0,0 +1,147 @@ +import pytest + +import networkx as nx +from networkx.algorithms.traversal.edgedfs import FORWARD, REVERSE + + +class TestEdgeBFS: + @classmethod + def setup_class(cls): + cls.nodes = [0, 1, 2, 3] + cls.edges = [(0, 1), (1, 0), (1, 0), (2, 0), (2, 1), (3, 1)] + + def test_empty(self): + G = nx.Graph() + edges = list(nx.edge_bfs(G)) + assert edges == [] + + def test_graph_single_source(self): + G = nx.Graph(self.edges) + G.add_edge(4, 5) + x = list(nx.edge_bfs(G, [0])) + x_ = [(0, 1), (0, 2), (1, 2), (1, 3)] + assert x == x_ + + def test_graph(self): + G = nx.Graph(self.edges) + x = list(nx.edge_bfs(G, self.nodes)) + x_ = [(0, 1), (0, 2), (1, 2), (1, 3)] + assert x == x_ + + def test_digraph(self): + G = nx.DiGraph(self.edges) + x = list(nx.edge_bfs(G, self.nodes)) + x_ = [(0, 1), (1, 0), (2, 0), (2, 1), (3, 1)] + assert x == x_ + + def test_digraph_orientation_invalid(self): + G = nx.DiGraph(self.edges) + edge_iterator = nx.edge_bfs(G, self.nodes, orientation="hello") + pytest.raises(nx.NetworkXError, list, edge_iterator) + + def test_digraph_orientation_none(self): + G = nx.DiGraph(self.edges) + x = list(nx.edge_bfs(G, self.nodes, orientation=None)) + x_ = [(0, 1), (1, 0), (2, 0), (2, 1), (3, 1)] + assert x == x_ + + def test_digraph_orientation_original(self): + G = nx.DiGraph(self.edges) + x = list(nx.edge_bfs(G, self.nodes, orientation="original")) + x_ = [ + (0, 1, FORWARD), + (1, 0, FORWARD), + (2, 0, FORWARD), + (2, 1, FORWARD), + (3, 1, FORWARD), + ] + assert x == x_ + + def test_digraph2(self): + G = nx.DiGraph() + nx.add_path(G, range(4)) + x = list(nx.edge_bfs(G, [0])) + x_ = [(0, 1), (1, 2), (2, 3)] + assert x == x_ + + def test_digraph_rev(self): + G = nx.DiGraph(self.edges) + x = list(nx.edge_bfs(G, self.nodes, orientation="reverse")) + x_ = [ + (1, 0, REVERSE), + (2, 0, REVERSE), + (0, 1, REVERSE), + (2, 1, REVERSE), + (3, 1, REVERSE), + ] + assert x == x_ + + def test_digraph_rev2(self): + G = nx.DiGraph() + nx.add_path(G, range(4)) + x = list(nx.edge_bfs(G, [3], orientation="reverse")) + x_ = [(2, 3, REVERSE), (1, 2, REVERSE), (0, 1, REVERSE)] + assert x == x_ + + def test_multigraph(self): + G = nx.MultiGraph(self.edges) + x = list(nx.edge_bfs(G, self.nodes)) + x_ = [(0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 2, 0), (1, 2, 0), (1, 3, 0)] + # This is an example of where hash randomization can break. + # There are 3! * 2 alternative outputs, such as: + # [(0, 1, 1), (1, 0, 0), (0, 1, 2), (1, 3, 0), (1, 2, 0)] + # But note, the edges (1,2,0) and (1,3,0) always follow the (0,1,k) + # edges. So the algorithm only guarantees a partial order. A total + # order is guaranteed only if the graph data structures are ordered. + assert x == x_ + + def test_multidigraph(self): + G = nx.MultiDiGraph(self.edges) + x = list(nx.edge_bfs(G, self.nodes)) + x_ = [(0, 1, 0), (1, 0, 0), (1, 0, 1), (2, 0, 0), (2, 1, 0), (3, 1, 0)] + assert x == x_ + + def test_multidigraph_rev(self): + G = nx.MultiDiGraph(self.edges) + x = list(nx.edge_bfs(G, self.nodes, orientation="reverse")) + x_ = [ + (1, 0, 0, REVERSE), + (1, 0, 1, REVERSE), + (2, 0, 0, REVERSE), + (0, 1, 0, REVERSE), + (2, 1, 0, REVERSE), + (3, 1, 0, REVERSE), + ] + assert x == x_ + + def test_digraph_ignore(self): + G = nx.DiGraph(self.edges) + x = list(nx.edge_bfs(G, self.nodes, orientation="ignore")) + x_ = [ + (0, 1, FORWARD), + (1, 0, REVERSE), + (2, 0, REVERSE), + (2, 1, REVERSE), + (3, 1, REVERSE), + ] + assert x == x_ + + def test_digraph_ignore2(self): + G = nx.DiGraph() + nx.add_path(G, range(4)) + x = list(nx.edge_bfs(G, [0], orientation="ignore")) + x_ = [(0, 1, FORWARD), (1, 2, FORWARD), (2, 3, FORWARD)] + assert x == x_ + + def test_multidigraph_ignore(self): + G = nx.MultiDiGraph(self.edges) + x = list(nx.edge_bfs(G, self.nodes, orientation="ignore")) + x_ = [ + (0, 1, 0, FORWARD), + (1, 0, 0, REVERSE), + (1, 0, 1, REVERSE), + (2, 0, 0, REVERSE), + (2, 1, 0, REVERSE), + (3, 1, 0, REVERSE), + ] + assert x == x_ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_edgedfs.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_edgedfs.py new file mode 100644 index 0000000000000000000000000000000000000000..7c1967cce04b3a0c9db80f9af39d7b1dfd8ef4cb --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/algorithms/traversal/tests/test_edgedfs.py @@ -0,0 +1,131 @@ +import pytest + +import networkx as nx +from networkx.algorithms import edge_dfs +from networkx.algorithms.traversal.edgedfs import FORWARD, REVERSE + +# These tests can fail with hash randomization. The easiest and clearest way +# to write these unit tests is for the edges to be output in an expected total +# order, but we cannot guarantee the order amongst outgoing edges from a node, +# unless each class uses an ordered data structure for neighbors. This is +# painful to do with the current API. The alternative is that the tests are +# written (IMO confusingly) so that there is not a total order over the edges, +# but only a partial order. Due to the small size of the graphs, hopefully +# failures due to hash randomization will not occur. For an example of how +# this can fail, see TestEdgeDFS.test_multigraph. + + +class TestEdgeDFS: + @classmethod + def setup_class(cls): + cls.nodes = [0, 1, 2, 3] + cls.edges = [(0, 1), (1, 0), (1, 0), (2, 1), (3, 1)] + + def test_empty(self): + G = nx.Graph() + edges = list(edge_dfs(G)) + assert edges == [] + + def test_graph(self): + G = nx.Graph(self.edges) + x = list(edge_dfs(G, self.nodes)) + x_ = [(0, 1), (1, 2), (1, 3)] + assert x == x_ + + def test_digraph(self): + G = nx.DiGraph(self.edges) + x = list(edge_dfs(G, self.nodes)) + x_ = [(0, 1), (1, 0), (2, 1), (3, 1)] + assert x == x_ + + def test_digraph_orientation_invalid(self): + G = nx.DiGraph(self.edges) + edge_iterator = edge_dfs(G, self.nodes, orientation="hello") + pytest.raises(nx.NetworkXError, list, edge_iterator) + + def test_digraph_orientation_none(self): + G = nx.DiGraph(self.edges) + x = list(edge_dfs(G, self.nodes, orientation=None)) + x_ = [(0, 1), (1, 0), (2, 1), (3, 1)] + assert x == x_ + + def test_digraph_orientation_original(self): + G = nx.DiGraph(self.edges) + x = list(edge_dfs(G, self.nodes, orientation="original")) + x_ = [(0, 1, FORWARD), (1, 0, FORWARD), (2, 1, FORWARD), (3, 1, FORWARD)] + assert x == x_ + + def test_digraph2(self): + G = nx.DiGraph() + nx.add_path(G, range(4)) + x = list(edge_dfs(G, [0])) + x_ = [(0, 1), (1, 2), (2, 3)] + assert x == x_ + + def test_digraph_rev(self): + G = nx.DiGraph(self.edges) + x = list(edge_dfs(G, self.nodes, orientation="reverse")) + x_ = [(1, 0, REVERSE), (0, 1, REVERSE), (2, 1, REVERSE), (3, 1, REVERSE)] + assert x == x_ + + def test_digraph_rev2(self): + G = nx.DiGraph() + nx.add_path(G, range(4)) + x = list(edge_dfs(G, [3], orientation="reverse")) + x_ = [(2, 3, REVERSE), (1, 2, REVERSE), (0, 1, REVERSE)] + assert x == x_ + + def test_multigraph(self): + G = nx.MultiGraph(self.edges) + x = list(edge_dfs(G, self.nodes)) + x_ = [(0, 1, 0), (1, 0, 1), (0, 1, 2), (1, 2, 0), (1, 3, 0)] + # This is an example of where hash randomization can break. + # There are 3! * 2 alternative outputs, such as: + # [(0, 1, 1), (1, 0, 0), (0, 1, 2), (1, 3, 0), (1, 2, 0)] + # But note, the edges (1,2,0) and (1,3,0) always follow the (0,1,k) + # edges. So the algorithm only guarantees a partial order. A total + # order is guaranteed only if the graph data structures are ordered. + assert x == x_ + + def test_multidigraph(self): + G = nx.MultiDiGraph(self.edges) + x = list(edge_dfs(G, self.nodes)) + x_ = [(0, 1, 0), (1, 0, 0), (1, 0, 1), (2, 1, 0), (3, 1, 0)] + assert x == x_ + + def test_multidigraph_rev(self): + G = nx.MultiDiGraph(self.edges) + x = list(edge_dfs(G, self.nodes, orientation="reverse")) + x_ = [ + (1, 0, 0, REVERSE), + (0, 1, 0, REVERSE), + (1, 0, 1, REVERSE), + (2, 1, 0, REVERSE), + (3, 1, 0, REVERSE), + ] + assert x == x_ + + def test_digraph_ignore(self): + G = nx.DiGraph(self.edges) + x = list(edge_dfs(G, self.nodes, orientation="ignore")) + x_ = [(0, 1, FORWARD), (1, 0, FORWARD), (2, 1, REVERSE), (3, 1, REVERSE)] + assert x == x_ + + def test_digraph_ignore2(self): + G = nx.DiGraph() + nx.add_path(G, range(4)) + x = list(edge_dfs(G, [0], orientation="ignore")) + x_ = [(0, 1, FORWARD), (1, 2, FORWARD), (2, 3, FORWARD)] + assert x == x_ + + def test_multidigraph_ignore(self): + G = nx.MultiDiGraph(self.edges) + x = list(edge_dfs(G, self.nodes, orientation="ignore")) + x_ = [ + (0, 1, 0, FORWARD), + (1, 0, 0, FORWARD), + (1, 0, 1, REVERSE), + (2, 1, 0, REVERSE), + (3, 1, 0, REVERSE), + ] + assert x == x_ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..721fa8b4767233bc2b624f6b2ce4d10533a4d66c --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/__init__.py @@ -0,0 +1,13 @@ +from .graph import Graph +from .digraph import DiGraph +from .multigraph import MultiGraph +from .multidigraph import MultiDiGraph + +from .function import * +from .graphviews import subgraph_view, reverse_view + +from networkx.classes import filters + +from networkx.classes import coreviews +from networkx.classes import graphviews +from networkx.classes import reportviews diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/coreviews.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/coreviews.py new file mode 100644 index 0000000000000000000000000000000000000000..4769ffa71ab823c154e6f7b990f0cb07299090a6 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/coreviews.py @@ -0,0 +1,435 @@ +"""Views of core data structures such as nested Mappings (e.g. dict-of-dicts). +These ``Views`` often restrict element access, with either the entire view or +layers of nested mappings being read-only. +""" + +from collections.abc import Mapping + +__all__ = [ + "AtlasView", + "AdjacencyView", + "MultiAdjacencyView", + "UnionAtlas", + "UnionAdjacency", + "UnionMultiInner", + "UnionMultiAdjacency", + "FilterAtlas", + "FilterAdjacency", + "FilterMultiInner", + "FilterMultiAdjacency", +] + + +class AtlasView(Mapping): + """An AtlasView is a Read-only Mapping of Mappings. + + It is a View into a dict-of-dict data structure. + The inner level of dict is read-write. But the + outer level is read-only. + + See Also + ======== + AdjacencyView: View into dict-of-dict-of-dict + MultiAdjacencyView: View into dict-of-dict-of-dict-of-dict + """ + + __slots__ = ("_atlas",) + + def __getstate__(self): + return {"_atlas": self._atlas} + + def __setstate__(self, state): + self._atlas = state["_atlas"] + + def __init__(self, d): + self._atlas = d + + def __len__(self): + return len(self._atlas) + + def __iter__(self): + return iter(self._atlas) + + def __getitem__(self, key): + return self._atlas[key] + + def copy(self): + return {n: self[n].copy() for n in self._atlas} + + def __str__(self): + return str(self._atlas) # {nbr: self[nbr] for nbr in self}) + + def __repr__(self): + return f"{self.__class__.__name__}({self._atlas!r})" + + +class AdjacencyView(AtlasView): + """An AdjacencyView is a Read-only Map of Maps of Maps. + + It is a View into a dict-of-dict-of-dict data structure. + The inner level of dict is read-write. But the + outer levels are read-only. + + See Also + ======== + AtlasView: View into dict-of-dict + MultiAdjacencyView: View into dict-of-dict-of-dict-of-dict + """ + + __slots__ = () # Still uses AtlasView slots names _atlas + + def __getitem__(self, name): + return AtlasView(self._atlas[name]) + + def copy(self): + return {n: self[n].copy() for n in self._atlas} + + +class MultiAdjacencyView(AdjacencyView): + """An MultiAdjacencyView is a Read-only Map of Maps of Maps of Maps. + + It is a View into a dict-of-dict-of-dict-of-dict data structure. + The inner level of dict is read-write. But the + outer levels are read-only. + + See Also + ======== + AtlasView: View into dict-of-dict + AdjacencyView: View into dict-of-dict-of-dict + """ + + __slots__ = () # Still uses AtlasView slots names _atlas + + def __getitem__(self, name): + return AdjacencyView(self._atlas[name]) + + def copy(self): + return {n: self[n].copy() for n in self._atlas} + + +class UnionAtlas(Mapping): + """A read-only union of two atlases (dict-of-dict). + + The two dict-of-dicts represent the inner dict of + an Adjacency: `G.succ[node]` and `G.pred[node]`. + The inner level of dict of both hold attribute key:value + pairs and is read-write. But the outer level is read-only. + + See Also + ======== + UnionAdjacency: View into dict-of-dict-of-dict + UnionMultiAdjacency: View into dict-of-dict-of-dict-of-dict + """ + + __slots__ = ("_succ", "_pred") + + def __getstate__(self): + return {"_succ": self._succ, "_pred": self._pred} + + def __setstate__(self, state): + self._succ = state["_succ"] + self._pred = state["_pred"] + + def __init__(self, succ, pred): + self._succ = succ + self._pred = pred + + def __len__(self): + return len(self._succ.keys() | self._pred.keys()) + + def __iter__(self): + return iter(set(self._succ.keys()) | set(self._pred.keys())) + + def __getitem__(self, key): + try: + return self._succ[key] + except KeyError: + return self._pred[key] + + def copy(self): + result = {nbr: dd.copy() for nbr, dd in self._succ.items()} + for nbr, dd in self._pred.items(): + if nbr in result: + result[nbr].update(dd) + else: + result[nbr] = dd.copy() + return result + + def __str__(self): + return str({nbr: self[nbr] for nbr in self}) + + def __repr__(self): + return f"{self.__class__.__name__}({self._succ!r}, {self._pred!r})" + + +class UnionAdjacency(Mapping): + """A read-only union of dict Adjacencies as a Map of Maps of Maps. + + The two input dict-of-dict-of-dicts represent the union of + `G.succ` and `G.pred`. Return values are UnionAtlas + The inner level of dict is read-write. But the + middle and outer levels are read-only. + + succ : a dict-of-dict-of-dict {node: nbrdict} + pred : a dict-of-dict-of-dict {node: nbrdict} + The keys for the two dicts should be the same + + See Also + ======== + UnionAtlas: View into dict-of-dict + UnionMultiAdjacency: View into dict-of-dict-of-dict-of-dict + """ + + __slots__ = ("_succ", "_pred") + + def __getstate__(self): + return {"_succ": self._succ, "_pred": self._pred} + + def __setstate__(self, state): + self._succ = state["_succ"] + self._pred = state["_pred"] + + def __init__(self, succ, pred): + # keys must be the same for two input dicts + assert len(set(succ.keys()) ^ set(pred.keys())) == 0 + self._succ = succ + self._pred = pred + + def __len__(self): + return len(self._succ) # length of each dict should be the same + + def __iter__(self): + return iter(self._succ) + + def __getitem__(self, nbr): + return UnionAtlas(self._succ[nbr], self._pred[nbr]) + + def copy(self): + return {n: self[n].copy() for n in self._succ} + + def __str__(self): + return str({nbr: self[nbr] for nbr in self}) + + def __repr__(self): + return f"{self.__class__.__name__}({self._succ!r}, {self._pred!r})" + + +class UnionMultiInner(UnionAtlas): + """A read-only union of two inner dicts of MultiAdjacencies. + + The two input dict-of-dict-of-dicts represent the union of + `G.succ[node]` and `G.pred[node]` for MultiDiGraphs. + Return values are UnionAtlas. + The inner level of dict is read-write. But the outer levels are read-only. + + See Also + ======== + UnionAtlas: View into dict-of-dict + UnionAdjacency: View into dict-of-dict-of-dict + UnionMultiAdjacency: View into dict-of-dict-of-dict-of-dict + """ + + __slots__ = () # Still uses UnionAtlas slots names _succ, _pred + + def __getitem__(self, node): + in_succ = node in self._succ + in_pred = node in self._pred + if in_succ: + if in_pred: + return UnionAtlas(self._succ[node], self._pred[node]) + return UnionAtlas(self._succ[node], {}) + return UnionAtlas({}, self._pred[node]) + + def copy(self): + nodes = set(self._succ.keys()) | set(self._pred.keys()) + return {n: self[n].copy() for n in nodes} + + +class UnionMultiAdjacency(UnionAdjacency): + """A read-only union of two dict MultiAdjacencies. + + The two input dict-of-dict-of-dict-of-dicts represent the union of + `G.succ` and `G.pred` for MultiDiGraphs. Return values are UnionAdjacency. + The inner level of dict is read-write. But the outer levels are read-only. + + See Also + ======== + UnionAtlas: View into dict-of-dict + UnionMultiInner: View into dict-of-dict-of-dict + """ + + __slots__ = () # Still uses UnionAdjacency slots names _succ, _pred + + def __getitem__(self, node): + return UnionMultiInner(self._succ[node], self._pred[node]) + + +class FilterAtlas(Mapping): # nodedict, nbrdict, keydict + """A read-only Mapping of Mappings with filtering criteria for nodes. + + It is a view into a dict-of-dict data structure, and it selects only + nodes that meet the criteria defined by ``NODE_OK``. + + See Also + ======== + FilterAdjacency + FilterMultiInner + FilterMultiAdjacency + """ + + def __init__(self, d, NODE_OK): + self._atlas = d + self.NODE_OK = NODE_OK + + def __len__(self): + # check whether NODE_OK stores the number of nodes as `length` + # or the nodes themselves as a set `nodes`. If not, count the nodes. + if hasattr(self.NODE_OK, "length"): + return self.NODE_OK.length + if hasattr(self.NODE_OK, "nodes"): + return len(self.NODE_OK.nodes & self._atlas.keys()) + return sum(1 for n in self._atlas if self.NODE_OK(n)) + + def __iter__(self): + try: # check that NODE_OK has attr 'nodes' + node_ok_shorter = 2 * len(self.NODE_OK.nodes) < len(self._atlas) + except AttributeError: + node_ok_shorter = False + if node_ok_shorter: + return (n for n in self.NODE_OK.nodes if n in self._atlas) + return (n for n in self._atlas if self.NODE_OK(n)) + + def __getitem__(self, key): + if key in self._atlas and self.NODE_OK(key): + return self._atlas[key] + raise KeyError(f"Key {key} not found") + + def __str__(self): + return str({nbr: self[nbr] for nbr in self}) + + def __repr__(self): + return f"{self.__class__.__name__}({self._atlas!r}, {self.NODE_OK!r})" + + +class FilterAdjacency(Mapping): # edgedict + """A read-only Mapping of Mappings with filtering criteria for nodes and edges. + + It is a view into a dict-of-dict-of-dict data structure, and it selects nodes + and edges that satisfy specific criteria defined by ``NODE_OK`` and ``EDGE_OK``, + respectively. + + See Also + ======== + FilterAtlas + FilterMultiInner + FilterMultiAdjacency + """ + + def __init__(self, d, NODE_OK, EDGE_OK): + self._atlas = d + self.NODE_OK = NODE_OK + self.EDGE_OK = EDGE_OK + + def __len__(self): + # check whether NODE_OK stores the number of nodes as `length` + # or the nodes themselves as a set `nodes`. If not, count the nodes. + if hasattr(self.NODE_OK, "length"): + return self.NODE_OK.length + if hasattr(self.NODE_OK, "nodes"): + return len(self.NODE_OK.nodes & self._atlas.keys()) + return sum(1 for n in self._atlas if self.NODE_OK(n)) + + def __iter__(self): + try: # check that NODE_OK has attr 'nodes' + node_ok_shorter = 2 * len(self.NODE_OK.nodes) < len(self._atlas) + except AttributeError: + node_ok_shorter = False + if node_ok_shorter: + return (n for n in self.NODE_OK.nodes if n in self._atlas) + return (n for n in self._atlas if self.NODE_OK(n)) + + def __getitem__(self, node): + if node in self._atlas and self.NODE_OK(node): + + def new_node_ok(nbr): + return self.NODE_OK(nbr) and self.EDGE_OK(node, nbr) + + return FilterAtlas(self._atlas[node], new_node_ok) + raise KeyError(f"Key {node} not found") + + def __str__(self): + return str({nbr: self[nbr] for nbr in self}) + + def __repr__(self): + name = self.__class__.__name__ + return f"{name}({self._atlas!r}, {self.NODE_OK!r}, {self.EDGE_OK!r})" + + +class FilterMultiInner(FilterAdjacency): # muliedge_seconddict + """A read-only Mapping of Mappings with filtering criteria for nodes and edges. + + It is a view into a dict-of-dict-of-dict-of-dict data structure, and it selects nodes + and edges that meet specific criteria defined by ``NODE_OK`` and ``EDGE_OK``. + + See Also + ======== + FilterAtlas + FilterAdjacency + FilterMultiAdjacency + """ + + def __iter__(self): + try: # check that NODE_OK has attr 'nodes' + node_ok_shorter = 2 * len(self.NODE_OK.nodes) < len(self._atlas) + except AttributeError: + node_ok_shorter = False + if node_ok_shorter: + my_nodes = (n for n in self.NODE_OK.nodes if n in self._atlas) + else: + my_nodes = (n for n in self._atlas if self.NODE_OK(n)) + for n in my_nodes: + some_keys_ok = False + for key in self._atlas[n]: + if self.EDGE_OK(n, key): + some_keys_ok = True + break + if some_keys_ok is True: + yield n + + def __getitem__(self, nbr): + if ( + nbr in self._atlas + and self.NODE_OK(nbr) + and any(self.EDGE_OK(nbr, key) for key in self._atlas[nbr]) + ): + + def new_node_ok(key): + return self.EDGE_OK(nbr, key) + + return FilterAtlas(self._atlas[nbr], new_node_ok) + raise KeyError(f"Key {nbr} not found") + + +class FilterMultiAdjacency(FilterAdjacency): # multiedgedict + """A read-only Mapping of Mappings with filtering criteria + for nodes and edges. + + It is a view into a dict-of-dict-of-dict-of-dict data structure, + and it selects nodes and edges that satisfy specific criteria + defined by ``NODE_OK`` and ``EDGE_OK``, respectively. + + See Also + ======== + FilterAtlas + FilterAdjacency + FilterMultiInner + """ + + def __getitem__(self, node): + if node in self._atlas and self.NODE_OK(node): + + def edge_ok(nbr, key): + return self.NODE_OK(nbr) and self.EDGE_OK(node, nbr, key) + + return FilterMultiInner(self._atlas[node], self.NODE_OK, edge_ok) + raise KeyError(f"Key {node} not found") diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/digraph.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/digraph.py new file mode 100644 index 0000000000000000000000000000000000000000..ae35128e26814315277ac4f0500abc53f36bbbb1 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/digraph.py @@ -0,0 +1,1363 @@ +"""Base class for directed graphs.""" + +from copy import deepcopy +from functools import cached_property + +import networkx as nx +from networkx import convert +from networkx.classes.coreviews import AdjacencyView +from networkx.classes.graph import Graph +from networkx.classes.reportviews import ( + DiDegreeView, + InDegreeView, + InEdgeView, + OutDegreeView, + OutEdgeView, +) +from networkx.exception import NetworkXError + +__all__ = ["DiGraph"] + + +class _CachedPropertyResetterAdjAndSucc: + """Data Descriptor class that syncs and resets cached properties adj and succ + + The cached properties `adj` and `succ` are reset whenever `_adj` or `_succ` + are set to new objects. In addition, the attributes `_succ` and `_adj` + are synced so these two names point to the same object. + + Warning: most of the time, when ``G._adj`` is set, ``G._pred`` should also + be set to maintain a valid data structure. They share datadicts. + + This object sits on a class and ensures that any instance of that + class clears its cached properties "succ" and "adj" whenever the + underlying instance attributes "_succ" or "_adj" are set to a new object. + It only affects the set process of the obj._adj and obj._succ attribute. + All get/del operations act as they normally would. + + For info on Data Descriptors see: https://docs.python.org/3/howto/descriptor.html + """ + + def __set__(self, obj, value): + od = obj.__dict__ + od["_adj"] = value + od["_succ"] = value + # reset cached properties + props = [ + "adj", + "succ", + "edges", + "out_edges", + "degree", + "out_degree", + "in_degree", + ] + for prop in props: + if prop in od: + del od[prop] + + +class _CachedPropertyResetterPred: + """Data Descriptor class for _pred that resets ``pred`` cached_property when needed + + This assumes that the ``cached_property`` ``G.pred`` should be reset whenever + ``G._pred`` is set to a new value. + + Warning: most of the time, when ``G._pred`` is set, ``G._adj`` should also + be set to maintain a valid data structure. They share datadicts. + + This object sits on a class and ensures that any instance of that + class clears its cached property "pred" whenever the underlying + instance attribute "_pred" is set to a new object. It only affects + the set process of the obj._pred attribute. All get/del operations + act as they normally would. + + For info on Data Descriptors see: https://docs.python.org/3/howto/descriptor.html + """ + + def __set__(self, obj, value): + od = obj.__dict__ + od["_pred"] = value + # reset cached properties + props = ["pred", "in_edges", "degree", "out_degree", "in_degree"] + for prop in props: + if prop in od: + del od[prop] + + +class DiGraph(Graph): + """ + Base class for directed graphs. + + A DiGraph stores nodes and edges with optional data, or attributes. + + DiGraphs hold directed edges. Self loops are allowed but multiple + (parallel) edges are not. + + Nodes can be arbitrary (hashable) Python objects with optional + key/value attributes. By convention `None` is not used as a node. + + Edges are represented as links between nodes with optional + key/value attributes. + + Parameters + ---------- + incoming_graph_data : input graph (optional, default: None) + Data to initialize graph. If None (default) an empty + graph is created. The data can be any format that is supported + by the to_networkx_graph() function, currently including edge list, + dict of dicts, dict of lists, NetworkX graph, 2D NumPy array, SciPy + sparse matrix, or PyGraphviz graph. + + attr : keyword arguments, optional (default= no attributes) + Attributes to add to graph as key=value pairs. + + See Also + -------- + Graph + MultiGraph + MultiDiGraph + + Examples + -------- + Create an empty graph structure (a "null graph") with no nodes and + no edges. + + >>> G = nx.DiGraph() + + G can be grown in several ways. + + **Nodes:** + + Add one node at a time: + + >>> G.add_node(1) + + Add the nodes from any container (a list, dict, set or + even the lines from a file or the nodes from another graph). + + >>> G.add_nodes_from([2, 3]) + >>> G.add_nodes_from(range(100, 110)) + >>> H = nx.path_graph(10) + >>> G.add_nodes_from(H) + + In addition to strings and integers any hashable Python object + (except None) can represent a node, e.g. a customized node object, + or even another Graph. + + >>> G.add_node(H) + + **Edges:** + + G can also be grown by adding edges. + + Add one edge, + + >>> G.add_edge(1, 2) + + a list of edges, + + >>> G.add_edges_from([(1, 2), (1, 3)]) + + or a collection of edges, + + >>> G.add_edges_from(H.edges) + + If some edges connect nodes not yet in the graph, the nodes + are added automatically. There are no errors when adding + nodes or edges that already exist. + + **Attributes:** + + Each graph, node, and edge can hold key/value attribute pairs + in an associated attribute dictionary (the keys must be hashable). + By default these are empty, but can be added or changed using + add_edge, add_node or direct manipulation of the attribute + dictionaries named graph, node and edge respectively. + + >>> G = nx.DiGraph(day="Friday") + >>> G.graph + {'day': 'Friday'} + + Add node attributes using add_node(), add_nodes_from() or G.nodes + + >>> G.add_node(1, time="5pm") + >>> G.add_nodes_from([3], time="2pm") + >>> G.nodes[1] + {'time': '5pm'} + >>> G.nodes[1]["room"] = 714 + >>> del G.nodes[1]["room"] # remove attribute + >>> list(G.nodes(data=True)) + [(1, {'time': '5pm'}), (3, {'time': '2pm'})] + + Add edge attributes using add_edge(), add_edges_from(), subscript + notation, or G.edges. + + >>> G.add_edge(1, 2, weight=4.7) + >>> G.add_edges_from([(3, 4), (4, 5)], color="red") + >>> G.add_edges_from([(1, 2, {"color": "blue"}), (2, 3, {"weight": 8})]) + >>> G[1][2]["weight"] = 4.7 + >>> G.edges[1, 2]["weight"] = 4 + + Warning: we protect the graph data structure by making `G.edges[1, 2]` a + read-only dict-like structure. However, you can assign to attributes + in e.g. `G.edges[1, 2]`. Thus, use 2 sets of brackets to add/change + data attributes: `G.edges[1, 2]['weight'] = 4` + (For multigraphs: `MG.edges[u, v, key][name] = value`). + + **Shortcuts:** + + Many common graph features allow python syntax to speed reporting. + + >>> 1 in G # check if node in graph + True + >>> [n for n in G if n < 3] # iterate through nodes + [1, 2] + >>> len(G) # number of nodes in graph + 5 + + Often the best way to traverse all edges of a graph is via the neighbors. + The neighbors are reported as an adjacency-dict `G.adj` or `G.adjacency()` + + >>> for n, nbrsdict in G.adjacency(): + ... for nbr, eattr in nbrsdict.items(): + ... if "weight" in eattr: + ... # Do something useful with the edges + ... pass + + But the edges reporting object is often more convenient: + + >>> for u, v, weight in G.edges(data="weight"): + ... if weight is not None: + ... # Do something useful with the edges + ... pass + + **Reporting:** + + Simple graph information is obtained using object-attributes and methods. + Reporting usually provides views instead of containers to reduce memory + usage. The views update as the graph is updated similarly to dict-views. + The objects `nodes`, `edges` and `adj` provide access to data attributes + via lookup (e.g. `nodes[n]`, `edges[u, v]`, `adj[u][v]`) and iteration + (e.g. `nodes.items()`, `nodes.data('color')`, + `nodes.data('color', default='blue')` and similarly for `edges`) + Views exist for `nodes`, `edges`, `neighbors()`/`adj` and `degree`. + + For details on these and other miscellaneous methods, see below. + + **Subclasses (Advanced):** + + The Graph class uses a dict-of-dict-of-dict data structure. + The outer dict (node_dict) holds adjacency information keyed by node. + The next dict (adjlist_dict) represents the adjacency information and holds + edge data keyed by neighbor. The inner dict (edge_attr_dict) represents + the edge data and holds edge attribute values keyed by attribute names. + + Each of these three dicts can be replaced in a subclass by a user defined + dict-like object. In general, the dict-like features should be + maintained but extra features can be added. To replace one of the + dicts create a new graph class by changing the class(!) variable + holding the factory for that dict-like structure. The variable names are + node_dict_factory, node_attr_dict_factory, adjlist_inner_dict_factory, + adjlist_outer_dict_factory, edge_attr_dict_factory and graph_attr_dict_factory. + + node_dict_factory : function, (default: dict) + Factory function to be used to create the dict containing node + attributes, keyed by node id. + It should require no arguments and return a dict-like object + + node_attr_dict_factory: function, (default: dict) + Factory function to be used to create the node attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object + + adjlist_outer_dict_factory : function, (default: dict) + Factory function to be used to create the outer-most dict + in the data structure that holds adjacency info keyed by node. + It should require no arguments and return a dict-like object. + + adjlist_inner_dict_factory : function, optional (default: dict) + Factory function to be used to create the adjacency list + dict which holds edge data keyed by neighbor. + It should require no arguments and return a dict-like object + + edge_attr_dict_factory : function, optional (default: dict) + Factory function to be used to create the edge attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object. + + graph_attr_dict_factory : function, (default: dict) + Factory function to be used to create the graph attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object. + + Typically, if your extension doesn't impact the data structure all + methods will inherited without issue except: `to_directed/to_undirected`. + By default these methods create a DiGraph/Graph class and you probably + want them to create your extension of a DiGraph/Graph. To facilitate + this we define two class variables that you can set in your subclass. + + to_directed_class : callable, (default: DiGraph or MultiDiGraph) + Class to create a new graph structure in the `to_directed` method. + If `None`, a NetworkX class (DiGraph or MultiDiGraph) is used. + + to_undirected_class : callable, (default: Graph or MultiGraph) + Class to create a new graph structure in the `to_undirected` method. + If `None`, a NetworkX class (Graph or MultiGraph) is used. + + **Subclassing Example** + + Create a low memory graph class that effectively disallows edge + attributes by using a single attribute dict for all edges. + This reduces the memory used, but you lose edge attributes. + + >>> class ThinGraph(nx.Graph): + ... all_edge_dict = {"weight": 1} + ... + ... def single_edge_dict(self): + ... return self.all_edge_dict + ... + ... edge_attr_dict_factory = single_edge_dict + >>> G = ThinGraph() + >>> G.add_edge(2, 1) + >>> G[2][1] + {'weight': 1} + >>> G.add_edge(2, 2) + >>> G[2][1] is G[2][2] + True + """ + + _adj = _CachedPropertyResetterAdjAndSucc() # type: ignore[assignment] + _succ = _adj # type: ignore[has-type] + _pred = _CachedPropertyResetterPred() + + # This __new__ method just does what Python itself does automatically. + # We include it here as part of the dispatchable/backend interface. + # If your goal is to understand how the graph classes work, you can ignore + # this method, even when subclassing the base classes. If you are subclassing + # in order to provide a backend that allows class instantiation, this method + # can be overridden to return your own backend graph class. + @nx._dispatchable(name="digraph__new__", graphs=None, returns_graph=True) + def __new__(cls, *args, **kwargs): + return object.__new__(cls) + + def __init__(self, incoming_graph_data=None, **attr): + """Initialize a graph with edges, name, or graph attributes. + + Parameters + ---------- + incoming_graph_data : input graph (optional, default: None) + Data to initialize graph. If None (default) an empty + graph is created. The data can be an edge list, or any + NetworkX graph object. If the corresponding optional Python + packages are installed the data can also be a 2D NumPy array, a + SciPy sparse array, or a PyGraphviz graph. + + attr : keyword arguments, optional (default= no attributes) + Attributes to add to graph as key=value pairs. + + See Also + -------- + convert + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G = nx.Graph(name="my graph") + >>> e = [(1, 2), (2, 3), (3, 4)] # list of edges + >>> G = nx.Graph(e) + + Arbitrary graph attribute pairs (key=value) may be assigned + + >>> G = nx.Graph(e, day="Friday") + >>> G.graph + {'day': 'Friday'} + + """ + self.graph = self.graph_attr_dict_factory() # dictionary for graph attributes + self._node = self.node_dict_factory() # dictionary for node attr + # We store two adjacency lists: + # the predecessors of node n are stored in the dict self._pred + # the successors of node n are stored in the dict self._succ=self._adj + self._adj = self.adjlist_outer_dict_factory() # empty adjacency dict successor + self._pred = self.adjlist_outer_dict_factory() # predecessor + # Note: self._succ = self._adj # successor + + self.__networkx_cache__ = {} + # attempt to load graph with data + if incoming_graph_data is not None: + convert.to_networkx_graph(incoming_graph_data, create_using=self) + # load graph attributes (must be after convert) + attr.pop("backend", None) # Ignore explicit `backend="networkx"` + self.graph.update(attr) + + @cached_property + def adj(self): + """Graph adjacency object holding the neighbors of each node. + + This object is a read-only dict-like structure with node keys + and neighbor-dict values. The neighbor-dict is keyed by neighbor + to the edge-data-dict. So `G.adj[3][2]['color'] = 'blue'` sets + the color of the edge `(3, 2)` to `"blue"`. + + Iterating over G.adj behaves like a dict. Useful idioms include + `for nbr, datadict in G.adj[n].items():`. + + The neighbor information is also provided by subscripting the graph. + So `for nbr, foovalue in G[node].data('foo', default=1):` works. + + For directed graphs, `G.adj` holds outgoing (successor) info. + """ + return AdjacencyView(self._succ) + + @cached_property + def succ(self): + """Graph adjacency object holding the successors of each node. + + This object is a read-only dict-like structure with node keys + and neighbor-dict values. The neighbor-dict is keyed by neighbor + to the edge-data-dict. So `G.succ[3][2]['color'] = 'blue'` sets + the color of the edge `(3, 2)` to `"blue"`. + + Iterating over G.succ behaves like a dict. Useful idioms include + `for nbr, datadict in G.succ[n].items():`. A data-view not provided + by dicts also exists: `for nbr, foovalue in G.succ[node].data('foo'):` + and a default can be set via a `default` argument to the `data` method. + + The neighbor information is also provided by subscripting the graph. + So `for nbr, foovalue in G[node].data('foo', default=1):` works. + + For directed graphs, `G.adj` is identical to `G.succ`. + """ + return AdjacencyView(self._succ) + + @cached_property + def pred(self): + """Graph adjacency object holding the predecessors of each node. + + This object is a read-only dict-like structure with node keys + and neighbor-dict values. The neighbor-dict is keyed by neighbor + to the edge-data-dict. So `G.pred[2][3]['color'] = 'blue'` sets + the color of the edge `(3, 2)` to `"blue"`. + + Iterating over G.pred behaves like a dict. Useful idioms include + `for nbr, datadict in G.pred[n].items():`. A data-view not provided + by dicts also exists: `for nbr, foovalue in G.pred[node].data('foo'):` + A default can be set via a `default` argument to the `data` method. + """ + return AdjacencyView(self._pred) + + def add_node(self, node_for_adding, **attr): + """Add a single node `node_for_adding` and update node attributes. + + Parameters + ---------- + node_for_adding : node + A node can be any hashable Python object except None. + attr : keyword arguments, optional + Set or change node attributes using key=value. + + See Also + -------- + add_nodes_from + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_node(1) + >>> G.add_node("Hello") + >>> K3 = nx.Graph([(0, 1), (1, 2), (2, 0)]) + >>> G.add_node(K3) + >>> G.number_of_nodes() + 3 + + Use keywords set/change node attributes: + + >>> G.add_node(1, size=10) + >>> G.add_node(3, weight=0.4, UTM=("13S", 382871, 3972649)) + + Notes + ----- + A hashable object is one that can be used as a key in a Python + dictionary. This includes strings, numbers, tuples of strings + and numbers, etc. + + On many platforms hashable items also include mutables such as + NetworkX Graphs, though one should be careful that the hash + doesn't change on mutables. + """ + if node_for_adding not in self._succ: + if node_for_adding is None: + raise ValueError("None cannot be a node") + self._succ[node_for_adding] = self.adjlist_inner_dict_factory() + self._pred[node_for_adding] = self.adjlist_inner_dict_factory() + attr_dict = self._node[node_for_adding] = self.node_attr_dict_factory() + attr_dict.update(attr) + else: # update attr even if node already exists + self._node[node_for_adding].update(attr) + nx._clear_cache(self) + + def add_nodes_from(self, nodes_for_adding, **attr): + """Add multiple nodes. + + Parameters + ---------- + nodes_for_adding : iterable container + A container of nodes (list, dict, set, etc.). + OR + A container of (node, attribute dict) tuples. + Node attributes are updated using the attribute dict. + attr : keyword arguments, optional (default= no attributes) + Update attributes for all nodes in nodes. + Node attributes specified in nodes as a tuple take + precedence over attributes specified via keyword arguments. + + See Also + -------- + add_node + + Notes + ----- + When adding nodes from an iterator over the graph you are changing, + a `RuntimeError` can be raised with message: + `RuntimeError: dictionary changed size during iteration`. This + happens when the graph's underlying dictionary is modified during + iteration. To avoid this error, evaluate the iterator into a separate + object, e.g. by using `list(iterator_of_nodes)`, and pass this + object to `G.add_nodes_from`. + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_nodes_from("Hello") + >>> K3 = nx.Graph([(0, 1), (1, 2), (2, 0)]) + >>> G.add_nodes_from(K3) + >>> sorted(G.nodes(), key=str) + [0, 1, 2, 'H', 'e', 'l', 'o'] + + Use keywords to update specific node attributes for every node. + + >>> G.add_nodes_from([1, 2], size=10) + >>> G.add_nodes_from([3, 4], weight=0.4) + + Use (node, attrdict) tuples to update attributes for specific nodes. + + >>> G.add_nodes_from([(1, dict(size=11)), (2, {"color": "blue"})]) + >>> G.nodes[1]["size"] + 11 + >>> H = nx.Graph() + >>> H.add_nodes_from(G.nodes(data=True)) + >>> H.nodes[1]["size"] + 11 + + Evaluate an iterator over a graph if using it to modify the same graph + + >>> G = nx.DiGraph([(0, 1), (1, 2), (3, 4)]) + >>> # wrong way - will raise RuntimeError + >>> # G.add_nodes_from(n + 1 for n in G.nodes) + >>> # correct way + >>> G.add_nodes_from(list(n + 1 for n in G.nodes)) + """ + for n in nodes_for_adding: + try: + newnode = n not in self._node + newdict = attr + except TypeError: + n, ndict = n + newnode = n not in self._node + newdict = attr.copy() + newdict.update(ndict) + if newnode: + if n is None: + raise ValueError("None cannot be a node") + self._succ[n] = self.adjlist_inner_dict_factory() + self._pred[n] = self.adjlist_inner_dict_factory() + self._node[n] = self.node_attr_dict_factory() + self._node[n].update(newdict) + nx._clear_cache(self) + + def remove_node(self, n): + """Remove node n. + + Removes the node n and all adjacent edges. + Attempting to remove a nonexistent node will raise an exception. + + Parameters + ---------- + n : node + A node in the graph + + Raises + ------ + NetworkXError + If n is not in the graph. + + See Also + -------- + remove_nodes_from + + Examples + -------- + >>> G = nx.path_graph(3) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> list(G.edges) + [(0, 1), (1, 2)] + >>> G.remove_node(1) + >>> list(G.edges) + [] + + """ + try: + nbrs = self._succ[n] + del self._node[n] + except KeyError as err: # NetworkXError if n not in self + raise NetworkXError(f"The node {n} is not in the digraph.") from err + for u in nbrs: + del self._pred[u][n] # remove all edges n-u in digraph + del self._succ[n] # remove node from succ + for u in self._pred[n]: + del self._succ[u][n] # remove all edges n-u in digraph + del self._pred[n] # remove node from pred + nx._clear_cache(self) + + def remove_nodes_from(self, nodes): + """Remove multiple nodes. + + Parameters + ---------- + nodes : iterable container + A container of nodes (list, dict, set, etc.). If a node + in the container is not in the graph it is silently ignored. + + See Also + -------- + remove_node + + Notes + ----- + When removing nodes from an iterator over the graph you are changing, + a `RuntimeError` will be raised with message: + `RuntimeError: dictionary changed size during iteration`. This + happens when the graph's underlying dictionary is modified during + iteration. To avoid this error, evaluate the iterator into a separate + object, e.g. by using `list(iterator_of_nodes)`, and pass this + object to `G.remove_nodes_from`. + + Examples + -------- + >>> G = nx.path_graph(3) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> e = list(G.nodes) + >>> e + [0, 1, 2] + >>> G.remove_nodes_from(e) + >>> list(G.nodes) + [] + + Evaluate an iterator over a graph if using it to modify the same graph + + >>> G = nx.DiGraph([(0, 1), (1, 2), (3, 4)]) + >>> # this command will fail, as the graph's dict is modified during iteration + >>> # G.remove_nodes_from(n for n in G.nodes if n < 2) + >>> # this command will work, since the dictionary underlying graph is not modified + >>> G.remove_nodes_from(list(n for n in G.nodes if n < 2)) + """ + for n in nodes: + try: + succs = self._succ[n] + del self._node[n] + for u in succs: + del self._pred[u][n] # remove all edges n-u in digraph + del self._succ[n] # now remove node + for u in self._pred[n]: + del self._succ[u][n] # remove all edges n-u in digraph + del self._pred[n] # now remove node + except KeyError: + pass # silent failure on remove + nx._clear_cache(self) + + def add_edge(self, u_of_edge, v_of_edge, **attr): + """Add an edge between u and v. + + The nodes u and v will be automatically added if they are + not already in the graph. + + Edge attributes can be specified with keywords or by directly + accessing the edge's attribute dictionary. See examples below. + + Parameters + ---------- + u_of_edge, v_of_edge : nodes + Nodes can be, for example, strings or numbers. + Nodes must be hashable (and not None) Python objects. + attr : keyword arguments, optional + Edge data (or labels or objects) can be assigned using + keyword arguments. + + See Also + -------- + add_edges_from : add a collection of edges + + Notes + ----- + Adding an edge that already exists updates the edge data. + + Many NetworkX algorithms designed for weighted graphs use + an edge attribute (by default `weight`) to hold a numerical value. + + Examples + -------- + The following all add the edge e=(1, 2) to graph G: + + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> e = (1, 2) + >>> G.add_edge(1, 2) # explicit two-node form + >>> G.add_edge(*e) # single edge as tuple of two nodes + >>> G.add_edges_from([(1, 2)]) # add edges from iterable container + + Associate data to edges using keywords: + + >>> G.add_edge(1, 2, weight=3) + >>> G.add_edge(1, 3, weight=7, capacity=15, length=342.7) + + For non-string attribute keys, use subscript notation. + + >>> G.add_edge(1, 2) + >>> G[1][2].update({0: 5}) + >>> G.edges[1, 2].update({0: 5}) + """ + u, v = u_of_edge, v_of_edge + # add nodes + if u not in self._succ: + if u is None: + raise ValueError("None cannot be a node") + self._succ[u] = self.adjlist_inner_dict_factory() + self._pred[u] = self.adjlist_inner_dict_factory() + self._node[u] = self.node_attr_dict_factory() + if v not in self._succ: + if v is None: + raise ValueError("None cannot be a node") + self._succ[v] = self.adjlist_inner_dict_factory() + self._pred[v] = self.adjlist_inner_dict_factory() + self._node[v] = self.node_attr_dict_factory() + # add the edge + datadict = self._adj[u].get(v, self.edge_attr_dict_factory()) + datadict.update(attr) + self._succ[u][v] = datadict + self._pred[v][u] = datadict + nx._clear_cache(self) + + def add_edges_from(self, ebunch_to_add, **attr): + """Add all the edges in ebunch_to_add. + + Parameters + ---------- + ebunch_to_add : container of edges + Each edge given in the container will be added to the + graph. The edges must be given as 2-tuples (u, v) or + 3-tuples (u, v, d) where d is a dictionary containing edge data. + attr : keyword arguments, optional + Edge data (or labels or objects) can be assigned using + keyword arguments. + + See Also + -------- + add_edge : add a single edge + add_weighted_edges_from : convenient way to add weighted edges + + Notes + ----- + Adding the same edge twice has no effect but any edge data + will be updated when each duplicate edge is added. + + Edge attributes specified in an ebunch take precedence over + attributes specified via keyword arguments. + + When adding edges from an iterator over the graph you are changing, + a `RuntimeError` can be raised with message: + `RuntimeError: dictionary changed size during iteration`. This + happens when the graph's underlying dictionary is modified during + iteration. To avoid this error, evaluate the iterator into a separate + object, e.g. by using `list(iterator_of_edges)`, and pass this + object to `G.add_edges_from`. + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_edges_from([(0, 1), (1, 2)]) # using a list of edge tuples + >>> e = zip(range(0, 3), range(1, 4)) + >>> G.add_edges_from(e) # Add the path graph 0-1-2-3 + + Associate data to edges + + >>> G.add_edges_from([(1, 2), (2, 3)], weight=3) + >>> G.add_edges_from([(3, 4), (1, 4)], label="WN2898") + + Evaluate an iterator over a graph if using it to modify the same graph + + >>> G = nx.DiGraph([(1, 2), (2, 3), (3, 4)]) + >>> # Grow graph by one new node, adding edges to all existing nodes. + >>> # wrong way - will raise RuntimeError + >>> # G.add_edges_from(((5, n) for n in G.nodes)) + >>> # right way - note that there will be no self-edge for node 5 + >>> G.add_edges_from(list((5, n) for n in G.nodes)) + """ + for e in ebunch_to_add: + ne = len(e) + if ne == 3: + u, v, dd = e + elif ne == 2: + u, v = e + dd = {} + else: + raise NetworkXError(f"Edge tuple {e} must be a 2-tuple or 3-tuple.") + if u not in self._succ: + if u is None: + raise ValueError("None cannot be a node") + self._succ[u] = self.adjlist_inner_dict_factory() + self._pred[u] = self.adjlist_inner_dict_factory() + self._node[u] = self.node_attr_dict_factory() + if v not in self._succ: + if v is None: + raise ValueError("None cannot be a node") + self._succ[v] = self.adjlist_inner_dict_factory() + self._pred[v] = self.adjlist_inner_dict_factory() + self._node[v] = self.node_attr_dict_factory() + datadict = self._adj[u].get(v, self.edge_attr_dict_factory()) + datadict.update(attr) + datadict.update(dd) + self._succ[u][v] = datadict + self._pred[v][u] = datadict + nx._clear_cache(self) + + def remove_edge(self, u, v): + """Remove the edge between u and v. + + Parameters + ---------- + u, v : nodes + Remove the edge between nodes u and v. + + Raises + ------ + NetworkXError + If there is not an edge between u and v. + + See Also + -------- + remove_edges_from : remove a collection of edges + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, etc + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.remove_edge(0, 1) + >>> e = (1, 2) + >>> G.remove_edge(*e) # unpacks e from an edge tuple + >>> e = (2, 3, {"weight": 7}) # an edge with attribute data + >>> G.remove_edge(*e[:2]) # select first part of edge tuple + """ + try: + del self._succ[u][v] + del self._pred[v][u] + except KeyError as err: + raise NetworkXError(f"The edge {u}-{v} not in graph.") from err + nx._clear_cache(self) + + def remove_edges_from(self, ebunch): + """Remove all edges specified in ebunch. + + Parameters + ---------- + ebunch: list or container of edge tuples + Each edge given in the list or container will be removed + from the graph. The edges can be: + + - 2-tuples (u, v) edge between u and v. + - 3-tuples (u, v, k) where k is ignored. + + See Also + -------- + remove_edge : remove a single edge + + Notes + ----- + Will fail silently if an edge in ebunch is not in the graph. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> ebunch = [(1, 2), (2, 3)] + >>> G.remove_edges_from(ebunch) + """ + for e in ebunch: + u, v = e[:2] # ignore edge data + if u in self._succ and v in self._succ[u]: + del self._succ[u][v] + del self._pred[v][u] + nx._clear_cache(self) + + def has_successor(self, u, v): + """Returns True if node u has successor v. + + This is true if graph has the edge u->v. + """ + return u in self._succ and v in self._succ[u] + + def has_predecessor(self, u, v): + """Returns True if node u has predecessor v. + + This is true if graph has the edge u<-v. + """ + return u in self._pred and v in self._pred[u] + + def successors(self, n): + """Returns an iterator over successor nodes of n. + + A successor of n is a node m such that there exists a directed + edge from n to m. + + Parameters + ---------- + n : node + A node in the graph + + Raises + ------ + NetworkXError + If n is not in the graph. + + See Also + -------- + predecessors + + Notes + ----- + neighbors() and successors() are the same. + """ + try: + return iter(self._succ[n]) + except KeyError as err: + raise NetworkXError(f"The node {n} is not in the digraph.") from err + + # digraph definitions + neighbors = successors + + def predecessors(self, n): + """Returns an iterator over predecessor nodes of n. + + A predecessor of n is a node m such that there exists a directed + edge from m to n. + + Parameters + ---------- + n : node + A node in the graph + + Raises + ------ + NetworkXError + If n is not in the graph. + + See Also + -------- + successors + """ + try: + return iter(self._pred[n]) + except KeyError as err: + raise NetworkXError(f"The node {n} is not in the digraph.") from err + + @cached_property + def edges(self): + """An OutEdgeView of the DiGraph as G.edges or G.edges(). + + edges(self, nbunch=None, data=False, default=None) + + The OutEdgeView provides set-like operations on the edge-tuples + as well as edge attribute lookup. When called, it also provides + an EdgeDataView object which allows control of access to edge + attributes (but does not provide set-like operations). + Hence, `G.edges[u, v]['color']` provides the value of the color + attribute for edge `(u, v)` while + `for (u, v, c) in G.edges.data('color', default='red'):` + iterates through all the edges yielding the color attribute + with default `'red'` if no color attribute exists. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges from these nodes. + data : string or bool, optional (default=False) + The edge attribute returned in 3-tuple (u, v, ddict[data]). + If True, return edge attribute dict in 3-tuple (u, v, ddict). + If False, return 2-tuple (u, v). + default : value, optional (default=None) + Value used for edges that don't have the requested attribute. + Only relevant if data is not True or False. + + Returns + ------- + edges : OutEdgeView + A view of edge attributes, usually it iterates over (u, v) + or (u, v, d) tuples of edges, but can also be used for + attribute lookup as `edges[u, v]['foo']`. + + See Also + -------- + in_edges, out_edges + + Notes + ----- + Nodes in nbunch that are not in the graph will be (quietly) ignored. + For directed graphs this returns the out-edges. + + Examples + -------- + >>> G = nx.DiGraph() # or MultiDiGraph, etc + >>> nx.add_path(G, [0, 1, 2]) + >>> G.add_edge(2, 3, weight=5) + >>> [e for e in G.edges] + [(0, 1), (1, 2), (2, 3)] + >>> G.edges.data() # default data is {} (empty dict) + OutEdgeDataView([(0, 1, {}), (1, 2, {}), (2, 3, {'weight': 5})]) + >>> G.edges.data("weight", default=1) + OutEdgeDataView([(0, 1, 1), (1, 2, 1), (2, 3, 5)]) + >>> G.edges([0, 2]) # only edges originating from these nodes + OutEdgeDataView([(0, 1), (2, 3)]) + >>> G.edges(0) # only edges from node 0 + OutEdgeDataView([(0, 1)]) + + """ + return OutEdgeView(self) + + # alias out_edges to edges + @cached_property + def out_edges(self): + return OutEdgeView(self) + + out_edges.__doc__ = edges.__doc__ + + @cached_property + def in_edges(self): + """A view of the in edges of the graph as G.in_edges or G.in_edges(). + + in_edges(self, nbunch=None, data=False, default=None): + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges incident to these nodes. + data : string or bool, optional (default=False) + The edge attribute returned in 3-tuple (u, v, ddict[data]). + If True, return edge attribute dict in 3-tuple (u, v, ddict). + If False, return 2-tuple (u, v). + default : value, optional (default=None) + Value used for edges that don't have the requested attribute. + Only relevant if data is not True or False. + + Returns + ------- + in_edges : InEdgeView or InEdgeDataView + A view of edge attributes, usually it iterates over (u, v) + or (u, v, d) tuples of edges, but can also be used for + attribute lookup as `edges[u, v]['foo']`. + + Examples + -------- + >>> G = nx.DiGraph() + >>> G.add_edge(1, 2, color="blue") + >>> G.in_edges() + InEdgeView([(1, 2)]) + >>> G.in_edges(nbunch=2) + InEdgeDataView([(1, 2)]) + + See Also + -------- + edges + """ + return InEdgeView(self) + + @cached_property + def degree(self): + """A DegreeView for the Graph as G.degree or G.degree(). + + The node degree is the number of edges adjacent to the node. + The weighted node degree is the sum of the edge weights for + edges incident to that node. + + This object provides an iterator for (node, degree) as well as + lookup for the degree for a single node. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges incident to these nodes. + + weight : string or None, optional (default=None) + The name of an edge attribute that holds the numerical value used + as a weight. If None, then each edge has weight 1. + The degree is the sum of the edge weights adjacent to the node. + + Returns + ------- + DiDegreeView or int + If multiple nodes are requested (the default), returns a `DiDegreeView` + mapping nodes to their degree. + If a single node is requested, returns the degree of the node as an integer. + + See Also + -------- + in_degree, out_degree + + Examples + -------- + >>> G = nx.DiGraph() # or MultiDiGraph + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.degree(0) # node 0 with degree 1 + 1 + >>> list(G.degree([0, 1, 2])) + [(0, 1), (1, 2), (2, 2)] + + """ + return DiDegreeView(self) + + @cached_property + def in_degree(self): + """An InDegreeView for (node, in_degree) or in_degree for single node. + + The node in_degree is the number of edges pointing to the node. + The weighted node degree is the sum of the edge weights for + edges incident to that node. + + This object provides an iteration over (node, in_degree) as well as + lookup for the degree for a single node. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges incident to these nodes. + + weight : string or None, optional (default=None) + The name of an edge attribute that holds the numerical value used + as a weight. If None, then each edge has weight 1. + The degree is the sum of the edge weights adjacent to the node. + + Returns + ------- + If a single node is requested + deg : int + In-degree of the node + + OR if multiple nodes are requested + nd_iter : iterator + The iterator returns two-tuples of (node, in-degree). + + See Also + -------- + degree, out_degree + + Examples + -------- + >>> G = nx.DiGraph() + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.in_degree(0) # node 0 with degree 0 + 0 + >>> list(G.in_degree([0, 1, 2])) + [(0, 0), (1, 1), (2, 1)] + + """ + return InDegreeView(self) + + @cached_property + def out_degree(self): + """An OutDegreeView for (node, out_degree) + + The node out_degree is the number of edges pointing out of the node. + The weighted node degree is the sum of the edge weights for + edges incident to that node. + + This object provides an iterator over (node, out_degree) as well as + lookup for the degree for a single node. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges incident to these nodes. + + weight : string or None, optional (default=None) + The name of an edge attribute that holds the numerical value used + as a weight. If None, then each edge has weight 1. + The degree is the sum of the edge weights adjacent to the node. + + Returns + ------- + If a single node is requested + deg : int + Out-degree of the node + + OR if multiple nodes are requested + nd_iter : iterator + The iterator returns two-tuples of (node, out-degree). + + See Also + -------- + degree, in_degree + + Examples + -------- + >>> G = nx.DiGraph() + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.out_degree(0) # node 0 with degree 1 + 1 + >>> list(G.out_degree([0, 1, 2])) + [(0, 1), (1, 1), (2, 1)] + + """ + return OutDegreeView(self) + + def clear(self): + """Remove all nodes and edges from the graph. + + This also removes the name, and all graph, node, and edge attributes. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.clear() + >>> list(G.nodes) + [] + >>> list(G.edges) + [] + + """ + self._succ.clear() + self._pred.clear() + self._node.clear() + self.graph.clear() + nx._clear_cache(self) + + def clear_edges(self): + """Remove all edges from the graph without altering nodes. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.clear_edges() + >>> list(G.nodes) + [0, 1, 2, 3] + >>> list(G.edges) + [] + + """ + for predecessor_dict in self._pred.values(): + predecessor_dict.clear() + for successor_dict in self._succ.values(): + successor_dict.clear() + nx._clear_cache(self) + + def is_multigraph(self): + """Returns True if graph is a multigraph, False otherwise.""" + return False + + def is_directed(self): + """Returns True if graph is directed, False otherwise.""" + return True + + def to_undirected(self, reciprocal=False, as_view=False): + """Returns an undirected representation of the digraph. + + Parameters + ---------- + reciprocal : bool (optional) + If True only keep edges that appear in both directions + in the original digraph. + as_view : bool (optional, default=False) + If True return an undirected view of the original directed graph. + + Returns + ------- + G : Graph + An undirected graph with the same name and nodes and + with edge (u, v, data) if either (u, v, data) or (v, u, data) + is in the digraph. If both edges exist in digraph and + their edge data is different, only one edge is created + with an arbitrary choice of which edge data to use. + You must check and correct for this manually if desired. + + See Also + -------- + Graph, copy, add_edge, add_edges_from + + Notes + ----- + If edges in both directions (u, v) and (v, u) exist in the + graph, attributes for the new undirected edge will be a combination of + the attributes of the directed edges. The edge data is updated + in the (arbitrary) order that the edges are encountered. For + more customized control of the edge attributes use add_edge(). + + This returns a "deepcopy" of the edge, node, and + graph attributes which attempts to completely copy + all of the data and references. + + This is in contrast to the similar G=DiGraph(D) which returns a + shallow copy of the data. + + See the Python copy module for more information on shallow + and deep copies, https://docs.python.org/3/library/copy.html. + + Warning: If you have subclassed DiGraph to use dict-like objects + in the data structure, those changes do not transfer to the + Graph created by this method. + + Examples + -------- + >>> G = nx.path_graph(2) # or MultiGraph, etc + >>> H = G.to_directed() + >>> list(H.edges) + [(0, 1), (1, 0)] + >>> G2 = H.to_undirected() + >>> list(G2.edges) + [(0, 1)] + """ + graph_class = self.to_undirected_class() + if as_view is True: + return nx.graphviews.generic_graph_view(self, graph_class) + # deepcopy when not a view + G = graph_class() + G.graph.update(deepcopy(self.graph)) + G.add_nodes_from((n, deepcopy(d)) for n, d in self._node.items()) + if reciprocal is True: + G.add_edges_from( + (u, v, deepcopy(d)) + for u, nbrs in self._adj.items() + for v, d in nbrs.items() + if v in self._pred[u] + ) + else: + G.add_edges_from( + (u, v, deepcopy(d)) + for u, nbrs in self._adj.items() + for v, d in nbrs.items() + ) + return G + + def reverse(self, copy=True): + """Returns the reverse of the graph. + + The reverse is a graph with the same nodes and edges + but with the directions of the edges reversed. + + Parameters + ---------- + copy : bool optional (default=True) + If True, return a new DiGraph holding the reversed edges. + If False, the reverse graph is created using a view of + the original graph. + """ + if copy: + H = self.__class__() + H.graph.update(deepcopy(self.graph)) + H.add_nodes_from((n, deepcopy(d)) for n, d in self.nodes.items()) + H.add_edges_from((v, u, deepcopy(d)) for u, v, d in self.edges(data=True)) + return H + return nx.reverse_view(self) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/filters.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/filters.py new file mode 100644 index 0000000000000000000000000000000000000000..e989e22bb6d7e79b6eab34103edd263d82694fd4 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/filters.py @@ -0,0 +1,95 @@ +"""Filter factories to hide or show sets of nodes and edges. + +These filters return the function used when creating `SubGraph`. +""" + +__all__ = [ + "no_filter", + "hide_nodes", + "hide_edges", + "hide_multiedges", + "hide_diedges", + "hide_multidiedges", + "show_nodes", + "show_edges", + "show_multiedges", + "show_diedges", + "show_multidiedges", +] + + +def no_filter(*items): + """Returns a filter function that always evaluates to True.""" + return True + + +def hide_nodes(nodes): + """Returns a filter function that hides specific nodes.""" + nodes = set(nodes) + return lambda node: node not in nodes + + +def hide_diedges(edges): + """Returns a filter function that hides specific directed edges.""" + edges = {(u, v) for u, v in edges} + return lambda u, v: (u, v) not in edges + + +def hide_edges(edges): + """Returns a filter function that hides specific undirected edges.""" + alledges = set(edges) | {(v, u) for (u, v) in edges} + return lambda u, v: (u, v) not in alledges + + +def hide_multidiedges(edges): + """Returns a filter function that hides specific multi-directed edges.""" + edges = {(u, v, k) for u, v, k in edges} + return lambda u, v, k: (u, v, k) not in edges + + +def hide_multiedges(edges): + """Returns a filter function that hides specific multi-undirected edges.""" + alledges = set(edges) | {(v, u, k) for (u, v, k) in edges} + return lambda u, v, k: (u, v, k) not in alledges + + +# write show_nodes as a class to make SubGraph pickleable +class show_nodes: + """Filter class to show specific nodes. + + Attach the set of nodes as an attribute to speed up this commonly used filter + + Note that another allowed attribute for filters is to store the number of nodes + on the filter as attribute `length` (used in `__len__`). It is a user + responsibility to ensure this attribute is accurate if present. + """ + + def __init__(self, nodes): + self.nodes = set(nodes) + + def __call__(self, node): + return node in self.nodes + + +def show_diedges(edges): + """Returns a filter function that shows specific directed edges.""" + edges = {(u, v) for u, v in edges} + return lambda u, v: (u, v) in edges + + +def show_edges(edges): + """Returns a filter function that shows specific undirected edges.""" + alledges = set(edges) | {(v, u) for (u, v) in edges} + return lambda u, v: (u, v) in alledges + + +def show_multidiedges(edges): + """Returns a filter function that shows specific multi-directed edges.""" + edges = {(u, v, k) for u, v, k in edges} + return lambda u, v, k: (u, v, k) in edges + + +def show_multiedges(edges): + """Returns a filter function that shows specific multi-undirected edges.""" + alledges = set(edges) | {(v, u, k) for (u, v, k) in edges} + return lambda u, v, k: (u, v, k) in alledges diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/function.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/function.py new file mode 100644 index 0000000000000000000000000000000000000000..31f088ede87f01b2815514f1914f67e222ff66b6 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/function.py @@ -0,0 +1,1549 @@ +"""Functional interface to graph methods and assorted utilities.""" + +from collections import Counter +from itertools import chain + +import networkx as nx +from networkx.utils import not_implemented_for, pairwise + +__all__ = [ + "nodes", + "edges", + "degree", + "degree_histogram", + "neighbors", + "number_of_nodes", + "number_of_edges", + "density", + "is_directed", + "freeze", + "is_frozen", + "subgraph", + "induced_subgraph", + "edge_subgraph", + "restricted_view", + "to_directed", + "to_undirected", + "add_star", + "add_path", + "add_cycle", + "create_empty_copy", + "set_node_attributes", + "get_node_attributes", + "remove_node_attributes", + "set_edge_attributes", + "get_edge_attributes", + "remove_edge_attributes", + "all_neighbors", + "non_neighbors", + "non_edges", + "common_neighbors", + "is_weighted", + "is_negatively_weighted", + "is_empty", + "selfloop_edges", + "nodes_with_selfloops", + "number_of_selfloops", + "path_weight", + "is_path", + "describe", +] + + +def nodes(G): + """Returns a NodeView over the graph nodes. + + This function wraps the :func:`G.nodes ` property. + """ + return G.nodes() + + +def edges(G, nbunch=None): + """Returns an edge view of edges incident to nodes in nbunch. + + Return all edges if nbunch is unspecified or nbunch=None. + + For digraphs, edges=out_edges + + This function wraps the :func:`G.edges ` property. + """ + return G.edges(nbunch) + + +def degree(G, nbunch=None, weight=None): + """Returns a degree view of single node or of nbunch of nodes. + If nbunch is omitted, then return degrees of *all* nodes. + + This function wraps the :func:`G.degree ` property. + """ + return G.degree(nbunch, weight) + + +def neighbors(G, n): + """Returns an iterator over all neighbors of node n. + + This function wraps the :func:`G.neighbors ` function. + """ + return G.neighbors(n) + + +def number_of_nodes(G): + """Returns the number of nodes in the graph. + + This function wraps the :func:`G.number_of_nodes ` function. + """ + return G.number_of_nodes() + + +def number_of_edges(G): + """Returns the number of edges in the graph. + + This function wraps the :func:`G.number_of_edges ` function. + """ + return G.number_of_edges() + + +def density(G): + r"""Returns the density of a graph. + + The density for undirected graphs is + + .. math:: + + d = \frac{2m}{n(n-1)}, + + and for directed graphs is + + .. math:: + + d = \frac{m}{n(n-1)}, + + where `n` is the number of nodes and `m` is the number of edges in `G`. + + Notes + ----- + The density is 0 for a graph without edges and 1 for a complete graph. + The density of multigraphs can be higher than 1. + + Self loops are counted in the total number of edges so graphs with self + loops can have density higher than 1. + """ + n = number_of_nodes(G) + m = number_of_edges(G) + if m == 0 or n <= 1: + return 0 + d = m / (n * (n - 1)) + if not G.is_directed(): + d *= 2 + return d + + +def degree_histogram(G): + """Returns a list of the frequency of each degree value. + + Parameters + ---------- + G : Networkx graph + A graph + + Returns + ------- + hist : list + A list of frequencies of degrees. + The degree values are the index in the list. + + Notes + ----- + Note: the bins are width one, hence len(list) can be large + (Order(number_of_edges)) + """ + counts = Counter(d for n, d in G.degree()) + return [counts.get(i, 0) for i in range(max(counts) + 1 if counts else 0)] + + +def is_directed(G): + """Return True if graph is directed.""" + return G.is_directed() + + +def frozen(*args, **kwargs): + """Dummy method for raising errors when trying to modify frozen graphs""" + raise nx.NetworkXError("Frozen graph can't be modified") + + +def freeze(G): + """Modify graph to prevent further change by adding or removing + nodes or edges. + + Node and edge data can still be modified. + + Parameters + ---------- + G : graph + A NetworkX graph + + Examples + -------- + >>> G = nx.path_graph(4) + >>> G = nx.freeze(G) + >>> try: + ... G.add_edge(4, 5) + ... except nx.NetworkXError as err: + ... print(str(err)) + Frozen graph can't be modified + + Notes + ----- + To "unfreeze" a graph you must make a copy by creating a new graph object: + + >>> graph = nx.path_graph(4) + >>> frozen_graph = nx.freeze(graph) + >>> unfrozen_graph = nx.Graph(frozen_graph) + >>> nx.is_frozen(unfrozen_graph) + False + + See Also + -------- + is_frozen + """ + G.add_node = frozen + G.add_nodes_from = frozen + G.remove_node = frozen + G.remove_nodes_from = frozen + G.add_edge = frozen + G.add_edges_from = frozen + G.add_weighted_edges_from = frozen + G.remove_edge = frozen + G.remove_edges_from = frozen + G.clear = frozen + G.clear_edges = frozen + G.frozen = True + return G + + +def is_frozen(G): + """Returns True if graph is frozen. + + Parameters + ---------- + G : graph + A NetworkX graph + + See Also + -------- + freeze + """ + try: + return G.frozen + except AttributeError: + return False + + +def add_star(G_to_add_to, nodes_for_star, **attr): + """Add a star to Graph G_to_add_to. + + The first node in `nodes_for_star` is the middle of the star. + It is connected to all other nodes. + + Parameters + ---------- + G_to_add_to : graph + A NetworkX graph + nodes_for_star : iterable container + A container of nodes. + attr : keyword arguments, optional (default= no attributes) + Attributes to add to every edge in star. + + See Also + -------- + add_path, add_cycle + + Examples + -------- + >>> G = nx.Graph() + >>> nx.add_star(G, [0, 1, 2, 3]) + >>> nx.add_star(G, [10, 11, 12], weight=2) + """ + nlist = iter(nodes_for_star) + try: + v = next(nlist) + except StopIteration: + return + G_to_add_to.add_node(v) + edges = ((v, n) for n in nlist) + G_to_add_to.add_edges_from(edges, **attr) + + +def add_path(G_to_add_to, nodes_for_path, **attr): + """Add a path to the Graph G_to_add_to. + + Parameters + ---------- + G_to_add_to : graph + A NetworkX graph + nodes_for_path : iterable container + A container of nodes. A path will be constructed from + the nodes (in order) and added to the graph. + attr : keyword arguments, optional (default= no attributes) + Attributes to add to every edge in path. + + See Also + -------- + add_star, add_cycle + + Examples + -------- + >>> G = nx.Graph() + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> nx.add_path(G, [10, 11, 12], weight=7) + """ + nlist = iter(nodes_for_path) + try: + first_node = next(nlist) + except StopIteration: + return + G_to_add_to.add_node(first_node) + G_to_add_to.add_edges_from(pairwise(chain((first_node,), nlist)), **attr) + + +def add_cycle(G_to_add_to, nodes_for_cycle, **attr): + """Add a cycle to the Graph G_to_add_to. + + Parameters + ---------- + G_to_add_to : graph + A NetworkX graph + nodes_for_cycle: iterable container + A container of nodes. A cycle will be constructed from + the nodes (in order) and added to the graph. + attr : keyword arguments, optional (default= no attributes) + Attributes to add to every edge in cycle. + + See Also + -------- + add_path, add_star + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> nx.add_cycle(G, [0, 1, 2, 3]) + >>> nx.add_cycle(G, [10, 11, 12], weight=7) + """ + nlist = iter(nodes_for_cycle) + try: + first_node = next(nlist) + except StopIteration: + return + G_to_add_to.add_node(first_node) + G_to_add_to.add_edges_from( + pairwise(chain((first_node,), nlist), cyclic=True), **attr + ) + + +def subgraph(G, nbunch): + """Returns the subgraph induced on nodes in nbunch. + + Parameters + ---------- + G : graph + A NetworkX graph + + nbunch : list, iterable + A container of nodes that will be iterated through once (thus + it should be an iterator or be iterable). Each element of the + container should be a valid node type: any hashable type except + None. If nbunch is None, return all edges data in the graph. + Nodes in nbunch that are not in the graph will be (quietly) + ignored. + + Notes + ----- + subgraph(G) calls G.subgraph() + """ + return G.subgraph(nbunch) + + +def induced_subgraph(G, nbunch): + """Returns a SubGraph view of `G` showing only nodes in nbunch. + + The induced subgraph of a graph on a set of nodes N is the + graph with nodes N and edges from G which have both ends in N. + + Parameters + ---------- + G : NetworkX Graph + nbunch : node, container of nodes or None (for all nodes) + + Returns + ------- + subgraph : SubGraph View + A read-only view of the subgraph in `G` induced by the nodes. + Changes to the graph `G` will be reflected in the view. + + Notes + ----- + To create a mutable subgraph with its own copies of nodes + edges and attributes use `subgraph.copy()` or `Graph(subgraph)` + + For an inplace reduction of a graph to a subgraph you can remove nodes: + `G.remove_nodes_from(n in G if n not in set(nbunch))` + + If you are going to compute subgraphs of your subgraphs you could + end up with a chain of views that can be very slow once the chain + has about 15 views in it. If they are all induced subgraphs, you + can short-cut the chain by making them all subgraphs of the original + graph. The graph class method `G.subgraph` does this when `G` is + a subgraph. In contrast, this function allows you to choose to build + chains or not, as you wish. The returned subgraph is a view on `G`. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> H = nx.induced_subgraph(G, [0, 1, 3]) + >>> list(H.edges) + [(0, 1)] + >>> list(H.nodes) + [0, 1, 3] + """ + induced_nodes = nx.filters.show_nodes(G.nbunch_iter(nbunch)) + return nx.subgraph_view(G, filter_node=induced_nodes) + + +def edge_subgraph(G, edges): + """Returns a view of the subgraph induced by the specified edges. + + The induced subgraph contains each edge in `edges` and each + node incident to any of those edges. + + Parameters + ---------- + G : NetworkX Graph + edges : iterable + An iterable of edges. Edges not present in `G` are ignored. + + Returns + ------- + subgraph : SubGraph View + A read-only edge-induced subgraph of `G`. + Changes to `G` are reflected in the view. + + Notes + ----- + To create a mutable subgraph with its own copies of nodes + edges and attributes use `subgraph.copy()` or `Graph(subgraph)` + + If you create a subgraph of a subgraph recursively you can end up + with a chain of subgraphs that becomes very slow with about 15 + nested subgraph views. Luckily the edge_subgraph filter nests + nicely so you can use the original graph as G in this function + to avoid chains. We do not rule out chains programmatically so + that odd cases like an `edge_subgraph` of a `restricted_view` + can be created. + + Examples + -------- + >>> G = nx.path_graph(5) + >>> H = G.edge_subgraph([(0, 1), (3, 4)]) + >>> list(H.nodes) + [0, 1, 3, 4] + >>> list(H.edges) + [(0, 1), (3, 4)] + """ + nxf = nx.filters + edges = set(edges) + nodes = set() + for e in edges: + nodes.update(e[:2]) + induced_nodes = nxf.show_nodes(nodes) + if G.is_multigraph(): + if G.is_directed(): + induced_edges = nxf.show_multidiedges(edges) + else: + induced_edges = nxf.show_multiedges(edges) + else: + if G.is_directed(): + induced_edges = nxf.show_diedges(edges) + else: + induced_edges = nxf.show_edges(edges) + return nx.subgraph_view(G, filter_node=induced_nodes, filter_edge=induced_edges) + + +def restricted_view(G, nodes, edges): + """Returns a view of `G` with hidden nodes and edges. + + The resulting subgraph filters out node `nodes` and edges `edges`. + Filtered out nodes also filter out any of their edges. + + Parameters + ---------- + G : NetworkX Graph + nodes : iterable + An iterable of nodes. Nodes not present in `G` are ignored. + edges : iterable + An iterable of edges. Edges not present in `G` are ignored. + + Returns + ------- + subgraph : SubGraph View + A read-only restricted view of `G` filtering out nodes and edges. + Changes to `G` are reflected in the view. + + Notes + ----- + To create a mutable subgraph with its own copies of nodes + edges and attributes use `subgraph.copy()` or `Graph(subgraph)` + + If you create a subgraph of a subgraph recursively you may end up + with a chain of subgraph views. Such chains can get quite slow + for lengths near 15. To avoid long chains, try to make your subgraph + based on the original graph. We do not rule out chains programmatically + so that odd cases like an `edge_subgraph` of a `restricted_view` + can be created. + + Examples + -------- + >>> G = nx.path_graph(5) + >>> H = nx.restricted_view(G, [0], [(1, 2), (3, 4)]) + >>> list(H.nodes) + [1, 2, 3, 4] + >>> list(H.edges) + [(2, 3)] + """ + nxf = nx.filters + hide_nodes = nxf.hide_nodes(nodes) + if G.is_multigraph(): + if G.is_directed(): + hide_edges = nxf.hide_multidiedges(edges) + else: + hide_edges = nxf.hide_multiedges(edges) + else: + if G.is_directed(): + hide_edges = nxf.hide_diedges(edges) + else: + hide_edges = nxf.hide_edges(edges) + return nx.subgraph_view(G, filter_node=hide_nodes, filter_edge=hide_edges) + + +def to_directed(graph): + """Returns a directed view of the graph `graph`. + + Identical to graph.to_directed(as_view=True) + Note that graph.to_directed defaults to `as_view=False` + while this function always provides a view. + """ + return graph.to_directed(as_view=True) + + +def to_undirected(graph): + """Returns an undirected view of the graph `graph`. + + Identical to graph.to_undirected(as_view=True) + Note that graph.to_undirected defaults to `as_view=False` + while this function always provides a view. + """ + return graph.to_undirected(as_view=True) + + +def create_empty_copy(G, with_data=True): + """Returns a copy of the graph G with all of the edges removed. + + Parameters + ---------- + G : graph + A NetworkX graph + + with_data : bool (default=True) + Propagate Graph and Nodes data to the new graph. + + See Also + -------- + empty_graph + + """ + H = G.__class__() + H.add_nodes_from(G.nodes(data=with_data)) + if with_data: + H.graph.update(G.graph) + return H + + +@nx._dispatchable(preserve_node_attrs=True, mutates_input=True) +def set_node_attributes(G, values, name=None): + """Sets node attributes from a given value or dictionary of values. + + .. Warning:: The call order of arguments `values` and `name` + switched between v1.x & v2.x. + + Parameters + ---------- + G : NetworkX Graph + + values : scalar value, dict-like + What the node attribute should be set to. If `values` is + not a dictionary, then it is treated as a single attribute value + that is then applied to every node in `G`. This means that if + you provide a mutable object, like a list, updates to that object + will be reflected in the node attribute for every node. + The attribute name will be `name`. + + If `values` is a dict or a dict of dict, it should be keyed + by node to either an attribute value or a dict of attribute key/value + pairs used to update the node's attributes. + + name : string (optional, default=None) + Name of the node attribute to set if values is a scalar. + + Examples + -------- + After computing some property of the nodes of a graph, you may want + to assign a node attribute to store the value of that property for + each node:: + + >>> G = nx.path_graph(3) + >>> bb = nx.betweenness_centrality(G) + >>> isinstance(bb, dict) + True + >>> nx.set_node_attributes(G, bb, "betweenness") + >>> G.nodes[1]["betweenness"] + 1.0 + + If you provide a list as the second argument, updates to the list + will be reflected in the node attribute for each node:: + + >>> G = nx.path_graph(3) + >>> labels = [] + >>> nx.set_node_attributes(G, labels, "labels") + >>> labels.append("foo") + >>> G.nodes[0]["labels"] + ['foo'] + >>> G.nodes[1]["labels"] + ['foo'] + >>> G.nodes[2]["labels"] + ['foo'] + + If you provide a dictionary of dictionaries as the second argument, + the outer dictionary is assumed to be keyed by node to an inner + dictionary of node attributes for that node:: + + >>> G = nx.path_graph(3) + >>> attrs = {0: {"attr1": 20, "attr2": "nothing"}, 1: {"attr2": 3}} + >>> nx.set_node_attributes(G, attrs) + >>> G.nodes[0]["attr1"] + 20 + >>> G.nodes[0]["attr2"] + 'nothing' + >>> G.nodes[1]["attr2"] + 3 + >>> G.nodes[2] + {} + + Note that if the dictionary contains nodes that are not in `G`, the + values are silently ignored:: + + >>> G = nx.Graph() + >>> G.add_node(0) + >>> nx.set_node_attributes(G, {0: "red", 1: "blue"}, name="color") + >>> G.nodes[0]["color"] + 'red' + >>> 1 in G.nodes + False + + """ + # Set node attributes based on type of `values` + if name is not None: # `values` must not be a dict of dict + try: # `values` is a dict + for n, v in values.items(): + try: + G.nodes[n][name] = values[n] + except KeyError: + pass + except AttributeError: # `values` is a constant + for n in G: + G.nodes[n][name] = values + else: # `values` must be dict of dict + for n, d in values.items(): + try: + G.nodes[n].update(d) + except KeyError: + pass + nx._clear_cache(G) + + +@nx._dispatchable(node_attrs={"name": "default"}) +def get_node_attributes(G, name, default=None): + """Get node attributes from graph + + Parameters + ---------- + G : NetworkX Graph + + name : string + Attribute name + + default: object (default=None) + Default value of the node attribute if there is no value set for that + node in graph. If `None` then nodes without this attribute are not + included in the returned dict. + + Returns + ------- + Dictionary of attributes keyed by node. + + Examples + -------- + >>> G = nx.Graph() + >>> G.add_nodes_from([1, 2, 3], color="red") + >>> color = nx.get_node_attributes(G, "color") + >>> color[1] + 'red' + >>> G.add_node(4) + >>> color = nx.get_node_attributes(G, "color", default="yellow") + >>> color[4] + 'yellow' + """ + if default is not None: + return {n: d.get(name, default) for n, d in G.nodes.items()} + return {n: d[name] for n, d in G.nodes.items() if name in d} + + +@nx._dispatchable(preserve_node_attrs=True, mutates_input=True) +def remove_node_attributes(G, *attr_names, nbunch=None): + """Remove node attributes from all nodes in the graph. + + Parameters + ---------- + G : NetworkX Graph + + *attr_names : List of Strings + The attribute names to remove from the graph. + + nbunch : List of Nodes + Remove the node attributes only from the nodes in this list. + + Examples + -------- + >>> G = nx.Graph() + >>> G.add_nodes_from([1, 2, 3], color="blue") + >>> nx.get_node_attributes(G, "color") + {1: 'blue', 2: 'blue', 3: 'blue'} + >>> nx.remove_node_attributes(G, "color") + >>> nx.get_node_attributes(G, "color") + {} + """ + + if nbunch is None: + nbunch = G.nodes() + + for attr in attr_names: + for n, d in G.nodes(data=True): + if n in nbunch: + try: + del d[attr] + except KeyError: + pass + + +@nx._dispatchable(preserve_edge_attrs=True, mutates_input=True) +def set_edge_attributes(G, values, name=None): + """Sets edge attributes from a given value or dictionary of values. + + .. Warning:: The call order of arguments `values` and `name` + switched between v1.x & v2.x. + + Parameters + ---------- + G : NetworkX Graph + + values : scalar value, dict-like + What the edge attribute should be set to. If `values` is + not a dictionary, then it is treated as a single attribute value + that is then applied to every edge in `G`. This means that if + you provide a mutable object, like a list, updates to that object + will be reflected in the edge attribute for each edge. The attribute + name will be `name`. + + If `values` is a dict or a dict of dict, it should be keyed + by edge tuple to either an attribute value or a dict of attribute + key/value pairs used to update the edge's attributes. + For multigraphs, the edge tuples must be of the form ``(u, v, key)``, + where `u` and `v` are nodes and `key` is the edge key. + For non-multigraphs, the keys must be tuples of the form ``(u, v)``. + + name : string (optional, default=None) + Name of the edge attribute to set if values is a scalar. + + Examples + -------- + After computing some property of the edges of a graph, you may want + to assign a edge attribute to store the value of that property for + each edge:: + + >>> G = nx.path_graph(3) + >>> bb = nx.edge_betweenness_centrality(G, normalized=False) + >>> nx.set_edge_attributes(G, bb, "betweenness") + >>> G.edges[1, 2]["betweenness"] + 2.0 + + If you provide a list as the second argument, updates to the list + will be reflected in the edge attribute for each edge:: + + >>> labels = [] + >>> nx.set_edge_attributes(G, labels, "labels") + >>> labels.append("foo") + >>> G.edges[0, 1]["labels"] + ['foo'] + >>> G.edges[1, 2]["labels"] + ['foo'] + + If you provide a dictionary of dictionaries as the second argument, + the entire dictionary will be used to update edge attributes:: + + >>> G = nx.path_graph(3) + >>> attrs = {(0, 1): {"attr1": 20, "attr2": "nothing"}, (1, 2): {"attr2": 3}} + >>> nx.set_edge_attributes(G, attrs) + >>> G[0][1]["attr1"] + 20 + >>> G[0][1]["attr2"] + 'nothing' + >>> G[1][2]["attr2"] + 3 + + The attributes of one Graph can be used to set those of another. + + >>> H = nx.path_graph(3) + >>> nx.set_edge_attributes(H, G.edges) + + Note that if the dict contains edges that are not in `G`, they are + silently ignored:: + + >>> G = nx.Graph([(0, 1)]) + >>> nx.set_edge_attributes(G, {(1, 2): {"weight": 2.0}}) + >>> (1, 2) in G.edges() + False + + For multigraphs, the `values` dict is expected to be keyed by 3-tuples + including the edge key:: + + >>> MG = nx.MultiGraph() + >>> edges = [(0, 1), (0, 1)] + >>> MG.add_edges_from(edges) # Returns list of edge keys + [0, 1] + >>> attributes = {(0, 1, 0): {"cost": 21}, (0, 1, 1): {"cost": 7}} + >>> nx.set_edge_attributes(MG, attributes) + >>> MG[0][1][0]["cost"] + 21 + >>> MG[0][1][1]["cost"] + 7 + + If MultiGraph attributes are desired for a Graph, you must convert the 3-tuple + multiedge to a 2-tuple edge and the last multiedge's attribute value will + overwrite the previous values. Continuing from the previous case we get:: + + >>> H = nx.path_graph([0, 1, 2]) + >>> nx.set_edge_attributes(H, {(u, v): ed for u, v, ed in MG.edges.data()}) + >>> nx.get_edge_attributes(H, "cost") + {(0, 1): 7} + + """ + if name is not None: + # `values` does not contain attribute names + try: + # if `values` is a dict using `.items()` => {edge: value} + if G.is_multigraph(): + for (u, v, key), value in values.items(): + try: + G._adj[u][v][key][name] = value + except KeyError: + pass + else: + for (u, v), value in values.items(): + try: + G._adj[u][v][name] = value + except KeyError: + pass + except AttributeError: + # treat `values` as a constant + for u, v, data in G.edges(data=True): + data[name] = values + else: + # `values` consists of doct-of-dict {edge: {attr: value}} shape + if G.is_multigraph(): + for (u, v, key), d in values.items(): + try: + G._adj[u][v][key].update(d) + except KeyError: + pass + else: + for (u, v), d in values.items(): + try: + G._adj[u][v].update(d) + except KeyError: + pass + nx._clear_cache(G) + + +@nx._dispatchable(edge_attrs={"name": "default"}) +def get_edge_attributes(G, name, default=None): + """Get edge attributes from graph + + Parameters + ---------- + G : NetworkX Graph + + name : string + Attribute name + + default: object (default=None) + Default value of the edge attribute if there is no value set for that + edge in graph. If `None` then edges without this attribute are not + included in the returned dict. + + Returns + ------- + Dictionary of attributes keyed by edge. For (di)graphs, the keys are + 2-tuples of the form: (u, v). For multi(di)graphs, the keys are 3-tuples of + the form: (u, v, key). + + Examples + -------- + >>> G = nx.Graph() + >>> nx.add_path(G, [1, 2, 3], color="red") + >>> color = nx.get_edge_attributes(G, "color") + >>> color[(1, 2)] + 'red' + >>> G.add_edge(3, 4) + >>> color = nx.get_edge_attributes(G, "color", default="yellow") + >>> color[(3, 4)] + 'yellow' + """ + if G.is_multigraph(): + edges = G.edges(keys=True, data=True) + else: + edges = G.edges(data=True) + if default is not None: + return {x[:-1]: x[-1].get(name, default) for x in edges} + return {x[:-1]: x[-1][name] for x in edges if name in x[-1]} + + +@nx._dispatchable(preserve_edge_attrs=True, mutates_input=True) +def remove_edge_attributes(G, *attr_names, ebunch=None): + """Remove edge attributes from all edges in the graph. + + Parameters + ---------- + G : NetworkX Graph + + *attr_names : List of Strings + The attribute names to remove from the graph. + + Examples + -------- + >>> G = nx.path_graph(3) + >>> nx.set_edge_attributes(G, {(u, v): u + v for u, v in G.edges()}, name="weight") + >>> nx.get_edge_attributes(G, "weight") + {(0, 1): 1, (1, 2): 3} + >>> remove_edge_attributes(G, "weight") + >>> nx.get_edge_attributes(G, "weight") + {} + """ + if ebunch is None: + ebunch = G.edges(keys=True) if G.is_multigraph() else G.edges() + + for attr in attr_names: + edges = ( + G.edges(keys=True, data=True) if G.is_multigraph() else G.edges(data=True) + ) + for *e, d in edges: + if tuple(e) in ebunch: + try: + del d[attr] + except KeyError: + pass + + +def all_neighbors(graph, node): + """Returns all of the neighbors of a node in the graph. + + If the graph is directed returns predecessors as well as successors. + + Parameters + ---------- + graph : NetworkX graph + Graph to find neighbors. + node : node + The node whose neighbors will be returned. + + Returns + ------- + neighbors : iterator + Iterator of neighbors + + Raises + ------ + NetworkXError + If `node` is not in the graph. + + Examples + -------- + For undirected graphs, this function is equivalent to ``G.neighbors(node)``. + + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> list(nx.all_neighbors(G, 1)) + [0, 2] + + For directed graphs, this function returns both predecessors and successors, + which may include duplicates if a node is both a predecessor and successor + (e.g., in bidirectional edges or self-loops). + + >>> DG = nx.DiGraph([(0, 1), (1, 2), (2, 1)]) + >>> list(nx.all_neighbors(DG, 1)) + [0, 2, 2] + + Notes + ----- + This function iterates over all neighbors (both predecessors and successors). + + See Also + -------- + Graph.neighbors : Returns successors for both Graph and DiGraph + DiGraph.predecessors : Returns predecessors for directed graphs only + DiGraph.successors : Returns successors for directed graphs only + """ + if graph.is_directed(): + values = chain(graph.predecessors(node), graph.successors(node)) + else: + values = graph.neighbors(node) + return values + + +def non_neighbors(graph, node): + """Returns the non-neighbors of the node in the graph. + + Parameters + ---------- + graph : NetworkX graph + Graph to find neighbors. + + node : node + The node whose neighbors will be returned. + + Returns + ------- + non_neighbors : set + Set of nodes in the graph that are not neighbors of the node. + """ + return graph._adj.keys() - graph._adj[node].keys() - {node} + + +def non_edges(graph): + """Returns the nonexistent edges in the graph. + + Parameters + ---------- + graph : NetworkX graph. + Graph to find nonexistent edges. + + Returns + ------- + non_edges : iterator + Iterator of edges that are not in the graph. + """ + if graph.is_directed(): + for u in graph: + for v in non_neighbors(graph, u): + yield (u, v) + else: + nodes = set(graph) + while nodes: + u = nodes.pop() + for v in nodes - set(graph[u]): + yield (u, v) + + +@not_implemented_for("directed") +def common_neighbors(G, u, v): + """Returns the common neighbors of two nodes in a graph. + + Parameters + ---------- + G : graph + A NetworkX undirected graph. + + u, v : nodes + Nodes in the graph. + + Returns + ------- + cnbors : set + Set of common neighbors of u and v in the graph. + + Raises + ------ + NetworkXError + If u or v is not a node in the graph. + + Examples + -------- + >>> G = nx.complete_graph(5) + >>> sorted(nx.common_neighbors(G, 0, 1)) + [2, 3, 4] + """ + if u not in G: + raise nx.NetworkXError("u is not in the graph.") + if v not in G: + raise nx.NetworkXError("v is not in the graph.") + + return G._adj[u].keys() & G._adj[v].keys() - {u, v} + + +@nx._dispatchable(preserve_edge_attrs=True) +def is_weighted(G, edge=None, weight="weight"): + """Returns True if `G` has weighted edges. + + Parameters + ---------- + G : graph + A NetworkX graph. + + edge : tuple, optional + A 2-tuple specifying the only edge in `G` that will be tested. If + None, then every edge in `G` is tested. + + weight: string, optional + The attribute name used to query for edge weights. + + Returns + ------- + bool + A boolean signifying if `G`, or the specified edge, is weighted. + + Raises + ------ + NetworkXError + If the specified edge does not exist. + + Examples + -------- + >>> G = nx.path_graph(4) + >>> nx.is_weighted(G) + False + >>> nx.is_weighted(G, (2, 3)) + False + + >>> G = nx.DiGraph() + >>> G.add_edge(1, 2, weight=1) + >>> nx.is_weighted(G) + True + + """ + if edge is not None: + data = G.get_edge_data(*edge) + if data is None: + msg = f"Edge {edge!r} does not exist." + raise nx.NetworkXError(msg) + return weight in data + + if is_empty(G): + # Special handling required since: all([]) == True + return False + + return all(weight in data for u, v, data in G.edges(data=True)) + + +@nx._dispatchable(edge_attrs="weight") +def is_negatively_weighted(G, edge=None, weight="weight"): + """Returns True if `G` has negatively weighted edges. + + Parameters + ---------- + G : graph + A NetworkX graph. + + edge : tuple, optional + A 2-tuple specifying the only edge in `G` that will be tested. If + None, then every edge in `G` is tested. + + weight: string, optional + The attribute name used to query for edge weights. + + Returns + ------- + bool + A boolean signifying if `G`, or the specified edge, is negatively + weighted. + + Raises + ------ + NetworkXError + If the specified edge does not exist. + + Examples + -------- + >>> G = nx.Graph() + >>> G.add_edges_from([(1, 3), (2, 4), (2, 6)]) + >>> G.add_edge(1, 2, weight=4) + >>> nx.is_negatively_weighted(G, (1, 2)) + False + >>> G[2][4]["weight"] = -2 + >>> nx.is_negatively_weighted(G) + True + >>> G = nx.DiGraph() + >>> edges = [("0", "3", 3), ("0", "1", -5), ("1", "0", -2)] + >>> G.add_weighted_edges_from(edges) + >>> nx.is_negatively_weighted(G) + True + + """ + if edge is not None: + data = G.get_edge_data(*edge) + if data is None: + msg = f"Edge {edge!r} does not exist." + raise nx.NetworkXError(msg) + return weight in data and data[weight] < 0 + + return any(weight in data and data[weight] < 0 for u, v, data in G.edges(data=True)) + + +@nx._dispatchable +def is_empty(G): + """Returns True if `G` has no edges. + + Parameters + ---------- + G : graph + A NetworkX graph. + + Returns + ------- + bool + True if `G` has no edges, and False otherwise. + + Notes + ----- + An empty graph can have nodes but not edges. The empty graph with zero + nodes is known as the null graph. This is an $O(n)$ operation where n + is the number of nodes in the graph. + + """ + return not any(G._adj.values()) + + +def nodes_with_selfloops(G): + """Returns an iterator over nodes with self loops. + + A node with a self loop has an edge with both ends adjacent + to that node. + + Returns + ------- + nodelist : iterator + A iterator over nodes with self loops. + + See Also + -------- + selfloop_edges, number_of_selfloops + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_edge(1, 1) + >>> G.add_edge(1, 2) + >>> list(nx.nodes_with_selfloops(G)) + [1] + + """ + return (n for n, nbrs in G._adj.items() if n in nbrs) + + +def selfloop_edges(G, data=False, keys=False, default=None): + """Returns an iterator over selfloop edges. + + A selfloop edge has the same node at both ends. + + Parameters + ---------- + G : graph + A NetworkX graph. + data : string or bool, optional (default=False) + Return selfloop edges as two tuples (u, v) (data=False) + or three-tuples (u, v, datadict) (data=True) + or three-tuples (u, v, datavalue) (data='attrname') + keys : bool, optional (default=False) + If True, return edge keys with each edge. + default : value, optional (default=None) + Value used for edges that don't have the requested attribute. + Only relevant if data is not True or False. + + Returns + ------- + edgeiter : iterator over edge tuples + An iterator over all selfloop edges. + + See Also + -------- + nodes_with_selfloops, number_of_selfloops + + Examples + -------- + >>> G = nx.MultiGraph() # or Graph, DiGraph, MultiDiGraph, etc + >>> ekey = G.add_edge(1, 1) + >>> ekey = G.add_edge(1, 2) + >>> list(nx.selfloop_edges(G)) + [(1, 1)] + >>> list(nx.selfloop_edges(G, data=True)) + [(1, 1, {})] + >>> list(nx.selfloop_edges(G, keys=True)) + [(1, 1, 0)] + >>> list(nx.selfloop_edges(G, keys=True, data=True)) + [(1, 1, 0, {})] + """ + if data is True: + if G.is_multigraph(): + if keys is True: + return ( + (n, n, k, d) + for n, nbrs in G._adj.items() + if n in nbrs + for k, d in nbrs[n].items() + ) + else: + return ( + (n, n, d) + for n, nbrs in G._adj.items() + if n in nbrs + for d in nbrs[n].values() + ) + else: + return ((n, n, nbrs[n]) for n, nbrs in G._adj.items() if n in nbrs) + elif data is not False: + if G.is_multigraph(): + if keys is True: + return ( + (n, n, k, d.get(data, default)) + for n, nbrs in G._adj.items() + if n in nbrs + for k, d in nbrs[n].items() + ) + else: + return ( + (n, n, d.get(data, default)) + for n, nbrs in G._adj.items() + if n in nbrs + for d in nbrs[n].values() + ) + else: + return ( + (n, n, nbrs[n].get(data, default)) + for n, nbrs in G._adj.items() + if n in nbrs + ) + else: + if G.is_multigraph(): + if keys is True: + return ( + (n, n, k) + for n, nbrs in G._adj.items() + if n in nbrs + for k in nbrs[n] + ) + else: + return ( + (n, n) + for n, nbrs in G._adj.items() + if n in nbrs + for i in range(len(nbrs[n])) # for easy edge removal (#4068) + ) + else: + return ((n, n) for n, nbrs in G._adj.items() if n in nbrs) + + +@nx._dispatchable +def number_of_selfloops(G): + """Returns the number of selfloop edges. + + A selfloop edge has the same node at both ends. + + Returns + ------- + nloops : int + The number of selfloops. + + See Also + -------- + nodes_with_selfloops, selfloop_edges + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_edge(1, 1) + >>> G.add_edge(1, 2) + >>> nx.number_of_selfloops(G) + 1 + """ + return sum(1 for _ in nx.selfloop_edges(G)) + + +def is_path(G, path): + """Returns whether or not the specified path exists. + + For it to return True, every node on the path must exist and + each consecutive pair must be connected via one or more edges. + + Parameters + ---------- + G : graph + A NetworkX graph. + + path : list + A list of nodes which defines the path to traverse + + Returns + ------- + bool + True if `path` is a valid path in `G` + + """ + try: + return all(nbr in G._adj[node] for node, nbr in nx.utils.pairwise(path)) + except (KeyError, TypeError): + return False + + +def path_weight(G, path, weight): + """Returns total cost associated with specified path and weight + + Parameters + ---------- + G : graph + A NetworkX graph. + + path: list + A list of node labels which defines the path to traverse + + weight: string + A string indicating which edge attribute to use for path cost + + Returns + ------- + cost: int or float + An integer or a float representing the total cost with respect to the + specified weight of the specified path + + Raises + ------ + NetworkXNoPath + If the specified edge does not exist. + """ + multigraph = G.is_multigraph() + cost = 0 + + if not nx.is_path(G, path): + raise nx.NetworkXNoPath("path does not exist") + for node, nbr in nx.utils.pairwise(path): + if multigraph: + cost += min(v[weight] for v in G._adj[node][nbr].values()) + else: + cost += G._adj[node][nbr][weight] + return cost + + +def describe(G, describe_hook=None): + """Prints a description of the graph G. + + By default, the description includes some basic properties of the graph. + You can also provide additional functions to compute and include + more properties in the description. + + Parameters + ---------- + G : graph + A NetworkX graph. + + describe_hook: callable, optional (default=None) + A function that takes a graph as input and returns a + dictionary of additional properties to include in the description. + The keys of the dictionary are the property names, and the values + are the corresponding property values. + + Examples + -------- + >>> G = nx.path_graph(5) + >>> nx.describe(G) + Number of nodes : 5 + Number of edges : 4 + Directed : False + Multigraph : False + Tree : True + Bipartite : True + Average degree (min, max) : 1.60 (1, 2) + Number of connected components : 1 + + >>> def augment_description(G): + ... return {"Average Shortest Path Length": nx.average_shortest_path_length(G)} + >>> nx.describe(G, describe_hook=augment_description) + Number of nodes : 5 + Number of edges : 4 + Directed : False + Multigraph : False + Tree : True + Bipartite : True + Average degree (min, max) : 1.60 (1, 2) + Number of connected components : 1 + Average Shortest Path Length : 2.0 + + >>> G.name = "Path Graph of 5 nodes" + >>> nx.describe(G) + Name of Graph : Path Graph of 5 nodes + Number of nodes : 5 + Number of edges : 4 + Directed : False + Multigraph : False + Tree : True + Bipartite : True + Average degree (min, max) : 1.60 (1, 2) + Number of connected components : 1 + + """ + info_dict = _create_describe_info_dict(G) + + if describe_hook is not None: + additional_info = describe_hook(G) + info_dict.update(additional_info) + + max_key_len = max(len(k) for k in info_dict) + for key, val in info_dict.items(): + print(f"{key:<{max_key_len}} : {val}") + + +def _create_describe_info_dict(G): + info = {} + if G.name != "": + info["Name of Graph"] = G.name + info.update( + { + "Number of nodes": len(G), + "Number of edges": G.number_of_edges(), + "Directed": G.is_directed(), + "Multigraph": G.is_multigraph(), + "Tree": nx.is_tree(G), + "Bipartite": nx.is_bipartite(G), + } + ) + if len(G) == 0: + return info + + degree_values = dict(nx.degree(G)).values() + avg_degree = sum(degree_values) / len(G) + max_degree, min_degree = max(degree_values), min(degree_values) + info["Average degree (min, max)"] = f"{avg_degree:.2f} ({min_degree}, {max_degree})" + + if G.is_directed(): + info["Number of strongly connected components"] = ( + nx.number_strongly_connected_components(G) + ) + info["Number of weakly connected components"] = ( + nx.number_weakly_connected_components(G) + ) + else: + info["Number of connected components"] = nx.number_connected_components(G) + return info diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/graph.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/graph.py new file mode 100644 index 0000000000000000000000000000000000000000..0eb184f4c5bfdd2a49890a480c2be08b4c0190d4 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/graph.py @@ -0,0 +1,2082 @@ +"""Base class for undirected graphs. + +The Graph class allows any hashable object as a node +and can associate key/value attribute pairs with each undirected edge. + +Self-loops are allowed but multiple edges are not (see MultiGraph). + +For directed graphs see DiGraph and MultiDiGraph. +""" + +from copy import deepcopy +from functools import cached_property + +import networkx as nx +from networkx import convert +from networkx.classes.coreviews import AdjacencyView +from networkx.classes.reportviews import DegreeView, EdgeView, NodeView +from networkx.exception import NetworkXError + +__all__ = ["Graph"] + + +class _CachedPropertyResetterAdj: + """Data Descriptor class for _adj that resets ``adj`` cached_property when needed + + This assumes that the ``cached_property`` ``G.adj`` should be reset whenever + ``G._adj`` is set to a new value. + + This object sits on a class and ensures that any instance of that + class clears its cached property "adj" whenever the underlying + instance attribute "_adj" is set to a new object. It only affects + the set process of the obj._adj attribute. All get/del operations + act as they normally would. + + For info on Data Descriptors see: https://docs.python.org/3/howto/descriptor.html + """ + + def __set__(self, obj, value): + od = obj.__dict__ + od["_adj"] = value + # reset cached properties + props = ["adj", "edges", "degree"] + for prop in props: + if prop in od: + del od[prop] + + +class _CachedPropertyResetterNode: + """Data Descriptor class for _node that resets ``nodes`` cached_property when needed + + This assumes that the ``cached_property`` ``G.node`` should be reset whenever + ``G._node`` is set to a new value. + + This object sits on a class and ensures that any instance of that + class clears its cached property "nodes" whenever the underlying + instance attribute "_node" is set to a new object. It only affects + the set process of the obj._adj attribute. All get/del operations + act as they normally would. + + For info on Data Descriptors see: https://docs.python.org/3/howto/descriptor.html + """ + + def __set__(self, obj, value): + od = obj.__dict__ + od["_node"] = value + # reset cached properties + if "nodes" in od: + del od["nodes"] + + +class Graph: + """ + Base class for undirected graphs. + + A Graph stores nodes and edges with optional data, or attributes. + + Graphs hold undirected edges. Self loops are allowed but multiple + (parallel) edges are not. + + Nodes can be arbitrary (hashable) Python objects with optional + key/value attributes, except that `None` is not allowed as a node. + + Edges are represented as links between nodes with optional + key/value attributes. + + Parameters + ---------- + incoming_graph_data : input graph (optional, default: None) + Data to initialize graph. If None (default) an empty + graph is created. The data can be any format that is supported + by the to_networkx_graph() function, currently including edge list, + dict of dicts, dict of lists, NetworkX graph, 2D NumPy array, SciPy + sparse matrix, or PyGraphviz graph. + + attr : keyword arguments, optional (default= no attributes) + Attributes to add to graph as key=value pairs. + + See Also + -------- + DiGraph + MultiGraph + MultiDiGraph + + Examples + -------- + Create an empty graph structure (a "null graph") with no nodes and + no edges. + + >>> G = nx.Graph() + + G can be grown in several ways. + + **Nodes:** + + Add one node at a time: + + >>> G.add_node(1) + + Add the nodes from any container (a list, dict, set or + even the lines from a file or the nodes from another graph). + + >>> G.add_nodes_from([2, 3]) + >>> G.add_nodes_from(range(100, 110)) + >>> H = nx.path_graph(10) + >>> G.add_nodes_from(H) + + In addition to strings and integers any hashable Python object + (except None) can represent a node, e.g. a customized node object, + or even another Graph. + + >>> G.add_node(H) + + **Edges:** + + G can also be grown by adding edges. + + Add one edge, + + >>> G.add_edge(1, 2) + + a list of edges, + + >>> G.add_edges_from([(1, 2), (1, 3)]) + + or a collection of edges, + + >>> G.add_edges_from(H.edges) + + If some edges connect nodes not yet in the graph, the nodes + are added automatically. There are no errors when adding + nodes or edges that already exist. + + **Attributes:** + + Each graph, node, and edge can hold key/value attribute pairs + in an associated attribute dictionary (the keys must be hashable). + By default these are empty, but can be added or changed using + add_edge, add_node or direct manipulation of the attribute + dictionaries named graph, node and edge respectively. + + >>> G = nx.Graph(day="Friday") + >>> G.graph + {'day': 'Friday'} + + Add node attributes using add_node(), add_nodes_from() or G.nodes + + >>> G.add_node(1, time="5pm") + >>> G.add_nodes_from([3], time="2pm") + >>> G.nodes[1] + {'time': '5pm'} + >>> G.nodes[1]["room"] = 714 # node must exist already to use G.nodes + >>> del G.nodes[1]["room"] # remove attribute + >>> list(G.nodes(data=True)) + [(1, {'time': '5pm'}), (3, {'time': '2pm'})] + + Add edge attributes using add_edge(), add_edges_from(), subscript + notation, or G.edges. + + >>> G.add_edge(1, 2, weight=4.7) + >>> G.add_edges_from([(3, 4), (4, 5)], color="red") + >>> G.add_edges_from([(1, 2, {"color": "blue"}), (2, 3, {"weight": 8})]) + >>> G[1][2]["weight"] = 4.7 + >>> G.edges[1, 2]["weight"] = 4 + + Warning: we protect the graph data structure by making `G.edges` a + read-only dict-like structure. However, you can assign to attributes + in e.g. `G.edges[1, 2]`. Thus, use 2 sets of brackets to add/change + data attributes: `G.edges[1, 2]['weight'] = 4` + (For multigraphs: `MG.edges[u, v, key][name] = value`). + + **Shortcuts:** + + Many common graph features allow python syntax to speed reporting. + + >>> 1 in G # check if node in graph + True + >>> [n for n in G if n < 3] # iterate through nodes + [1, 2] + >>> len(G) # number of nodes in graph + 5 + + Often the best way to traverse all edges of a graph is via the neighbors. + The neighbors are reported as an adjacency-dict `G.adj` or `G.adjacency()` + + >>> for n, nbrsdict in G.adjacency(): + ... for nbr, eattr in nbrsdict.items(): + ... if "weight" in eattr: + ... # Do something useful with the edges + ... pass + + But the edges() method is often more convenient: + + >>> for u, v, weight in G.edges.data("weight"): + ... if weight is not None: + ... # Do something useful with the edges + ... pass + + **Reporting:** + + Simple graph information is obtained using object-attributes and methods. + Reporting typically provides views instead of containers to reduce memory + usage. The views update as the graph is updated similarly to dict-views. + The objects `nodes`, `edges` and `adj` provide access to data attributes + via lookup (e.g. `nodes[n]`, `edges[u, v]`, `adj[u][v]`) and iteration + (e.g. `nodes.items()`, `nodes.data('color')`, + `nodes.data('color', default='blue')` and similarly for `edges`) + Views exist for `nodes`, `edges`, `neighbors()`/`adj` and `degree`. + + For details on these and other miscellaneous methods, see below. + + **Subclasses (Advanced):** + + The Graph class uses a dict-of-dict-of-dict data structure. + The outer dict (node_dict) holds adjacency information keyed by node. + The next dict (adjlist_dict) represents the adjacency information and holds + edge data keyed by neighbor. The inner dict (edge_attr_dict) represents + the edge data and holds edge attribute values keyed by attribute names. + + Each of these three dicts can be replaced in a subclass by a user defined + dict-like object. In general, the dict-like features should be + maintained but extra features can be added. To replace one of the + dicts create a new graph class by changing the class(!) variable + holding the factory for that dict-like structure. + + node_dict_factory : function, (default: dict) + Factory function to be used to create the dict containing node + attributes, keyed by node id. + It should require no arguments and return a dict-like object + + node_attr_dict_factory: function, (default: dict) + Factory function to be used to create the node attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object + + adjlist_outer_dict_factory : function, (default: dict) + Factory function to be used to create the outer-most dict + in the data structure that holds adjacency info keyed by node. + It should require no arguments and return a dict-like object. + + adjlist_inner_dict_factory : function, (default: dict) + Factory function to be used to create the adjacency list + dict which holds edge data keyed by neighbor. + It should require no arguments and return a dict-like object + + edge_attr_dict_factory : function, (default: dict) + Factory function to be used to create the edge attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object. + + graph_attr_dict_factory : function, (default: dict) + Factory function to be used to create the graph attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object. + + Typically, if your extension doesn't impact the data structure all + methods will inherit without issue except: `to_directed/to_undirected`. + By default these methods create a DiGraph/Graph class and you probably + want them to create your extension of a DiGraph/Graph. To facilitate + this we define two class variables that you can set in your subclass. + + to_directed_class : callable, (default: DiGraph or MultiDiGraph) + Class to create a new graph structure in the `to_directed` method. + If `None`, a NetworkX class (DiGraph or MultiDiGraph) is used. + + to_undirected_class : callable, (default: Graph or MultiGraph) + Class to create a new graph structure in the `to_undirected` method. + If `None`, a NetworkX class (Graph or MultiGraph) is used. + + **Subclassing Example** + + Create a low memory graph class that effectively disallows edge + attributes by using a single attribute dict for all edges. + This reduces the memory used, but you lose edge attributes. + + >>> class ThinGraph(nx.Graph): + ... all_edge_dict = {"weight": 1} + ... + ... def single_edge_dict(self): + ... return self.all_edge_dict + ... + ... edge_attr_dict_factory = single_edge_dict + >>> G = ThinGraph() + >>> G.add_edge(2, 1) + >>> G[2][1] + {'weight': 1} + >>> G.add_edge(2, 2) + >>> G[2][1] is G[2][2] + True + """ + + __networkx_backend__ = "networkx" + + _adj = _CachedPropertyResetterAdj() + _node = _CachedPropertyResetterNode() + + node_dict_factory = dict + node_attr_dict_factory = dict + adjlist_outer_dict_factory = dict + adjlist_inner_dict_factory = dict + edge_attr_dict_factory = dict + graph_attr_dict_factory = dict + + def to_directed_class(self): + """Returns the class to use for empty directed copies. + + If you subclass the base classes, use this to designate + what directed class to use for `to_directed()` copies. + """ + return nx.DiGraph + + def to_undirected_class(self): + """Returns the class to use for empty undirected copies. + + If you subclass the base classes, use this to designate + what directed class to use for `to_directed()` copies. + """ + return Graph + + # This __new__ method just does what Python itself does automatically. + # We include it here as part of the dispatchable/backend interface. + # If your goal is to understand how the graph classes work, you can ignore + # this method, even when subclassing the base classes. If you are subclassing + # in order to provide a backend that allows class instantiation, this method + # can be overridden to return your own backend graph class. + @nx._dispatchable(name="graph__new__", graphs=None, returns_graph=True) + def __new__(cls, *args, **kwargs): + return object.__new__(cls) + + def __init__(self, incoming_graph_data=None, **attr): + """Initialize a graph with edges, name, or graph attributes. + + Parameters + ---------- + incoming_graph_data : input graph (optional, default: None) + Data to initialize graph. If None (default) an empty + graph is created. The data can be an edge list, or any + NetworkX graph object. If the corresponding optional Python + packages are installed the data can also be a 2D NumPy array, a + SciPy sparse array, or a PyGraphviz graph. + + attr : keyword arguments, optional (default= no attributes) + Attributes to add to graph as key=value pairs. + + See Also + -------- + convert + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G = nx.Graph(name="my graph") + >>> e = [(1, 2), (2, 3), (3, 4)] # list of edges + >>> G = nx.Graph(e) + + Arbitrary graph attribute pairs (key=value) may be assigned + + >>> G = nx.Graph(e, day="Friday") + >>> G.graph + {'day': 'Friday'} + + """ + self.graph = self.graph_attr_dict_factory() # dictionary for graph attributes + self._node = self.node_dict_factory() # empty node attribute dict + self._adj = self.adjlist_outer_dict_factory() # empty adjacency dict + self.__networkx_cache__ = {} + # attempt to load graph with data + if incoming_graph_data is not None: + convert.to_networkx_graph(incoming_graph_data, create_using=self) + # load graph attributes (must be after convert) + attr.pop("backend", None) # Ignore explicit `backend="networkx"` + self.graph.update(attr) + + @cached_property + def adj(self): + """Graph adjacency object holding the neighbors of each node. + + This object is a read-only dict-like structure with node keys + and neighbor-dict values. The neighbor-dict is keyed by neighbor + to the edge-data-dict. So `G.adj[3][2]['color'] = 'blue'` sets + the color of the edge `(3, 2)` to `"blue"`. + + Iterating over G.adj behaves like a dict. Useful idioms include + `for nbr, datadict in G.adj[n].items():`. + + The neighbor information is also provided by subscripting the graph. + So `for nbr, foovalue in G[node].data('foo', default=1):` works. + + For directed graphs, `G.adj` holds outgoing (successor) info. + """ + return AdjacencyView(self._adj) + + @property + def name(self): + """String identifier of the graph. + + This graph attribute appears in the attribute dict G.graph + keyed by the string `"name"`. as well as an attribute (technically + a property) `G.name`. This is entirely user controlled. + """ + return self.graph.get("name", "") + + @name.setter + def name(self, s): + self.graph["name"] = s + nx._clear_cache(self) + + def __str__(self): + """Returns a short summary of the graph. + + Returns + ------- + info : string + Graph information including the graph name (if any), graph type, and the + number of nodes and edges. + + Examples + -------- + >>> G = nx.Graph(name="foo") + >>> str(G) + "Graph named 'foo' with 0 nodes and 0 edges" + + >>> G = nx.path_graph(3) + >>> str(G) + 'Graph with 3 nodes and 2 edges' + + """ + return "".join( + [ + type(self).__name__, + f" named {self.name!r}" if self.name else "", + f" with {self.number_of_nodes()} nodes and {self.number_of_edges()} edges", + ] + ) + + def __iter__(self): + """Iterate over the nodes. Use: 'for n in G'. + + Returns + ------- + niter : iterator + An iterator over all nodes in the graph. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> [n for n in G] + [0, 1, 2, 3] + >>> list(G) + [0, 1, 2, 3] + """ + return iter(self._node) + + def __contains__(self, n): + """Returns True if n is a node, False otherwise. Use: 'n in G'. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> 1 in G + True + """ + try: + return n in self._node + except TypeError: + return False + + def __len__(self): + """Returns the number of nodes in the graph. Use: 'len(G)'. + + Returns + ------- + nnodes : int + The number of nodes in the graph. + + See Also + -------- + number_of_nodes: identical method + order: identical method + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> len(G) + 4 + + """ + return len(self._node) + + def __getitem__(self, n): + """Returns a dict of neighbors of node n. Use: 'G[n]'. + + Parameters + ---------- + n : node + A node in the graph. + + Returns + ------- + adj_dict : dictionary + The adjacency dictionary for nodes connected to n. + + Notes + ----- + G[n] is the same as G.adj[n] and similar to G.neighbors(n) + (which is an iterator over G.adj[n]) + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G[0] + AtlasView({1: {}}) + """ + return self.adj[n] + + def add_node(self, node_for_adding, **attr): + """Add a single node `node_for_adding` and update node attributes. + + Parameters + ---------- + node_for_adding : node + A node can be any hashable Python object except None. + attr : keyword arguments, optional + Set or change node attributes using key=value. + + See Also + -------- + add_nodes_from + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_node(1) + >>> G.add_node("Hello") + >>> K3 = nx.Graph([(0, 1), (1, 2), (2, 0)]) + >>> G.add_node(K3) + >>> G.number_of_nodes() + 3 + + Use keywords set/change node attributes: + + >>> G.add_node(1, size=10) + >>> G.add_node(3, weight=0.4, UTM=("13S", 382871, 3972649)) + + Notes + ----- + A hashable object is one that can be used as a key in a Python + dictionary. This includes strings, numbers, tuples of strings + and numbers, etc. + + On many platforms hashable items also include mutables such as + NetworkX Graphs, though one should be careful that the hash + doesn't change on mutables. + """ + if node_for_adding not in self._node: + if node_for_adding is None: + raise ValueError("None cannot be a node") + self._adj[node_for_adding] = self.adjlist_inner_dict_factory() + attr_dict = self._node[node_for_adding] = self.node_attr_dict_factory() + attr_dict.update(attr) + else: # update attr even if node already exists + self._node[node_for_adding].update(attr) + nx._clear_cache(self) + + def add_nodes_from(self, nodes_for_adding, **attr): + """Add multiple nodes. + + Parameters + ---------- + nodes_for_adding : iterable container + A container of nodes (list, dict, set, etc.). + OR + A container of (node, attribute dict) tuples. + Node attributes are updated using the attribute dict. + attr : keyword arguments, optional (default= no attributes) + Update attributes for all nodes in nodes. + Node attributes specified in nodes as a tuple take + precedence over attributes specified via keyword arguments. + + See Also + -------- + add_node + + Notes + ----- + When adding nodes from an iterator over the graph you are changing, + a `RuntimeError` can be raised with message: + `RuntimeError: dictionary changed size during iteration`. This + happens when the graph's underlying dictionary is modified during + iteration. To avoid this error, evaluate the iterator into a separate + object, e.g. by using `list(iterator_of_nodes)`, and pass this + object to `G.add_nodes_from`. + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_nodes_from("Hello") + >>> K3 = nx.Graph([(0, 1), (1, 2), (2, 0)]) + >>> G.add_nodes_from(K3) + >>> sorted(G.nodes(), key=str) + [0, 1, 2, 'H', 'e', 'l', 'o'] + + Use keywords to update specific node attributes for every node. + + >>> G.add_nodes_from([1, 2], size=10) + >>> G.add_nodes_from([3, 4], weight=0.4) + + Use (node, attrdict) tuples to update attributes for specific nodes. + + >>> G.add_nodes_from([(1, dict(size=11)), (2, {"color": "blue"})]) + >>> G.nodes[1]["size"] + 11 + >>> H = nx.Graph() + >>> H.add_nodes_from(G.nodes(data=True)) + >>> H.nodes[1]["size"] + 11 + + Evaluate an iterator over a graph if using it to modify the same graph + + >>> G = nx.Graph([(0, 1), (1, 2), (3, 4)]) + >>> # wrong way - will raise RuntimeError + >>> # G.add_nodes_from(n + 1 for n in G.nodes) + >>> # correct way + >>> G.add_nodes_from(list(n + 1 for n in G.nodes)) + """ + for n in nodes_for_adding: + try: + newnode = n not in self._node + newdict = attr + except TypeError: + n, ndict = n + newnode = n not in self._node + newdict = attr.copy() + newdict.update(ndict) + if newnode: + if n is None: + raise ValueError("None cannot be a node") + self._adj[n] = self.adjlist_inner_dict_factory() + self._node[n] = self.node_attr_dict_factory() + self._node[n].update(newdict) + nx._clear_cache(self) + + def remove_node(self, n): + """Remove node n. + + Removes the node n and all adjacent edges. + Attempting to remove a nonexistent node will raise an exception. + + Parameters + ---------- + n : node + A node in the graph + + Raises + ------ + NetworkXError + If n is not in the graph. + + See Also + -------- + remove_nodes_from + + Examples + -------- + >>> G = nx.path_graph(3) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> list(G.edges) + [(0, 1), (1, 2)] + >>> G.remove_node(1) + >>> list(G.edges) + [] + + """ + adj = self._adj + try: + nbrs = list(adj[n]) # list handles self-loops (allows mutation) + del self._node[n] + except KeyError as err: # NetworkXError if n not in self + raise NetworkXError(f"The node {n} is not in the graph.") from err + for u in nbrs: + del adj[u][n] # remove all edges n-u in graph + del adj[n] # now remove node + nx._clear_cache(self) + + def remove_nodes_from(self, nodes): + """Remove multiple nodes. + + Parameters + ---------- + nodes : iterable container + A container of nodes (list, dict, set, etc.). If a node + in the container is not in the graph it is silently + ignored. + + See Also + -------- + remove_node + + Notes + ----- + When removing nodes from an iterator over the graph you are changing, + a `RuntimeError` will be raised with message: + `RuntimeError: dictionary changed size during iteration`. This + happens when the graph's underlying dictionary is modified during + iteration. To avoid this error, evaluate the iterator into a separate + object, e.g. by using `list(iterator_of_nodes)`, and pass this + object to `G.remove_nodes_from`. + + Examples + -------- + >>> G = nx.path_graph(3) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> e = list(G.nodes) + >>> e + [0, 1, 2] + >>> G.remove_nodes_from(e) + >>> list(G.nodes) + [] + + Evaluate an iterator over a graph if using it to modify the same graph + + >>> G = nx.Graph([(0, 1), (1, 2), (3, 4)]) + >>> # this command will fail, as the graph's dict is modified during iteration + >>> # G.remove_nodes_from(n for n in G.nodes if n < 2) + >>> # this command will work, since the dictionary underlying graph is not modified + >>> G.remove_nodes_from(list(n for n in G.nodes if n < 2)) + """ + adj = self._adj + for n in nodes: + try: + del self._node[n] + for u in list(adj[n]): # list handles self-loops + del adj[u][n] # (allows mutation of dict in loop) + del adj[n] + except KeyError: + pass + nx._clear_cache(self) + + @cached_property + def nodes(self): + """A NodeView of the Graph as G.nodes or G.nodes(). + + Can be used as `G.nodes` for data lookup and for set-like operations. + Can also be used as `G.nodes(data='color', default=None)` to return a + NodeDataView which reports specific node data but no set operations. + It presents a dict-like interface as well with `G.nodes.items()` + iterating over `(node, nodedata)` 2-tuples and `G.nodes[3]['foo']` + providing the value of the `foo` attribute for node `3`. In addition, + a view `G.nodes.data('foo')` provides a dict-like interface to the + `foo` attribute of each node. `G.nodes.data('foo', default=1)` + provides a default for nodes that do not have attribute `foo`. + + Parameters + ---------- + data : string or bool, optional (default=False) + The node attribute returned in 2-tuple (n, ddict[data]). + If True, return entire node attribute dict as (n, ddict). + If False, return just the nodes n. + + default : value, optional (default=None) + Value used for nodes that don't have the requested attribute. + Only relevant if data is not True or False. + + Returns + ------- + NodeView + Allows set-like operations over the nodes as well as node + attribute dict lookup and calling to get a NodeDataView. + A NodeDataView iterates over `(n, data)` and has no set operations. + A NodeView iterates over `n` and includes set operations. + + When called, if data is False, an iterator over nodes. + Otherwise an iterator of 2-tuples (node, attribute value) + where the attribute is specified in `data`. + If data is True then the attribute becomes the + entire data dictionary. + + Notes + ----- + If your node data is not needed, it is simpler and equivalent + to use the expression ``for n in G``, or ``list(G)``. + + Examples + -------- + There are two simple ways of getting a list of all nodes in the graph: + + >>> G = nx.path_graph(3) + >>> list(G.nodes) + [0, 1, 2] + >>> list(G) + [0, 1, 2] + + To get the node data along with the nodes: + + >>> G.add_node(1, time="5pm") + >>> G.nodes[0]["foo"] = "bar" + >>> list(G.nodes(data=True)) + [(0, {'foo': 'bar'}), (1, {'time': '5pm'}), (2, {})] + >>> list(G.nodes.data()) + [(0, {'foo': 'bar'}), (1, {'time': '5pm'}), (2, {})] + + >>> list(G.nodes(data="foo")) + [(0, 'bar'), (1, None), (2, None)] + >>> list(G.nodes.data("foo")) + [(0, 'bar'), (1, None), (2, None)] + + >>> list(G.nodes(data="time")) + [(0, None), (1, '5pm'), (2, None)] + >>> list(G.nodes.data("time")) + [(0, None), (1, '5pm'), (2, None)] + + >>> list(G.nodes(data="time", default="Not Available")) + [(0, 'Not Available'), (1, '5pm'), (2, 'Not Available')] + >>> list(G.nodes.data("time", default="Not Available")) + [(0, 'Not Available'), (1, '5pm'), (2, 'Not Available')] + + If some of your nodes have an attribute and the rest are assumed + to have a default attribute value you can create a dictionary + from node/attribute pairs using the `default` keyword argument + to guarantee the value is never None:: + + >>> G = nx.Graph() + >>> G.add_node(0) + >>> G.add_node(1, weight=2) + >>> G.add_node(2, weight=3) + >>> dict(G.nodes(data="weight", default=1)) + {0: 1, 1: 2, 2: 3} + + """ + return NodeView(self) + + def number_of_nodes(self): + """Returns the number of nodes in the graph. + + Returns + ------- + nnodes : int + The number of nodes in the graph. + + See Also + -------- + order: identical method + __len__: identical method + + Examples + -------- + >>> G = nx.path_graph(3) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.number_of_nodes() + 3 + """ + return len(self._node) + + def order(self): + """Returns the number of nodes in the graph. + + Returns + ------- + nnodes : int + The number of nodes in the graph. + + See Also + -------- + number_of_nodes: identical method + __len__: identical method + + Examples + -------- + >>> G = nx.path_graph(3) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.order() + 3 + """ + return len(self._node) + + def has_node(self, n): + """Returns True if the graph contains the node n. + + Identical to `n in G` + + Parameters + ---------- + n : node + + Examples + -------- + >>> G = nx.path_graph(3) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.has_node(0) + True + + It is more readable and simpler to use + + >>> 0 in G + True + + """ + try: + return n in self._node + except TypeError: + return False + + def add_edge(self, u_of_edge, v_of_edge, **attr): + """Add an edge between u and v. + + The nodes u and v will be automatically added if they are + not already in the graph. + + Edge attributes can be specified with keywords or by directly + accessing the edge's attribute dictionary. See examples below. + + Parameters + ---------- + u_of_edge, v_of_edge : nodes + Nodes can be, for example, strings or numbers. + Nodes must be hashable (and not None) Python objects. + attr : keyword arguments, optional + Edge data (or labels or objects) can be assigned using + keyword arguments. + + See Also + -------- + add_edges_from : add a collection of edges + + Notes + ----- + Adding an edge that already exists updates the edge data. + + Many NetworkX algorithms designed for weighted graphs use + an edge attribute (by default `weight`) to hold a numerical value. + + Examples + -------- + The following all add the edge e=(1, 2) to graph G: + + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> e = (1, 2) + >>> G.add_edge(1, 2) # explicit two-node form + >>> G.add_edge(*e) # single edge as tuple of two nodes + >>> G.add_edges_from([(1, 2)]) # add edges from iterable container + + Associate data to edges using keywords: + + >>> G.add_edge(1, 2, weight=3) + >>> G.add_edge(1, 3, weight=7, capacity=15, length=342.7) + + For non-string attribute keys, use subscript notation. + + >>> G.add_edge(1, 2) + >>> G[1][2].update({0: 5}) + >>> G.edges[1, 2].update({0: 5}) + """ + u, v = u_of_edge, v_of_edge + # add nodes + if u not in self._node: + if u is None: + raise ValueError("None cannot be a node") + self._adj[u] = self.adjlist_inner_dict_factory() + self._node[u] = self.node_attr_dict_factory() + if v not in self._node: + if v is None: + raise ValueError("None cannot be a node") + self._adj[v] = self.adjlist_inner_dict_factory() + self._node[v] = self.node_attr_dict_factory() + # add the edge + datadict = self._adj[u].get(v, self.edge_attr_dict_factory()) + datadict.update(attr) + self._adj[u][v] = datadict + self._adj[v][u] = datadict + nx._clear_cache(self) + + def add_edges_from(self, ebunch_to_add, **attr): + """Add all the edges in ebunch_to_add. + + Parameters + ---------- + ebunch_to_add : container of edges + Each edge given in the container will be added to the + graph. The edges must be given as 2-tuples (u, v) or + 3-tuples (u, v, d) where d is a dictionary containing edge data. + attr : keyword arguments, optional + Edge data (or labels or objects) can be assigned using + keyword arguments. + + See Also + -------- + add_edge : add a single edge + add_weighted_edges_from : convenient way to add weighted edges + + Notes + ----- + Adding the same edge twice has no effect but any edge data + will be updated when each duplicate edge is added. + + Edge attributes specified in an ebunch take precedence over + attributes specified via keyword arguments. + + When adding edges from an iterator over the graph you are changing, + a `RuntimeError` can be raised with message: + `RuntimeError: dictionary changed size during iteration`. This + happens when the graph's underlying dictionary is modified during + iteration. To avoid this error, evaluate the iterator into a separate + object, e.g. by using `list(iterator_of_edges)`, and pass this + object to `G.add_edges_from`. + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_edges_from([(0, 1), (1, 2)]) # using a list of edge tuples + >>> e = zip(range(0, 3), range(1, 4)) + >>> G.add_edges_from(e) # Add the path graph 0-1-2-3 + + Associate data to edges + + >>> G.add_edges_from([(1, 2), (2, 3)], weight=3) + >>> G.add_edges_from([(3, 4), (1, 4)], label="WN2898") + + Evaluate an iterator over a graph if using it to modify the same graph + + >>> G = nx.Graph([(1, 2), (2, 3), (3, 4)]) + >>> # Grow graph by one new node, adding edges to all existing nodes. + >>> # wrong way - will raise RuntimeError + >>> # G.add_edges_from(((5, n) for n in G.nodes)) + >>> # correct way - note that there will be no self-edge for node 5 + >>> G.add_edges_from(list((5, n) for n in G.nodes)) + """ + for e in ebunch_to_add: + ne = len(e) + if ne == 3: + u, v, dd = e + elif ne == 2: + u, v = e + dd = {} # doesn't need edge_attr_dict_factory + else: + raise NetworkXError(f"Edge tuple {e} must be a 2-tuple or 3-tuple.") + if u not in self._node: + if u is None: + raise ValueError("None cannot be a node") + self._adj[u] = self.adjlist_inner_dict_factory() + self._node[u] = self.node_attr_dict_factory() + if v not in self._node: + if v is None: + raise ValueError("None cannot be a node") + self._adj[v] = self.adjlist_inner_dict_factory() + self._node[v] = self.node_attr_dict_factory() + datadict = self._adj[u].get(v, self.edge_attr_dict_factory()) + datadict.update(attr) + datadict.update(dd) + self._adj[u][v] = datadict + self._adj[v][u] = datadict + nx._clear_cache(self) + + def add_weighted_edges_from(self, ebunch_to_add, weight="weight", **attr): + """Add weighted edges in `ebunch_to_add` with specified weight attr + + Parameters + ---------- + ebunch_to_add : container of edges + Each edge given in the list or container will be added + to the graph. The edges must be given as 3-tuples (u, v, w) + where w is a number. + weight : string, optional (default= 'weight') + The attribute name for the edge weights to be added. + attr : keyword arguments, optional (default= no attributes) + Edge attributes to add/update for all edges. + + See Also + -------- + add_edge : add a single edge + add_edges_from : add multiple edges + + Notes + ----- + Adding the same edge twice for Graph/DiGraph simply updates + the edge data. For MultiGraph/MultiDiGraph, duplicate edges + are stored. + + When adding edges from an iterator over the graph you are changing, + a `RuntimeError` can be raised with message: + `RuntimeError: dictionary changed size during iteration`. This + happens when the graph's underlying dictionary is modified during + iteration. To avoid this error, evaluate the iterator into a separate + object, e.g. by using `list(iterator_of_edges)`, and pass this + object to `G.add_weighted_edges_from`. + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_weighted_edges_from([(0, 1, 3.0), (1, 2, 7.5)]) + + Evaluate an iterator over edges before passing it + + >>> G = nx.Graph([(1, 2), (2, 3), (3, 4)]) + >>> weight = 0.1 + >>> # Grow graph by one new node, adding edges to all existing nodes. + >>> # wrong way - will raise RuntimeError + >>> # G.add_weighted_edges_from(((5, n, weight) for n in G.nodes)) + >>> # correct way - note that there will be no self-edge for node 5 + >>> G.add_weighted_edges_from(list((5, n, weight) for n in G.nodes)) + """ + self.add_edges_from(((u, v, {weight: d}) for u, v, d in ebunch_to_add), **attr) + nx._clear_cache(self) + + def remove_edge(self, u, v): + """Remove the edge between u and v. + + Parameters + ---------- + u, v : nodes + Remove the edge between nodes u and v. + + Raises + ------ + NetworkXError + If there is not an edge between u and v. + + See Also + -------- + remove_edges_from : remove a collection of edges + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, etc + >>> G.remove_edge(0, 1) + >>> e = (1, 2) + >>> G.remove_edge(*e) # unpacks e from an edge tuple + >>> e = (2, 3, {"weight": 7}) # an edge with attribute data + >>> G.remove_edge(*e[:2]) # select first part of edge tuple + """ + try: + del self._adj[u][v] + if u != v: # self-loop needs only one entry removed + del self._adj[v][u] + except KeyError as err: + raise NetworkXError(f"The edge {u}-{v} is not in the graph") from err + nx._clear_cache(self) + + def remove_edges_from(self, ebunch): + """Remove all edges specified in ebunch. + + Parameters + ---------- + ebunch: list or container of edge tuples + Each edge given in the list or container will be removed + from the graph. The edges can be: + + - 2-tuples (u, v) edge between u and v. + - 3-tuples (u, v, k) where k is ignored. + + See Also + -------- + remove_edge : remove a single edge + + Notes + ----- + Will fail silently if an edge in ebunch is not in the graph. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> ebunch = [(1, 2), (2, 3)] + >>> G.remove_edges_from(ebunch) + """ + adj = self._adj + for e in ebunch: + u, v = e[:2] # ignore edge data if present + if u in adj and v in adj[u]: + del adj[u][v] + if u != v: # self loop needs only one entry removed + del adj[v][u] + nx._clear_cache(self) + + def update(self, edges=None, nodes=None): + """Update the graph using nodes/edges/graphs as input. + + Like dict.update, this method takes a graph as input, adding the + graph's nodes and edges to this graph. It can also take two inputs: + edges and nodes. Finally it can take either edges or nodes. + To specify only nodes the keyword `nodes` must be used. + + The collections of edges and nodes are treated similarly to + the add_edges_from/add_nodes_from methods. When iterated, they + should yield 2-tuples (u, v) or 3-tuples (u, v, datadict). + + Parameters + ---------- + edges : Graph object, collection of edges, or None + The first parameter can be a graph or some edges. If it has + attributes `nodes` and `edges`, then it is taken to be a + Graph-like object and those attributes are used as collections + of nodes and edges to be added to the graph. + If the first parameter does not have those attributes, it is + treated as a collection of edges and added to the graph. + If the first argument is None, no edges are added. + nodes : collection of nodes, or None + The second parameter is treated as a collection of nodes + to be added to the graph unless it is None. + If `edges is None` and `nodes is None` an exception is raised. + If the first parameter is a Graph, then `nodes` is ignored. + + Examples + -------- + >>> G = nx.path_graph(5) + >>> G.update(nx.complete_graph(range(4, 10))) + >>> from itertools import combinations + >>> edges = ( + ... (u, v, {"power": u * v}) + ... for u, v in combinations(range(10, 20), 2) + ... if u * v < 225 + ... ) + >>> nodes = [1000] # for singleton, use a container + >>> G.update(edges, nodes) + + Notes + ----- + It you want to update the graph using an adjacency structure + it is straightforward to obtain the edges/nodes from adjacency. + The following examples provide common cases, your adjacency may + be slightly different and require tweaks of these examples:: + + >>> # dict-of-set/list/tuple + >>> adj = {1: {2, 3}, 2: {1, 3}, 3: {1, 2}} + >>> e = [(u, v) for u, nbrs in adj.items() for v in nbrs] + >>> G.update(edges=e, nodes=adj) + + >>> DG = nx.DiGraph() + >>> # dict-of-dict-of-attribute + >>> adj = {1: {2: 1.3, 3: 0.7}, 2: {1: 1.4}, 3: {1: 0.7}} + >>> e = [ + ... (u, v, {"weight": d}) + ... for u, nbrs in adj.items() + ... for v, d in nbrs.items() + ... ] + >>> DG.update(edges=e, nodes=adj) + + >>> # dict-of-dict-of-dict + >>> adj = {1: {2: {"weight": 1.3}, 3: {"color": 0.7, "weight": 1.2}}} + >>> e = [ + ... (u, v, {"weight": d}) + ... for u, nbrs in adj.items() + ... for v, d in nbrs.items() + ... ] + >>> DG.update(edges=e, nodes=adj) + + >>> # predecessor adjacency (dict-of-set) + >>> pred = {1: {2, 3}, 2: {3}, 3: {3}} + >>> e = [(v, u) for u, nbrs in pred.items() for v in nbrs] + + >>> # MultiGraph dict-of-dict-of-dict-of-attribute + >>> MDG = nx.MultiDiGraph() + >>> adj = { + ... 1: {2: {0: {"weight": 1.3}, 1: {"weight": 1.2}}}, + ... 3: {2: {0: {"weight": 0.7}}}, + ... } + >>> e = [ + ... (u, v, ekey, d) + ... for u, nbrs in adj.items() + ... for v, keydict in nbrs.items() + ... for ekey, d in keydict.items() + ... ] + >>> MDG.update(edges=e) + + See Also + -------- + add_edges_from: add multiple edges to a graph + add_nodes_from: add multiple nodes to a graph + """ + if edges is not None: + if nodes is not None: + self.add_nodes_from(nodes) + self.add_edges_from(edges) + else: + # check if edges is a Graph object + try: + graph_nodes = edges.nodes + graph_edges = edges.edges + except AttributeError: + # edge not Graph-like + self.add_edges_from(edges) + else: # edges is Graph-like + self.add_nodes_from(graph_nodes.data()) + self.add_edges_from(graph_edges.data()) + self.graph.update(edges.graph) + elif nodes is not None: + self.add_nodes_from(nodes) + else: + raise NetworkXError("update needs nodes or edges input") + + def has_edge(self, u, v): + """Returns True if the edge (u, v) is in the graph. + + This is the same as `v in G[u]` without KeyError exceptions. + + Parameters + ---------- + u, v : nodes + Nodes can be, for example, strings or numbers. + Nodes must be hashable (and not None) Python objects. + + Returns + ------- + edge_ind : bool + True if edge is in the graph, False otherwise. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.has_edge(0, 1) # using two nodes + True + >>> e = (0, 1) + >>> G.has_edge(*e) # e is a 2-tuple (u, v) + True + >>> e = (0, 1, {"weight": 7}) + >>> G.has_edge(*e[:2]) # e is a 3-tuple (u, v, data_dictionary) + True + + The following syntax are equivalent: + + >>> G.has_edge(0, 1) + True + >>> 1 in G[0] # though this gives KeyError if 0 not in G + True + + """ + try: + return v in self._adj[u] + except KeyError: + return False + + def neighbors(self, n): + """Returns an iterator over all neighbors of node n. + + This is identical to `iter(G[n])` + + Parameters + ---------- + n : node + A node in the graph + + Returns + ------- + neighbors : iterator + An iterator over all neighbors of node n + + Raises + ------ + NetworkXError + If the node n is not in the graph. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> [n for n in G.neighbors(0)] + [1] + + Notes + ----- + Alternate ways to access the neighbors are ``G.adj[n]`` or ``G[n]``: + + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_edge("a", "b", weight=7) + >>> G["a"] + AtlasView({'b': {'weight': 7}}) + >>> G = nx.path_graph(4) + >>> [n for n in G[0]] + [1] + """ + try: + return iter(self._adj[n]) + except KeyError as err: + raise NetworkXError(f"The node {n} is not in the graph.") from err + + @cached_property + def edges(self): + """An EdgeView of the Graph as G.edges or G.edges(). + + edges(self, nbunch=None, data=False, default=None) + + The EdgeView provides set-like operations on the edge-tuples + as well as edge attribute lookup. When called, it also provides + an EdgeDataView object which allows control of access to edge + attributes (but does not provide set-like operations). + Hence, `G.edges[u, v]['color']` provides the value of the color + attribute for edge `(u, v)` while + `for (u, v, c) in G.edges.data('color', default='red'):` + iterates through all the edges yielding the color attribute + with default `'red'` if no color attribute exists. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges from these nodes. + data : string or bool, optional (default=False) + The edge attribute returned in 3-tuple (u, v, ddict[data]). + If True, return edge attribute dict in 3-tuple (u, v, ddict). + If False, return 2-tuple (u, v). + default : value, optional (default=None) + Value used for edges that don't have the requested attribute. + Only relevant if data is not True or False. + + Returns + ------- + edges : EdgeView + A view of edge attributes, usually it iterates over (u, v) + or (u, v, d) tuples of edges, but can also be used for + attribute lookup as `edges[u, v]['foo']`. + + Notes + ----- + Nodes in nbunch that are not in the graph will be (quietly) ignored. + For directed graphs this returns the out-edges. + + Examples + -------- + >>> G = nx.path_graph(3) # or MultiGraph, etc + >>> G.add_edge(2, 3, weight=5) + >>> [e for e in G.edges] + [(0, 1), (1, 2), (2, 3)] + >>> G.edges.data() # default data is {} (empty dict) + EdgeDataView([(0, 1, {}), (1, 2, {}), (2, 3, {'weight': 5})]) + >>> G.edges.data("weight", default=1) + EdgeDataView([(0, 1, 1), (1, 2, 1), (2, 3, 5)]) + >>> G.edges([0, 3]) # only edges from these nodes + EdgeDataView([(0, 1), (3, 2)]) + >>> G.edges(0) # only edges from node 0 + EdgeDataView([(0, 1)]) + """ + return EdgeView(self) + + def get_edge_data(self, u, v, default=None): + """Returns the attribute dictionary associated with edge (u, v). + + This is identical to `G[u][v]` except the default is returned + instead of an exception if the edge doesn't exist. + + Parameters + ---------- + u, v : nodes + default: any Python object (default=None) + Value to return if the edge (u, v) is not found. + + Returns + ------- + edge_dict : dictionary + The edge attribute dictionary. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G[0][1] + {} + + Warning: Assigning to `G[u][v]` is not permitted. + But it is safe to assign attributes `G[u][v]['foo']` + + >>> G[0][1]["weight"] = 7 + >>> G[0][1]["weight"] + 7 + >>> G[1][0]["weight"] + 7 + + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.get_edge_data(0, 1) # default edge data is {} + {} + >>> e = (0, 1) + >>> G.get_edge_data(*e) # tuple form + {} + >>> G.get_edge_data("a", "b", default=0) # edge not in graph, return 0 + 0 + """ + try: + return self._adj[u][v] + except KeyError: + return default + + def adjacency(self): + """Returns an iterator over (node, adjacency dict) tuples for all nodes. + + For directed graphs, only outgoing neighbors/adjacencies are included. + + Returns + ------- + adj_iter : iterator + An iterator over (node, adjacency dictionary) for all nodes in + the graph. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> [(n, nbrdict) for n, nbrdict in G.adjacency()] + [(0, {1: {}}), (1, {0: {}, 2: {}}), (2, {1: {}, 3: {}}), (3, {2: {}})] + + """ + return iter(self._adj.items()) + + @cached_property + def degree(self): + """A DegreeView for the Graph as G.degree or G.degree(). + + The node degree is the number of edges adjacent to the node. + The weighted node degree is the sum of the edge weights for + edges incident to that node. + + This object provides an iterator for (node, degree) as well as + lookup for the degree for a single node. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges incident to these nodes. + + weight : string or None, optional (default=None) + The name of an edge attribute that holds the numerical value used + as a weight. If None, then each edge has weight 1. + The degree is the sum of the edge weights adjacent to the node. + + Returns + ------- + DegreeView or int + If multiple nodes are requested (the default), returns a `DegreeView` + mapping nodes to their degree. + If a single node is requested, returns the degree of the node as an integer. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.degree[0] # node 0 has degree 1 + 1 + >>> list(G.degree([0, 1, 2])) + [(0, 1), (1, 2), (2, 2)] + """ + return DegreeView(self) + + def clear(self): + """Remove all nodes and edges from the graph. + + This also removes the name, and all graph, node, and edge attributes. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.clear() + >>> list(G.nodes) + [] + >>> list(G.edges) + [] + + """ + self._adj.clear() + self._node.clear() + self.graph.clear() + nx._clear_cache(self) + + def clear_edges(self): + """Remove all edges from the graph without altering nodes. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.clear_edges() + >>> list(G.nodes) + [0, 1, 2, 3] + >>> list(G.edges) + [] + """ + for nbr_dict in self._adj.values(): + nbr_dict.clear() + nx._clear_cache(self) + + def is_multigraph(self): + """Returns True if graph is a multigraph, False otherwise.""" + return False + + def is_directed(self): + """Returns True if graph is directed, False otherwise.""" + return False + + def copy(self, as_view=False): + """Returns a copy of the graph. + + The copy method by default returns an independent shallow copy + of the graph and attributes. That is, if an attribute is a + container, that container is shared by the original an the copy. + Use Python's `copy.deepcopy` for new containers. + + If `as_view` is True then a view is returned instead of a copy. + + Notes + ----- + All copies reproduce the graph structure, but data attributes + may be handled in different ways. There are four types of copies + of a graph that people might want. + + Deepcopy -- A "deepcopy" copies the graph structure as well as + all data attributes and any objects they might contain. + The entire graph object is new so that changes in the copy + do not affect the original object. (see Python's copy.deepcopy) + + Data Reference (Shallow) -- For a shallow copy the graph structure + is copied but the edge, node and graph attribute dicts are + references to those in the original graph. This saves + time and memory but could cause confusion if you change an attribute + in one graph and it changes the attribute in the other. + NetworkX does not provide this level of shallow copy. + + Independent Shallow -- This copy creates new independent attribute + dicts and then does a shallow copy of the attributes. That is, any + attributes that are containers are shared between the new graph + and the original. This is exactly what `dict.copy()` provides. + You can obtain this style copy using: + + >>> G = nx.path_graph(5) + >>> H = G.copy() + >>> H = G.copy(as_view=False) + >>> H = nx.Graph(G) + >>> H = G.__class__(G) + + Fresh Data -- For fresh data, the graph structure is copied while + new empty data attribute dicts are created. The resulting graph + is independent of the original and it has no edge, node or graph + attributes. Fresh copies are not enabled. Instead use: + + >>> H = G.__class__() + >>> H.add_nodes_from(G) + >>> H.add_edges_from(G.edges) + + View -- Inspired by dict-views, graph-views act like read-only + versions of the original graph, providing a copy of the original + structure without requiring any memory for copying the information. + + See the Python copy module for more information on shallow + and deep copies, https://docs.python.org/3/library/copy.html. + + Parameters + ---------- + as_view : bool, optional (default=False) + If True, the returned graph-view provides a read-only view + of the original graph without actually copying any data. + + Returns + ------- + G : Graph + A copy of the graph. + + See Also + -------- + to_directed: return a directed copy of the graph. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> H = G.copy() + + """ + if as_view is True: + return nx.graphviews.generic_graph_view(self) + G = self.__class__() + G.graph.update(self.graph) + G.add_nodes_from((n, d.copy()) for n, d in self._node.items()) + G.add_edges_from( + (u, v, datadict.copy()) + for u, nbrs in self._adj.items() + for v, datadict in nbrs.items() + ) + return G + + def to_directed(self, as_view=False): + """Returns a directed representation of the graph. + + Returns + ------- + G : DiGraph + A directed graph with the same name, same nodes, and with + each edge (u, v, data) replaced by two directed edges + (u, v, data) and (v, u, data). + + Notes + ----- + This returns a "deepcopy" of the edge, node, and + graph attributes which attempts to completely copy + all of the data and references. + + This is in contrast to the similar D=DiGraph(G) which returns a + shallow copy of the data. + + See the Python copy module for more information on shallow + and deep copies, https://docs.python.org/3/library/copy.html. + + Warning: If you have subclassed Graph to use dict-like objects + in the data structure, those changes do not transfer to the + DiGraph created by this method. + + Examples + -------- + >>> G = nx.Graph() # or MultiGraph, etc + >>> G.add_edge(0, 1) + >>> H = G.to_directed() + >>> list(H.edges) + [(0, 1), (1, 0)] + + If already directed, return a (deep) copy + + >>> G = nx.DiGraph() # or MultiDiGraph, etc + >>> G.add_edge(0, 1) + >>> H = G.to_directed() + >>> list(H.edges) + [(0, 1)] + """ + graph_class = self.to_directed_class() + if as_view is True: + return nx.graphviews.generic_graph_view(self, graph_class) + # deepcopy when not a view + G = graph_class() + G.graph.update(deepcopy(self.graph)) + G.add_nodes_from((n, deepcopy(d)) for n, d in self._node.items()) + G.add_edges_from( + (u, v, deepcopy(data)) + for u, nbrs in self._adj.items() + for v, data in nbrs.items() + ) + return G + + def to_undirected(self, as_view=False): + """Returns an undirected copy of the graph. + + Parameters + ---------- + as_view : bool (optional, default=False) + If True return a view of the original undirected graph. + + Returns + ------- + G : Graph/MultiGraph + A deepcopy of the graph. + + See Also + -------- + Graph, copy, add_edge, add_edges_from + + Notes + ----- + This returns a "deepcopy" of the edge, node, and + graph attributes which attempts to completely copy + all of the data and references. + + This is in contrast to the similar `G = nx.DiGraph(D)` which returns a + shallow copy of the data. + + See the Python copy module for more information on shallow + and deep copies, https://docs.python.org/3/library/copy.html. + + Warning: If you have subclassed DiGraph to use dict-like objects + in the data structure, those changes do not transfer to the + Graph created by this method. + + Examples + -------- + >>> G = nx.path_graph(2) # or MultiGraph, etc + >>> H = G.to_directed() + >>> list(H.edges) + [(0, 1), (1, 0)] + >>> G2 = H.to_undirected() + >>> list(G2.edges) + [(0, 1)] + """ + graph_class = self.to_undirected_class() + if as_view is True: + return nx.graphviews.generic_graph_view(self, graph_class) + # deepcopy when not a view + G = graph_class() + G.graph.update(deepcopy(self.graph)) + G.add_nodes_from((n, deepcopy(d)) for n, d in self._node.items()) + G.add_edges_from( + (u, v, deepcopy(d)) + for u, nbrs in self._adj.items() + for v, d in nbrs.items() + ) + return G + + def subgraph(self, nodes): + """Returns a SubGraph view of the subgraph induced on `nodes`. + + The induced subgraph of the graph contains the nodes in `nodes` + and the edges between those nodes. + + Parameters + ---------- + nodes : list, iterable + A container of nodes which will be iterated through once. + + Returns + ------- + G : SubGraph View + A subgraph view of the graph. The graph structure cannot be + changed but node/edge attributes can and are shared with the + original graph. + + Notes + ----- + The graph, edge and node attributes are shared with the original graph. + Changes to the graph structure is ruled out by the view, but changes + to attributes are reflected in the original graph. + + To create a subgraph with its own copy of the edge/node attributes use: + G.subgraph(nodes).copy() + + For an inplace reduction of a graph to a subgraph you can remove nodes: + G.remove_nodes_from([n for n in G if n not in set(nodes)]) + + Subgraph views are sometimes NOT what you want. In most cases where + you want to do more than simply look at the induced edges, it makes + more sense to just create the subgraph as its own graph with code like: + + :: + + # Create a subgraph SG based on a (possibly multigraph) G + SG = G.__class__() + SG.add_nodes_from((n, G.nodes[n]) for n in largest_wcc) + if SG.is_multigraph(): + SG.add_edges_from( + (n, nbr, key, d) + for n, nbrs in G.adj.items() + if n in largest_wcc + for nbr, keydict in nbrs.items() + if nbr in largest_wcc + for key, d in keydict.items() + ) + else: + SG.add_edges_from( + (n, nbr, d) + for n, nbrs in G.adj.items() + if n in largest_wcc + for nbr, d in nbrs.items() + if nbr in largest_wcc + ) + SG.graph.update(G.graph) + + Subgraphs are not guaranteed to preserve the order of nodes or edges + as they appear in the original graph. For example: + + >>> G = nx.Graph() + >>> G.add_nodes_from(reversed(range(10))) + >>> list(G) + [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] + >>> list(G.subgraph([1, 3, 2])) + [1, 2, 3] + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> H = G.subgraph([0, 1, 2]) + >>> list(H.edges) + [(0, 1), (1, 2)] + """ + induced_nodes = nx.filters.show_nodes(self.nbunch_iter(nodes)) + # if already a subgraph, don't make a chain + subgraph = nx.subgraph_view + if hasattr(self, "_NODE_OK"): + return subgraph( + self._graph, filter_node=induced_nodes, filter_edge=self._EDGE_OK + ) + return subgraph(self, filter_node=induced_nodes) + + def edge_subgraph(self, edges): + """Returns the subgraph induced by the specified edges. + + The induced subgraph contains each edge in `edges` and each + node incident to any one of those edges. + + Parameters + ---------- + edges : iterable + An iterable of edges in this graph. + + Returns + ------- + G : Graph + An edge-induced subgraph of this graph with the same edge + attributes. + + Notes + ----- + The graph, edge, and node attributes in the returned subgraph + view are references to the corresponding attributes in the original + graph. The view is read-only. + + To create a full graph version of the subgraph with its own copy + of the edge or node attributes, use:: + + G.edge_subgraph(edges).copy() + + Examples + -------- + >>> G = nx.path_graph(5) + >>> H = G.edge_subgraph([(0, 1), (3, 4)]) + >>> list(H.nodes) + [0, 1, 3, 4] + >>> list(H.edges) + [(0, 1), (3, 4)] + + """ + return nx.edge_subgraph(self, edges) + + def size(self, weight=None): + """Returns the number of edges or total of all edge weights. + + Parameters + ---------- + weight : string or None, optional (default=None) + The edge attribute that holds the numerical value used + as a weight. If None, then each edge has weight 1. + + Returns + ------- + size : numeric + The number of edges or + (if weight keyword is provided) the total weight sum. + + If weight is None, returns an int. Otherwise a float + (or more general numeric if the weights are more general). + + See Also + -------- + number_of_edges + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.size() + 3 + + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_edge("a", "b", weight=2) + >>> G.add_edge("b", "c", weight=4) + >>> G.size() + 2 + >>> G.size(weight="weight") + 6.0 + """ + s = sum(d for v, d in self.degree(weight=weight)) + # If `weight` is None, the sum of the degrees is guaranteed to be + # even, so we can perform integer division and hence return an + # integer. Otherwise, the sum of the weighted degrees is not + # guaranteed to be an integer, so we perform "real" division. + return s // 2 if weight is None else s / 2 + + def number_of_edges(self, u=None, v=None): + """Returns the number of edges between two nodes. + + Parameters + ---------- + u, v : nodes, optional (default=all edges) + If u and v are specified, return the number of edges between + u and v. Otherwise return the total number of all edges. + + Returns + ------- + nedges : int + The number of edges in the graph. If nodes `u` and `v` are + specified return the number of edges between those nodes. If + the graph is directed, this only returns the number of edges + from `u` to `v`. + + See Also + -------- + size + + Examples + -------- + For undirected graphs, this method counts the total number of + edges in the graph: + + >>> G = nx.path_graph(4) + >>> G.number_of_edges() + 3 + + If you specify two nodes, this counts the total number of edges + joining the two nodes: + + >>> G.number_of_edges(0, 1) + 1 + + For directed graphs, this method can count the total number of + directed edges from `u` to `v`: + + >>> G = nx.DiGraph() + >>> G.add_edge(0, 1) + >>> G.add_edge(1, 0) + >>> G.number_of_edges(0, 1) + 1 + + """ + if u is None: + return int(self.size()) + if v in self._adj[u]: + return 1 + return 0 + + def nbunch_iter(self, nbunch=None): + """Returns an iterator over nodes contained in nbunch that are + also in the graph. + + The nodes in an iterable nbunch are checked for membership in the graph + and if not are silently ignored. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges incident to these nodes. + + Returns + ------- + niter : iterator + An iterator over nodes in nbunch that are also in the graph. + If nbunch is None, iterate over all nodes in the graph. + + Raises + ------ + NetworkXError + If nbunch is not a node or sequence of nodes. + If a node in nbunch is not hashable. + + See Also + -------- + Graph.__iter__ + + Notes + ----- + When nbunch is an iterator, the returned iterator yields values + directly from nbunch, becoming exhausted when nbunch is exhausted. + + To test whether nbunch is a single node, one can use + "if nbunch in self:", even after processing with this routine. + + If nbunch is not a node or a (possibly empty) sequence/iterator + or None, a :exc:`NetworkXError` is raised. Also, if any object in + nbunch is not hashable, a :exc:`NetworkXError` is raised. + """ + if nbunch is None: # include all nodes via iterator + bunch = iter(self._adj) + elif nbunch in self: # if nbunch is a single node + bunch = iter([nbunch]) + else: # if nbunch is a sequence of nodes + + def bunch_iter(nlist, adj): + try: + for n in nlist: + if n in adj: + yield n + except TypeError as err: + exc, message = err, err.args[0] + # capture error for non-sequence/iterator nbunch. + if "iter" in message: + exc = NetworkXError( + "nbunch is not a node or a sequence of nodes." + ) + # capture single nodes that are not in the graph. + if "object is not iterable" in message: + exc = NetworkXError(f"Node {nbunch} is not in the graph.") + # capture error for unhashable node. + if "hashable" in message: + exc = NetworkXError( + f"Node {n} in sequence nbunch is not a valid node." + ) + raise exc + + bunch = bunch_iter(nbunch, self._adj) + return bunch diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/graphviews.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/graphviews.py new file mode 100644 index 0000000000000000000000000000000000000000..0b09df649ef48fa484d27e51d86cce1e10d593a7 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/graphviews.py @@ -0,0 +1,269 @@ +"""View of Graphs as SubGraph, Reverse, Directed, Undirected. + +In some algorithms it is convenient to temporarily morph +a graph to exclude some nodes or edges. It should be better +to do that via a view than to remove and then re-add. +In other algorithms it is convenient to temporarily morph +a graph to reverse directed edges, or treat a directed graph +as undirected, etc. This module provides those graph views. + +The resulting views are essentially read-only graphs that +report data from the original graph object. We provide an +attribute G._graph which points to the underlying graph object. + +Note: Since graphviews look like graphs, one can end up with +view-of-view-of-view chains. Be careful with chains because +they become very slow with about 15 nested views. +For the common simple case of node induced subgraphs created +from the graph class, we short-cut the chain by returning a +subgraph of the original graph directly rather than a subgraph +of a subgraph. We are careful not to disrupt any edge filter in +the middle subgraph. In general, determining how to short-cut +the chain is tricky and much harder with restricted_views than +with induced subgraphs. +Often it is easiest to use .copy() to avoid chains. +""" + +import networkx as nx +from networkx.classes.coreviews import ( + FilterAdjacency, + FilterAtlas, + FilterMultiAdjacency, + UnionAdjacency, + UnionMultiAdjacency, +) +from networkx.classes.filters import no_filter +from networkx.exception import NetworkXError +from networkx.utils import not_implemented_for + +__all__ = ["generic_graph_view", "subgraph_view", "reverse_view"] + + +def generic_graph_view(G, create_using=None): + """Returns a read-only view of `G`. + + The graph `G` and its attributes are not copied but viewed through the new graph object + of the same class as `G` (or of the class specified in `create_using`). + + Parameters + ---------- + G : graph + A directed/undirected graph/multigraph. + + create_using : NetworkX graph constructor, optional (default=None) + Graph type to create. If graph instance, then cleared before populated. + If `None`, then the appropriate Graph type is inferred from `G`. + + Returns + ------- + newG : graph + A view of the input graph `G` and its attributes as viewed through + the `create_using` class. + + Raises + ------ + NetworkXError + If `G` is a multigraph (or multidigraph) but `create_using` is not, or vice versa. + + Notes + ----- + The returned graph view is read-only (cannot modify the graph). + Yet the view reflects any changes in `G`. The intent is to mimic dict views. + + Examples + -------- + >>> G = nx.Graph() + >>> G.add_edge(1, 2, weight=0.3) + >>> G.add_edge(2, 3, weight=0.5) + >>> G.edges(data=True) + EdgeDataView([(1, 2, {'weight': 0.3}), (2, 3, {'weight': 0.5})]) + + The view exposes the attributes from the original graph. + + >>> viewG = nx.graphviews.generic_graph_view(G) + >>> viewG.edges(data=True) + EdgeDataView([(1, 2, {'weight': 0.3}), (2, 3, {'weight': 0.5})]) + + Changes to `G` are reflected in `viewG`. + + >>> G.remove_edge(2, 3) + >>> G.edges(data=True) + EdgeDataView([(1, 2, {'weight': 0.3})]) + + >>> viewG.edges(data=True) + EdgeDataView([(1, 2, {'weight': 0.3})]) + + We can change the graph type with the `create_using` parameter. + + >>> type(G) + + >>> viewDG = nx.graphviews.generic_graph_view(G, create_using=nx.DiGraph) + >>> type(viewDG) + + """ + if create_using is None: + newG = G.__class__() + else: + newG = nx.empty_graph(0, create_using) + if G.is_multigraph() != newG.is_multigraph(): + raise NetworkXError("Multigraph for G must agree with create_using") + newG = nx.freeze(newG) + + # create view by assigning attributes from G + newG._graph = G + newG.graph = G.graph + + newG._node = G._node + if newG.is_directed(): + if G.is_directed(): + newG._succ = G._succ + newG._pred = G._pred + # newG._adj is synced with _succ + else: + newG._succ = G._adj + newG._pred = G._adj + # newG._adj is synced with _succ + elif G.is_directed(): + if G.is_multigraph(): + newG._adj = UnionMultiAdjacency(G._succ, G._pred) + else: + newG._adj = UnionAdjacency(G._succ, G._pred) + else: + newG._adj = G._adj + return newG + + +def subgraph_view(G, *, filter_node=no_filter, filter_edge=no_filter): + """View of `G` applying a filter on nodes and edges. + + `subgraph_view` provides a read-only view of the input graph that excludes + nodes and edges based on the outcome of two filter functions `filter_node` + and `filter_edge`. + + The `filter_node` function takes one argument --- the node --- and returns + `True` if the node should be included in the subgraph, and `False` if it + should not be included. + + The `filter_edge` function takes two (or three arguments if `G` is a + multi-graph) --- the nodes describing an edge, plus the edge-key if + parallel edges are possible --- and returns `True` if the edge should be + included in the subgraph, and `False` if it should not be included. + + Both node and edge filter functions are called on graph elements as they + are queried, meaning there is no up-front cost to creating the view. + + Parameters + ---------- + G : networkx.Graph + A directed/undirected graph/multigraph + + filter_node : callable, optional + A function taking a node as input, which returns `True` if the node + should appear in the view. + + filter_edge : callable, optional + A function taking as input the two nodes describing an edge (plus the + edge-key if `G` is a multi-graph), which returns `True` if the edge + should appear in the view. + + Returns + ------- + graph : networkx.Graph + A read-only graph view of the input graph. + + Examples + -------- + >>> G = nx.path_graph(6) + + Filter functions operate on the node, and return `True` if the node should + appear in the view: + + >>> def filter_node(n1): + ... return n1 != 5 + >>> view = nx.subgraph_view(G, filter_node=filter_node) + >>> view.nodes() + NodeView((0, 1, 2, 3, 4)) + + We can use a closure pattern to filter graph elements based on additional + data --- for example, filtering on edge data attached to the graph: + + >>> G[3][4]["cross_me"] = False + >>> def filter_edge(n1, n2): + ... return G[n1][n2].get("cross_me", True) + >>> view = nx.subgraph_view(G, filter_edge=filter_edge) + >>> view.edges() + EdgeView([(0, 1), (1, 2), (2, 3), (4, 5)]) + + >>> view = nx.subgraph_view( + ... G, + ... filter_node=filter_node, + ... filter_edge=filter_edge, + ... ) + >>> view.nodes() + NodeView((0, 1, 2, 3, 4)) + >>> view.edges() + EdgeView([(0, 1), (1, 2), (2, 3)]) + """ + newG = nx.freeze(G.__class__()) + newG._NODE_OK = filter_node + newG._EDGE_OK = filter_edge + + # create view by assigning attributes from G + newG._graph = G + newG.graph = G.graph + + newG._node = FilterAtlas(G._node, filter_node) + if G.is_multigraph(): + Adj = FilterMultiAdjacency + + def reverse_edge(u, v, k=None): + return filter_edge(v, u, k) + + else: + Adj = FilterAdjacency + + def reverse_edge(u, v, k=None): + return filter_edge(v, u) + + if G.is_directed(): + newG._succ = Adj(G._succ, filter_node, filter_edge) + newG._pred = Adj(G._pred, filter_node, reverse_edge) + # newG._adj is synced with _succ + else: + newG._adj = Adj(G._adj, filter_node, filter_edge) + return newG + + +@not_implemented_for("undirected") +def reverse_view(G): + """View of `G` with edge directions reversed + + `reverse_view` returns a read-only view of the input graph where + edge directions are reversed. + + Identical to digraph.reverse(copy=False) + + Parameters + ---------- + G : networkx.DiGraph + + Returns + ------- + graph : networkx.DiGraph + + Examples + -------- + >>> G = nx.DiGraph() + >>> G.add_edge(1, 2) + >>> G.add_edge(2, 3) + >>> G.edges() + OutEdgeView([(1, 2), (2, 3)]) + + >>> view = nx.reverse_view(G) + >>> view.edges() + OutEdgeView([(2, 1), (3, 2)]) + """ + newG = generic_graph_view(G) + newG._succ, newG._pred = G._pred, G._succ + # newG._adj is synced with _succ + return newG diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/multidigraph.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/multidigraph.py new file mode 100644 index 0000000000000000000000000000000000000000..27c987037e2a47dd80045042893139f0aad226f5 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/multidigraph.py @@ -0,0 +1,977 @@ +"""Base class for MultiDiGraph.""" + +from copy import deepcopy +from functools import cached_property + +import networkx as nx +from networkx import convert +from networkx.classes.coreviews import MultiAdjacencyView +from networkx.classes.digraph import DiGraph +from networkx.classes.multigraph import MultiGraph +from networkx.classes.reportviews import ( + DiMultiDegreeView, + InMultiDegreeView, + InMultiEdgeView, + OutMultiDegreeView, + OutMultiEdgeView, +) +from networkx.exception import NetworkXError + +__all__ = ["MultiDiGraph"] + + +class MultiDiGraph(MultiGraph, DiGraph): + """A directed graph class that can store multiedges. + + Multiedges are multiple edges between two nodes. Each edge + can hold optional data or attributes. + + A MultiDiGraph holds directed edges. Self loops are allowed. + + Nodes can be arbitrary (hashable) Python objects with optional + key/value attributes. By convention `None` is not used as a node. + + Edges are represented as links between nodes with optional + key/value attributes. + + Parameters + ---------- + incoming_graph_data : input graph (optional, default: None) + Data to initialize graph. If None (default) an empty + graph is created. The data can be any format that is supported + by the to_networkx_graph() function, currently including edge list, + dict of dicts, dict of lists, NetworkX graph, 2D NumPy array, SciPy + sparse matrix, or PyGraphviz graph. + + multigraph_input : bool or None (default None) + Note: Only used when `incoming_graph_data` is a dict. + If True, `incoming_graph_data` is assumed to be a + dict-of-dict-of-dict-of-dict structure keyed by + node to neighbor to edge keys to edge data for multi-edges. + A NetworkXError is raised if this is not the case. + If False, :func:`to_networkx_graph` is used to try to determine + the dict's graph data structure as either a dict-of-dict-of-dict + keyed by node to neighbor to edge data, or a dict-of-iterable + keyed by node to neighbors. + If None, the treatment for True is tried, but if it fails, + the treatment for False is tried. + + attr : keyword arguments, optional (default= no attributes) + Attributes to add to graph as key=value pairs. + + See Also + -------- + Graph + DiGraph + MultiGraph + + Examples + -------- + Create an empty graph structure (a "null graph") with no nodes and + no edges. + + >>> G = nx.MultiDiGraph() + + G can be grown in several ways. + + **Nodes:** + + Add one node at a time: + + >>> G.add_node(1) + + Add the nodes from any container (a list, dict, set or + even the lines from a file or the nodes from another graph). + + >>> G.add_nodes_from([2, 3]) + >>> G.add_nodes_from(range(100, 110)) + >>> H = nx.path_graph(10) + >>> G.add_nodes_from(H) + + In addition to strings and integers any hashable Python object + (except None) can represent a node, e.g. a customized node object, + or even another Graph. + + >>> G.add_node(H) + + **Edges:** + + G can also be grown by adding edges. + + Add one edge, + + >>> key = G.add_edge(1, 2) + + a list of edges, + + >>> keys = G.add_edges_from([(1, 2), (1, 3)]) + + or a collection of edges, + + >>> keys = G.add_edges_from(H.edges) + + If some edges connect nodes not yet in the graph, the nodes + are added automatically. If an edge already exists, an additional + edge is created and stored using a key to identify the edge. + By default the key is the lowest unused integer. + + >>> keys = G.add_edges_from([(4, 5, dict(route=282)), (4, 5, dict(route=37))]) + >>> G[4] + AdjacencyView({5: {0: {}, 1: {'route': 282}, 2: {'route': 37}}}) + + **Attributes:** + + Each graph, node, and edge can hold key/value attribute pairs + in an associated attribute dictionary (the keys must be hashable). + By default these are empty, but can be added or changed using + add_edge, add_node or direct manipulation of the attribute + dictionaries named graph, node and edge respectively. + + >>> G = nx.MultiDiGraph(day="Friday") + >>> G.graph + {'day': 'Friday'} + + Add node attributes using add_node(), add_nodes_from() or G.nodes + + >>> G.add_node(1, time="5pm") + >>> G.add_nodes_from([3], time="2pm") + >>> G.nodes[1] + {'time': '5pm'} + >>> G.nodes[1]["room"] = 714 + >>> del G.nodes[1]["room"] # remove attribute + >>> list(G.nodes(data=True)) + [(1, {'time': '5pm'}), (3, {'time': '2pm'})] + + Add edge attributes using add_edge(), add_edges_from(), subscript + notation, or G.edges. + + >>> key = G.add_edge(1, 2, weight=4.7) + >>> keys = G.add_edges_from([(3, 4), (4, 5)], color="red") + >>> keys = G.add_edges_from([(1, 2, {"color": "blue"}), (2, 3, {"weight": 8})]) + >>> G[1][2][0]["weight"] = 4.7 + >>> G.edges[1, 2, 0]["weight"] = 4 + + Warning: we protect the graph data structure by making `G.edges[1, + 2, 0]` a read-only dict-like structure. However, you can assign to + attributes in e.g. `G.edges[1, 2, 0]`. Thus, use 2 sets of brackets + to add/change data attributes: `G.edges[1, 2, 0]['weight'] = 4` + (for multigraphs the edge key is required: `MG.edges[u, v, + key][name] = value`). + + **Shortcuts:** + + Many common graph features allow python syntax to speed reporting. + + >>> 1 in G # check if node in graph + True + >>> [n for n in G if n < 3] # iterate through nodes + [1, 2] + >>> len(G) # number of nodes in graph + 5 + >>> G[1] # adjacency dict-like view mapping neighbor -> edge key -> edge attributes + AdjacencyView({2: {0: {'weight': 4}, 1: {'color': 'blue'}}}) + + Often the best way to traverse all edges of a graph is via the neighbors. + The neighbors are available as an adjacency-view `G.adj` object or via + the method `G.adjacency()`. + + >>> for n, nbrsdict in G.adjacency(): + ... for nbr, keydict in nbrsdict.items(): + ... for key, eattr in keydict.items(): + ... if "weight" in eattr: + ... # Do something useful with the edges + ... pass + + But the edges() method is often more convenient: + + >>> for u, v, keys, weight in G.edges(data="weight", keys=True): + ... if weight is not None: + ... # Do something useful with the edges + ... pass + + **Reporting:** + + Simple graph information is obtained using methods and object-attributes. + Reporting usually provides views instead of containers to reduce memory + usage. The views update as the graph is updated similarly to dict-views. + The objects `nodes`, `edges` and `adj` provide access to data attributes + via lookup (e.g. `nodes[n]`, `edges[u, v, k]`, `adj[u][v]`) and iteration + (e.g. `nodes.items()`, `nodes.data('color')`, + `nodes.data('color', default='blue')` and similarly for `edges`) + Views exist for `nodes`, `edges`, `neighbors()`/`adj` and `degree`. + + For details on these and other miscellaneous methods, see below. + + **Subclasses (Advanced):** + + The MultiDiGraph class uses a dict-of-dict-of-dict-of-dict structure. + The outer dict (node_dict) holds adjacency information keyed by node. + The next dict (adjlist_dict) represents the adjacency information + and holds edge_key dicts keyed by neighbor. The edge_key dict holds + each edge_attr dict keyed by edge key. The inner dict + (edge_attr_dict) represents the edge data and holds edge attribute + values keyed by attribute names. + + Each of these four dicts in the dict-of-dict-of-dict-of-dict + structure can be replaced by a user defined dict-like object. + In general, the dict-like features should be maintained but + extra features can be added. To replace one of the dicts create + a new graph class by changing the class(!) variable holding the + factory for that dict-like structure. The variable names are + node_dict_factory, node_attr_dict_factory, adjlist_inner_dict_factory, + adjlist_outer_dict_factory, edge_key_dict_factory, edge_attr_dict_factory + and graph_attr_dict_factory. + + node_dict_factory : function, (default: dict) + Factory function to be used to create the dict containing node + attributes, keyed by node id. + It should require no arguments and return a dict-like object + + node_attr_dict_factory: function, (default: dict) + Factory function to be used to create the node attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object + + adjlist_outer_dict_factory : function, (default: dict) + Factory function to be used to create the outer-most dict + in the data structure that holds adjacency info keyed by node. + It should require no arguments and return a dict-like object. + + adjlist_inner_dict_factory : function, (default: dict) + Factory function to be used to create the adjacency list + dict which holds multiedge key dicts keyed by neighbor. + It should require no arguments and return a dict-like object. + + edge_key_dict_factory : function, (default: dict) + Factory function to be used to create the edge key dict + which holds edge data keyed by edge key. + It should require no arguments and return a dict-like object. + + edge_attr_dict_factory : function, (default: dict) + Factory function to be used to create the edge attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object. + + graph_attr_dict_factory : function, (default: dict) + Factory function to be used to create the graph attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object. + + Typically, if your extension doesn't impact the data structure all + methods will inherited without issue except: `to_directed/to_undirected`. + By default these methods create a DiGraph/Graph class and you probably + want them to create your extension of a DiGraph/Graph. To facilitate + this we define two class variables that you can set in your subclass. + + to_directed_class : callable, (default: DiGraph or MultiDiGraph) + Class to create a new graph structure in the `to_directed` method. + If `None`, a NetworkX class (DiGraph or MultiDiGraph) is used. + + to_undirected_class : callable, (default: Graph or MultiGraph) + Class to create a new graph structure in the `to_undirected` method. + If `None`, a NetworkX class (Graph or MultiGraph) is used. + + **Subclassing Example** + + Create a low memory graph class that effectively disallows edge + attributes by using a single attribute dict for all edges. + This reduces the memory used, but you lose edge attributes. + + >>> class ThinGraph(nx.Graph): + ... all_edge_dict = {"weight": 1} + ... + ... def single_edge_dict(self): + ... return self.all_edge_dict + ... + ... edge_attr_dict_factory = single_edge_dict + >>> G = ThinGraph() + >>> G.add_edge(2, 1) + >>> G[2][1] + {'weight': 1} + >>> G.add_edge(2, 2) + >>> G[2][1] is G[2][2] + True + """ + + # node_dict_factory = dict # already assigned in Graph + # adjlist_outer_dict_factory = dict + # adjlist_inner_dict_factory = dict + edge_key_dict_factory = dict + # edge_attr_dict_factory = dict + + # This __new__ method just does what Python itself does automatically. + # We include it here as part of the dispatchable/backend interface. + # If your goal is to understand how the graph classes work, you can ignore + # this method, even when subclassing the base classes. If you are subclassing + # in order to provide a backend that allows class instantiation, this method + # can be overridden to return your own backend graph class. + @nx._dispatchable(name="multidigraph__new__", graphs=None, returns_graph=True) + def __new__(cls, *args, **kwargs): + return object.__new__(cls) + + def __init__(self, incoming_graph_data=None, multigraph_input=None, **attr): + """Initialize a graph with edges, name, or graph attributes. + + Parameters + ---------- + incoming_graph_data : input graph + Data to initialize graph. If incoming_graph_data=None (default) + an empty graph is created. The data can be an edge list, or any + NetworkX graph object. If the corresponding optional Python + packages are installed the data can also be a 2D NumPy array, a + SciPy sparse array, or a PyGraphviz graph. + + multigraph_input : bool or None (default None) + Note: Only used when `incoming_graph_data` is a dict. + If True, `incoming_graph_data` is assumed to be a + dict-of-dict-of-dict-of-dict structure keyed by + node to neighbor to edge keys to edge data for multi-edges. + A NetworkXError is raised if this is not the case. + If False, :func:`to_networkx_graph` is used to try to determine + the dict's graph data structure as either a dict-of-dict-of-dict + keyed by node to neighbor to edge data, or a dict-of-iterable + keyed by node to neighbors. + If None, the treatment for True is tried, but if it fails, + the treatment for False is tried. + + attr : keyword arguments, optional (default= no attributes) + Attributes to add to graph as key=value pairs. + + See Also + -------- + convert + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G = nx.Graph(name="my graph") + >>> e = [(1, 2), (2, 3), (3, 4)] # list of edges + >>> G = nx.Graph(e) + + Arbitrary graph attribute pairs (key=value) may be assigned + + >>> G = nx.Graph(e, day="Friday") + >>> G.graph + {'day': 'Friday'} + + """ + attr.pop("backend", None) # Ignore explicit `backend="networkx"` + # multigraph_input can be None/True/False. So check "is not False" + if isinstance(incoming_graph_data, dict) and multigraph_input is not False: + DiGraph.__init__(self) + try: + convert.from_dict_of_dicts( + incoming_graph_data, create_using=self, multigraph_input=True + ) + self.graph.update(attr) + except Exception as err: + if multigraph_input is True: + raise nx.NetworkXError( + f"converting multigraph_input raised:\n{type(err)}: {err}" + ) + DiGraph.__init__(self, incoming_graph_data, **attr) + else: + DiGraph.__init__(self, incoming_graph_data, **attr) + + @cached_property + def adj(self): + """Graph adjacency object holding the neighbors of each node. + + This object is a read-only dict-like structure with node keys + and neighbor-dict values. The neighbor-dict is keyed by neighbor + to the edgekey-dict. So `G.adj[3][2][0]['color'] = 'blue'` sets + the color of the edge `(3, 2, 0)` to `"blue"`. + + Iterating over G.adj behaves like a dict. Useful idioms include + `for nbr, datadict in G.adj[n].items():`. + + The neighbor information is also provided by subscripting the graph. + So `for nbr, foovalue in G[node].data('foo', default=1):` works. + + For directed graphs, `G.adj` holds outgoing (successor) info. + """ + return MultiAdjacencyView(self._succ) + + @cached_property + def succ(self): + """Graph adjacency object holding the successors of each node. + + This object is a read-only dict-like structure with node keys + and neighbor-dict values. The neighbor-dict is keyed by neighbor + to the edgekey-dict. So `G.adj[3][2][0]['color'] = 'blue'` sets + the color of the edge `(3, 2, 0)` to `"blue"`. + + Iterating over G.adj behaves like a dict. Useful idioms include + `for nbr, datadict in G.adj[n].items():`. + + The neighbor information is also provided by subscripting the graph. + So `for nbr, foovalue in G[node].data('foo', default=1):` works. + + For directed graphs, `G.succ` is identical to `G.adj`. + """ + return MultiAdjacencyView(self._succ) + + @cached_property + def pred(self): + """Graph adjacency object holding the predecessors of each node. + + This object is a read-only dict-like structure with node keys + and neighbor-dict values. The neighbor-dict is keyed by neighbor + to the edgekey-dict. So `G.adj[3][2][0]['color'] = 'blue'` sets + the color of the edge `(3, 2, 0)` to `"blue"`. + + Iterating over G.adj behaves like a dict. Useful idioms include + `for nbr, datadict in G.adj[n].items():`. + """ + return MultiAdjacencyView(self._pred) + + def add_edge(self, u_for_edge, v_for_edge, key=None, **attr): + """Add an edge between u and v. + + The nodes u and v will be automatically added if they are + not already in the graph. + + Edge attributes can be specified with keywords or by directly + accessing the edge's attribute dictionary. See examples below. + + Parameters + ---------- + u_for_edge, v_for_edge : nodes + Nodes can be, for example, strings or numbers. + Nodes must be hashable (and not None) Python objects. + key : hashable identifier, optional (default=lowest unused integer) + Used to distinguish multiedges between a pair of nodes. + attr : keyword arguments, optional + Edge data (or labels or objects) can be assigned using + keyword arguments. + + Returns + ------- + The edge key assigned to the edge. + + See Also + -------- + add_edges_from : add a collection of edges + + Notes + ----- + To replace/update edge data, use the optional key argument + to identify a unique edge. Otherwise a new edge will be created. + + NetworkX algorithms designed for weighted graphs cannot use + multigraphs directly because it is not clear how to handle + multiedge weights. Convert to Graph using edge attribute + 'weight' to enable weighted graph algorithms. + + Default keys are generated using the method `new_edge_key()`. + This method can be overridden by subclassing the base class and + providing a custom `new_edge_key()` method. + + Examples + -------- + The following all add the edge e=(1, 2) to graph G: + + >>> G = nx.MultiDiGraph() + >>> e = (1, 2) + >>> key = G.add_edge(1, 2) # explicit two-node form + >>> G.add_edge(*e) # single edge as tuple of two nodes + 1 + >>> G.add_edges_from([(1, 2)]) # add edges from iterable container + [2] + + Associate data to edges using keywords: + + >>> key = G.add_edge(1, 2, weight=3) + >>> key = G.add_edge(1, 2, key=0, weight=4) # update data for key=0 + >>> key = G.add_edge(1, 3, weight=7, capacity=15, length=342.7) + + For non-string attribute keys, use subscript notation. + + >>> ekey = G.add_edge(1, 2) + >>> G[1][2][0].update({0: 5}) + >>> G.edges[1, 2, 0].update({0: 5}) + """ + u, v = u_for_edge, v_for_edge + # add nodes + if u not in self._succ: + if u is None: + raise ValueError("None cannot be a node") + self._succ[u] = self.adjlist_inner_dict_factory() + self._pred[u] = self.adjlist_inner_dict_factory() + self._node[u] = self.node_attr_dict_factory() + if v not in self._succ: + if v is None: + raise ValueError("None cannot be a node") + self._succ[v] = self.adjlist_inner_dict_factory() + self._pred[v] = self.adjlist_inner_dict_factory() + self._node[v] = self.node_attr_dict_factory() + if key is None: + key = self.new_edge_key(u, v) + if v in self._succ[u]: + keydict = self._adj[u][v] + datadict = keydict.get(key, self.edge_attr_dict_factory()) + datadict.update(attr) + keydict[key] = datadict + else: + # selfloops work this way without special treatment + datadict = self.edge_attr_dict_factory() + datadict.update(attr) + keydict = self.edge_key_dict_factory() + keydict[key] = datadict + self._succ[u][v] = keydict + self._pred[v][u] = keydict + nx._clear_cache(self) + return key + + def remove_edge(self, u, v, key=None): + """Remove an edge between u and v. + + Parameters + ---------- + u, v : nodes + Remove an edge between nodes u and v. + key : hashable identifier, optional (default=None) + Used to distinguish multiple edges between a pair of nodes. + If None, remove a single edge between u and v. If there are + multiple edges, removes the last edge added in terms of + insertion order. + + Raises + ------ + NetworkXError + If there is not an edge between u and v, or + if there is no edge with the specified key. + + See Also + -------- + remove_edges_from : remove a collection of edges + + Examples + -------- + >>> G = nx.MultiDiGraph() + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.remove_edge(0, 1) + >>> e = (1, 2) + >>> G.remove_edge(*e) # unpacks e from an edge tuple + + For multiple edges + + >>> G = nx.MultiDiGraph() + >>> G.add_edges_from([(1, 2), (1, 2), (1, 2)]) # key_list returned + [0, 1, 2] + + When ``key=None`` (the default), edges are removed in the opposite + order that they were added: + + >>> G.remove_edge(1, 2) + >>> G.edges(keys=True) + OutMultiEdgeView([(1, 2, 0), (1, 2, 1)]) + + For edges with keys + + >>> G = nx.MultiDiGraph() + >>> G.add_edge(1, 2, key="first") + 'first' + >>> G.add_edge(1, 2, key="second") + 'second' + >>> G.remove_edge(1, 2, key="first") + >>> G.edges(keys=True) + OutMultiEdgeView([(1, 2, 'second')]) + + """ + try: + d = self._adj[u][v] + except KeyError as err: + raise NetworkXError(f"The edge {u}-{v} is not in the graph.") from err + # remove the edge with specified data + if key is None: + d.popitem() + else: + try: + del d[key] + except KeyError as err: + msg = f"The edge {u}-{v} with key {key} is not in the graph." + raise NetworkXError(msg) from err + if len(d) == 0: + # remove the key entries if last edge + del self._succ[u][v] + del self._pred[v][u] + nx._clear_cache(self) + + @cached_property + def edges(self): + """An OutMultiEdgeView of the Graph as G.edges or G.edges(). + + edges(self, nbunch=None, data=False, keys=False, default=None) + + The OutMultiEdgeView provides set-like operations on the edge-tuples + as well as edge attribute lookup. When called, it also provides + an EdgeDataView object which allows control of access to edge + attributes (but does not provide set-like operations). + Hence, ``G.edges[u, v, k]['color']`` provides the value of the color + attribute for the edge from ``u`` to ``v`` with key ``k`` while + ``for (u, v, k, c) in G.edges(data='color', default='red', keys=True):`` + iterates through all the edges yielding the color attribute with + default `'red'` if no color attribute exists. + + Edges are returned as tuples with optional data and keys + in the order (node, neighbor, key, data). If ``keys=True`` is not + provided, the tuples will just be (node, neighbor, data), but + multiple tuples with the same node and neighbor will be + generated when multiple edges between two nodes exist. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges from these nodes. + data : string or bool, optional (default=False) + The edge attribute returned in 3-tuple (u, v, ddict[data]). + If True, return edge attribute dict in 3-tuple (u, v, ddict). + If False, return 2-tuple (u, v). + keys : bool, optional (default=False) + If True, return edge keys with each edge, creating (u, v, k, + d) tuples when data is also requested (the default) and (u, + v, k) tuples when data is not requested. + default : value, optional (default=None) + Value used for edges that don't have the requested attribute. + Only relevant if data is not True or False. + + Returns + ------- + edges : OutMultiEdgeView + A view of edge attributes, usually it iterates over (u, v) + (u, v, k) or (u, v, k, d) tuples of edges, but can also be + used for attribute lookup as ``edges[u, v, k]['foo']``. + + Notes + ----- + Nodes in nbunch that are not in the graph will be (quietly) ignored. + For directed graphs this returns the out-edges. + + Examples + -------- + >>> G = nx.MultiDiGraph() + >>> nx.add_path(G, [0, 1, 2]) + >>> key = G.add_edge(2, 3, weight=5) + >>> key2 = G.add_edge(1, 2) # second edge between these nodes + >>> [e for e in G.edges()] + [(0, 1), (1, 2), (1, 2), (2, 3)] + >>> list(G.edges(data=True)) # default data is {} (empty dict) + [(0, 1, {}), (1, 2, {}), (1, 2, {}), (2, 3, {'weight': 5})] + >>> list(G.edges(data="weight", default=1)) + [(0, 1, 1), (1, 2, 1), (1, 2, 1), (2, 3, 5)] + >>> list(G.edges(keys=True)) # default keys are integers + [(0, 1, 0), (1, 2, 0), (1, 2, 1), (2, 3, 0)] + >>> list(G.edges(data=True, keys=True)) + [(0, 1, 0, {}), (1, 2, 0, {}), (1, 2, 1, {}), (2, 3, 0, {'weight': 5})] + >>> list(G.edges(data="weight", default=1, keys=True)) + [(0, 1, 0, 1), (1, 2, 0, 1), (1, 2, 1, 1), (2, 3, 0, 5)] + >>> list(G.edges([0, 2])) + [(0, 1), (2, 3)] + >>> list(G.edges(0)) + [(0, 1)] + >>> list(G.edges(1)) + [(1, 2), (1, 2)] + + See Also + -------- + in_edges, out_edges + """ + return OutMultiEdgeView(self) + + # alias out_edges to edges + @cached_property + def out_edges(self): + return OutMultiEdgeView(self) + + out_edges.__doc__ = edges.__doc__ + + @cached_property + def in_edges(self): + """A view of the in edges of the graph as G.in_edges or G.in_edges(). + + in_edges(self, nbunch=None, data=False, keys=False, default=None) + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges incident to these nodes. + data : string or bool, optional (default=False) + The edge attribute returned in 3-tuple (u, v, ddict[data]). + If True, return edge attribute dict in 3-tuple (u, v, ddict). + If False, return 2-tuple (u, v). + keys : bool, optional (default=False) + If True, return edge keys with each edge, creating 3-tuples + (u, v, k) or with data, 4-tuples (u, v, k, d). + default : value, optional (default=None) + Value used for edges that don't have the requested attribute. + Only relevant if data is not True or False. + + Returns + ------- + in_edges : InMultiEdgeView or InMultiEdgeDataView + A view of edge attributes, usually it iterates over (u, v) + or (u, v, k) or (u, v, k, d) tuples of edges, but can also be + used for attribute lookup as `edges[u, v, k]['foo']`. + + See Also + -------- + edges + """ + return InMultiEdgeView(self) + + @cached_property + def degree(self): + """A DegreeView for the Graph as G.degree or G.degree(). + + The node degree is the number of edges adjacent to the node. + The weighted node degree is the sum of the edge weights for + edges incident to that node. + + This object provides an iterator for (node, degree) as well as + lookup for the degree for a single node. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges incident to these nodes. + + weight : string or None, optional (default=None) + The name of an edge attribute that holds the numerical value used + as a weight. If None, then each edge has weight 1. + The degree is the sum of the edge weights adjacent to the node. + + Returns + ------- + DiMultiDegreeView or int + If multiple nodes are requested (the default), returns a `DiMultiDegreeView` + mapping nodes to their degree. + If a single node is requested, returns the degree of the node as an integer. + + See Also + -------- + out_degree, in_degree + + Examples + -------- + >>> G = nx.MultiDiGraph() + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.degree(0) # node 0 with degree 1 + 1 + >>> list(G.degree([0, 1, 2])) + [(0, 1), (1, 2), (2, 2)] + >>> G.add_edge(0, 1) # parallel edge + 1 + >>> list(G.degree([0, 1, 2])) # parallel edges are counted + [(0, 2), (1, 3), (2, 2)] + + """ + return DiMultiDegreeView(self) + + @cached_property + def in_degree(self): + """A DegreeView for (node, in_degree) or in_degree for single node. + + The node in-degree is the number of edges pointing into the node. + The weighted node degree is the sum of the edge weights for + edges incident to that node. + + This object provides an iterator for (node, degree) as well as + lookup for the degree for a single node. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges incident to these nodes. + + weight : string or None, optional (default=None) + The edge attribute that holds the numerical value used + as a weight. If None, then each edge has weight 1. + The degree is the sum of the edge weights adjacent to the node. + + Returns + ------- + If a single node is requested + deg : int + Degree of the node + + OR if multiple nodes are requested + nd_iter : iterator + The iterator returns two-tuples of (node, in-degree). + + See Also + -------- + degree, out_degree + + Examples + -------- + >>> G = nx.MultiDiGraph() + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.in_degree(0) # node 0 with degree 0 + 0 + >>> list(G.in_degree([0, 1, 2])) + [(0, 0), (1, 1), (2, 1)] + >>> G.add_edge(0, 1) # parallel edge + 1 + >>> list(G.in_degree([0, 1, 2])) # parallel edges counted + [(0, 0), (1, 2), (2, 1)] + + """ + return InMultiDegreeView(self) + + @cached_property + def out_degree(self): + """Returns an iterator for (node, out-degree) or out-degree for single node. + + out_degree(self, nbunch=None, weight=None) + + The node out-degree is the number of edges pointing out of the node. + This function returns the out-degree for a single node or an iterator + for a bunch of nodes or if nothing is passed as argument. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges incident to these nodes. + + weight : string or None, optional (default=None) + The edge attribute that holds the numerical value used + as a weight. If None, then each edge has weight 1. + The degree is the sum of the edge weights. + + Returns + ------- + If a single node is requested + deg : int + Degree of the node + + OR if multiple nodes are requested + nd_iter : iterator + The iterator returns two-tuples of (node, out-degree). + + See Also + -------- + degree, in_degree + + Examples + -------- + >>> G = nx.MultiDiGraph() + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.out_degree(0) # node 0 with degree 1 + 1 + >>> list(G.out_degree([0, 1, 2])) + [(0, 1), (1, 1), (2, 1)] + >>> G.add_edge(0, 1) # parallel edge + 1 + >>> list(G.out_degree([0, 1, 2])) # counts parallel edges + [(0, 2), (1, 1), (2, 1)] + + """ + return OutMultiDegreeView(self) + + def is_multigraph(self): + """Returns True if graph is a multigraph, False otherwise.""" + return True + + def is_directed(self): + """Returns True if graph is directed, False otherwise.""" + return True + + def to_undirected(self, reciprocal=False, as_view=False): + """Returns an undirected representation of the digraph. + + Parameters + ---------- + reciprocal : bool (optional) + If True only keep edges that appear in both directions + in the original digraph. + as_view : bool (optional, default=False) + If True return an undirected view of the original directed graph. + + Returns + ------- + G : MultiGraph + An undirected graph with the same name and nodes and + with edge (u, v, data) if either (u, v, data) or (v, u, data) + is in the digraph. If both edges exist in digraph and + their edge data is different, only one edge is created + with an arbitrary choice of which edge data to use. + You must check and correct for this manually if desired. + + See Also + -------- + MultiGraph, copy, add_edge, add_edges_from + + Notes + ----- + This returns a "deepcopy" of the edge, node, and + graph attributes which attempts to completely copy + all of the data and references. + + This is in contrast to the similar D=MultiDiGraph(G) which + returns a shallow copy of the data. + + See the Python copy module for more information on shallow + and deep copies, https://docs.python.org/3/library/copy.html. + + Warning: If you have subclassed MultiDiGraph to use dict-like + objects in the data structure, those changes do not transfer + to the MultiGraph created by this method. + + Examples + -------- + >>> G = nx.path_graph(2) # or MultiGraph, etc + >>> H = G.to_directed() + >>> list(H.edges) + [(0, 1), (1, 0)] + >>> G2 = H.to_undirected() + >>> list(G2.edges) + [(0, 1)] + """ + graph_class = self.to_undirected_class() + if as_view is True: + return nx.graphviews.generic_graph_view(self, graph_class) + # deepcopy when not a view + G = graph_class() + G.graph.update(deepcopy(self.graph)) + G.add_nodes_from((n, deepcopy(d)) for n, d in self._node.items()) + if reciprocal is True: + G.add_edges_from( + (u, v, key, deepcopy(data)) + for u, nbrs in self._adj.items() + for v, keydict in nbrs.items() + for key, data in keydict.items() + if v in self._pred[u] and key in self._pred[u][v] + ) + else: + G.add_edges_from( + (u, v, key, deepcopy(data)) + for u, nbrs in self._adj.items() + for v, keydict in nbrs.items() + for key, data in keydict.items() + ) + return G + + def reverse(self, copy=True): + """Returns the reverse of the graph. + + The reverse is a graph with the same nodes and edges + but with the directions of the edges reversed. + + Parameters + ---------- + copy : bool optional (default=True) + If True, return a new DiGraph holding the reversed edges. + If False, the reverse graph is created using a view of + the original graph. + """ + if copy: + H = self.__class__() + H.graph.update(deepcopy(self.graph)) + H.add_nodes_from((n, deepcopy(d)) for n, d in self._node.items()) + H.add_edges_from( + (v, u, k, deepcopy(d)) + for u, v, k, d in self.edges(keys=True, data=True) + ) + return H + return nx.reverse_view(self) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/multigraph.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/multigraph.py new file mode 100644 index 0000000000000000000000000000000000000000..a942f2e04ccea8a877e40d9b03cd8484844cb147 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/multigraph.py @@ -0,0 +1,1294 @@ +"""Base class for MultiGraph.""" + +from copy import deepcopy +from functools import cached_property + +import networkx as nx +from networkx import NetworkXError, convert +from networkx.classes.coreviews import MultiAdjacencyView +from networkx.classes.graph import Graph +from networkx.classes.reportviews import MultiDegreeView, MultiEdgeView + +__all__ = ["MultiGraph"] + + +class MultiGraph(Graph): + """ + An undirected graph class that can store multiedges. + + Multiedges are multiple edges between two nodes. Each edge + can hold optional data or attributes. + + A MultiGraph holds undirected edges. Self loops are allowed. + + Nodes can be arbitrary (hashable) Python objects with optional + key/value attributes. By convention `None` is not used as a node. + + Edges are represented as links between nodes with optional + key/value attributes, in a MultiGraph each edge has a key to + distinguish between multiple edges that have the same source and + destination nodes. + + Parameters + ---------- + incoming_graph_data : input graph (optional, default: None) + Data to initialize graph. If None (default) an empty + graph is created. The data can be any format that is supported + by the to_networkx_graph() function, currently including edge list, + dict of dicts, dict of lists, NetworkX graph, 2D NumPy array, + SciPy sparse array, or PyGraphviz graph. + + multigraph_input : bool or None (default None) + Note: Only used when `incoming_graph_data` is a dict. + If True, `incoming_graph_data` is assumed to be a + dict-of-dict-of-dict-of-dict structure keyed by + node to neighbor to edge keys to edge data for multi-edges. + A NetworkXError is raised if this is not the case. + If False, :func:`to_networkx_graph` is used to try to determine + the dict's graph data structure as either a dict-of-dict-of-dict + keyed by node to neighbor to edge data, or a dict-of-iterable + keyed by node to neighbors. + If None, the treatment for True is tried, but if it fails, + the treatment for False is tried. + + attr : keyword arguments, optional (default= no attributes) + Attributes to add to graph as key=value pairs. + + See Also + -------- + Graph + DiGraph + MultiDiGraph + + Examples + -------- + Create an empty graph structure (a "null graph") with no nodes and + no edges. + + >>> G = nx.MultiGraph() + + G can be grown in several ways. + + **Nodes:** + + Add one node at a time: + + >>> G.add_node(1) + + Add the nodes from any container (a list, dict, set or + even the lines from a file or the nodes from another graph). + + >>> G.add_nodes_from([2, 3]) + >>> G.add_nodes_from(range(100, 110)) + >>> H = nx.path_graph(10) + >>> G.add_nodes_from(H) + + In addition to strings and integers any hashable Python object + (except None) can represent a node, e.g. a customized node object, + or even another Graph. + + >>> G.add_node(H) + + **Edges:** + + G can also be grown by adding edges. + + Add one edge, + + >>> key = G.add_edge(1, 2) + + a list of edges, + + >>> keys = G.add_edges_from([(1, 2), (1, 3)]) + + or a collection of edges, + + >>> keys = G.add_edges_from(H.edges) + + If some edges connect nodes not yet in the graph, the nodes + are added automatically. If an edge already exists, an additional + edge is created and stored using a key to identify the edge. + By default the key is the lowest unused integer. + + >>> keys = G.add_edges_from([(4, 5, {"route": 28}), (4, 5, {"route": 37})]) + >>> G[4] + AdjacencyView({3: {0: {}}, 5: {0: {}, 1: {'route': 28}, 2: {'route': 37}}}) + + **Attributes:** + + Each graph, node, and edge can hold key/value attribute pairs + in an associated attribute dictionary (the keys must be hashable). + By default these are empty, but can be added or changed using + add_edge, add_node or direct manipulation of the attribute + dictionaries named graph, node and edge respectively. + + >>> G = nx.MultiGraph(day="Friday") + >>> G.graph + {'day': 'Friday'} + + Add node attributes using add_node(), add_nodes_from() or G.nodes + + >>> G.add_node(1, time="5pm") + >>> G.add_nodes_from([3], time="2pm") + >>> G.nodes[1] + {'time': '5pm'} + >>> G.nodes[1]["room"] = 714 + >>> del G.nodes[1]["room"] # remove attribute + >>> list(G.nodes(data=True)) + [(1, {'time': '5pm'}), (3, {'time': '2pm'})] + + Add edge attributes using add_edge(), add_edges_from(), subscript + notation, or G.edges. + + >>> key = G.add_edge(1, 2, weight=4.7) + >>> keys = G.add_edges_from([(3, 4), (4, 5)], color="red") + >>> keys = G.add_edges_from([(1, 2, {"color": "blue"}), (2, 3, {"weight": 8})]) + >>> G[1][2][0]["weight"] = 4.7 + >>> G.edges[1, 2, 0]["weight"] = 4 + + Warning: we protect the graph data structure by making `G.edges[1, + 2, 0]` a read-only dict-like structure. However, you can assign to + attributes in e.g. `G.edges[1, 2, 0]`. Thus, use 2 sets of brackets + to add/change data attributes: `G.edges[1, 2, 0]['weight'] = 4`. + + **Shortcuts:** + + Many common graph features allow python syntax to speed reporting. + + >>> 1 in G # check if node in graph + True + >>> [n for n in G if n < 3] # iterate through nodes + [1, 2] + >>> len(G) # number of nodes in graph + 5 + >>> G[1] # adjacency dict-like view mapping neighbor -> edge key -> edge attributes + AdjacencyView({2: {0: {'weight': 4}, 1: {'color': 'blue'}}}) + + Often the best way to traverse all edges of a graph is via the neighbors. + The neighbors are reported as an adjacency-dict `G.adj` or `G.adjacency()`. + + >>> for n, nbrsdict in G.adjacency(): + ... for nbr, keydict in nbrsdict.items(): + ... for key, eattr in keydict.items(): + ... if "weight" in eattr: + ... # Do something useful with the edges + ... pass + + But the edges() method is often more convenient: + + >>> for u, v, keys, weight in G.edges(data="weight", keys=True): + ... if weight is not None: + ... # Do something useful with the edges + ... pass + + **Reporting:** + + Simple graph information is obtained using methods and object-attributes. + Reporting usually provides views instead of containers to reduce memory + usage. The views update as the graph is updated similarly to dict-views. + The objects `nodes`, `edges` and `adj` provide access to data attributes + via lookup (e.g. `nodes[n]`, `edges[u, v, k]`, `adj[u][v]`) and iteration + (e.g. `nodes.items()`, `nodes.data('color')`, + `nodes.data('color', default='blue')` and similarly for `edges`) + Views exist for `nodes`, `edges`, `neighbors()`/`adj` and `degree`. + + For details on these and other miscellaneous methods, see below. + + **Subclasses (Advanced):** + + The MultiGraph class uses a dict-of-dict-of-dict-of-dict data structure. + The outer dict (node_dict) holds adjacency information keyed by node. + The next dict (adjlist_dict) represents the adjacency information + and holds edge_key dicts keyed by neighbor. The edge_key dict holds + each edge_attr dict keyed by edge key. The inner dict + (edge_attr_dict) represents the edge data and holds edge attribute + values keyed by attribute names. + + Each of these four dicts in the dict-of-dict-of-dict-of-dict + structure can be replaced by a user defined dict-like object. + In general, the dict-like features should be maintained but + extra features can be added. To replace one of the dicts create + a new graph class by changing the class(!) variable holding the + factory for that dict-like structure. The variable names are + node_dict_factory, node_attr_dict_factory, adjlist_inner_dict_factory, + adjlist_outer_dict_factory, edge_key_dict_factory, edge_attr_dict_factory + and graph_attr_dict_factory. + + node_dict_factory : function, (default: dict) + Factory function to be used to create the dict containing node + attributes, keyed by node id. + It should require no arguments and return a dict-like object + + node_attr_dict_factory: function, (default: dict) + Factory function to be used to create the node attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object + + adjlist_outer_dict_factory : function, (default: dict) + Factory function to be used to create the outer-most dict + in the data structure that holds adjacency info keyed by node. + It should require no arguments and return a dict-like object. + + adjlist_inner_dict_factory : function, (default: dict) + Factory function to be used to create the adjacency list + dict which holds multiedge key dicts keyed by neighbor. + It should require no arguments and return a dict-like object. + + edge_key_dict_factory : function, (default: dict) + Factory function to be used to create the edge key dict + which holds edge data keyed by edge key. + It should require no arguments and return a dict-like object. + + edge_attr_dict_factory : function, (default: dict) + Factory function to be used to create the edge attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object. + + graph_attr_dict_factory : function, (default: dict) + Factory function to be used to create the graph attribute + dict which holds attribute values keyed by attribute name. + It should require no arguments and return a dict-like object. + + Typically, if your extension doesn't impact the data structure all + methods will inherited without issue except: `to_directed/to_undirected`. + By default these methods create a DiGraph/Graph class and you probably + want them to create your extension of a DiGraph/Graph. To facilitate + this we define two class variables that you can set in your subclass. + + to_directed_class : callable, (default: DiGraph or MultiDiGraph) + Class to create a new graph structure in the `to_directed` method. + If `None`, a NetworkX class (DiGraph or MultiDiGraph) is used. + + to_undirected_class : callable, (default: Graph or MultiGraph) + Class to create a new graph structure in the `to_undirected` method. + If `None`, a NetworkX class (Graph or MultiGraph) is used. + + **Subclassing Example** + + Create a low memory graph class that effectively disallows edge + attributes by using a single attribute dict for all edges. + This reduces the memory used, but you lose edge attributes. + + >>> class ThinGraph(nx.Graph): + ... all_edge_dict = {"weight": 1} + ... + ... def single_edge_dict(self): + ... return self.all_edge_dict + ... + ... edge_attr_dict_factory = single_edge_dict + >>> G = ThinGraph() + >>> G.add_edge(2, 1) + >>> G[2][1] + {'weight': 1} + >>> G.add_edge(2, 2) + >>> G[2][1] is G[2][2] + True + """ + + # node_dict_factory = dict # already assigned in Graph + # adjlist_outer_dict_factory = dict + # adjlist_inner_dict_factory = dict + edge_key_dict_factory = dict + # edge_attr_dict_factory = dict + + def to_directed_class(self): + """Returns the class to use for empty directed copies. + + If you subclass the base classes, use this to designate + what directed class to use for `to_directed()` copies. + """ + return nx.MultiDiGraph + + def to_undirected_class(self): + """Returns the class to use for empty undirected copies. + + If you subclass the base classes, use this to designate + what directed class to use for `to_directed()` copies. + """ + return MultiGraph + + # This __new__ method just does what Python itself does automatically. + # We include it here as part of the dispatchable/backend interface. + # If your goal is to understand how the graph classes work, you can ignore + # this method, even when subclassing the base classes. If you are subclassing + # in order to provide a backend that allows class instantiation, this method + # can be overridden to return your own backend graph class. + @nx._dispatchable(name="multigraph__new__", graphs=None, returns_graph=True) + def __new__(cls, *args, **kwargs): + return object.__new__(cls) + + def __init__(self, incoming_graph_data=None, multigraph_input=None, **attr): + """Initialize a graph with edges, name, or graph attributes. + + Parameters + ---------- + incoming_graph_data : input graph + Data to initialize graph. If incoming_graph_data=None (default) + an empty graph is created. The data can be an edge list, or any + NetworkX graph object. If the corresponding optional Python + packages are installed the data can also be a 2D NumPy array, a + SciPy sparse array, or a PyGraphviz graph. + + multigraph_input : bool or None (default None) + Note: Only used when `incoming_graph_data` is a dict. + If True, `incoming_graph_data` is assumed to be a + dict-of-dict-of-dict-of-dict structure keyed by + node to neighbor to edge keys to edge data for multi-edges. + A NetworkXError is raised if this is not the case. + If False, :func:`to_networkx_graph` is used to try to determine + the dict's graph data structure as either a dict-of-dict-of-dict + keyed by node to neighbor to edge data, or a dict-of-iterable + keyed by node to neighbors. + If None, the treatment for True is tried, but if it fails, + the treatment for False is tried. + + attr : keyword arguments, optional (default= no attributes) + Attributes to add to graph as key=value pairs. + + See Also + -------- + convert + + Examples + -------- + >>> G = nx.MultiGraph() + >>> G = nx.MultiGraph(name="my graph") + >>> e = [(1, 2), (1, 2), (2, 3), (3, 4)] # list of edges + >>> G = nx.MultiGraph(e) + + Arbitrary graph attribute pairs (key=value) may be assigned + + >>> G = nx.MultiGraph(e, day="Friday") + >>> G.graph + {'day': 'Friday'} + + """ + attr.pop("backend", None) # Ignore explicit `backend="networkx"` + # multigraph_input can be None/True/False. So check "is not False" + if isinstance(incoming_graph_data, dict) and multigraph_input is not False: + Graph.__init__(self) + try: + convert.from_dict_of_dicts( + incoming_graph_data, create_using=self, multigraph_input=True + ) + self.graph.update(attr) + except Exception as err: + if multigraph_input is True: + raise nx.NetworkXError( + f"converting multigraph_input raised:\n{type(err)}: {err}" + ) + Graph.__init__(self, incoming_graph_data, **attr) + else: + Graph.__init__(self, incoming_graph_data, **attr) + + @cached_property + def adj(self): + """Graph adjacency object holding the neighbors of each node. + + This object is a read-only dict-like structure with node keys + and neighbor-dict values. The neighbor-dict is keyed by neighbor + to the edgekey-data-dict. So `G.adj[3][2][0]['color'] = 'blue'` sets + the color of the edge `(3, 2, 0)` to `"blue"`. + + Iterating over G.adj behaves like a dict. Useful idioms include + `for nbr, edgesdict in G.adj[n].items():`. + + The neighbor information is also provided by subscripting the graph. + + Examples + -------- + >>> e = [(1, 2), (1, 2), (1, 3), (3, 4)] # list of edges + >>> G = nx.MultiGraph(e) + >>> G.edges[1, 2, 0]["weight"] = 3 + >>> result = set() + >>> for edgekey, data in G[1][2].items(): + ... result.add(data.get("weight", 1)) + >>> result + {1, 3} + + For directed graphs, `G.adj` holds outgoing (successor) info. + """ + return MultiAdjacencyView(self._adj) + + def new_edge_key(self, u, v): + """Returns an unused key for edges between nodes `u` and `v`. + + The nodes `u` and `v` do not need to be already in the graph. + + Notes + ----- + In the standard MultiGraph class the new key is the number of existing + edges between `u` and `v` (increased if necessary to ensure unused). + The first edge will have key 0, then 1, etc. If an edge is removed + further new_edge_keys may not be in this order. + + Parameters + ---------- + u, v : nodes + + Returns + ------- + key : int + """ + try: + keydict = self._adj[u][v] + except KeyError: + return 0 + key = len(keydict) + while key in keydict: + key += 1 + return key + + def add_edge(self, u_for_edge, v_for_edge, key=None, **attr): + """Add an edge between u and v. + + The nodes u and v will be automatically added if they are + not already in the graph. + + Edge attributes can be specified with keywords or by directly + accessing the edge's attribute dictionary. See examples below. + + Parameters + ---------- + u_for_edge, v_for_edge : nodes + Nodes can be, for example, strings or numbers. + Nodes must be hashable (and not None) Python objects. + key : hashable identifier, optional (default=lowest unused integer) + Used to distinguish multiedges between a pair of nodes. + attr : keyword arguments, optional + Edge data (or labels or objects) can be assigned using + keyword arguments. + + Returns + ------- + The edge key assigned to the edge. + + See Also + -------- + add_edges_from : add a collection of edges + + Notes + ----- + To replace/update edge data, use the optional key argument + to identify a unique edge. Otherwise a new edge will be created. + + NetworkX algorithms designed for weighted graphs cannot use + multigraphs directly because it is not clear how to handle + multiedge weights. Convert to Graph using edge attribute + 'weight' to enable weighted graph algorithms. + + Default keys are generated using the method `new_edge_key()`. + This method can be overridden by subclassing the base class and + providing a custom `new_edge_key()` method. + + Examples + -------- + The following each add an additional edge e=(1, 2) to graph G: + + >>> G = nx.MultiGraph() + >>> e = (1, 2) + >>> ekey = G.add_edge(1, 2) # explicit two-node form + >>> G.add_edge(*e) # single edge as tuple of two nodes + 1 + >>> G.add_edges_from([(1, 2)]) # add edges from iterable container + [2] + + Associate data to edges using keywords: + + >>> ekey = G.add_edge(1, 2, weight=3) + >>> ekey = G.add_edge(1, 2, key=0, weight=4) # update data for key=0 + >>> ekey = G.add_edge(1, 3, weight=7, capacity=15, length=342.7) + + For non-string attribute keys, use subscript notation. + + >>> ekey = G.add_edge(1, 2) + >>> G[1][2][0].update({0: 5}) + >>> G.edges[1, 2, 0].update({0: 5}) + """ + u, v = u_for_edge, v_for_edge + # add nodes + if u not in self._adj: + if u is None: + raise ValueError("None cannot be a node") + self._adj[u] = self.adjlist_inner_dict_factory() + self._node[u] = self.node_attr_dict_factory() + if v not in self._adj: + if v is None: + raise ValueError("None cannot be a node") + self._adj[v] = self.adjlist_inner_dict_factory() + self._node[v] = self.node_attr_dict_factory() + if key is None: + key = self.new_edge_key(u, v) + if v in self._adj[u]: + keydict = self._adj[u][v] + datadict = keydict.get(key, self.edge_attr_dict_factory()) + datadict.update(attr) + keydict[key] = datadict + else: + # selfloops work this way without special treatment + datadict = self.edge_attr_dict_factory() + datadict.update(attr) + keydict = self.edge_key_dict_factory() + keydict[key] = datadict + self._adj[u][v] = keydict + self._adj[v][u] = keydict + nx._clear_cache(self) + return key + + def add_edges_from(self, ebunch_to_add, **attr): + """Add all the edges in ebunch_to_add. + + Parameters + ---------- + ebunch_to_add : container of edges + Each edge given in the container will be added to the + graph. The edges can be: + + - 2-tuples (u, v) or + - 3-tuples (u, v, d) for an edge data dict d, or + - 3-tuples (u, v, k) for not iterable key k, or + - 4-tuples (u, v, k, d) for an edge with data and key k + + attr : keyword arguments, optional + Edge data (or labels or objects) can be assigned using + keyword arguments. + + Returns + ------- + A list of edge keys assigned to the edges in `ebunch`. + + See Also + -------- + add_edge : add a single edge + add_weighted_edges_from : convenient way to add weighted edges + + Notes + ----- + Adding the same edge twice has no effect but any edge data + will be updated when each duplicate edge is added. + + Edge attributes specified in an ebunch take precedence over + attributes specified via keyword arguments. + + Default keys are generated using the method ``new_edge_key()``. + This method can be overridden by subclassing the base class and + providing a custom ``new_edge_key()`` method. + + When adding edges from an iterator over the graph you are changing, + a `RuntimeError` can be raised with message: + `RuntimeError: dictionary changed size during iteration`. This + happens when the graph's underlying dictionary is modified during + iteration. To avoid this error, evaluate the iterator into a separate + object, e.g. by using `list(iterator_of_edges)`, and pass this + object to `G.add_edges_from`. + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> G.add_edges_from([(0, 1), (1, 2)]) # using a list of edge tuples + >>> e = zip(range(0, 3), range(1, 4)) + >>> G.add_edges_from(e) # Add the path graph 0-1-2-3 + + Associate data to edges + + >>> G.add_edges_from([(1, 2), (2, 3)], weight=3) + >>> G.add_edges_from([(3, 4), (1, 4)], label="WN2898") + + Evaluate an iterator over a graph if using it to modify the same graph + + >>> G = nx.MultiGraph([(1, 2), (2, 3), (3, 4)]) + >>> # Grow graph by one new node, adding edges to all existing nodes. + >>> # wrong way - will raise RuntimeError + >>> # G.add_edges_from(((5, n) for n in G.nodes)) + >>> # right way - note that there will be no self-edge for node 5 + >>> assigned_keys = G.add_edges_from(list((5, n) for n in G.nodes)) + """ + keylist = [] + for e in ebunch_to_add: + ne = len(e) + if ne == 4: + u, v, key, dd = e + elif ne == 3: + u, v, dd = e + key = None + elif ne == 2: + u, v = e + dd = {} + key = None + else: + msg = f"Edge tuple {e} must be a 2-tuple, 3-tuple or 4-tuple." + raise NetworkXError(msg) + ddd = {} + ddd.update(attr) + try: + ddd.update(dd) + except (TypeError, ValueError): + if ne != 3: + raise + key = dd # ne == 3 with 3rd value not dict, must be a key + key = self.add_edge(u, v, key) + self[u][v][key].update(ddd) + keylist.append(key) + nx._clear_cache(self) + return keylist + + def remove_edge(self, u, v, key=None): + """Remove an edge between u and v. + + Parameters + ---------- + u, v : nodes + Remove an edge between nodes u and v. + key : hashable identifier, optional (default=None) + Used to distinguish multiple edges between a pair of nodes. + If None, remove a single edge between u and v. If there are + multiple edges, removes the last edge added in terms of + insertion order. + + Raises + ------ + NetworkXError + If there is not an edge between u and v, or + if there is no edge with the specified key. + + See Also + -------- + remove_edges_from : remove a collection of edges + + Examples + -------- + >>> G = nx.MultiGraph() + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.remove_edge(0, 1) + >>> e = (1, 2) + >>> G.remove_edge(*e) # unpacks e from an edge tuple + + For multiple edges + + >>> G = nx.MultiGraph() # or MultiDiGraph, etc + >>> G.add_edges_from([(1, 2), (1, 2), (1, 2)]) # key_list returned + [0, 1, 2] + + When ``key=None`` (the default), edges are removed in the opposite + order that they were added: + + >>> G.remove_edge(1, 2) + >>> G.edges(keys=True) + MultiEdgeView([(1, 2, 0), (1, 2, 1)]) + >>> G.remove_edge(2, 1) # edges are not directed + >>> G.edges(keys=True) + MultiEdgeView([(1, 2, 0)]) + + For edges with keys + + >>> G = nx.MultiGraph() + >>> G.add_edge(1, 2, key="first") + 'first' + >>> G.add_edge(1, 2, key="second") + 'second' + >>> G.remove_edge(1, 2, key="first") + >>> G.edges(keys=True) + MultiEdgeView([(1, 2, 'second')]) + + """ + try: + d = self._adj[u][v] + except KeyError as err: + raise NetworkXError(f"The edge {u}-{v} is not in the graph.") from err + # remove the edge with specified data + if key is None: + d.popitem() + else: + try: + del d[key] + except KeyError as err: + msg = f"The edge {u}-{v} with key {key} is not in the graph." + raise NetworkXError(msg) from err + if len(d) == 0: + # remove the key entries if last edge + del self._adj[u][v] + if u != v: # check for selfloop + del self._adj[v][u] + nx._clear_cache(self) + + def remove_edges_from(self, ebunch): + """Remove all edges specified in ebunch. + + Parameters + ---------- + ebunch: list or container of edge tuples + Each edge given in the list or container will be removed + from the graph. The edges can be: + + - 2-tuples (u, v) A single edge between u and v is removed. + - 3-tuples (u, v, key) The edge identified by key is removed. + - 4-tuples (u, v, key, data) where data is ignored. + + See Also + -------- + remove_edge : remove a single edge + + Notes + ----- + Will fail silently if an edge in ebunch is not in the graph. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> ebunch = [(1, 2), (2, 3)] + >>> G.remove_edges_from(ebunch) + + Removing multiple copies of edges + + >>> G = nx.MultiGraph() + >>> keys = G.add_edges_from([(1, 2), (1, 2), (1, 2)]) + >>> G.remove_edges_from([(1, 2), (2, 1)]) # edges aren't directed + >>> list(G.edges()) + [(1, 2)] + >>> G.remove_edges_from([(1, 2), (1, 2)]) # silently ignore extra copy + >>> list(G.edges) # now empty graph + [] + + When the edge is a 2-tuple ``(u, v)`` but there are multiple edges between + u and v in the graph, the most recent edge (in terms of insertion + order) is removed. + + >>> G = nx.MultiGraph() + >>> for key in ("x", "y", "a"): + ... k = G.add_edge(0, 1, key=key) + >>> G.edges(keys=True) + MultiEdgeView([(0, 1, 'x'), (0, 1, 'y'), (0, 1, 'a')]) + >>> G.remove_edges_from([(0, 1)]) + >>> G.edges(keys=True) + MultiEdgeView([(0, 1, 'x'), (0, 1, 'y')]) + + """ + for e in ebunch: + try: + self.remove_edge(*e[:3]) + except NetworkXError: + pass + nx._clear_cache(self) + + def has_edge(self, u, v, key=None): + """Returns True if the graph has an edge between nodes u and v. + + This is the same as `v in G[u] or key in G[u][v]` + without KeyError exceptions. + + Parameters + ---------- + u, v : nodes + Nodes can be, for example, strings or numbers. + + key : hashable identifier, optional (default=None) + If specified return True only if the edge with + key is found. + + Returns + ------- + edge_ind : bool + True if edge is in the graph, False otherwise. + + Examples + -------- + Can be called either using two nodes u, v, an edge tuple (u, v), + or an edge tuple (u, v, key). + + >>> G = nx.MultiGraph() # or MultiDiGraph + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.has_edge(0, 1) # using two nodes + True + >>> e = (0, 1) + >>> G.has_edge(*e) # e is a 2-tuple (u, v) + True + >>> G.add_edge(0, 1, key="a") + 'a' + >>> G.has_edge(0, 1, key="a") # specify key + True + >>> G.has_edge(1, 0, key="a") # edges aren't directed + True + >>> e = (0, 1, "a") + >>> G.has_edge(*e) # e is a 3-tuple (u, v, 'a') + True + + The following syntax are equivalent: + + >>> G.has_edge(0, 1) + True + >>> 1 in G[0] # though this gives :exc:`KeyError` if 0 not in G + True + >>> 0 in G[1] # other order; also gives :exc:`KeyError` if 0 not in G + True + + """ + try: + if key is None: + return v in self._adj[u] + else: + return key in self._adj[u][v] + except KeyError: + return False + + @cached_property + def edges(self): + """Returns an iterator over the edges. + + edges(self, nbunch=None, data=False, keys=False, default=None) + + The MultiEdgeView provides set-like operations on the edge-tuples + as well as edge attribute lookup. When called, it also provides + an EdgeDataView object which allows control of access to edge + attributes (but does not provide set-like operations). + Hence, ``G.edges[u, v, k]['color']`` provides the value of the color + attribute for the edge from ``u`` to ``v`` with key ``k`` while + ``for (u, v, k, c) in G.edges(data='color', keys=True, default="red"):`` + iterates through all the edges yielding the color attribute with + default `'red'` if no color attribute exists. + + Edges are returned as tuples with optional data and keys + in the order (node, neighbor, key, data). If ``keys=True`` is not + provided, the tuples will just be (node, neighbor, data), but + multiple tuples with the same node and neighbor will be generated + when multiple edges exist between two nodes. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges from these nodes. + data : string or bool, optional (default=False) + The edge attribute returned in 3-tuple (u, v, ddict[data]). + If True, return edge attribute dict in 3-tuple (u, v, ddict). + If False, return 2-tuple (u, v). + keys : bool, optional (default=False) + If True, return edge keys with each edge, creating (u, v, k) + tuples or (u, v, k, d) tuples if data is also requested. + default : value, optional (default=None) + Value used for edges that don't have the requested attribute. + Only relevant if data is not True or False. + + Returns + ------- + edges : MultiEdgeView + A view of edge attributes, usually it iterates over (u, v) + (u, v, k) or (u, v, k, d) tuples of edges, but can also be + used for attribute lookup as ``edges[u, v, k]['foo']``. + + Notes + ----- + Nodes in nbunch that are not in the graph will be (quietly) ignored. + For directed graphs this returns the out-edges. + + Examples + -------- + >>> G = nx.MultiGraph() + >>> nx.add_path(G, [0, 1, 2]) + >>> key = G.add_edge(2, 3, weight=5) + >>> key2 = G.add_edge(2, 1, weight=2) # multi-edge + >>> [e for e in G.edges()] + [(0, 1), (1, 2), (1, 2), (2, 3)] + >>> G.edges.data() # default data is {} (empty dict) + MultiEdgeDataView([(0, 1, {}), (1, 2, {}), (1, 2, {'weight': 2}), (2, 3, {'weight': 5})]) + >>> G.edges.data("weight", default=1) + MultiEdgeDataView([(0, 1, 1), (1, 2, 1), (1, 2, 2), (2, 3, 5)]) + >>> G.edges(keys=True) # default keys are integers + MultiEdgeView([(0, 1, 0), (1, 2, 0), (1, 2, 1), (2, 3, 0)]) + >>> G.edges.data(keys=True) + MultiEdgeDataView([(0, 1, 0, {}), (1, 2, 0, {}), (1, 2, 1, {'weight': 2}), (2, 3, 0, {'weight': 5})]) + >>> G.edges.data("weight", default=1, keys=True) + MultiEdgeDataView([(0, 1, 0, 1), (1, 2, 0, 1), (1, 2, 1, 2), (2, 3, 0, 5)]) + >>> G.edges([0, 3]) # Note ordering of tuples from listed sources + MultiEdgeDataView([(0, 1), (3, 2)]) + >>> G.edges([0, 3, 2, 1]) # Note ordering of tuples + MultiEdgeDataView([(0, 1), (3, 2), (2, 1), (2, 1)]) + >>> G.edges(0) + MultiEdgeDataView([(0, 1)]) + """ + return MultiEdgeView(self) + + def get_edge_data(self, u, v, key=None, default=None): + """Returns the attribute dictionary associated with edge (u, v, + key). + + If a key is not provided, returns a dictionary mapping edge keys + to attribute dictionaries for each edge between u and v. + + This is identical to `G[u][v][key]` except the default is returned + instead of an exception is the edge doesn't exist. + + Parameters + ---------- + u, v : nodes + + default : any Python object (default=None) + Value to return if the specific edge (u, v, key) is not + found, OR if there are no edges between u and v and no key + is specified. + + key : hashable identifier, optional (default=None) + Return data only for the edge with specified key, as an + attribute dictionary (rather than a dictionary mapping keys + to attribute dictionaries). + + Returns + ------- + edge_dict : dictionary + The edge attribute dictionary, OR a dictionary mapping edge + keys to attribute dictionaries for each of those edges if no + specific key is provided (even if there's only one edge + between u and v). + + Examples + -------- + >>> G = nx.MultiGraph() # or MultiDiGraph + >>> key = G.add_edge(0, 1, key="a", weight=7) + >>> G[0][1]["a"] # key='a' + {'weight': 7} + >>> G.edges[0, 1, "a"] # key='a' + {'weight': 7} + + Warning: we protect the graph data structure by making + `G.edges` and `G[1][2]` read-only dict-like structures. + However, you can assign values to attributes in e.g. + `G.edges[1, 2, 'a']` or `G[1][2]['a']` using an additional + bracket as shown next. You need to specify all edge info + to assign to the edge data associated with an edge. + + >>> G[0][1]["a"]["weight"] = 10 + >>> G.edges[0, 1, "a"]["weight"] = 10 + >>> G[0][1]["a"]["weight"] + 10 + >>> G.edges[1, 0, "a"]["weight"] + 10 + + >>> G = nx.MultiGraph() # or MultiDiGraph + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.edges[0, 1, 0]["weight"] = 5 + >>> G.get_edge_data(0, 1) + {0: {'weight': 5}} + >>> e = (0, 1) + >>> G.get_edge_data(*e) # tuple form + {0: {'weight': 5}} + >>> G.get_edge_data(3, 0) # edge not in graph, returns None + >>> G.get_edge_data(3, 0, default=0) # edge not in graph, return default + 0 + >>> G.get_edge_data(1, 0, 0) # specific key gives back + {'weight': 5} + """ + try: + if key is None: + return self._adj[u][v] + else: + return self._adj[u][v][key] + except KeyError: + return default + + @cached_property + def degree(self): + """A DegreeView for the Graph as G.degree or G.degree(). + + The node degree is the number of edges adjacent to the node. + The weighted node degree is the sum of the edge weights for + edges incident to that node. + + This object provides an iterator for (node, degree) as well as + lookup for the degree for a single node. + + Parameters + ---------- + nbunch : single node, container, or all nodes (default= all nodes) + The view will only report edges incident to these nodes. + + weight : string or None, optional (default=None) + The name of an edge attribute that holds the numerical value used + as a weight. If None, then each edge has weight 1. + The degree is the sum of the edge weights adjacent to the node. + + Returns + ------- + MultiDegreeView or int + If multiple nodes are requested (the default), returns a `MultiDegreeView` + mapping nodes to their degree. + If a single node is requested, returns the degree of the node as an integer. + + Examples + -------- + >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> nx.add_path(G, [0, 1, 2, 3]) + >>> G.degree(0) # node 0 with degree 1 + 1 + >>> list(G.degree([0, 1])) + [(0, 1), (1, 2)] + + """ + return MultiDegreeView(self) + + def is_multigraph(self): + """Returns True if graph is a multigraph, False otherwise.""" + return True + + def is_directed(self): + """Returns True if graph is directed, False otherwise.""" + return False + + def copy(self, as_view=False): + """Returns a copy of the graph. + + The copy method by default returns an independent shallow copy + of the graph and attributes. That is, if an attribute is a + container, that container is shared by the original an the copy. + Use Python's `copy.deepcopy` for new containers. + + If `as_view` is True then a view is returned instead of a copy. + + Notes + ----- + All copies reproduce the graph structure, but data attributes + may be handled in different ways. There are four types of copies + of a graph that people might want. + + Deepcopy -- A "deepcopy" copies the graph structure as well as + all data attributes and any objects they might contain. + The entire graph object is new so that changes in the copy + do not affect the original object. (see Python's copy.deepcopy) + + Data Reference (Shallow) -- For a shallow copy the graph structure + is copied but the edge, node and graph attribute dicts are + references to those in the original graph. This saves + time and memory but could cause confusion if you change an attribute + in one graph and it changes the attribute in the other. + NetworkX does not provide this level of shallow copy. + + Independent Shallow -- This copy creates new independent attribute + dicts and then does a shallow copy of the attributes. That is, any + attributes that are containers are shared between the new graph + and the original. This is exactly what `dict.copy()` provides. + You can obtain this style copy using: + + >>> G = nx.path_graph(5) + >>> H = G.copy() + >>> H = G.copy(as_view=False) + >>> H = nx.Graph(G) + >>> H = G.__class__(G) + + Fresh Data -- For fresh data, the graph structure is copied while + new empty data attribute dicts are created. The resulting graph + is independent of the original and it has no edge, node or graph + attributes. Fresh copies are not enabled. Instead use: + + >>> H = G.__class__() + >>> H.add_nodes_from(G) + >>> H.add_edges_from(G.edges) + + View -- Inspired by dict-views, graph-views act like read-only + versions of the original graph, providing a copy of the original + structure without requiring any memory for copying the information. + + See the Python copy module for more information on shallow + and deep copies, https://docs.python.org/3/library/copy.html. + + Parameters + ---------- + as_view : bool, optional (default=False) + If True, the returned graph-view provides a read-only view + of the original graph without actually copying any data. + + Returns + ------- + G : Graph + A copy of the graph. + + See Also + -------- + to_directed: return a directed copy of the graph. + + Examples + -------- + >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc + >>> H = G.copy() + + """ + if as_view is True: + return nx.graphviews.generic_graph_view(self) + G = self.__class__() + G.graph.update(self.graph) + G.add_nodes_from((n, d.copy()) for n, d in self._node.items()) + G.add_edges_from( + (u, v, key, datadict.copy()) + for u, nbrs in self._adj.items() + for v, keydict in nbrs.items() + for key, datadict in keydict.items() + ) + return G + + def to_directed(self, as_view=False): + """Returns a directed representation of the graph. + + Returns + ------- + G : MultiDiGraph + A directed graph with the same name, same nodes, and with + each edge (u, v, k, data) replaced by two directed edges + (u, v, k, data) and (v, u, k, data). + + Notes + ----- + This returns a "deepcopy" of the edge, node, and + graph attributes which attempts to completely copy + all of the data and references. + + This is in contrast to the similar D=MultiDiGraph(G) which + returns a shallow copy of the data. + + See the Python copy module for more information on shallow + and deep copies, https://docs.python.org/3/library/copy.html. + + Warning: If you have subclassed MultiGraph to use dict-like objects + in the data structure, those changes do not transfer to the + MultiDiGraph created by this method. + + Examples + -------- + >>> G = nx.MultiGraph() + >>> G.add_edge(0, 1) + 0 + >>> G.add_edge(0, 1) + 1 + >>> H = G.to_directed() + >>> list(H.edges) + [(0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1)] + + If already directed, return a (deep) copy + + >>> G = nx.MultiDiGraph() + >>> G.add_edge(0, 1) + 0 + >>> H = G.to_directed() + >>> list(H.edges) + [(0, 1, 0)] + """ + graph_class = self.to_directed_class() + if as_view is True: + return nx.graphviews.generic_graph_view(self, graph_class) + # deepcopy when not a view + G = graph_class() + G.graph.update(deepcopy(self.graph)) + G.add_nodes_from((n, deepcopy(d)) for n, d in self._node.items()) + G.add_edges_from( + (u, v, key, deepcopy(datadict)) + for u, nbrs in self.adj.items() + for v, keydict in nbrs.items() + for key, datadict in keydict.items() + ) + return G + + def to_undirected(self, as_view=False): + """Returns an undirected copy of the graph. + + Returns + ------- + G : Graph/MultiGraph + A deepcopy of the graph. + + See Also + -------- + copy, add_edge, add_edges_from + + Notes + ----- + This returns a "deepcopy" of the edge, node, and + graph attributes which attempts to completely copy + all of the data and references. + + This is in contrast to the similar `G = nx.MultiGraph(D)` + which returns a shallow copy of the data. + + See the Python copy module for more information on shallow + and deep copies, https://docs.python.org/3/library/copy.html. + + Warning: If you have subclassed MultiGraph to use dict-like + objects in the data structure, those changes do not transfer + to the MultiGraph created by this method. + + Examples + -------- + >>> G = nx.MultiGraph([(0, 1), (0, 1), (1, 2)]) + >>> H = G.to_directed() + >>> list(H.edges) + [(0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 2, 0), (2, 1, 0)] + >>> G2 = H.to_undirected() + >>> list(G2.edges) + [(0, 1, 0), (0, 1, 1), (1, 2, 0)] + """ + graph_class = self.to_undirected_class() + if as_view is True: + return nx.graphviews.generic_graph_view(self, graph_class) + # deepcopy when not a view + G = graph_class() + G.graph.update(deepcopy(self.graph)) + G.add_nodes_from((n, deepcopy(d)) for n, d in self._node.items()) + G.add_edges_from( + (u, v, key, deepcopy(datadict)) + for u, nbrs in self._adj.items() + for v, keydict in nbrs.items() + for key, datadict in keydict.items() + ) + return G + + def number_of_edges(self, u=None, v=None): + """Returns the number of edges between two nodes. + + Parameters + ---------- + u, v : nodes, optional (Default=all edges) + If u and v are specified, return the number of edges between + u and v. Otherwise return the total number of all edges. + + Returns + ------- + nedges : int + The number of edges in the graph. If nodes `u` and `v` are + specified return the number of edges between those nodes. If + the graph is directed, this only returns the number of edges + from `u` to `v`. + + See Also + -------- + size + + Examples + -------- + For undirected multigraphs, this method counts the total number + of edges in the graph:: + + >>> G = nx.MultiGraph() + >>> G.add_edges_from([(0, 1), (0, 1), (1, 2)]) + [0, 1, 0] + >>> G.number_of_edges() + 3 + + If you specify two nodes, this counts the total number of edges + joining the two nodes:: + + >>> G.number_of_edges(0, 1) + 2 + + For directed multigraphs, this method can count the total number + of directed edges from `u` to `v`:: + + >>> G = nx.MultiDiGraph() + >>> G.add_edges_from([(0, 1), (0, 1), (1, 0)]) + [0, 1, 0] + >>> G.number_of_edges(0, 1) + 2 + >>> G.number_of_edges(1, 0) + 1 + + """ + if u is None: + return self.size() + try: + edgedata = self._adj[u][v] + except KeyError: + return 0 # no such edge + return len(edgedata) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/reportviews.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/reportviews.py new file mode 100644 index 0000000000000000000000000000000000000000..789662de19600ec2a7922db612c525dfb75695ea --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/reportviews.py @@ -0,0 +1,1447 @@ +""" +View Classes provide node, edge and degree "views" of a graph. + +Views for nodes, edges and degree are provided for all base graph classes. +A view means a read-only object that is quick to create, automatically +updated when the graph changes, and provides basic access like `n in V`, +`for n in V`, `V[n]` and sometimes set operations. + +The views are read-only iterable containers that are updated as the +graph is updated. As with dicts, the graph should not be updated +while iterating through the view. Views can be iterated multiple times. + +Edge and Node views also allow data attribute lookup. +The resulting attribute dict is writable as `G.edges[3, 4]['color']='red'` +Degree views allow lookup of degree values for single nodes. +Weighted degree is supported with the `weight` argument. + +NodeView +======== + + `V = G.nodes` (or `V = G.nodes()`) allows `len(V)`, `n in V`, set + operations e.g. "G.nodes & H.nodes", and `dd = G.nodes[n]`, where + `dd` is the node data dict. Iteration is over the nodes by default. + +NodeDataView +============ + + To iterate over (node, data) pairs, use arguments to `G.nodes()` + to create a DataView e.g. `DV = G.nodes(data='color', default='red')`. + The DataView iterates as `for n, color in DV` and allows + `(n, 'red') in DV`. Using `DV = G.nodes(data=True)`, the DataViews + use the full datadict in writeable form also allowing contain testing as + `(n, {'color': 'red'}) in VD`. DataViews allow set operations when + data attributes are hashable. + +DegreeView +========== + + `V = G.degree` allows iteration over (node, degree) pairs as well + as lookup: `deg=V[n]`. There are many flavors of DegreeView + for In/Out/Directed/Multi. For Directed Graphs, `G.degree` + counts both in and out going edges. `G.out_degree` and + `G.in_degree` count only specific directions. + Weighted degree using edge data attributes is provide via + `V = G.degree(weight='attr_name')` where any string with the + attribute name can be used. `weight=None` is the default. + No set operations are implemented for degrees, use NodeView. + + The argument `nbunch` restricts iteration to nodes in nbunch. + The DegreeView can still lookup any node even if nbunch is specified. + +EdgeView +======== + + `V = G.edges` or `V = G.edges()` allows iteration over edges as well as + `e in V`, set operations and edge data lookup `dd = G.edges[2, 3]`. + Iteration is over 2-tuples `(u, v)` for Graph/DiGraph. For multigraphs + edges 3-tuples `(u, v, key)` are the default but 2-tuples can be obtained + via `V = G.edges(keys=False)`. + + Set operations for directed graphs treat the edges as a set of 2-tuples. + For undirected graphs, 2-tuples are not a unique representation of edges. + So long as the set being compared to contains unique representations + of its edges, the set operations will act as expected. If the other + set contains both `(0, 1)` and `(1, 0)` however, the result of set + operations may contain both representations of the same edge. + +EdgeDataView +============ + + Edge data can be reported using an EdgeDataView typically created + by calling an EdgeView: `DV = G.edges(data='weight', default=1)`. + The EdgeDataView allows iteration over edge tuples, membership checking + but no set operations. + + Iteration depends on `data` and `default` and for multigraph `keys` + If `data is False` (the default) then iterate over 2-tuples `(u, v)`. + If `data is True` iterate over 3-tuples `(u, v, datadict)`. + Otherwise iterate over `(u, v, datadict.get(data, default))`. + For Multigraphs, if `keys is True`, replace `u, v` with `u, v, key` + to create 3-tuples and 4-tuples. + + The argument `nbunch` restricts edges to those incident to nodes in nbunch. +""" + +from abc import ABC +from collections.abc import Mapping, Set + +import networkx as nx + +__all__ = [ + "NodeView", + "NodeDataView", + "EdgeView", + "OutEdgeView", + "InEdgeView", + "EdgeDataView", + "OutEdgeDataView", + "InEdgeDataView", + "MultiEdgeView", + "OutMultiEdgeView", + "InMultiEdgeView", + "MultiEdgeDataView", + "OutMultiEdgeDataView", + "InMultiEdgeDataView", + "DegreeView", + "DiDegreeView", + "InDegreeView", + "OutDegreeView", + "MultiDegreeView", + "DiMultiDegreeView", + "InMultiDegreeView", + "OutMultiDegreeView", +] + + +# NodeViews +class NodeView(Mapping, Set): + """A NodeView class to act as G.nodes for a NetworkX Graph + + Set operations act on the nodes without considering data. + Iteration is over nodes. Node data can be looked up like a dict. + Use NodeDataView to iterate over node data or to specify a data + attribute for lookup. NodeDataView is created by calling the NodeView. + + Parameters + ---------- + graph : NetworkX graph-like class + + Examples + -------- + >>> G = nx.path_graph(3) + >>> NV = G.nodes() + >>> 2 in NV + True + >>> for n in NV: + ... print(n) + 0 + 1 + 2 + >>> assert NV & {1, 2, 3} == {1, 2} + + >>> G.add_node(2, color="blue") + >>> NV[2] + {'color': 'blue'} + >>> G.add_node(8, color="red") + >>> NDV = G.nodes(data=True) + >>> (2, NV[2]) in NDV + True + >>> for n, dd in NDV: + ... print((n, dd.get("color", "aqua"))) + (0, 'aqua') + (1, 'aqua') + (2, 'blue') + (8, 'red') + >>> NDV[2] == NV[2] + True + + >>> NVdata = G.nodes(data="color", default="aqua") + >>> (2, NVdata[2]) in NVdata + True + >>> for n, dd in NVdata: + ... print((n, dd)) + (0, 'aqua') + (1, 'aqua') + (2, 'blue') + (8, 'red') + >>> NVdata[2] == NV[2] # NVdata gets 'color', NV gets datadict + False + """ + + __slots__ = ("_nodes",) + + def __getstate__(self): + return {"_nodes": self._nodes} + + def __setstate__(self, state): + self._nodes = state["_nodes"] + + def __init__(self, graph): + self._nodes = graph._node + + # Mapping methods + def __len__(self): + return len(self._nodes) + + def __iter__(self): + return iter(self._nodes) + + def __getitem__(self, n): + if isinstance(n, slice): + raise nx.NetworkXError( + f"{type(self).__name__} does not support slicing, " + f"try list(G.nodes)[{n.start}:{n.stop}:{n.step}]" + ) + return self._nodes[n] + + # Set methods + def __contains__(self, n): + return n in self._nodes + + @classmethod + def _from_iterable(cls, it): + return set(it) + + # DataView method + def __call__(self, data=False, default=None): + if data is False: + return self + return NodeDataView(self._nodes, data, default) + + def data(self, data=True, default=None): + """ + Return a read-only view of node data. + + Parameters + ---------- + data : bool or node data key, default=True + If ``data=True`` (the default), return a `NodeDataView` object that + maps each node to *all* of its attributes. `data` may also be an + arbitrary key, in which case the `NodeDataView` maps each node to + the value for the keyed attribute. In this case, if a node does + not have the `data` attribute, the `default` value is used. + default : object, default=None + The value used when a node does not have a specific attribute. + + Returns + ------- + NodeDataView + The layout of the returned NodeDataView depends on the value of the + `data` parameter. + + Notes + ----- + If ``data=False``, returns a `NodeView` object without data. + + See Also + -------- + NodeDataView + + Examples + -------- + >>> G = nx.Graph() + >>> G.add_nodes_from( + ... [ + ... (0, {"color": "red", "weight": 10}), + ... (1, {"color": "blue"}), + ... (2, {"color": "yellow", "weight": 2}), + ... ] + ... ) + + Accessing node data with ``data=True`` (the default) returns a + NodeDataView mapping each node to all of its attributes: + + >>> G.nodes.data() + NodeDataView({0: {'color': 'red', 'weight': 10}, 1: {'color': 'blue'}, 2: {'color': 'yellow', 'weight': 2}}) + + If `data` represents a key in the node attribute dict, a NodeDataView mapping + the nodes to the value for that specific key is returned: + + >>> G.nodes.data("color") + NodeDataView({0: 'red', 1: 'blue', 2: 'yellow'}, data='color') + + If a specific key is not found in an attribute dict, the value specified + by `default` is returned: + + >>> G.nodes.data("weight", default=-999) + NodeDataView({0: 10, 1: -999, 2: 2}, data='weight') + + Note that there is no check that the `data` key is in any of the + node attribute dictionaries: + + >>> G.nodes.data("height") + NodeDataView({0: None, 1: None, 2: None}, data='height') + """ + if data is False: + return self + return NodeDataView(self._nodes, data, default) + + def __str__(self): + return str(list(self)) + + def __repr__(self): + return f"{self.__class__.__name__}({tuple(self)})" + + +class NodeDataView(Set): + """A DataView class for nodes of a NetworkX Graph + + The main use for this class is to iterate through node-data pairs. + The data can be the entire data-dictionary for each node, or it + can be a specific attribute (with default) for each node. + Set operations are enabled with NodeDataView, but don't work in + cases where the data is not hashable. Use with caution. + Typically, set operations on nodes use NodeView, not NodeDataView. + That is, they use `G.nodes` instead of `G.nodes(data='foo')`. + + Parameters + ========== + graph : NetworkX graph-like class + data : bool or string (default=False) + default : object (default=None) + """ + + __slots__ = ("_nodes", "_data", "_default") + + def __getstate__(self): + return {"_nodes": self._nodes, "_data": self._data, "_default": self._default} + + def __setstate__(self, state): + self._nodes = state["_nodes"] + self._data = state["_data"] + self._default = state["_default"] + + def __init__(self, nodedict, data=False, default=None): + self._nodes = nodedict + self._data = data + self._default = default + + @classmethod + def _from_iterable(cls, it): + try: + return set(it) + except TypeError as err: + if "unhashable" in str(err): + msg = " : Could be b/c data=True or your values are unhashable" + raise TypeError(str(err) + msg) from err + raise + + def __len__(self): + return len(self._nodes) + + def __iter__(self): + data = self._data + if data is False: + return iter(self._nodes) + if data is True: + return iter(self._nodes.items()) + return ( + (n, dd[data] if data in dd else self._default) + for n, dd in self._nodes.items() + ) + + def __contains__(self, n): + try: + node_in = n in self._nodes + except TypeError: + n, d = n + return n in self._nodes and self[n] == d + if node_in is True: + return node_in + try: + n, d = n + except (TypeError, ValueError): + return False + return n in self._nodes and self[n] == d + + def __getitem__(self, n): + if isinstance(n, slice): + raise nx.NetworkXError( + f"{type(self).__name__} does not support slicing, " + f"try list(G.nodes.data())[{n.start}:{n.stop}:{n.step}]" + ) + ddict = self._nodes[n] + data = self._data + if data is False or data is True: + return ddict + return ddict[data] if data in ddict else self._default + + def __str__(self): + return str(list(self)) + + def __repr__(self): + name = self.__class__.__name__ + if self._data is False: + return f"{name}({tuple(self)})" + if self._data is True: + return f"{name}({dict(self)})" + return f"{name}({dict(self)}, data={self._data!r})" + + +# DegreeViews +class DiDegreeView: + """A View class for degree of nodes in a NetworkX Graph + + The functionality is like dict.items() with (node, degree) pairs. + Additional functionality includes read-only lookup of node degree, + and calling with optional features nbunch (for only a subset of nodes) + and weight (use edge weights to compute degree). + + Parameters + ========== + graph : NetworkX graph-like class + nbunch : node, container of nodes, or None meaning all nodes (default=None) + weight : bool or string (default=None) + + Notes + ----- + DegreeView can still lookup any node even if nbunch is specified. + + Examples + -------- + >>> G = nx.path_graph(3) + >>> DV = G.degree() + >>> assert DV[2] == 1 + >>> assert sum(deg for n, deg in DV) == 4 + + >>> DVweight = G.degree(weight="span") + >>> G.add_edge(1, 2, span=34) + >>> DVweight[2] + 34 + >>> DVweight[0] # default edge weight is 1 + 1 + >>> sum(span for n, span in DVweight) # sum weighted degrees + 70 + + >>> DVnbunch = G.degree(nbunch=(1, 2)) + >>> assert len(list(DVnbunch)) == 2 # iteration over nbunch only + """ + + def __init__(self, G, nbunch=None, weight=None): + self._graph = G + self._succ = G._succ if hasattr(G, "_succ") else G._adj + self._pred = G._pred if hasattr(G, "_pred") else G._adj + self._nodes = self._succ if nbunch is None else list(G.nbunch_iter(nbunch)) + self._weight = weight + + def __call__(self, nbunch=None, weight=None): + if nbunch is None: + if weight == self._weight: + return self + return self.__class__(self._graph, None, weight) + try: + if nbunch in self._nodes: + if weight == self._weight: + return self[nbunch] + return self.__class__(self._graph, None, weight)[nbunch] + except TypeError: + pass + return self.__class__(self._graph, nbunch, weight) + + def __getitem__(self, n): + weight = self._weight + succs = self._succ[n] + preds = self._pred[n] + if weight is None: + return len(succs) + len(preds) + return sum(dd.get(weight, 1) for dd in succs.values()) + sum( + dd.get(weight, 1) for dd in preds.values() + ) + + def __iter__(self): + weight = self._weight + if weight is None: + for n in self._nodes: + succs = self._succ[n] + preds = self._pred[n] + yield (n, len(succs) + len(preds)) + else: + for n in self._nodes: + succs = self._succ[n] + preds = self._pred[n] + deg = sum(dd.get(weight, 1) for dd in succs.values()) + sum( + dd.get(weight, 1) for dd in preds.values() + ) + yield (n, deg) + + def __len__(self): + return len(self._nodes) + + def __str__(self): + return str(list(self)) + + def __repr__(self): + return f"{self.__class__.__name__}({dict(self)})" + + +class DegreeView(DiDegreeView): + """A DegreeView class to act as G.degree for a NetworkX Graph + + Typical usage focuses on iteration over `(node, degree)` pairs. + The degree is by default the number of edges incident to the node. + Optional argument `weight` enables weighted degree using the edge + attribute named in the `weight` argument. Reporting and iteration + can also be restricted to a subset of nodes using `nbunch`. + + Additional functionality include node lookup so that `G.degree[n]` + reported the (possibly weighted) degree of node `n`. Calling the + view creates a view with different arguments `nbunch` or `weight`. + + Parameters + ========== + graph : NetworkX graph-like class + nbunch : node, container of nodes, or None meaning all nodes (default=None) + weight : string or None (default=None) + + Notes + ----- + DegreeView can still lookup any node even if nbunch is specified. + + Examples + -------- + >>> G = nx.path_graph(3) + >>> DV = G.degree() + >>> assert DV[2] == 1 + >>> assert G.degree[2] == 1 + >>> assert sum(deg for n, deg in DV) == 4 + + >>> DVweight = G.degree(weight="span") + >>> G.add_edge(1, 2, span=34) + >>> DVweight[2] + 34 + >>> DVweight[0] # default edge weight is 1 + 1 + >>> sum(span for n, span in DVweight) # sum weighted degrees + 70 + + >>> DVnbunch = G.degree(nbunch=(1, 2)) + >>> assert len(list(DVnbunch)) == 2 # iteration over nbunch only + """ + + def __getitem__(self, n): + weight = self._weight + nbrs = self._succ[n] + if weight is None: + return len(nbrs) + (n in nbrs) + return sum(dd.get(weight, 1) for dd in nbrs.values()) + ( + n in nbrs and nbrs[n].get(weight, 1) + ) + + def __iter__(self): + weight = self._weight + if weight is None: + for n in self._nodes: + nbrs = self._succ[n] + yield (n, len(nbrs) + (n in nbrs)) + else: + for n in self._nodes: + nbrs = self._succ[n] + deg = sum(dd.get(weight, 1) for dd in nbrs.values()) + ( + n in nbrs and nbrs[n].get(weight, 1) + ) + yield (n, deg) + + +class OutDegreeView(DiDegreeView): + """A DegreeView class to report out_degree for a DiGraph; See DegreeView""" + + def __getitem__(self, n): + weight = self._weight + nbrs = self._succ[n] + if self._weight is None: + return len(nbrs) + return sum(dd.get(self._weight, 1) for dd in nbrs.values()) + + def __iter__(self): + weight = self._weight + if weight is None: + for n in self._nodes: + succs = self._succ[n] + yield (n, len(succs)) + else: + for n in self._nodes: + succs = self._succ[n] + deg = sum(dd.get(weight, 1) for dd in succs.values()) + yield (n, deg) + + +class InDegreeView(DiDegreeView): + """A DegreeView class to report in_degree for a DiGraph; See DegreeView""" + + def __getitem__(self, n): + weight = self._weight + nbrs = self._pred[n] + if weight is None: + return len(nbrs) + return sum(dd.get(weight, 1) for dd in nbrs.values()) + + def __iter__(self): + weight = self._weight + if weight is None: + for n in self._nodes: + preds = self._pred[n] + yield (n, len(preds)) + else: + for n in self._nodes: + preds = self._pred[n] + deg = sum(dd.get(weight, 1) for dd in preds.values()) + yield (n, deg) + + +class MultiDegreeView(DiDegreeView): + """A DegreeView class for undirected multigraphs; See DegreeView""" + + def __getitem__(self, n): + weight = self._weight + nbrs = self._succ[n] + if weight is None: + return sum(len(keys) for keys in nbrs.values()) + ( + n in nbrs and len(nbrs[n]) + ) + # edge weighted graph - degree is sum of nbr edge weights + deg = sum( + d.get(weight, 1) for key_dict in nbrs.values() for d in key_dict.values() + ) + if n in nbrs: + deg += sum(d.get(weight, 1) for d in nbrs[n].values()) + return deg + + def __iter__(self): + weight = self._weight + if weight is None: + for n in self._nodes: + nbrs = self._succ[n] + deg = sum(len(keys) for keys in nbrs.values()) + ( + n in nbrs and len(nbrs[n]) + ) + yield (n, deg) + else: + for n in self._nodes: + nbrs = self._succ[n] + deg = sum( + d.get(weight, 1) + for key_dict in nbrs.values() + for d in key_dict.values() + ) + if n in nbrs: + deg += sum(d.get(weight, 1) for d in nbrs[n].values()) + yield (n, deg) + + +class DiMultiDegreeView(DiDegreeView): + """A DegreeView class for MultiDiGraph; See DegreeView""" + + def __getitem__(self, n): + weight = self._weight + succs = self._succ[n] + preds = self._pred[n] + if weight is None: + return sum(len(keys) for keys in succs.values()) + sum( + len(keys) for keys in preds.values() + ) + # edge weighted graph - degree is sum of nbr edge weights + deg = sum( + d.get(weight, 1) for key_dict in succs.values() for d in key_dict.values() + ) + sum( + d.get(weight, 1) for key_dict in preds.values() for d in key_dict.values() + ) + return deg + + def __iter__(self): + weight = self._weight + if weight is None: + for n in self._nodes: + succs = self._succ[n] + preds = self._pred[n] + deg = sum(len(keys) for keys in succs.values()) + sum( + len(keys) for keys in preds.values() + ) + yield (n, deg) + else: + for n in self._nodes: + succs = self._succ[n] + preds = self._pred[n] + deg = sum( + d.get(weight, 1) + for key_dict in succs.values() + for d in key_dict.values() + ) + sum( + d.get(weight, 1) + for key_dict in preds.values() + for d in key_dict.values() + ) + yield (n, deg) + + +class InMultiDegreeView(DiDegreeView): + """A DegreeView class for inward degree of MultiDiGraph; See DegreeView""" + + def __getitem__(self, n): + weight = self._weight + nbrs = self._pred[n] + if weight is None: + return sum(len(data) for data in nbrs.values()) + # edge weighted graph - degree is sum of nbr edge weights + return sum( + d.get(weight, 1) for key_dict in nbrs.values() for d in key_dict.values() + ) + + def __iter__(self): + weight = self._weight + if weight is None: + for n in self._nodes: + nbrs = self._pred[n] + deg = sum(len(data) for data in nbrs.values()) + yield (n, deg) + else: + for n in self._nodes: + nbrs = self._pred[n] + deg = sum( + d.get(weight, 1) + for key_dict in nbrs.values() + for d in key_dict.values() + ) + yield (n, deg) + + +class OutMultiDegreeView(DiDegreeView): + """A DegreeView class for outward degree of MultiDiGraph; See DegreeView""" + + def __getitem__(self, n): + weight = self._weight + nbrs = self._succ[n] + if weight is None: + return sum(len(data) for data in nbrs.values()) + # edge weighted graph - degree is sum of nbr edge weights + return sum( + d.get(weight, 1) for key_dict in nbrs.values() for d in key_dict.values() + ) + + def __iter__(self): + weight = self._weight + if weight is None: + for n in self._nodes: + nbrs = self._succ[n] + deg = sum(len(data) for data in nbrs.values()) + yield (n, deg) + else: + for n in self._nodes: + nbrs = self._succ[n] + deg = sum( + d.get(weight, 1) + for key_dict in nbrs.values() + for d in key_dict.values() + ) + yield (n, deg) + + +# A base class for all edge views. Ensures all edge view and edge data view +# objects/classes are captured by `isinstance(obj, EdgeViewABC)` and +# `issubclass(cls, EdgeViewABC)` respectively +class EdgeViewABC(ABC): + pass + + +# EdgeDataViews +class OutEdgeDataView(EdgeViewABC): + """EdgeDataView for outward edges of DiGraph; See EdgeDataView""" + + __slots__ = ( + "_viewer", + "_nbunch", + "_data", + "_default", + "_adjdict", + "_nodes_nbrs", + "_report", + ) + + def __getstate__(self): + return { + "viewer": self._viewer, + "nbunch": self._nbunch, + "data": self._data, + "default": self._default, + } + + def __setstate__(self, state): + self.__init__(**state) + + def __init__(self, viewer, nbunch=None, data=False, *, default=None): + self._viewer = viewer + adjdict = self._adjdict = viewer._adjdict + if nbunch is None: + self._nodes_nbrs = adjdict.items + else: + # dict retains order of nodes but acts like a set + nbunch = dict.fromkeys(viewer._graph.nbunch_iter(nbunch)) + self._nodes_nbrs = lambda: [(n, adjdict[n]) for n in nbunch] + self._nbunch = nbunch + self._data = data + self._default = default + # Set _report based on data and default + if data is True: + self._report = lambda n, nbr, dd: (n, nbr, dd) + elif data is False: + self._report = lambda n, nbr, dd: (n, nbr) + else: # data is attribute name + self._report = ( + lambda n, nbr, dd: (n, nbr, dd[data]) + if data in dd + else (n, nbr, default) + ) + + def __len__(self): + return sum(len(nbrs) for n, nbrs in self._nodes_nbrs()) + + def __iter__(self): + return ( + self._report(n, nbr, dd) + for n, nbrs in self._nodes_nbrs() + for nbr, dd in nbrs.items() + ) + + def __contains__(self, e): + u, v = e[:2] + if self._nbunch is not None and u not in self._nbunch: + return False # this edge doesn't start in nbunch + try: + ddict = self._adjdict[u][v] + except KeyError: + return False + return e == self._report(u, v, ddict) + + def __str__(self): + return str(list(self)) + + def __repr__(self): + return f"{self.__class__.__name__}({list(self)})" + + +class EdgeDataView(OutEdgeDataView): + """A EdgeDataView class for edges of Graph + + This view is primarily used to iterate over the edges reporting + edges as node-tuples with edge data optionally reported. The + argument `nbunch` allows restriction to edges incident to nodes + in that container/singleton. The default (nbunch=None) + reports all edges. The arguments `data` and `default` control + what edge data is reported. The default `data is False` reports + only node-tuples for each edge. If `data is True` the entire edge + data dict is returned. Otherwise `data` is assumed to hold the name + of the edge attribute to report with default `default` if that + edge attribute is not present. + + Parameters + ---------- + nbunch : container of nodes, node or None (default None) + data : False, True or string (default False) + default : default value (default None) + + Examples + -------- + >>> G = nx.path_graph(3) + >>> G.add_edge(1, 2, foo="bar") + >>> list(G.edges(data="foo", default="biz")) + [(0, 1, 'biz'), (1, 2, 'bar')] + >>> assert (0, 1, "biz") in G.edges(data="foo", default="biz") + """ + + __slots__ = () + + def __len__(self): + return sum(1 for e in self) + + def __iter__(self): + seen = {} + for n, nbrs in self._nodes_nbrs(): + for nbr, dd in nbrs.items(): + if nbr not in seen: + yield self._report(n, nbr, dd) + seen[n] = 1 + del seen + + def __contains__(self, e): + u, v = e[:2] + if self._nbunch is not None and u not in self._nbunch and v not in self._nbunch: + return False # this edge doesn't start and it doesn't end in nbunch + try: + ddict = self._adjdict[u][v] + except KeyError: + return False + return e == self._report(u, v, ddict) + + +class InEdgeDataView(OutEdgeDataView): + """An EdgeDataView class for outward edges of DiGraph; See EdgeDataView""" + + __slots__ = () + + def __iter__(self): + return ( + self._report(nbr, n, dd) + for n, nbrs in self._nodes_nbrs() + for nbr, dd in nbrs.items() + ) + + def __contains__(self, e): + u, v = e[:2] + if self._nbunch is not None and v not in self._nbunch: + return False # this edge doesn't end in nbunch + try: + ddict = self._adjdict[v][u] + except KeyError: + return False + return e == self._report(u, v, ddict) + + +class OutMultiEdgeDataView(OutEdgeDataView): + """An EdgeDataView for outward edges of MultiDiGraph; See EdgeDataView""" + + __slots__ = ("keys",) + + def __getstate__(self): + return { + "viewer": self._viewer, + "nbunch": self._nbunch, + "keys": self.keys, + "data": self._data, + "default": self._default, + } + + def __setstate__(self, state): + self.__init__(**state) + + def __init__(self, viewer, nbunch=None, data=False, *, default=None, keys=False): + self._viewer = viewer + adjdict = self._adjdict = viewer._adjdict + self.keys = keys + if nbunch is None: + self._nodes_nbrs = adjdict.items + else: + # dict retains order of nodes but acts like a set + nbunch = dict.fromkeys(viewer._graph.nbunch_iter(nbunch)) + self._nodes_nbrs = lambda: [(n, adjdict[n]) for n in nbunch] + self._nbunch = nbunch + self._data = data + self._default = default + # Set _report based on data and default + if data is True: + if keys is True: + self._report = lambda n, nbr, k, dd: (n, nbr, k, dd) + else: + self._report = lambda n, nbr, k, dd: (n, nbr, dd) + elif data is False: + if keys is True: + self._report = lambda n, nbr, k, dd: (n, nbr, k) + else: + self._report = lambda n, nbr, k, dd: (n, nbr) + else: # data is attribute name + if keys is True: + self._report = ( + lambda n, nbr, k, dd: (n, nbr, k, dd[data]) + if data in dd + else (n, nbr, k, default) + ) + else: + self._report = ( + lambda n, nbr, k, dd: (n, nbr, dd[data]) + if data in dd + else (n, nbr, default) + ) + + def __len__(self): + return sum(1 for e in self) + + def __iter__(self): + return ( + self._report(n, nbr, k, dd) + for n, nbrs in self._nodes_nbrs() + for nbr, kd in nbrs.items() + for k, dd in kd.items() + ) + + def __contains__(self, e): + u, v = e[:2] + if self._nbunch is not None and u not in self._nbunch: + return False # this edge doesn't start in nbunch + try: + kdict = self._adjdict[u][v] + except KeyError: + return False + if self.keys is True: + k = e[2] + try: + dd = kdict[k] + except KeyError: + return False + return e == self._report(u, v, k, dd) + return any(e == self._report(u, v, k, dd) for k, dd in kdict.items()) + + +class MultiEdgeDataView(OutMultiEdgeDataView): + """An EdgeDataView class for edges of MultiGraph; See EdgeDataView""" + + __slots__ = () + + def __iter__(self): + seen = {} + for n, nbrs in self._nodes_nbrs(): + for nbr, kd in nbrs.items(): + if nbr not in seen: + for k, dd in kd.items(): + yield self._report(n, nbr, k, dd) + seen[n] = 1 + del seen + + def __contains__(self, e): + u, v = e[:2] + if self._nbunch is not None and u not in self._nbunch and v not in self._nbunch: + return False # this edge doesn't start and doesn't end in nbunch + try: + kdict = self._adjdict[u][v] + except KeyError: + try: + kdict = self._adjdict[v][u] + except KeyError: + return False + if self.keys is True: + k = e[2] + try: + dd = kdict[k] + except KeyError: + return False + return e == self._report(u, v, k, dd) + return any(e == self._report(u, v, k, dd) for k, dd in kdict.items()) + + +class InMultiEdgeDataView(OutMultiEdgeDataView): + """An EdgeDataView for inward edges of MultiDiGraph; See EdgeDataView""" + + __slots__ = () + + def __iter__(self): + return ( + self._report(nbr, n, k, dd) + for n, nbrs in self._nodes_nbrs() + for nbr, kd in nbrs.items() + for k, dd in kd.items() + ) + + def __contains__(self, e): + u, v = e[:2] + if self._nbunch is not None and v not in self._nbunch: + return False # this edge doesn't end in nbunch + try: + kdict = self._adjdict[v][u] + except KeyError: + return False + if self.keys is True: + k = e[2] + dd = kdict[k] + return e == self._report(u, v, k, dd) + return any(e == self._report(u, v, k, dd) for k, dd in kdict.items()) + + +# EdgeViews have set operations and no data reported +class OutEdgeView(Set, Mapping, EdgeViewABC): + """A EdgeView class for outward edges of a DiGraph""" + + __slots__ = ("_adjdict", "_graph", "_nodes_nbrs") + + def __getstate__(self): + return {"_graph": self._graph, "_adjdict": self._adjdict} + + def __setstate__(self, state): + self._graph = state["_graph"] + self._adjdict = state["_adjdict"] + self._nodes_nbrs = self._adjdict.items + + @classmethod + def _from_iterable(cls, it): + return set(it) + + dataview = OutEdgeDataView + + def __init__(self, G): + self._graph = G + self._adjdict = G._succ if hasattr(G, "succ") else G._adj + self._nodes_nbrs = self._adjdict.items + + # Set methods + def __len__(self): + return sum(len(nbrs) for n, nbrs in self._nodes_nbrs()) + + def __iter__(self): + for n, nbrs in self._nodes_nbrs(): + for nbr in nbrs: + yield (n, nbr) + + def __contains__(self, e): + try: + u, v = e + return v in self._adjdict[u] + except KeyError: + return False + + # Mapping Methods + def __getitem__(self, e): + if isinstance(e, slice): + raise nx.NetworkXError( + f"{type(self).__name__} does not support slicing, " + f"try list(G.edges)[{e.start}:{e.stop}:{e.step}]" + ) + u, v = e + try: + return self._adjdict[u][v] + except KeyError as ex: # Customize msg to indicate exception origin + raise KeyError(f"The edge {e} is not in the graph.") + + # EdgeDataView methods + def __call__(self, nbunch=None, data=False, *, default=None): + if nbunch is None and data is False: + return self + return self.dataview(self, nbunch, data, default=default) + + def data(self, data=True, default=None, nbunch=None): + """ + Return a read-only view of edge data. + + Parameters + ---------- + data : bool or edge attribute key + If ``data=True``, then the data view maps each edge to a dictionary + containing all of its attributes. If `data` is a key in the edge + dictionary, then the data view maps each edge to its value for + the keyed attribute. In this case, if the edge doesn't have the + attribute, the `default` value is returned. + default : object, default=None + The value used when an edge does not have a specific attribute + nbunch : container of nodes, optional (default=None) + Allows restriction to edges only involving certain nodes. All edges + are considered by default. + + Returns + ------- + dataview + Returns an `EdgeDataView` for undirected Graphs, `OutEdgeDataView` + for DiGraphs, `MultiEdgeDataView` for MultiGraphs and + `OutMultiEdgeDataView` for MultiDiGraphs. + + Notes + ----- + If ``data=False``, returns an `EdgeView` without any edge data. + + See Also + -------- + EdgeDataView + OutEdgeDataView + MultiEdgeDataView + OutMultiEdgeDataView + + Examples + -------- + >>> G = nx.Graph() + >>> G.add_edges_from( + ... [ + ... (0, 1, {"dist": 3, "capacity": 20}), + ... (1, 2, {"dist": 4}), + ... (2, 0, {"dist": 5}), + ... ] + ... ) + + Accessing edge data with ``data=True`` (the default) returns an + edge data view object listing each edge with all of its attributes: + + >>> G.edges.data() + EdgeDataView([(0, 1, {'dist': 3, 'capacity': 20}), (0, 2, {'dist': 5}), (1, 2, {'dist': 4})]) + + If `data` represents a key in the edge attribute dict, a dataview listing + each edge with its value for that specific key is returned: + + >>> G.edges.data("dist") + EdgeDataView([(0, 1, 3), (0, 2, 5), (1, 2, 4)]) + + `nbunch` can be used to limit the edges: + + >>> G.edges.data("dist", nbunch=[0]) + EdgeDataView([(0, 1, 3), (0, 2, 5)]) + + If a specific key is not found in an edge attribute dict, the value + specified by `default` is used: + + >>> G.edges.data("capacity") + EdgeDataView([(0, 1, 20), (0, 2, None), (1, 2, None)]) + + Note that there is no check that the `data` key is present in any of + the edge attribute dictionaries: + + >>> G.edges.data("speed") + EdgeDataView([(0, 1, None), (0, 2, None), (1, 2, None)]) + """ + if nbunch is None and data is False: + return self + return self.dataview(self, nbunch, data, default=default) + + # String Methods + def __str__(self): + return str(list(self)) + + def __repr__(self): + return f"{self.__class__.__name__}({list(self)})" + + +class EdgeView(OutEdgeView): + """A EdgeView class for edges of a Graph + + This densely packed View allows iteration over edges, data lookup + like a dict and set operations on edges represented by node-tuples. + In addition, edge data can be controlled by calling this object + possibly creating an EdgeDataView. Typically edges are iterated over + and reported as `(u, v)` node tuples or `(u, v, key)` node/key tuples + for multigraphs. Those edge representations can also be using to + lookup the data dict for any edge. Set operations also are available + where those tuples are the elements of the set. + Calling this object with optional arguments `data`, `default` and `keys` + controls the form of the tuple (see EdgeDataView). Optional argument + `nbunch` allows restriction to edges only involving certain nodes. + + If `data is False` (the default) then iterate over 2-tuples `(u, v)`. + If `data is True` iterate over 3-tuples `(u, v, datadict)`. + Otherwise iterate over `(u, v, datadict.get(data, default))`. + For Multigraphs, if `keys is True`, replace `u, v` with `u, v, key` above. + + Parameters + ========== + graph : NetworkX graph-like class + nbunch : (default= all nodes in graph) only report edges with these nodes + keys : (only for MultiGraph. default=False) report edge key in tuple + data : bool or string (default=False) see above + default : object (default=None) + + Examples + ======== + >>> G = nx.path_graph(4) + >>> EV = G.edges() + >>> (2, 3) in EV + True + >>> for u, v in EV: + ... print((u, v)) + (0, 1) + (1, 2) + (2, 3) + >>> assert EV & {(1, 2), (3, 4)} == {(1, 2)} + + >>> EVdata = G.edges(data="color", default="aqua") + >>> G.add_edge(2, 3, color="blue") + >>> assert (2, 3, "blue") in EVdata + >>> for u, v, c in EVdata: + ... print(f"({u}, {v}) has color: {c}") + (0, 1) has color: aqua + (1, 2) has color: aqua + (2, 3) has color: blue + + >>> EVnbunch = G.edges(nbunch=2) + >>> assert (2, 3) in EVnbunch + >>> assert (0, 1) not in EVnbunch + >>> for u, v in EVnbunch: + ... assert u == 2 or v == 2 + + >>> MG = nx.path_graph(4, create_using=nx.MultiGraph) + >>> EVmulti = MG.edges(keys=True) + >>> (2, 3, 0) in EVmulti + True + >>> (2, 3) in EVmulti # 2-tuples work even when keys is True + True + >>> key = MG.add_edge(2, 3) + >>> for u, v, k in EVmulti: + ... print((u, v, k)) + (0, 1, 0) + (1, 2, 0) + (2, 3, 0) + (2, 3, 1) + """ + + __slots__ = () + + dataview = EdgeDataView + + def __len__(self): + num_nbrs = (len(nbrs) + (n in nbrs) for n, nbrs in self._nodes_nbrs()) + return sum(num_nbrs) // 2 + + def __iter__(self): + seen = {} + for n, nbrs in self._nodes_nbrs(): + for nbr in list(nbrs): + if nbr not in seen: + yield (n, nbr) + seen[n] = 1 + del seen + + def __contains__(self, e): + try: + u, v = e[:2] + return v in self._adjdict[u] or u in self._adjdict[v] + except (KeyError, ValueError): + return False + + +class InEdgeView(OutEdgeView): + """A EdgeView class for inward edges of a DiGraph""" + + __slots__ = () + + def __setstate__(self, state): + self._graph = state["_graph"] + self._adjdict = state["_adjdict"] + self._nodes_nbrs = self._adjdict.items + + dataview = InEdgeDataView + + def __init__(self, G): + self._graph = G + self._adjdict = G._pred if hasattr(G, "pred") else G._adj + self._nodes_nbrs = self._adjdict.items + + def __iter__(self): + for n, nbrs in self._nodes_nbrs(): + for nbr in nbrs: + yield (nbr, n) + + def __contains__(self, e): + try: + u, v = e + return u in self._adjdict[v] + except KeyError: + return False + + def __getitem__(self, e): + if isinstance(e, slice): + raise nx.NetworkXError( + f"{type(self).__name__} does not support slicing, " + f"try list(G.in_edges)[{e.start}:{e.stop}:{e.step}]" + ) + u, v = e + return self._adjdict[v][u] + + +class OutMultiEdgeView(OutEdgeView): + """A EdgeView class for outward edges of a MultiDiGraph""" + + __slots__ = () + + dataview = OutMultiEdgeDataView + + def __len__(self): + return sum( + len(kdict) for n, nbrs in self._nodes_nbrs() for nbr, kdict in nbrs.items() + ) + + def __iter__(self): + for n, nbrs in self._nodes_nbrs(): + for nbr, kdict in nbrs.items(): + for key in kdict: + yield (n, nbr, key) + + def __contains__(self, e): + N = len(e) + if N == 3: + u, v, k = e + elif N == 2: + u, v = e + k = 0 + else: + raise ValueError("MultiEdge must have length 2 or 3") + try: + return k in self._adjdict[u][v] + except KeyError: + return False + + def __getitem__(self, e): + if isinstance(e, slice): + raise nx.NetworkXError( + f"{type(self).__name__} does not support slicing, " + f"try list(G.edges)[{e.start}:{e.stop}:{e.step}]" + ) + u, v, k = e + return self._adjdict[u][v][k] + + def __call__(self, nbunch=None, data=False, *, default=None, keys=False): + if nbunch is None and data is False and keys is True: + return self + return self.dataview(self, nbunch, data, default=default, keys=keys) + + def data(self, data=True, default=None, nbunch=None, keys=False): + if nbunch is None and data is False and keys is True: + return self + return self.dataview(self, nbunch, data, default=default, keys=keys) + + +class MultiEdgeView(OutMultiEdgeView): + """A EdgeView class for edges of a MultiGraph""" + + __slots__ = () + + dataview = MultiEdgeDataView + + def __len__(self): + return sum(1 for e in self) + + def __iter__(self): + seen = {} + for n, nbrs in self._nodes_nbrs(): + for nbr, kd in nbrs.items(): + if nbr not in seen: + for k, dd in kd.items(): + yield (n, nbr, k) + seen[n] = 1 + del seen + + +class InMultiEdgeView(OutMultiEdgeView): + """A EdgeView class for inward edges of a MultiDiGraph""" + + __slots__ = () + + def __setstate__(self, state): + self._graph = state["_graph"] + self._adjdict = state["_adjdict"] + self._nodes_nbrs = self._adjdict.items + + dataview = InMultiEdgeDataView + + def __init__(self, G): + self._graph = G + self._adjdict = G._pred if hasattr(G, "pred") else G._adj + self._nodes_nbrs = self._adjdict.items + + def __iter__(self): + for n, nbrs in self._nodes_nbrs(): + for nbr, kdict in nbrs.items(): + for key in kdict: + yield (nbr, n, key) + + def __contains__(self, e): + N = len(e) + if N == 3: + u, v, k = e + elif N == 2: + u, v = e + k = 0 + else: + raise ValueError("MultiEdge must have length 2 or 3") + try: + return k in self._adjdict[v][u] + except KeyError: + return False + + def __getitem__(self, e): + if isinstance(e, slice): + raise nx.NetworkXError( + f"{type(self).__name__} does not support slicing, " + f"try list(G.in_edges)[{e.start}:{e.stop}:{e.step}]" + ) + u, v, k = e + return self._adjdict[v][u][k] diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb1023ea58af4d8126297afe9cd919d9e1a4f4e7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/dispatch_interface.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/dispatch_interface.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81e2f504585d1d0e3069311fea0512dc8230423b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/dispatch_interface.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/historical_tests.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/historical_tests.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f3c0510098d6d2ef4379d31b2774f67d69ea66e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/historical_tests.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_coreviews.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_coreviews.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..148d9ccc7665061f8a29f14380e026f57a53ea2d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_coreviews.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_digraph.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_digraph.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..42ff1c5434aba0240e831133f3d89012808c9c4e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_digraph.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_digraph_historical.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_digraph_historical.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd351c49d96c2e156967833cac462dc833d4d6e4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_digraph_historical.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_filters.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_filters.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34a4a1e8f124191d8deaff6d99d454c2f6b9aca6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_filters.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_graph.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_graph.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..75d3c251466c07232f94a5e9d2ba52020b7b7b24 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_graph.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_graph_historical.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_graph_historical.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9974a205344392d62606eb404441e73f4c2ee88 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_graph_historical.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_graphviews.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_graphviews.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1e381c369f20bb616665f63f29f885e78012a95 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_graphviews.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_multidigraph.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_multidigraph.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4ed3e6b89e74a438ea6de42641197c96af856d7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_multidigraph.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_multigraph.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_multigraph.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb9b51f915f7a1800c5827dc9f3771d1e50fed57 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_multigraph.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_reportviews.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_reportviews.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cef0399a01b1fea93c012cbfd96d65ab071a6f58 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_reportviews.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_special.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_special.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..64176569741997ce6dfe622c384c914b1884d995 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/classes/tests/__pycache__/test_special.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/gml.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/gml.py new file mode 100644 index 0000000000000000000000000000000000000000..c53496c3e7fd2797ce2f786e665d0ad069d8184c --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/gml.py @@ -0,0 +1,879 @@ +""" +Read graphs in GML format. + +"GML, the Graph Modelling Language, is our proposal for a portable +file format for graphs. GML's key features are portability, simple +syntax, extensibility and flexibility. A GML file consists of a +hierarchical key-value lists. Graphs can be annotated with arbitrary +data structures. The idea for a common file format was born at the +GD'95; this proposal is the outcome of many discussions. GML is the +standard file format in the Graphlet graph editor system. It has been +overtaken and adapted by several other systems for drawing graphs." + +GML files are stored using a 7-bit ASCII encoding with any extended +ASCII characters (iso8859-1) appearing as HTML character entities. +You will need to give some thought into how the exported data should +interact with different languages and even different Python versions. +Re-importing from gml is also a concern. + +Without specifying a `stringizer`/`destringizer`, the code is capable of +writing `int`/`float`/`str`/`dict`/`list` data as required by the GML +specification. For writing other data types, and for reading data other +than `str` you need to explicitly supply a `stringizer`/`destringizer`. + +For additional documentation on the GML file format, please see the +`GML website `_. + +Several example graphs in GML format may be found on Mark Newman's +`Network data page `_. +""" + +import html.entities as htmlentitydefs +import re +from ast import literal_eval +from collections import defaultdict +from enum import Enum +from io import StringIO +from typing import Any, NamedTuple + +import networkx as nx +from networkx.exception import NetworkXError +from networkx.utils import open_file + +__all__ = ["read_gml", "parse_gml", "generate_gml", "write_gml"] + + +def escape(text): + """Use XML character references to escape characters. + + Use XML character references for unprintable or non-ASCII + characters, double quotes and ampersands in a string + """ + + def fixup(m): + ch = m.group(0) + return "&#" + str(ord(ch)) + ";" + + text = re.sub('[^ -~]|[&"]', fixup, text) + return text if isinstance(text, str) else str(text) + + +def unescape(text): + """Replace XML character references with the referenced characters""" + + def fixup(m): + text = m.group(0) + if text[1] == "#": + # Character reference + if text[2] == "x": + code = int(text[3:-1], 16) + else: + code = int(text[2:-1]) + else: + # Named entity + try: + code = htmlentitydefs.name2codepoint[text[1:-1]] + except KeyError: + return text # leave unchanged + try: + return chr(code) + except (ValueError, OverflowError): + return text # leave unchanged + + return re.sub("&(?:[0-9A-Za-z]+|#(?:[0-9]+|x[0-9A-Fa-f]+));", fixup, text) + + +def literal_destringizer(rep): + """Convert a Python literal to the value it represents. + + Parameters + ---------- + rep : string + A Python literal. + + Returns + ------- + value : object + The value of the Python literal. + + Raises + ------ + ValueError + If `rep` is not a Python literal. + """ + if isinstance(rep, str): + orig_rep = rep + try: + return literal_eval(rep) + except SyntaxError as err: + raise ValueError(f"{orig_rep!r} is not a valid Python literal") from err + else: + raise ValueError(f"{rep!r} is not a string") + + +@open_file(0, mode="rb") +@nx._dispatchable(graphs=None, returns_graph=True) +def read_gml(path, label="label", destringizer=None): + """Read graph in GML format from `path`. + + Parameters + ---------- + path : file or string + Filename or file handle to read. + Filenames ending in .gz or .bz2 will be decompressed. + + label : string, optional + If not None, the parsed nodes will be renamed according to node + attributes indicated by `label`. Default value: 'label'. + + destringizer : callable, optional + A `destringizer` that recovers values stored as strings in GML. If it + cannot convert a string to a value, a `ValueError` is raised. Default + value : None. + + Returns + ------- + G : NetworkX graph + The parsed graph. + + Raises + ------ + NetworkXError + If the input cannot be parsed. + + See Also + -------- + write_gml, parse_gml + literal_destringizer + + Notes + ----- + GML files are stored using a 7-bit ASCII encoding with any extended + ASCII characters (iso8859-1) appearing as HTML character entities. + Without specifying a `stringizer`/`destringizer`, the code is capable of + writing `int`/`float`/`str`/`dict`/`list` data as required by the GML + specification. For writing other data types, and for reading data other + than `str` you need to explicitly supply a `stringizer`/`destringizer`. + + For additional documentation on the GML file format, please see the + `GML url `_. + + See the module docstring :mod:`networkx.readwrite.gml` for more details. + + Examples + -------- + >>> G = nx.path_graph(4) + >>> nx.write_gml(G, "test_path4.gml") + + GML values are interpreted as strings by default: + + >>> H = nx.read_gml("test_path4.gml") + >>> H.nodes + NodeView(('0', '1', '2', '3')) + + When a `destringizer` is provided, GML values are converted to the provided type. + For example, integer nodes can be recovered as shown below: + + >>> J = nx.read_gml("test_path4.gml", destringizer=int) + >>> J.nodes + NodeView((0, 1, 2, 3)) + + """ + + def filter_lines(lines): + for line in lines: + try: + line = line.decode("ascii") + except UnicodeDecodeError as err: + raise NetworkXError("input is not ASCII-encoded") from err + if not isinstance(line, str): + lines = str(lines) + if line and line[-1] == "\n": + line = line[:-1] + yield line + + G = parse_gml_lines(filter_lines(path), label, destringizer) + return G + + +@nx._dispatchable(graphs=None, returns_graph=True) +def parse_gml(lines, label="label", destringizer=None): + """Parse GML graph from a string or iterable. + + Parameters + ---------- + lines : string or iterable of strings + Data in GML format. + + label : string, optional + If not None, the parsed nodes will be renamed according to node + attributes indicated by `label`. Default value: 'label'. + + destringizer : callable, optional + A `destringizer` that recovers values stored as strings in GML. If it + cannot convert a string to a value, a `ValueError` is raised. Default + value : None. + + Returns + ------- + G : NetworkX graph + The parsed graph. + + Raises + ------ + NetworkXError + If the input cannot be parsed. + + See Also + -------- + write_gml, read_gml + + Notes + ----- + This stores nested GML attributes as dictionaries in the NetworkX graph, + node, and edge attribute structures. + + GML files are stored using a 7-bit ASCII encoding with any extended + ASCII characters (iso8859-1) appearing as HTML character entities. + Without specifying a `stringizer`/`destringizer`, the code is capable of + writing `int`/`float`/`str`/`dict`/`list` data as required by the GML + specification. For writing other data types, and for reading data other + than `str` you need to explicitly supply a `stringizer`/`destringizer`. + + For additional documentation on the GML file format, please see the + `GML url `_. + + See the module docstring :mod:`networkx.readwrite.gml` for more details. + """ + + def decode_line(line): + if isinstance(line, bytes): + try: + line.decode("ascii") + except UnicodeDecodeError as err: + raise NetworkXError("input is not ASCII-encoded") from err + if not isinstance(line, str): + line = str(line) + return line + + def filter_lines(lines): + if isinstance(lines, str): + lines = decode_line(lines) + lines = lines.splitlines() + yield from lines + else: + for line in lines: + line = decode_line(line) + if line and line[-1] == "\n": + line = line[:-1] + if line.find("\n") != -1: + raise NetworkXError("input line contains newline") + yield line + + G = parse_gml_lines(filter_lines(lines), label, destringizer) + return G + + +class Pattern(Enum): + """encodes the index of each token-matching pattern in `tokenize`.""" + + KEYS = 0 + REALS = 1 + INTS = 2 + STRINGS = 3 + DICT_START = 4 + DICT_END = 5 + COMMENT_WHITESPACE = 6 + + +class Token(NamedTuple): + category: Pattern + value: Any + line: int + position: int + + +LIST_START_VALUE = "_networkx_list_start" + + +def parse_gml_lines(lines, label, destringizer): + """Parse GML `lines` into a graph.""" + + def tokenize(): + patterns = [ + r"[A-Za-z][0-9A-Za-z_]*\b", # keys + # reals + r"[+-]?(?:[0-9]*\.[0-9]+|[0-9]+\.[0-9]*|INF)(?:[Ee][+-]?[0-9]+)?", + r"[+-]?[0-9]+", # ints + r'".*?"', # strings + r"\[", # dict start + r"\]", # dict end + r"#.*$|\s+", # comments and whitespaces + ] + tokens = re.compile("|".join(f"({pattern})" for pattern in patterns)) + lineno = 0 + multilines = [] # entries spread across multiple lines + for line in lines: + pos = 0 + + # deal with entries spread across multiple lines + # + # should we actually have to deal with escaped "s then do it here + if multilines: + multilines.append(line.strip()) + if line[-1] == '"': # closing multiline entry + # multiline entries will be joined by space. cannot + # reintroduce newlines as this will break the tokenizer + line = " ".join(multilines) + multilines = [] + else: # continued multiline entry + lineno += 1 + continue + else: + if line.count('"') == 1: # opening multiline entry + if line.strip()[0] != '"' and line.strip()[-1] != '"': + # since we expect something like key "value", the " should not be found at ends + # otherwise tokenizer will pick up the formatting mistake. + multilines = [line.rstrip()] + lineno += 1 + continue + + length = len(line) + + while pos < length: + match = tokens.match(line, pos) + if match is None: + m = f"cannot tokenize {line[pos:]} at ({lineno + 1}, {pos + 1})" + raise NetworkXError(m) + for i in range(len(patterns)): + group = match.group(i + 1) + if group is not None: + if i == 0: # keys + value = group.rstrip() + elif i == 1: # reals + value = float(group) + elif i == 2: # ints + value = int(group) + else: + value = group + if i != 6: # comments and whitespaces + yield Token(Pattern(i), value, lineno + 1, pos + 1) + pos += len(group) + break + lineno += 1 + yield Token(None, None, lineno + 1, 1) # EOF + + def unexpected(curr_token, expected): + category, value, lineno, pos = curr_token + value = repr(value) if value is not None else "EOF" + raise NetworkXError(f"expected {expected}, found {value} at ({lineno}, {pos})") + + def consume(curr_token, category, expected): + if curr_token.category == category: + return next(tokens) + unexpected(curr_token, expected) + + def parse_kv(curr_token): + dct = defaultdict(list) + while curr_token.category == Pattern.KEYS: + key = curr_token.value + curr_token = next(tokens) + category = curr_token.category + if category == Pattern.REALS or category == Pattern.INTS: + value = curr_token.value + curr_token = next(tokens) + elif category == Pattern.STRINGS: + value = unescape(curr_token.value[1:-1]) + if destringizer: + try: + value = destringizer(value) + except ValueError: + pass + # Special handling for empty lists and tuples + if value == "()": + value = () + if value == "[]": + value = [] + curr_token = next(tokens) + elif category == Pattern.DICT_START: + curr_token, value = parse_dict(curr_token) + else: + # Allow for string convertible id and label values + if key in ("id", "label", "source", "target"): + try: + # String convert the token value + value = unescape(str(curr_token.value)) + if destringizer: + try: + value = destringizer(value) + except ValueError: + pass + curr_token = next(tokens) + except Exception: + msg = ( + "an int, float, string, '[' or string" + + " convertible ASCII value for node id or label" + ) + unexpected(curr_token, msg) + # Special handling for nan and infinity. Since the gml language + # defines unquoted strings as keys, the numeric and string branches + # are skipped and we end up in this special branch, so we need to + # convert the current token value to a float for NAN and plain INF. + # +/-INF are handled in the pattern for 'reals' in tokenize(). This + # allows labels and values to be nan or infinity, but not keys. + elif curr_token.value in {"NAN", "INF"}: + value = float(curr_token.value) + curr_token = next(tokens) + else: # Otherwise error out + unexpected(curr_token, "an int, float, string or '['") + dct[key].append(value) + + def clean_dict_value(value): + if not isinstance(value, list): + return value + if len(value) == 1: + return value[0] + if value[0] == LIST_START_VALUE: + return value[1:] + return value + + dct = {key: clean_dict_value(value) for key, value in dct.items()} + return curr_token, dct + + def parse_dict(curr_token): + # dict start + curr_token = consume(curr_token, Pattern.DICT_START, "'['") + # dict contents + curr_token, dct = parse_kv(curr_token) + # dict end + curr_token = consume(curr_token, Pattern.DICT_END, "']'") + return curr_token, dct + + def parse_graph(): + curr_token, dct = parse_kv(next(tokens)) + if curr_token.category is not None: # EOF + unexpected(curr_token, "EOF") + if "graph" not in dct: + raise NetworkXError("input contains no graph") + graph = dct["graph"] + if isinstance(graph, list): + raise NetworkXError("input contains more than one graph") + return graph + + tokens = tokenize() + graph = parse_graph() + + directed = graph.pop("directed", False) + multigraph = graph.pop("multigraph", False) + if not multigraph: + G = nx.DiGraph() if directed else nx.Graph() + else: + G = nx.MultiDiGraph() if directed else nx.MultiGraph() + graph_attr = {k: v for k, v in graph.items() if k not in ("node", "edge")} + G.graph.update(graph_attr) + + def pop_attr(dct, category, attr, i): + try: + return dct.pop(attr) + except KeyError as err: + raise NetworkXError(f"{category} #{i} has no {attr!r} attribute") from err + + nodes = graph.get("node", []) + mapping = {} + node_labels = set() + for i, node in enumerate(nodes if isinstance(nodes, list) else [nodes]): + id = pop_attr(node, "node", "id", i) + if id in G: + raise NetworkXError(f"node id {id!r} is duplicated") + if label is not None and label != "id": + node_label = pop_attr(node, "node", label, i) + if node_label in node_labels: + raise NetworkXError(f"node label {node_label!r} is duplicated") + node_labels.add(node_label) + mapping[id] = node_label + G.add_node(id, **node) + + edges = graph.get("edge", []) + for i, edge in enumerate(edges if isinstance(edges, list) else [edges]): + source = pop_attr(edge, "edge", "source", i) + target = pop_attr(edge, "edge", "target", i) + if source not in G: + raise NetworkXError(f"edge #{i} has undefined source {source!r}") + if target not in G: + raise NetworkXError(f"edge #{i} has undefined target {target!r}") + if not multigraph: + if not G.has_edge(source, target): + G.add_edge(source, target, **edge) + else: + arrow = "->" if directed else "--" + msg = f"edge #{i} ({source!r}{arrow}{target!r}) is duplicated" + raise nx.NetworkXError(msg) + else: + key = edge.pop("key", None) + if key is not None and G.has_edge(source, target, key): + arrow = "->" if directed else "--" + msg = f"edge #{i} ({source!r}{arrow}{target!r}, {key!r})" + msg2 = 'Hint: If multigraph add "multigraph 1" to file header.' + raise nx.NetworkXError(msg + " is duplicated\n" + msg2) + G.add_edge(source, target, key, **edge) + + if label is not None and label != "id": + G = nx.relabel_nodes(G, mapping) + return G + + +def literal_stringizer(value): + """Convert a `value` to a Python literal in GML representation. + + Parameters + ---------- + value : object + The `value` to be converted to GML representation. + + Returns + ------- + rep : string + A double-quoted Python literal representing value. Unprintable + characters are replaced by XML character references. + + Raises + ------ + ValueError + If `value` cannot be converted to GML. + + Notes + ----- + The original value can be recovered using the + :func:`networkx.readwrite.gml.literal_destringizer` function. + """ + + def stringize(value): + if isinstance(value, int | bool) or value is None: + if value is True: # GML uses 1/0 for boolean values. + buf.write(str(1)) + elif value is False: + buf.write(str(0)) + else: + buf.write(str(value)) + elif isinstance(value, str): + text = repr(value) + if text[0] != "u": + try: + value.encode("latin1") + except UnicodeEncodeError: + text = "u" + text + buf.write(text) + elif isinstance(value, float | complex | str | bytes): + buf.write(repr(value)) + elif isinstance(value, list): + buf.write("[") + first = True + for item in value: + if not first: + buf.write(",") + else: + first = False + stringize(item) + buf.write("]") + elif isinstance(value, tuple): + if len(value) > 1: + buf.write("(") + first = True + for item in value: + if not first: + buf.write(",") + else: + first = False + stringize(item) + buf.write(")") + elif value: + buf.write("(") + stringize(value[0]) + buf.write(",)") + else: + buf.write("()") + elif isinstance(value, dict): + buf.write("{") + first = True + for key, value in value.items(): + if not first: + buf.write(",") + else: + first = False + stringize(key) + buf.write(":") + stringize(value) + buf.write("}") + elif isinstance(value, set): + buf.write("{") + first = True + for item in value: + if not first: + buf.write(",") + else: + first = False + stringize(item) + buf.write("}") + else: + msg = f"{value!r} cannot be converted into a Python literal" + raise ValueError(msg) + + buf = StringIO() + stringize(value) + return buf.getvalue() + + +def generate_gml(G, stringizer=None): + r"""Generate a single entry of the graph `G` in GML format. + + Parameters + ---------- + G : NetworkX graph + The graph to be converted to GML. + + stringizer : callable, optional + A `stringizer` which converts non-int/non-float/non-dict values into + strings. If it cannot convert a value into a string, it should raise a + `ValueError` to indicate that. Default value: None. + + Returns + ------- + lines: generator of strings + Lines of GML data. Newlines are not appended. + + Raises + ------ + NetworkXError + If `stringizer` cannot convert a value into a string, or the value to + convert is not a string while `stringizer` is None. + + See Also + -------- + literal_stringizer + + Notes + ----- + Graph attributes named 'directed', 'multigraph', 'node' or + 'edge', node attributes named 'id' or 'label', edge attributes + named 'source' or 'target' (or 'key' if `G` is a multigraph) + are ignored because these attribute names are used to encode the graph + structure. + + GML files are stored using a 7-bit ASCII encoding with any extended + ASCII characters (iso8859-1) appearing as HTML character entities. + Without specifying a `stringizer`/`destringizer`, the code is capable of + writing `int`/`float`/`str`/`dict`/`list` data as required by the GML + specification. For writing other data types, and for reading data other + than `str` you need to explicitly supply a `stringizer`/`destringizer`. + + For additional documentation on the GML file format, please see the + `GML url `_. + + See the module docstring :mod:`networkx.readwrite.gml` for more details. + + Examples + -------- + >>> G = nx.Graph() + >>> G.add_node("1") + >>> print("\n".join(nx.generate_gml(G))) + graph [ + node [ + id 0 + label "1" + ] + ] + >>> G = nx.MultiGraph([("a", "b"), ("a", "b")]) + >>> print("\n".join(nx.generate_gml(G))) + graph [ + multigraph 1 + node [ + id 0 + label "a" + ] + node [ + id 1 + label "b" + ] + edge [ + source 0 + target 1 + key 0 + ] + edge [ + source 0 + target 1 + key 1 + ] + ] + """ + valid_keys = re.compile("^[A-Za-z][0-9A-Za-z_]*$") + + def stringize(key, value, ignored_keys, indent, in_list=False): + if not isinstance(key, str): + raise NetworkXError(f"{key!r} is not a string") + if not valid_keys.match(key): + raise NetworkXError(f"{key!r} is not a valid key") + if not isinstance(key, str): + key = str(key) + if key not in ignored_keys: + if isinstance(value, int | bool): + if key == "label": + yield indent + key + ' "' + str(value) + '"' + elif value is True: + # python bool is an instance of int + yield indent + key + " 1" + elif value is False: + yield indent + key + " 0" + # GML only supports signed 32-bit integers + elif value < -(2**31) or value >= 2**31: + yield indent + key + ' "' + str(value) + '"' + else: + yield indent + key + " " + str(value) + elif isinstance(value, float): + text = repr(value).upper() + # GML matches INF to keys, so prepend + to INF. Use repr(float(*)) + # instead of string literal to future proof against changes to repr. + if text == repr(float("inf")).upper(): + text = "+" + text + else: + # GML requires that a real literal contain a decimal point, but + # repr may not output a decimal point when the mantissa is + # integral and hence needs fixing. + epos = text.rfind("E") + if epos != -1 and text.find(".", 0, epos) == -1: + text = text[:epos] + "." + text[epos:] + if key == "label": + yield indent + key + ' "' + text + '"' + else: + yield indent + key + " " + text + elif isinstance(value, dict): + yield indent + key + " [" + next_indent = indent + " " + for key, value in value.items(): + yield from stringize(key, value, (), next_indent) + yield indent + "]" + elif isinstance(value, tuple) and key == "label": + yield indent + key + f' "({",".join(repr(v) for v in value)})"' + elif isinstance(value, list | tuple) and key != "label" and not in_list: + if len(value) == 0: + yield indent + key + " " + f'"{value!r}"' + if len(value) == 1: + yield indent + key + " " + f'"{LIST_START_VALUE}"' + for val in value: + yield from stringize(key, val, (), indent, True) + else: + if stringizer: + try: + value = stringizer(value) + except ValueError as err: + raise NetworkXError( + f"{value!r} cannot be converted into a string" + ) from err + if not isinstance(value, str): + raise NetworkXError(f"{value!r} is not a string") + yield indent + key + ' "' + escape(value) + '"' + + multigraph = G.is_multigraph() + yield "graph [" + + # Output graph attributes + if G.is_directed(): + yield " directed 1" + if multigraph: + yield " multigraph 1" + ignored_keys = {"directed", "multigraph", "node", "edge"} + for attr, value in G.graph.items(): + yield from stringize(attr, value, ignored_keys, " ") + + # Output node data + node_id = dict(zip(G, range(len(G)))) + ignored_keys = {"id", "label"} + for node, attrs in G.nodes.items(): + yield " node [" + yield " id " + str(node_id[node]) + yield from stringize("label", node, (), " ") + for attr, value in attrs.items(): + yield from stringize(attr, value, ignored_keys, " ") + yield " ]" + + # Output edge data + ignored_keys = {"source", "target"} + kwargs = {"data": True} + if multigraph: + ignored_keys.add("key") + kwargs["keys"] = True + for e in G.edges(**kwargs): + yield " edge [" + yield " source " + str(node_id[e[0]]) + yield " target " + str(node_id[e[1]]) + if multigraph: + yield from stringize("key", e[2], (), " ") + for attr, value in e[-1].items(): + yield from stringize(attr, value, ignored_keys, " ") + yield " ]" + yield "]" + + +@open_file(1, mode="wb") +def write_gml(G, path, stringizer=None): + """Write a graph `G` in GML format to the file or file handle `path`. + + Parameters + ---------- + G : NetworkX graph + The graph to be converted to GML. + + path : string or file + Filename or file handle to write to. + Filenames ending in .gz or .bz2 will be compressed. + + stringizer : callable, optional + A `stringizer` which converts non-int/non-float/non-dict values into + strings. If it cannot convert a value into a string, it should raise a + `ValueError` to indicate that. Default value: None. + + Raises + ------ + NetworkXError + If `stringizer` cannot convert a value into a string, or the value to + convert is not a string while `stringizer` is None. + + See Also + -------- + read_gml, generate_gml + literal_stringizer + + Notes + ----- + Graph attributes named 'directed', 'multigraph', 'node' or + 'edge', node attributes named 'id' or 'label', edge attributes + named 'source' or 'target' (or 'key' if `G` is a multigraph) + are ignored because these attribute names are used to encode the graph + structure. + + GML files are stored using a 7-bit ASCII encoding with any extended + ASCII characters (iso8859-1) appearing as HTML character entities. + Without specifying a `stringizer`/`destringizer`, the code is capable of + writing `int`/`float`/`str`/`dict`/`list` data as required by the GML + specification. For writing other data types, and for reading data other + than `str` you need to explicitly supply a `stringizer`/`destringizer`. + + Note that while we allow non-standard GML to be read from a file, we make + sure to write GML format. In particular, underscores are not allowed in + attribute names. + For additional documentation on the GML file format, please see the + `GML url `_. + + See the module docstring :mod:`networkx.readwrite.gml` for more details. + + Examples + -------- + >>> G = nx.path_graph(5) + >>> nx.write_gml(G, "test_path5.gml") + + Filenames ending in .gz or .bz2 will be compressed. + + >>> nx.write_gml(G, "test_path5.gml.gz") + """ + for line in generate_gml(G, stringizer): + path.write((line + "\n").encode("ascii")) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/json_graph/node_link.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/json_graph/node_link.py new file mode 100644 index 0000000000000000000000000000000000000000..71b74f8549729ea5bc82803397f476baec4a53a9 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/json_graph/node_link.py @@ -0,0 +1,261 @@ +import warnings +from itertools import count + +import networkx as nx + +__all__ = ["node_link_data", "node_link_graph"] + + +def _to_tuple(x): + """Converts lists to tuples, including nested lists. + + All other non-list inputs are passed through unmodified. This function is + intended to be used to convert potentially nested lists from json files + into valid nodes. + + Examples + -------- + >>> _to_tuple([1, 2, [3, 4]]) + (1, 2, (3, 4)) + """ + if not isinstance(x, tuple | list): + return x + return tuple(map(_to_tuple, x)) + + +def node_link_data( + G, + *, + source="source", + target="target", + name="id", + key="key", + edges="edges", + nodes="nodes", +): + """Returns data in node-link format that is suitable for JSON serialization + and use in JavaScript documents. + + Parameters + ---------- + G : NetworkX graph + source : string + A string that provides the 'source' attribute name for storing NetworkX-internal graph data. + target : string + A string that provides the 'target' attribute name for storing NetworkX-internal graph data. + name : string + A string that provides the 'name' attribute name for storing NetworkX-internal graph data. + key : string + A string that provides the 'key' attribute name for storing NetworkX-internal graph data. + edges : string + A string that provides the 'edges' attribute name for storing NetworkX-internal graph data. + nodes : string + A string that provides the 'nodes' attribute name for storing NetworkX-internal graph data. + + Returns + ------- + data : dict + A dictionary with node-link formatted data. + + Raises + ------ + NetworkXError + If the values of 'source', 'target' and 'key' are not unique. + + Examples + -------- + >>> from pprint import pprint + >>> G = nx.Graph([("A", "B")]) + >>> data1 = nx.node_link_data(G) + >>> pprint(data1) + {'directed': False, + 'edges': [{'source': 'A', 'target': 'B'}], + 'graph': {}, + 'multigraph': False, + 'nodes': [{'id': 'A'}, {'id': 'B'}]} + + To serialize with JSON + + >>> import json + >>> s1 = json.dumps(data1) + >>> pprint(s1) + ('{"directed": false, "multigraph": false, "graph": {}, "nodes": [{"id": "A"}, ' + '{"id": "B"}], "edges": [{"source": "A", "target": "B"}]}') + + + A graph can also be serialized by passing `node_link_data` as an encoder function. + + >>> s1 = json.dumps(G, default=nx.node_link_data) + >>> pprint(s1) + ('{"directed": false, "multigraph": false, "graph": {}, "nodes": [{"id": "A"}, ' + '{"id": "B"}], "edges": [{"source": "A", "target": "B"}]}') + + The attribute names for storing NetworkX-internal graph data can + be specified as keyword options. + + >>> H = nx.gn_graph(2) + >>> data2 = nx.node_link_data( + ... H, edges="links", source="from", target="to", nodes="vertices" + ... ) + >>> pprint(data2) + {'directed': True, + 'graph': {}, + 'links': [{'from': 1, 'to': 0}], + 'multigraph': False, + 'vertices': [{'id': 0}, {'id': 1}]} + + Notes + ----- + Graph, node, and edge attributes are stored in this format. Note that + attribute keys will be converted to strings in order to comply with JSON. + + Attribute 'key' is only used for multigraphs. + + To use `node_link_data` in conjunction with `node_link_graph`, + the keyword names for the attributes must match. + + See Also + -------- + node_link_graph, adjacency_data, tree_data + """ + multigraph = G.is_multigraph() + + # Allow 'key' to be omitted from attrs if the graph is not a multigraph. + key = None if not multigraph else key + if len({source, target, key}) < 3: + raise nx.NetworkXError("Attribute names are not unique.") + data = { + "directed": G.is_directed(), + "multigraph": multigraph, + "graph": G.graph, + nodes: [{**G.nodes[n], name: n} for n in G], + } + if multigraph: + data[edges] = [ + {**d, source: u, target: v, key: k} + for u, v, k, d in G.edges(keys=True, data=True) + ] + else: + data[edges] = [{**d, source: u, target: v} for u, v, d in G.edges(data=True)] + return data + + +@nx._dispatchable(graphs=None, returns_graph=True) +def node_link_graph( + data, + directed=False, + multigraph=True, + *, + source="source", + target="target", + name="id", + key="key", + edges="edges", + nodes="nodes", +): + """Returns graph from node-link data format. + + Useful for de-serialization from JSON. + + Parameters + ---------- + data : dict + node-link formatted graph data + + directed : bool + If True, and direction not specified in data, return a directed graph. + + multigraph : bool + If True, and multigraph not specified in data, return a multigraph. + + source : string + A string that provides the 'source' attribute name for storing NetworkX-internal graph data. + target : string + A string that provides the 'target' attribute name for storing NetworkX-internal graph data. + name : string + A string that provides the 'name' attribute name for storing NetworkX-internal graph data. + key : string + A string that provides the 'key' attribute name for storing NetworkX-internal graph data. + edges : string + A string that provides the 'edges' attribute name for storing NetworkX-internal graph data. + nodes : string + A string that provides the 'nodes' attribute name for storing NetworkX-internal graph data. + + Returns + ------- + G : NetworkX graph + A NetworkX graph object + + Examples + -------- + + Create data in node-link format by converting a graph. + + >>> from pprint import pprint + >>> G = nx.Graph([("A", "B")]) + >>> data = nx.node_link_data(G) + >>> pprint(data) + {'directed': False, + 'edges': [{'source': 'A', 'target': 'B'}], + 'graph': {}, + 'multigraph': False, + 'nodes': [{'id': 'A'}, {'id': 'B'}]} + + Revert data in node-link format to a graph. + + >>> H = nx.node_link_graph(data) + >>> print(H.edges) + [('A', 'B')] + + To serialize and deserialize a graph with JSON, + + >>> import json + >>> d = json.dumps(nx.node_link_data(G)) + >>> H = nx.node_link_graph(json.loads(d)) + >>> print(G.edges, H.edges) + [('A', 'B')] [('A', 'B')] + + + Notes + ----- + Attribute 'key' is only used for multigraphs. + + To use `node_link_data` in conjunction with `node_link_graph`, + the keyword names for the attributes must match. + + See Also + -------- + node_link_data, adjacency_data, tree_data + """ + multigraph = data.get("multigraph", multigraph) + directed = data.get("directed", directed) + if multigraph: + graph = nx.MultiGraph() + else: + graph = nx.Graph() + if directed: + graph = graph.to_directed() + + # Allow 'key' to be omitted from attrs if the graph is not a multigraph. + key = None if not multigraph else key + graph.graph = data.get("graph", {}) + c = count() + for d in data[nodes]: + node = _to_tuple(d.get(name, next(c))) + nodedata = {str(k): v for k, v in d.items() if k != name} + graph.add_node(node, **nodedata) + for d in data[edges]: + src = tuple(d[source]) if isinstance(d[source], list) else d[source] + tgt = tuple(d[target]) if isinstance(d[target], list) else d[target] + if not multigraph: + edgedata = {str(k): v for k, v in d.items() if k != source and k != target} + graph.add_edge(src, tgt, **edgedata) + else: + ky = d.get(key, None) + edgedata = { + str(k): v + for k, v in d.items() + if k != source and k != target and k != key + } + graph.add_edge(src, tgt, ky, **edgedata) + return graph diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/pajek.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/pajek.py new file mode 100644 index 0000000000000000000000000000000000000000..2cab6b9ae68ba9c9869f0452394838925ff2a7db --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/pajek.py @@ -0,0 +1,286 @@ +""" +***** +Pajek +***** +Read graphs in Pajek format. + +This implementation handles directed and undirected graphs including +those with self loops and parallel edges. + +Format +------ +See http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/draweps.htm +for format information. + +""" + +import warnings + +import networkx as nx +from networkx.utils import open_file + +__all__ = ["read_pajek", "parse_pajek", "generate_pajek", "write_pajek"] + + +def generate_pajek(G): + """Generate lines in Pajek graph format. + + Parameters + ---------- + G : graph + A Networkx graph + + References + ---------- + See http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/draweps.htm + for format information. + """ + if G.name == "": + name = "NetworkX" + else: + name = G.name + # Apparently many Pajek format readers can't process this line + # So we'll leave it out for now. + # yield '*network %s'%name + + # write nodes with attributes + yield f"*vertices {G.order()}" + nodes = list(G) + # make dictionary mapping nodes to integers + nodenumber = dict(zip(nodes, range(1, len(nodes) + 1))) + for n in nodes: + # copy node attributes and pop mandatory attributes + # to avoid duplication. + na = G.nodes.get(n, {}).copy() + x = na.pop("x", 0.0) + y = na.pop("y", 0.0) + try: + id = int(na.pop("id", nodenumber[n])) + except ValueError as err: + err.args += ( + ( + "Pajek format requires 'id' to be an int()." + " Refer to the 'Relabeling nodes' section." + ), + ) + raise + nodenumber[n] = id + shape = na.pop("shape", "ellipse") + s = " ".join(map(make_qstr, (id, n, x, y, shape))) + # only optional attributes are left in na. + for k, v in na.items(): + if isinstance(v, str) and v.strip() != "": + s += f" {make_qstr(k)} {make_qstr(v)}" + else: + warnings.warn( + f"Node attribute {k} is not processed. {('Empty attribute' if isinstance(v, str) else 'Non-string attribute')}." + ) + yield s + + # write edges with attributes + if G.is_directed(): + yield "*arcs" + else: + yield "*edges" + for u, v, edgedata in G.edges(data=True): + d = edgedata.copy() + value = d.pop("weight", 1.0) # use 1 as default edge value + s = " ".join(map(make_qstr, (nodenumber[u], nodenumber[v], value))) + for k, v in d.items(): + if isinstance(v, str) and v.strip() != "": + s += f" {make_qstr(k)} {make_qstr(v)}" + else: + warnings.warn( + f"Edge attribute {k} is not processed. {('Empty attribute' if isinstance(v, str) else 'Non-string attribute')}." + ) + yield s + + +@open_file(1, mode="wb") +def write_pajek(G, path, encoding="UTF-8"): + """Write graph in Pajek format to path. + + Parameters + ---------- + G : graph + A Networkx graph + path : file or string + File or filename to write. + Filenames ending in .gz or .bz2 will be compressed. + + Examples + -------- + >>> G = nx.path_graph(4) + >>> nx.write_pajek(G, "test.netP4") + + Warnings + -------- + Optional node attributes and edge attributes must be non-empty strings. + Otherwise it will not be written into the file. You will need to + convert those attributes to strings if you want to keep them. + + References + ---------- + See http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/draweps.htm + for format information. + """ + for line in generate_pajek(G): + line += "\n" + path.write(line.encode(encoding)) + + +@open_file(0, mode="rb") +@nx._dispatchable(graphs=None, returns_graph=True) +def read_pajek(path, encoding="UTF-8"): + """Read graph in Pajek format from path. + + Parameters + ---------- + path : file or string + Filename or file handle to read. + Filenames ending in .gz or .bz2 will be decompressed. + + Returns + ------- + G : NetworkX MultiGraph or MultiDiGraph. + + Examples + -------- + >>> G = nx.path_graph(4) + >>> nx.write_pajek(G, "test.net") + >>> G = nx.read_pajek("test.net") + + To create a Graph instead of a MultiGraph use + + >>> G1 = nx.Graph(G) + + References + ---------- + See http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/draweps.htm + for format information. + """ + lines = (line.decode(encoding) for line in path) + return parse_pajek(lines) + + +@nx._dispatchable(graphs=None, returns_graph=True) +def parse_pajek(lines): + """Parse Pajek format graph from string or iterable. + + Parameters + ---------- + lines : string or iterable + Data in Pajek format. + + Returns + ------- + G : NetworkX graph + + See Also + -------- + read_pajek + + """ + import shlex + + # multigraph=False + if isinstance(lines, str): + lines = iter(lines.split("\n")) + lines = iter([line.rstrip("\n") for line in lines]) + G = nx.MultiDiGraph() # are multiedges allowed in Pajek? assume yes + labels = [] # in the order of the file, needed for matrix + while lines: + try: + l = next(lines) + except: # EOF + break + if l.lower().startswith("*network"): + try: + label, name = l.split(None, 1) + except ValueError: + # Line was not of the form: *network NAME + pass + else: + G.graph["name"] = name + elif l.lower().startswith("*vertices"): + nodelabels = {} + l, nnodes = l.split() + for i in range(int(nnodes)): + l = next(lines) + try: + splitline = [ + x.decode("utf-8") for x in shlex.split(str(l).encode("utf-8")) + ] + except AttributeError: + splitline = shlex.split(str(l)) + id, label = splitline[0:2] + labels.append(label) + G.add_node(label) + nodelabels[id] = label + G.nodes[label]["id"] = id + try: + x, y, shape = splitline[2:5] + G.nodes[label].update( + {"x": float(x), "y": float(y), "shape": shape} + ) + except: + pass + extra_attr = zip(splitline[5::2], splitline[6::2]) + G.nodes[label].update(extra_attr) + elif l.lower().startswith("*edges") or l.lower().startswith("*arcs"): + if l.lower().startswith("*edge"): + # switch from multidigraph to multigraph + G = nx.MultiGraph(G) + if l.lower().startswith("*arcs"): + # switch to directed with multiple arcs for each existing edge + G = G.to_directed() + for l in lines: + try: + splitline = [ + x.decode("utf-8") for x in shlex.split(str(l).encode("utf-8")) + ] + except AttributeError: + splitline = shlex.split(str(l)) + + if len(splitline) < 2: + continue + ui, vi = splitline[0:2] + u = nodelabels.get(ui, ui) + v = nodelabels.get(vi, vi) + # parse the data attached to this edge and put in a dictionary + edge_data = {} + try: + # there should always be a single value on the edge? + w = splitline[2:3] + edge_data.update({"weight": float(w[0])}) + except: + pass + # if there isn't, just assign a 1 + # edge_data.update({'value':1}) + extra_attr = zip(splitline[3::2], splitline[4::2]) + edge_data.update(extra_attr) + # if G.has_edge(u,v): + # multigraph=True + G.add_edge(u, v, **edge_data) + elif l.lower().startswith("*matrix"): + G = nx.DiGraph(G) + adj_list = ( + (labels[row], labels[col], {"weight": int(data)}) + for (row, line) in enumerate(lines) + for (col, data) in enumerate(line.split()) + if int(data) != 0 + ) + G.add_edges_from(adj_list) + + return G + + +def make_qstr(t): + """Returns the string representation of t. + Add outer double-quotes if the string has a space. + """ + if not isinstance(t, str): + t = str(t) + if " " in t: + t = f'"{t}"' + return t diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_adjlist.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_adjlist.py new file mode 100644 index 0000000000000000000000000000000000000000..015eaf8276a3b178b0bdb2c67b54ccfdc63256ae --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_adjlist.py @@ -0,0 +1,354 @@ +""" +Unit tests for adjlist. +""" + +import io + +import pytest + +import networkx as nx +from networkx.utils import edges_equal, graphs_equal, nodes_equal + + +class TestGenerateAdjlist: + @pytest.mark.parametrize("graph_type", [nx.Graph, nx.MultiGraph]) + def test_undirected(self, graph_type): + G = nx.complete_graph(5, create_using=graph_type) + lines = [ + "0 1 2 3 4", + "1 2 3 4", + "2 3 4", + "3 4", + "4", + ] + assert list(nx.generate_adjlist(G)) == lines + + @pytest.mark.parametrize("graph_type", [nx.DiGraph, nx.MultiDiGraph]) + def test_directed(self, graph_type): + G = nx.complete_graph(5, create_using=graph_type) + lines = [ + "0 1 2 3 4", + "1 0 2 3 4", + "2 0 1 3 4", + "3 0 1 2 4", + "4 0 1 2 3", + ] + assert list(nx.generate_adjlist(G)) == lines + + G = nx.path_graph(5, create_using=graph_type) + G.add_edge(1, 0) + lines = [ + "0 1", + "1 2 0", + "2 3", + "3 4", + "4", + ] + assert list(nx.generate_adjlist(G)) == lines + + @pytest.mark.parametrize("delimiter", [" ", ",", "\t"]) + def test_delimiter(self, delimiter): + G = nx.complete_graph(3) + lines = [ + f"0{delimiter}1{delimiter}2", + f"1{delimiter}2", + f"2", + ] + assert list(nx.generate_adjlist(G, delimiter=delimiter)) == lines + + def test_multiple_edges_undirected(self): + G = nx.complete_graph(3, create_using=nx.MultiGraph) + G.add_edge(0, 1) + lines = [ + "0 1 1 2", + "1 2", + "2", + ] + assert list(nx.generate_adjlist(G)) == lines + + def test_multiple_edges_directed(self): + G = nx.complete_graph(3, create_using=nx.MultiDiGraph) + G.add_edge(0, 1) + lines = [ + "0 1 1 2", + "1 0 2", + "2 0 1", + ] + assert list(nx.generate_adjlist(G)) == lines + + G.add_edge(1, 0) + lines[1] = "1 0 0 2" + assert list(nx.generate_adjlist(G)) == lines + + def test_multiple_edges_with_data(self): + G = nx.complete_graph(3, create_using=nx.MultiGraph) + G.add_edge(0, 1, weight=1) + G.add_edge(0, 1, weight=2) + lines = [ + "0 1 1 1 2", + "1 2", + "2", + ] + assert list(nx.generate_adjlist(G)) == lines + + def test_with_self_loop(self): + G = nx.complete_graph(3) + G.add_edge(0, 0) + lines = [ + "0 1 2 0", + "1 2", + "2", + ] + assert list(nx.generate_adjlist(G)) == lines + + +class TestAdjlist: + @classmethod + def setup_class(cls): + cls.G = nx.Graph(name="test") + e = [("a", "b"), ("b", "c"), ("c", "d"), ("d", "e"), ("e", "f"), ("a", "f")] + cls.G.add_edges_from(e) + cls.G.add_node("g") + cls.DG = nx.DiGraph(cls.G) + cls.XG = nx.MultiGraph() + cls.XG.add_weighted_edges_from([(1, 2, 5), (1, 2, 5), (1, 2, 1), (3, 3, 42)]) + cls.XDG = nx.MultiDiGraph(cls.XG) + + def test_read_multiline_adjlist_1(self): + # Unit test for https://networkx.lanl.gov/trac/ticket/252 + s = b"""# comment line +1 2 +# comment line +2 +3 +""" + bytesIO = io.BytesIO(s) + G = nx.read_multiline_adjlist(bytesIO) + adj = {"1": {"3": {}, "2": {}}, "3": {"1": {}}, "2": {"1": {}}} + assert graphs_equal(G, nx.Graph(adj)) + + def test_unicode(self, tmp_path): + G = nx.Graph() + name1 = chr(2344) + chr(123) + chr(6543) + name2 = chr(5543) + chr(1543) + chr(324) + G.add_edge(name1, "Radiohead", **{name2: 3}) + + fname = tmp_path / "adjlist.txt" + nx.write_multiline_adjlist(G, fname) + H = nx.read_multiline_adjlist(fname) + assert graphs_equal(G, H) + + def test_latin1_err(self, tmp_path): + G = nx.Graph() + name1 = chr(2344) + chr(123) + chr(6543) + name2 = chr(5543) + chr(1543) + chr(324) + G.add_edge(name1, "Radiohead", **{name2: 3}) + fname = tmp_path / "adjlist.txt" + with pytest.raises(UnicodeEncodeError): + nx.write_multiline_adjlist(G, fname, encoding="latin-1") + + def test_latin1(self, tmp_path): + G = nx.Graph() + name1 = "Bj" + chr(246) + "rk" + name2 = chr(220) + "ber" + G.add_edge(name1, "Radiohead", **{name2: 3}) + fname = tmp_path / "adjlist.txt" + nx.write_multiline_adjlist(G, fname, encoding="latin-1") + H = nx.read_multiline_adjlist(fname, encoding="latin-1") + assert graphs_equal(G, H) + + def test_parse_adjlist(self): + lines = ["1 2 5", "2 3 4", "3 5", "4", "5"] + nx.parse_adjlist(lines, nodetype=int) # smoke test + with pytest.raises(TypeError): + nx.parse_adjlist(lines, nodetype="int") + lines = ["1 2 5", "2 b", "c"] + with pytest.raises(TypeError): + nx.parse_adjlist(lines, nodetype=int) + + def test_adjlist_graph(self, tmp_path): + G = self.G + fname = tmp_path / "adjlist.txt" + nx.write_adjlist(G, fname) + H = nx.read_adjlist(fname) + H2 = nx.read_adjlist(fname) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges())) + + def test_adjlist_digraph(self, tmp_path): + G = self.DG + fname = tmp_path / "adjlist.txt" + nx.write_adjlist(G, fname) + H = nx.read_adjlist(fname, create_using=nx.DiGraph()) + H2 = nx.read_adjlist(fname, create_using=nx.DiGraph()) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges()), directed=True) + + def test_adjlist_integers(self, tmp_path): + fname = tmp_path / "adjlist.txt" + G = nx.convert_node_labels_to_integers(self.G) + nx.write_adjlist(G, fname) + H = nx.read_adjlist(fname, nodetype=int) + H2 = nx.read_adjlist(fname, nodetype=int) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges())) + + def test_adjlist_multigraph(self, tmp_path): + G = self.XG + fname = tmp_path / "adjlist.txt" + nx.write_adjlist(G, fname) + H = nx.read_adjlist(fname, nodetype=int, create_using=nx.MultiGraph()) + H2 = nx.read_adjlist(fname, nodetype=int, create_using=nx.MultiGraph()) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges())) + + def test_adjlist_multidigraph(self, tmp_path): + G = self.XDG + fname = tmp_path / "adjlist.txt" + nx.write_adjlist(G, fname) + H = nx.read_adjlist(fname, nodetype=int, create_using=nx.MultiDiGraph()) + H2 = nx.read_adjlist(fname, nodetype=int, create_using=nx.MultiDiGraph()) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges()), directed=True) + + def test_adjlist_delimiter(self): + fh = io.BytesIO() + G = nx.path_graph(3) + nx.write_adjlist(G, fh, delimiter=":") + fh.seek(0) + H = nx.read_adjlist(fh, nodetype=int, delimiter=":") + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges())) + + +class TestMultilineAdjlist: + @classmethod + def setup_class(cls): + cls.G = nx.Graph(name="test") + e = [("a", "b"), ("b", "c"), ("c", "d"), ("d", "e"), ("e", "f"), ("a", "f")] + cls.G.add_edges_from(e) + cls.G.add_node("g") + cls.DG = nx.DiGraph(cls.G) + cls.DG.remove_edge("b", "a") + cls.DG.remove_edge("b", "c") + cls.XG = nx.MultiGraph() + cls.XG.add_weighted_edges_from([(1, 2, 5), (1, 2, 5), (1, 2, 1), (3, 3, 42)]) + cls.XDG = nx.MultiDiGraph(cls.XG) + + def test_parse_multiline_adjlist(self): + lines = [ + "1 2", + "b {'weight':3, 'name': 'Frodo'}", + "c {}", + "d 1", + "e {'weight':6, 'name': 'Saruman'}", + ] + nx.parse_multiline_adjlist(iter(lines)) # smoke test + with pytest.raises(TypeError): + nx.parse_multiline_adjlist(iter(lines), nodetype=int) + nx.parse_multiline_adjlist(iter(lines), edgetype=str) # smoke test + with pytest.raises(TypeError): + nx.parse_multiline_adjlist(iter(lines), nodetype=int) + lines = ["1 a"] + with pytest.raises(TypeError): + nx.parse_multiline_adjlist(iter(lines)) + lines = ["a 2"] + with pytest.raises(TypeError): + nx.parse_multiline_adjlist(iter(lines), nodetype=int) + lines = ["1 2"] + with pytest.raises(TypeError): + nx.parse_multiline_adjlist(iter(lines)) + lines = ["1 2", "2 {}"] + with pytest.raises(TypeError): + nx.parse_multiline_adjlist(iter(lines)) + + def test_multiline_adjlist_graph(self, tmp_path): + G = self.G + fname = tmp_path / "adjlist.txt" + nx.write_multiline_adjlist(G, fname) + H = nx.read_multiline_adjlist(fname) + H2 = nx.read_multiline_adjlist(fname) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges())) + + def test_multiline_adjlist_digraph(self, tmp_path): + G = self.DG + fname = tmp_path / "adjlist.txt" + nx.write_multiline_adjlist(G, fname) + H = nx.read_multiline_adjlist(fname, create_using=nx.DiGraph()) + H2 = nx.read_multiline_adjlist(fname, create_using=nx.DiGraph()) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges()), directed=True) + + def test_multiline_adjlist_integers(self, tmp_path): + fname = tmp_path / "adjlist.txt" + G = nx.convert_node_labels_to_integers(self.G) + nx.write_multiline_adjlist(G, fname) + H = nx.read_multiline_adjlist(fname, nodetype=int) + H2 = nx.read_multiline_adjlist(fname, nodetype=int) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges())) + + def test_multiline_adjlist_multigraph(self, tmp_path): + G = self.XG + fname = tmp_path / "adjlist.txt" + nx.write_multiline_adjlist(G, fname) + H = nx.read_multiline_adjlist(fname, nodetype=int, create_using=nx.MultiGraph()) + H2 = nx.read_multiline_adjlist( + fname, nodetype=int, create_using=nx.MultiGraph() + ) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges())) + + def test_multiline_adjlist_multidigraph(self, tmp_path): + G = self.XDG + fname = tmp_path / "adjlist.txt" + nx.write_multiline_adjlist(G, fname) + H = nx.read_multiline_adjlist( + fname, nodetype=int, create_using=nx.MultiDiGraph() + ) + H2 = nx.read_multiline_adjlist( + fname, nodetype=int, create_using=nx.MultiDiGraph() + ) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges()), directed=True) + + def test_multiline_adjlist_delimiter(self): + fh = io.BytesIO() + G = nx.path_graph(3) + nx.write_multiline_adjlist(G, fh, delimiter=":") + fh.seek(0) + H = nx.read_multiline_adjlist(fh, nodetype=int, delimiter=":") + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges())) + + +@pytest.mark.parametrize( + ("lines", "delim"), + ( + (["1 2 5", "2 3 4", "3 5", "4", "5"], None), # No extra whitespace + (["1\t2\t5", "2\t3\t4", "3\t5", "4", "5"], "\t"), # tab-delimited + ( + ["1\t2\t5", "2\t3\t4", "3\t5\t", "4\t", "5"], + "\t", + ), # tab-delimited, extra delims + ( + ["1\t2\t5", "2\t3\t4", "3\t5\t\t\n", "4\t", "5"], + "\t", + ), # extra delim+newlines + ), +) +def test_adjlist_rstrip_parsing(lines, delim): + """Regression test related to gh-7465""" + expected = nx.Graph([(1, 2), (1, 5), (2, 3), (2, 4), (3, 5)]) + nx.utils.graphs_equal(nx.parse_adjlist(lines, delimiter=delim), expected) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_edgelist.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_edgelist.py new file mode 100644 index 0000000000000000000000000000000000000000..a185cf83736f0cfe901dd5c2f6cbea941e55c485 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_edgelist.py @@ -0,0 +1,318 @@ +""" +Unit tests for edgelists. +""" + +import io +import textwrap + +import pytest + +import networkx as nx +from networkx.utils import edges_equal, graphs_equal, nodes_equal + +edges_no_data = textwrap.dedent( + """ + # comment line + 1 2 + # comment line + 2 3 + """ +) + + +edges_with_values = textwrap.dedent( + """ + # comment line + 1 2 2.0 + # comment line + 2 3 3.0 + """ +) + + +edges_with_weight = textwrap.dedent( + """ + # comment line + 1 2 {'weight':2.0} + # comment line + 2 3 {'weight':3.0} + """ +) + + +edges_with_multiple_attrs = textwrap.dedent( + """ + # comment line + 1 2 {'weight':2.0, 'color':'green'} + # comment line + 2 3 {'weight':3.0, 'color':'red'} + """ +) + + +edges_with_multiple_attrs_csv = textwrap.dedent( + """ + # comment line + 1, 2, {'weight':2.0, 'color':'green'} + # comment line + 2, 3, {'weight':3.0, 'color':'red'} + """ +) + + +_expected_edges_weights = [(1, 2, {"weight": 2.0}), (2, 3, {"weight": 3.0})] +_expected_edges_multiattr = [ + (1, 2, {"weight": 2.0, "color": "green"}), + (2, 3, {"weight": 3.0, "color": "red"}), +] + + +@pytest.mark.parametrize( + ("data", "extra_kwargs"), + ( + (edges_no_data, {}), + (edges_with_values, {}), + (edges_with_weight, {}), + (edges_with_multiple_attrs, {}), + (edges_with_multiple_attrs_csv, {"delimiter": ","}), + ), +) +def test_read_edgelist_no_data(data, extra_kwargs): + bytesIO = io.BytesIO(data.encode("utf-8")) + G = nx.read_edgelist(bytesIO, nodetype=int, data=False, **extra_kwargs) + assert edges_equal(G.edges(), [(1, 2), (2, 3)]) + + +def test_read_weighted_edgelist(): + bytesIO = io.BytesIO(edges_with_values.encode("utf-8")) + G = nx.read_weighted_edgelist(bytesIO, nodetype=int) + assert edges_equal(G.edges(data=True), _expected_edges_weights) + + +@pytest.mark.parametrize( + ("data", "extra_kwargs", "expected"), + ( + (edges_with_weight, {}, _expected_edges_weights), + (edges_with_multiple_attrs, {}, _expected_edges_multiattr), + ( + edges_with_multiple_attrs_csv, + {"delimiter": ","}, + _expected_edges_multiattr, + ), + ), +) +def test_read_edgelist_with_data(data, extra_kwargs, expected): + bytesIO = io.BytesIO(data.encode("utf-8")) + G = nx.read_edgelist(bytesIO, nodetype=int, **extra_kwargs) + assert edges_equal(G.edges(data=True), expected) + + +@pytest.fixture +def example_graph(): + G = nx.Graph() + G.add_weighted_edges_from([(1, 2, 3.0), (2, 3, 27.0), (3, 4, 3.0)]) + return G + + +def test_parse_edgelist_no_data(example_graph): + G = example_graph + H = nx.parse_edgelist(["1 2", "2 3", "3 4"], nodetype=int) + assert nodes_equal(G.nodes, H.nodes) + assert edges_equal(G.edges, H.edges) + + +def test_parse_edgelist_with_data_dict(example_graph): + G = example_graph + H = nx.parse_edgelist( + ["1 2 {'weight': 3}", "2 3 {'weight': 27}", "3 4 {'weight': 3.0}"], nodetype=int + ) + assert nodes_equal(G.nodes, H.nodes) + assert edges_equal(G.edges(data=True), H.edges(data=True)) + + +def test_parse_edgelist_with_data_list(example_graph): + G = example_graph + H = nx.parse_edgelist( + ["1 2 3", "2 3 27", "3 4 3.0"], nodetype=int, data=(("weight", float),) + ) + assert nodes_equal(G.nodes, H.nodes) + assert edges_equal(G.edges(data=True), H.edges(data=True)) + + +def test_parse_edgelist(): + # ignore lines with less than 2 nodes + lines = ["1;2", "2 3", "3 4"] + G = nx.parse_edgelist(lines, nodetype=int) + assert list(G.edges()) == [(2, 3), (3, 4)] + # unknown nodetype + with pytest.raises(TypeError, match="Failed to convert nodes"): + lines = ["1 2", "2 3", "3 4"] + nx.parse_edgelist(lines, nodetype="nope") + # lines have invalid edge format + with pytest.raises(TypeError, match="Failed to convert edge data"): + lines = ["1 2 3", "2 3", "3 4"] + nx.parse_edgelist(lines, nodetype=int) + # edge data and data_keys not the same length + with pytest.raises(IndexError, match="not the same length"): + lines = ["1 2 3", "2 3 27", "3 4 3.0"] + nx.parse_edgelist( + lines, nodetype=int, data=(("weight", float), ("capacity", int)) + ) + # edge data can't be converted to edge type + with pytest.raises(TypeError, match="Failed to convert"): + lines = ["1 2 't1'", "2 3 't3'", "3 4 't3'"] + nx.parse_edgelist(lines, nodetype=int, data=(("weight", float),)) + + +def test_comments_None(): + edgelist = ["node#1 node#2", "node#2 node#3"] + # comments=None supported to ignore all comment characters + G = nx.parse_edgelist(edgelist, comments=None) + H = nx.Graph([e.split(" ") for e in edgelist]) + assert edges_equal(G.edges, H.edges) + + +class TestEdgelist: + @classmethod + def setup_class(cls): + cls.G = nx.Graph(name="test") + e = [("a", "b"), ("b", "c"), ("c", "d"), ("d", "e"), ("e", "f"), ("a", "f")] + cls.G.add_edges_from(e) + cls.G.add_node("g") + cls.DG = nx.DiGraph(cls.G) + cls.XG = nx.MultiGraph() + cls.XG.add_weighted_edges_from([(1, 2, 5), (1, 2, 5), (1, 2, 1), (3, 3, 42)]) + cls.XDG = nx.MultiDiGraph(cls.XG) + + def test_write_edgelist_1(self): + fh = io.BytesIO() + G = nx.Graph() + G.add_edges_from([(1, 2), (2, 3)]) + nx.write_edgelist(G, fh, data=False) + fh.seek(0) + assert fh.read() == b"1 2\n2 3\n" + + def test_write_edgelist_2(self): + fh = io.BytesIO() + G = nx.Graph() + G.add_edges_from([(1, 2), (2, 3)]) + nx.write_edgelist(G, fh, data=True) + fh.seek(0) + assert fh.read() == b"1 2 {}\n2 3 {}\n" + + def test_write_edgelist_3(self): + fh = io.BytesIO() + G = nx.Graph() + G.add_edge(1, 2, weight=2.0) + G.add_edge(2, 3, weight=3.0) + nx.write_edgelist(G, fh, data=True) + fh.seek(0) + assert fh.read() == b"1 2 {'weight': 2.0}\n2 3 {'weight': 3.0}\n" + + def test_write_edgelist_4(self): + fh = io.BytesIO() + G = nx.Graph() + G.add_edge(1, 2, weight=2.0) + G.add_edge(2, 3, weight=3.0) + nx.write_edgelist(G, fh, data=[("weight")]) + fh.seek(0) + assert fh.read() == b"1 2 2.0\n2 3 3.0\n" + + def test_unicode(self, tmp_path): + G = nx.Graph() + name1 = chr(2344) + chr(123) + chr(6543) + name2 = chr(5543) + chr(1543) + chr(324) + G.add_edge(name1, "Radiohead", **{name2: 3}) + fname = tmp_path / "el.txt" + nx.write_edgelist(G, fname) + H = nx.read_edgelist(fname) + assert graphs_equal(G, H) + + def test_latin1_issue(self, tmp_path): + G = nx.Graph() + name1 = chr(2344) + chr(123) + chr(6543) + name2 = chr(5543) + chr(1543) + chr(324) + G.add_edge(name1, "Radiohead", **{name2: 3}) + fname = tmp_path / "el.txt" + with pytest.raises(UnicodeEncodeError): + nx.write_edgelist(G, fname, encoding="latin-1") + + def test_latin1(self, tmp_path): + G = nx.Graph() + name1 = "Bj" + chr(246) + "rk" + name2 = chr(220) + "ber" + G.add_edge(name1, "Radiohead", **{name2: 3}) + fname = tmp_path / "el.txt" + + nx.write_edgelist(G, fname, encoding="latin-1") + H = nx.read_edgelist(fname, encoding="latin-1") + assert graphs_equal(G, H) + + def test_edgelist_graph(self, tmp_path): + G = self.G + fname = tmp_path / "el.txt" + nx.write_edgelist(G, fname) + H = nx.read_edgelist(fname) + H2 = nx.read_edgelist(fname) + assert H is not H2 # they should be different graphs + G.remove_node("g") # isolated nodes are not written in edgelist + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges())) + + def test_edgelist_digraph(self, tmp_path): + G = self.DG + fname = tmp_path / "el.txt" + nx.write_edgelist(G, fname) + H = nx.read_edgelist(fname, create_using=nx.DiGraph()) + H2 = nx.read_edgelist(fname, create_using=nx.DiGraph()) + assert H is not H2 # they should be different graphs + G.remove_node("g") # isolated nodes are not written in edgelist + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges()), directed=True) + + def test_edgelist_integers(self, tmp_path): + G = nx.convert_node_labels_to_integers(self.G) + fname = tmp_path / "el.txt" + nx.write_edgelist(G, fname) + H = nx.read_edgelist(fname, nodetype=int) + # isolated nodes are not written in edgelist + G.remove_nodes_from(list(nx.isolates(G))) + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges())) + + def test_edgelist_multigraph(self, tmp_path): + G = self.XG + fname = tmp_path / "el.txt" + nx.write_edgelist(G, fname) + H = nx.read_edgelist(fname, nodetype=int, create_using=nx.MultiGraph()) + H2 = nx.read_edgelist(fname, nodetype=int, create_using=nx.MultiGraph()) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges())) + + def test_edgelist_multidigraph(self, tmp_path): + G = self.XDG + fname = tmp_path / "el.txt" + nx.write_edgelist(G, fname) + H = nx.read_edgelist(fname, nodetype=int, create_using=nx.MultiDiGraph()) + H2 = nx.read_edgelist(fname, nodetype=int, create_using=nx.MultiDiGraph()) + assert H is not H2 # they should be different graphs + assert nodes_equal(list(H), list(G)) + assert edges_equal(list(H.edges()), list(G.edges()), directed=True) + + +def test_edgelist_consistent_strip_handling(): + """See gh-7462 + + Input when printed looks like:: + + 1 2 3 + 2 3 + 3 4 3.0 + + Note the trailing \\t after the `3` in the second row, indicating an empty + data value. + """ + s = io.StringIO("1\t2\t3\n2\t3\t\n3\t4\t3.0") + G = nx.parse_edgelist(s, delimiter="\t", nodetype=int, data=[("value", str)]) + assert sorted(G.edges(data="value")) == [(1, 2, "3"), (2, 3, ""), (3, 4, "3.0")] diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_gexf.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_gexf.py new file mode 100644 index 0000000000000000000000000000000000000000..4e487cc6f4afe6de138eabb04633b8427f4999da --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_gexf.py @@ -0,0 +1,612 @@ +import io +import time + +import pytest + +import networkx as nx + + +def test_gexf_v1_3(tmp_path): + """'Basic graph' example from https://gexf.net/schema.html""" + # GEXF file from published example + data = """ + + + + + + + + + + + +""" + with open(fname := (tmp_path / "basic.gexf"), "w") as fh: + fh.write(data) + + # Expected output based on xml input + expected = nx.DiGraph([("0", "1")]) + nx.set_node_attributes(expected, {"0": "Hello", "1": "Word"}, name="label") + expected.graph = {"mode": "static", "edge_default": {}} + + # Load example with version explicitly set + G = nx.read_gexf(fname, version="1.3") + assert nx.utils.graphs_equal(G, expected) + + # And with the "default" version + G = nx.read_gexf(fname) + assert nx.utils.graphs_equal(G, expected) + + +@pytest.mark.parametrize("time_attr", ("start", "end")) +@pytest.mark.parametrize("dyn_attr", ("static", "dynamic")) +def test_dynamic_graph_has_timeformat(time_attr, dyn_attr, tmp_path): + """Ensure that graphs which have a 'start' or 'stop' attribute get a + 'timeformat' attribute upon parsing. See gh-7914.""" + G = nx.MultiGraph(mode=dyn_attr) + G.add_node(0) + G.nodes[0][time_attr] = 1 + # Write out + fname = tmp_path / "foo.gexf" + nx.write_gexf(G, fname) + # Check that timeformat is added to saved data + with open(fname) as fh: + assert 'timeformat="long"' in fh.read() + # Round-trip + H = nx.read_gexf(fname) + # If any node has a "start" or "end" attr, it is considered dynamic + # regardless of the graph "mode" attr + assert H.graph["mode"] == "dynamic" + assert nx.utils.nodes_equal(G.edges, H.edges) + + +class TestGEXF: + @classmethod + def setup_class(cls): + cls.simple_directed_data = """ + + + + + + + + + + + +""" + cls.simple_directed_graph = nx.DiGraph() + cls.simple_directed_graph.add_node("0", label="Hello") + cls.simple_directed_graph.add_node("1", label="World") + cls.simple_directed_graph.add_edge("0", "1", id="0") + + cls.simple_directed_fh = io.BytesIO(cls.simple_directed_data.encode("UTF-8")) + + cls.attribute_data = """\ + + + Gephi.org + A Web network + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" + cls.attribute_graph = nx.DiGraph() + cls.attribute_graph.graph["node_default"] = {"frog": True} + cls.attribute_graph.add_node( + "0", label="Gephi", url="https://gephi.org", indegree=1, frog=False + ) + cls.attribute_graph.add_node( + "1", label="Webatlas", url="http://webatlas.fr", indegree=2, frog=False + ) + cls.attribute_graph.add_node( + "2", label="RTGI", url="http://rtgi.fr", indegree=1, frog=True + ) + cls.attribute_graph.add_node( + "3", + label="BarabasiLab", + url="http://barabasilab.com", + indegree=1, + frog=True, + ) + cls.attribute_graph.add_edge("0", "1", id="0", label="foo") + cls.attribute_graph.add_edge("0", "2", id="1") + cls.attribute_graph.add_edge("1", "0", id="2") + cls.attribute_graph.add_edge("2", "1", id="3") + cls.attribute_graph.add_edge("0", "3", id="4") + cls.attribute_fh = io.BytesIO(cls.attribute_data.encode("UTF-8")) + + cls.simple_undirected_data = """ + + + + + + + + + + + +""" + cls.simple_undirected_graph = nx.Graph() + cls.simple_undirected_graph.add_node("0", label="Hello") + cls.simple_undirected_graph.add_node("1", label="World") + cls.simple_undirected_graph.add_edge("0", "1", id="0") + + cls.simple_undirected_fh = io.BytesIO( + cls.simple_undirected_data.encode("UTF-8") + ) + + def test_read_simple_directed_graphml(self): + G = self.simple_directed_graph + H = nx.read_gexf(self.simple_directed_fh) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(G.edges()) == sorted(H.edges()) + assert sorted(G.edges(data=True)) == sorted(H.edges(data=True)) + self.simple_directed_fh.seek(0) + + def test_write_read_simple_directed_graphml(self): + G = self.simple_directed_graph + fh = io.BytesIO() + nx.write_gexf(G, fh) + fh.seek(0) + H = nx.read_gexf(fh) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(G.edges()) == sorted(H.edges()) + assert sorted(G.edges(data=True)) == sorted(H.edges(data=True)) + self.simple_directed_fh.seek(0) + + def test_read_simple_undirected_graphml(self): + G = self.simple_undirected_graph + H = nx.read_gexf(self.simple_undirected_fh) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(sorted(e) for e in G.edges()) == sorted( + sorted(e) for e in H.edges() + ) + self.simple_undirected_fh.seek(0) + + def test_read_attribute_graphml(self): + G = self.attribute_graph + H = nx.read_gexf(self.attribute_fh) + assert sorted(G.nodes(True)) == sorted(H.nodes(data=True)) + ge = sorted(G.edges(data=True)) + he = sorted(H.edges(data=True)) + for a, b in zip(ge, he): + assert a == b + self.attribute_fh.seek(0) + + def test_directed_edge_in_undirected(self): + s = """ + + + + + + + + + + + +""" + fh = io.BytesIO(s.encode("UTF-8")) + pytest.raises(nx.NetworkXError, nx.read_gexf, fh) + + def test_undirected_edge_in_directed(self): + s = """ + + + + + + + + + + + +""" + fh = io.BytesIO(s.encode("UTF-8")) + pytest.raises(nx.NetworkXError, nx.read_gexf, fh) + + def test_key_raises(self): + s = """ + + + + + + + + + + + + + + + +""" + fh = io.BytesIO(s.encode("UTF-8")) + pytest.raises(nx.NetworkXError, nx.read_gexf, fh) + + def test_relabel(self): + s = """ + + + + + + + + + + + +""" + fh = io.BytesIO(s.encode("UTF-8")) + G = nx.read_gexf(fh, relabel=True) + assert sorted(G.nodes()) == ["Hello", "Word"] + + def test_default_attribute(self): + G = nx.Graph() + G.add_node(1, label="1", color="green") + nx.add_path(G, [0, 1, 2, 3]) + G.add_edge(1, 2, foo=3) + G.graph["node_default"] = {"color": "yellow"} + G.graph["edge_default"] = {"foo": 7} + fh = io.BytesIO() + nx.write_gexf(G, fh) + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(sorted(e) for e in G.edges()) == sorted( + sorted(e) for e in H.edges() + ) + # Reading a gexf graph always sets mode attribute to either + # 'static' or 'dynamic'. Remove the mode attribute from the + # read graph for the sake of comparing remaining attributes. + del H.graph["mode"] + assert G.graph == H.graph + + def test_serialize_ints_to_strings(self): + G = nx.Graph() + G.add_node(1, id=7, label=77) + fh = io.BytesIO() + nx.write_gexf(G, fh) + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert list(H) == [7] + assert H.nodes[7]["label"] == "77" + + def test_write_with_node_attributes(self): + # Addresses #673. + G = nx.Graph() + G.add_edges_from([(0, 1), (1, 2), (2, 3)]) + for i in range(4): + G.nodes[i]["id"] = i + G.nodes[i]["label"] = i + G.nodes[i]["pid"] = i + G.nodes[i]["start"] = i + G.nodes[i]["end"] = i + 1 + + expected = f""" + + NetworkX {nx.__version__} + + + + + + + + + + + + + + +""" + obtained = "\n".join(nx.generate_gexf(G)) + assert expected == obtained + + def test_edge_id_construct(self): + G = nx.Graph() + G.add_edges_from([(0, 1, {"id": 0}), (1, 2, {"id": 2}), (2, 3)]) + + expected = f""" + + NetworkX {nx.__version__} + + + + + + + + + + + + + + +""" + + obtained = "\n".join(nx.generate_gexf(G)) + assert expected == obtained + + def test_numpy_type(self): + np = pytest.importorskip("numpy") + G = nx.path_graph(4) + nx.set_node_attributes(G, {n: n for n in np.arange(4)}, "number") + G[0][1]["edge-number"] = np.float64(1.1) + + expected = f""" + + NetworkX {nx.__version__} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" + obtained = "\n".join(nx.generate_gexf(G)) + assert expected == obtained + + def test_bool(self): + G = nx.Graph() + G.add_node(1, testattr=True) + fh = io.BytesIO() + nx.write_gexf(G, fh) + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert H.nodes[1]["testattr"] + + # Test for NaN, INF and -INF + def test_specials(self): + from math import isnan + + inf, nan = float("inf"), float("nan") + G = nx.Graph() + G.add_node(1, testattr=inf, strdata="inf", key="a") + G.add_node(2, testattr=nan, strdata="nan", key="b") + G.add_node(3, testattr=-inf, strdata="-inf", key="c") + + fh = io.BytesIO() + nx.write_gexf(G, fh) + fh.seek(0) + filetext = fh.read() + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + + assert b"INF" in filetext + assert b"NaN" in filetext + assert b"-INF" in filetext + + assert H.nodes[1]["testattr"] == inf + assert isnan(H.nodes[2]["testattr"]) + assert H.nodes[3]["testattr"] == -inf + + assert H.nodes[1]["strdata"] == "inf" + assert H.nodes[2]["strdata"] == "nan" + assert H.nodes[3]["strdata"] == "-inf" + + assert H.nodes[1]["networkx_key"] == "a" + assert H.nodes[2]["networkx_key"] == "b" + assert H.nodes[3]["networkx_key"] == "c" + + def test_simple_list(self): + G = nx.Graph() + list_value = [(1, 2, 3), (9, 1, 2)] + G.add_node(1, key=list_value) + fh = io.BytesIO() + nx.write_gexf(G, fh) + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert H.nodes[1]["networkx_key"] == list_value + + def test_dynamic_mode(self): + G = nx.Graph() + G.add_node(1, label="1", color="green") + G.graph["mode"] = "dynamic" + fh = io.BytesIO() + nx.write_gexf(G, fh) + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(sorted(e) for e in G.edges()) == sorted( + sorted(e) for e in H.edges() + ) + + def test_multigraph_with_missing_attributes(self): + G = nx.MultiGraph() + G.add_node(0, label="1", color="green") + G.add_node(1, label="2", color="green") + G.add_edge(0, 1, id="0", weight=3, type="undirected", start=0, end=1) + G.add_edge(0, 1, id="1", label="foo", start=0, end=1) + G.add_edge(0, 1) + fh = io.BytesIO() + nx.write_gexf(G, fh) + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(sorted(e) for e in G.edges()) == sorted( + sorted(e) for e in H.edges() + ) + + def test_missing_viz_attributes(self): + G = nx.Graph() + G.add_node(0, label="1", color="green") + G.nodes[0]["viz"] = {"size": 54} + G.nodes[0]["viz"]["position"] = {"x": 0, "y": 1, "z": 0} + G.nodes[0]["viz"]["color"] = {"r": 0, "g": 0, "b": 256} + G.nodes[0]["viz"]["shape"] = "http://random.url" + G.nodes[0]["viz"]["thickness"] = 2 + fh = io.BytesIO() + nx.write_gexf(G, fh, version="1.1draft") + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(sorted(e) for e in G.edges()) == sorted( + sorted(e) for e in H.edges() + ) + + # Test missing alpha value for version >draft1.1 - set default alpha value + # to 1.0 instead of `None` when writing for better general compatibility + fh = io.BytesIO() + # G.nodes[0]["viz"]["color"] does not have an alpha value explicitly defined + # so the default is used instead + nx.write_gexf(G, fh, version="1.2draft") + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert H.nodes[0]["viz"]["color"]["a"] == 1.0 + + # Second graph for the other branch + G = nx.Graph() + G.add_node(0, label="1", color="green") + G.nodes[0]["viz"] = {"size": 54} + G.nodes[0]["viz"]["position"] = {"x": 0, "y": 1, "z": 0} + G.nodes[0]["viz"]["color"] = {"r": 0, "g": 0, "b": 256, "a": 0.5} + G.nodes[0]["viz"]["shape"] = "ftp://random.url" + G.nodes[0]["viz"]["thickness"] = 2 + fh = io.BytesIO() + nx.write_gexf(G, fh) + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(sorted(e) for e in G.edges()) == sorted( + sorted(e) for e in H.edges() + ) + + def test_slice_and_spell(self): + # Test spell first, so version = 1.2 + G = nx.Graph() + G.add_node(0, label="1", color="green") + G.nodes[0]["spells"] = [(1, 2)] + fh = io.BytesIO() + nx.write_gexf(G, fh) + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(sorted(e) for e in G.edges()) == sorted( + sorted(e) for e in H.edges() + ) + + G = nx.Graph() + G.add_node(0, label="1", color="green") + G.nodes[0]["slices"] = [(1, 2)] + fh = io.BytesIO() + nx.write_gexf(G, fh, version="1.1draft") + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(sorted(e) for e in G.edges()) == sorted( + sorted(e) for e in H.edges() + ) + + def test_add_parent(self): + G = nx.Graph() + G.add_node(0, label="1", color="green", parents=[1, 2]) + fh = io.BytesIO() + nx.write_gexf(G, fh) + fh.seek(0) + H = nx.read_gexf(fh, node_type=int) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(sorted(e) for e in G.edges()) == sorted( + sorted(e) for e in H.edges() + ) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_gml.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_gml.py new file mode 100644 index 0000000000000000000000000000000000000000..df250979b149b7276babed267d59cb7cbcab22c6 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_gml.py @@ -0,0 +1,744 @@ +import codecs +import io +import math +from ast import literal_eval +from contextlib import contextmanager +from textwrap import dedent + +import pytest + +import networkx as nx +from networkx.readwrite.gml import literal_destringizer, literal_stringizer + + +class TestGraph: + @classmethod + def setup_class(cls): + cls.simple_data = """Creator "me" +Version "xx" +graph [ + comment "This is a sample graph" + directed 1 + IsPlanar 1 + pos [ x 0 y 1 ] + node [ + id 1 + label "Node 1" + pos [ x 1 y 1 ] + ] + node [ + id 2 + pos [ x 1 y 2 ] + label "Node 2" + ] + node [ + id 3 + label "Node 3" + pos [ x 1 y 3 ] + ] + edge [ + source 1 + target 2 + label "Edge from node 1 to node 2" + color [line "blue" thickness 3] + + ] + edge [ + source 2 + target 3 + label "Edge from node 2 to node 3" + ] + edge [ + source 3 + target 1 + label "Edge from node 3 to node 1" + ] +] +""" + + def test_parse_gml_cytoscape_bug(self): + # example from issue #321, originally #324 in trac + cytoscape_example = """ +Creator "Cytoscape" +Version 1.0 +graph [ + node [ + root_index -3 + id -3 + graphics [ + x -96.0 + y -67.0 + w 40.0 + h 40.0 + fill "#ff9999" + type "ellipse" + outline "#666666" + outline_width 1.5 + ] + label "node2" + ] + node [ + root_index -2 + id -2 + graphics [ + x 63.0 + y 37.0 + w 40.0 + h 40.0 + fill "#ff9999" + type "ellipse" + outline "#666666" + outline_width 1.5 + ] + label "node1" + ] + node [ + root_index -1 + id -1 + graphics [ + x -31.0 + y -17.0 + w 40.0 + h 40.0 + fill "#ff9999" + type "ellipse" + outline "#666666" + outline_width 1.5 + ] + label "node0" + ] + edge [ + root_index -2 + target -2 + source -1 + graphics [ + width 1.5 + fill "#0000ff" + type "line" + Line [ + ] + source_arrow 0 + target_arrow 3 + ] + label "DirectedEdge" + ] + edge [ + root_index -1 + target -1 + source -3 + graphics [ + width 1.5 + fill "#0000ff" + type "line" + Line [ + ] + source_arrow 0 + target_arrow 3 + ] + label "DirectedEdge" + ] +] +""" + nx.parse_gml(cytoscape_example) + + def test_parse_gml(self): + G = nx.parse_gml(self.simple_data, label="label") + assert sorted(G.nodes()) == ["Node 1", "Node 2", "Node 3"] + assert sorted(G.edges()) == [ + ("Node 1", "Node 2"), + ("Node 2", "Node 3"), + ("Node 3", "Node 1"), + ] + + assert sorted(G.edges(data=True)) == [ + ( + "Node 1", + "Node 2", + { + "color": {"line": "blue", "thickness": 3}, + "label": "Edge from node 1 to node 2", + }, + ), + ("Node 2", "Node 3", {"label": "Edge from node 2 to node 3"}), + ("Node 3", "Node 1", {"label": "Edge from node 3 to node 1"}), + ] + + def test_read_gml(self, tmp_path): + fname = tmp_path / "test.gml" + with open(fname, "w") as fh: + fh.write(self.simple_data) + Gin = nx.read_gml(fname, label="label") + G = nx.parse_gml(self.simple_data, label="label") + assert sorted(G.nodes(data=True)) == sorted(Gin.nodes(data=True)) + assert sorted(G.edges(data=True)) == sorted(Gin.edges(data=True)) + + def test_labels_are_strings(self): + # GML requires labels to be strings (i.e., in quotes) + answer = """graph [ + node [ + id 0 + label "1203" + ] +]""" + G = nx.Graph() + G.add_node(1203) + data = "\n".join(nx.generate_gml(G, stringizer=literal_stringizer)) + assert data == answer + + def test_relabel_duplicate(self): + data = """ +graph +[ + label "" + directed 1 + node + [ + id 0 + label "same" + ] + node + [ + id 1 + label "same" + ] +] +""" + fh = io.BytesIO(data.encode("UTF-8")) + fh.seek(0) + pytest.raises(nx.NetworkXError, nx.read_gml, fh, label="label") + + @pytest.mark.parametrize("stringizer", (None, literal_stringizer)) + def test_tuplelabels(self, stringizer): + # https://github.com/networkx/networkx/pull/1048 + # Writing tuple labels to GML failed. + G = nx.Graph() + G.add_edge((0, 1), (1, 0)) + data = "\n".join(nx.generate_gml(G, stringizer=stringizer)) + answer = """graph [ + node [ + id 0 + label "(0,1)" + ] + node [ + id 1 + label "(1,0)" + ] + edge [ + source 0 + target 1 + ] +]""" + assert data == answer + + def test_quotes(self, tmp_path): + # https://github.com/networkx/networkx/issues/1061 + # Encoding quotes as HTML entities. + G = nx.path_graph(1) + G.name = "path_graph(1)" + attr = 'This is "quoted" and this is a copyright: ' + chr(169) + G.nodes[0]["demo"] = attr + with open(tmp_path / "test.gml", "w+b") as fobj: + nx.write_gml(G, fobj) + fobj.seek(0) + # Should be bytes in 2.x and 3.x + data = fobj.read().strip().decode("ascii") + answer = """graph [ + name "path_graph(1)" + node [ + id 0 + label "0" + demo "This is "quoted" and this is a copyright: ©" + ] +]""" + assert data == answer + + def test_unicode_node(self, tmp_path): + node = "node" + chr(169) + G = nx.Graph() + G.add_node(node) + with open(tmp_path / "test.gml", "w+b") as fobj: + nx.write_gml(G, fobj) + fobj.seek(0) + # Should be bytes in 2.x and 3.x + data = fobj.read().strip().decode("ascii") + answer = """graph [ + node [ + id 0 + label "node©" + ] +]""" + assert data == answer + + def test_float_label(self, tmp_path): + node = 1.0 + G = nx.Graph() + G.add_node(node) + with open(tmp_path / "test.gml", "w+b") as fobj: + nx.write_gml(G, fobj) + fobj.seek(0) + # Should be bytes in 2.x and 3.x + data = fobj.read().strip().decode("ascii") + answer = """graph [ + node [ + id 0 + label "1.0" + ] +]""" + assert data == answer + + def test_special_float_label(self, tmp_path): + special_floats = [float("nan"), float("+inf"), float("-inf")] + try: + import numpy as np + + special_floats += [np.nan, np.inf, np.inf * -1] + except ImportError: + special_floats += special_floats + + G = nx.cycle_graph(len(special_floats)) + attrs = dict(enumerate(special_floats)) + nx.set_node_attributes(G, attrs, "nodefloat") + edges = list(G.edges) + attrs = {edges[i]: value for i, value in enumerate(special_floats)} + nx.set_edge_attributes(G, attrs, "edgefloat") + + with open(tmp_path / "test.gml", "w+b") as fobj: + nx.write_gml(G, fobj) + fobj.seek(0) + # Should be bytes in 2.x and 3.x + data = fobj.read().strip().decode("ascii") + answer = """graph [ + node [ + id 0 + label "0" + nodefloat NAN + ] + node [ + id 1 + label "1" + nodefloat +INF + ] + node [ + id 2 + label "2" + nodefloat -INF + ] + node [ + id 3 + label "3" + nodefloat NAN + ] + node [ + id 4 + label "4" + nodefloat +INF + ] + node [ + id 5 + label "5" + nodefloat -INF + ] + edge [ + source 0 + target 1 + edgefloat NAN + ] + edge [ + source 0 + target 5 + edgefloat +INF + ] + edge [ + source 1 + target 2 + edgefloat -INF + ] + edge [ + source 2 + target 3 + edgefloat NAN + ] + edge [ + source 3 + target 4 + edgefloat +INF + ] + edge [ + source 4 + target 5 + edgefloat -INF + ] +]""" + assert data == answer + + fobj.seek(0) + graph = nx.read_gml(fobj) + for indx, value in enumerate(special_floats): + node_value = graph.nodes[str(indx)]["nodefloat"] + if math.isnan(value): + assert math.isnan(node_value) + else: + assert node_value == value + + edge = edges[indx] + string_edge = (str(edge[0]), str(edge[1])) + edge_value = graph.edges[string_edge]["edgefloat"] + if math.isnan(value): + assert math.isnan(edge_value) + else: + assert edge_value == value + + def test_name(self): + G = nx.parse_gml('graph [ name "x" node [ id 0 label "x" ] ]') + assert "x" == G.graph["name"] + G = nx.parse_gml('graph [ node [ id 0 label "x" ] ]') + assert "" == G.name + assert "name" not in G.graph + + def test_graph_types(self): + for directed in [None, False, True]: + for multigraph in [None, False, True]: + gml = "graph [" + if directed is not None: + gml += " directed " + str(int(directed)) + if multigraph is not None: + gml += " multigraph " + str(int(multigraph)) + gml += ' node [ id 0 label "0" ]' + gml += " edge [ source 0 target 0 ]" + gml += " ]" + G = nx.parse_gml(gml) + assert bool(directed) == G.is_directed() + assert bool(multigraph) == G.is_multigraph() + gml = "graph [\n" + if directed is True: + gml += " directed 1\n" + if multigraph is True: + gml += " multigraph 1\n" + gml += """ node [ + id 0 + label "0" + ] + edge [ + source 0 + target 0 +""" + if multigraph: + gml += " key 0\n" + gml += " ]\n]" + assert gml == "\n".join(nx.generate_gml(G)) + + def test_data_types(self): + data = [ + True, + False, + 10**20, + -2e33, + "'", + '"&&&""', + [{(b"\xfd",): "\x7f", chr(0x4444): (1, 2)}, (2, "3")], + ] + data.append(chr(0x14444)) + data.append(literal_eval("{2.3j, 1 - 2.3j, ()}")) + G = nx.Graph() + G.name = data + G.graph["data"] = data + G.add_node(0, int=-1, data={"data": data}) + G.add_edge(0, 0, float=-2.5, data=data) + gml = "\n".join(nx.generate_gml(G, stringizer=literal_stringizer)) + G = nx.parse_gml(gml, destringizer=literal_destringizer) + assert data == G.name + assert {"name": data, "data": data} == G.graph + assert list(G.nodes(data=True)) == [(0, {"int": -1, "data": {"data": data}})] + assert list(G.edges(data=True)) == [(0, 0, {"float": -2.5, "data": data})] + G = nx.Graph() + G.graph["data"] = "frozenset([1, 2, 3])" + G = nx.parse_gml(nx.generate_gml(G), destringizer=literal_eval) + assert G.graph["data"] == "frozenset([1, 2, 3])" + + def test_escape_unescape(self): + gml = """graph [ + name "&"䑄��&unknown;" +]""" + G = nx.parse_gml(gml) + assert ( + '&"\x0f' + chr(0x4444) + "��&unknown;" + == G.name + ) + gml = "\n".join(nx.generate_gml(G)) + alnu = "#1234567890;&#x1234567890abcdef" + answer = ( + """graph [ + name "&"䑄&""" + + alnu + + """;&unknown;" +]""" + ) + assert answer == gml + + def test_exceptions(self, tmp_path): + pytest.raises(ValueError, literal_destringizer, "(") + pytest.raises(ValueError, literal_destringizer, "frozenset([1, 2, 3])") + pytest.raises(ValueError, literal_destringizer, literal_destringizer) + pytest.raises(ValueError, literal_stringizer, frozenset([1, 2, 3])) + pytest.raises(ValueError, literal_stringizer, literal_stringizer) + with open(tmp_path / "test.gml", "w+b") as f: + f.write(codecs.BOM_UTF8 + b"graph[]") + f.seek(0) + pytest.raises(nx.NetworkXError, nx.read_gml, f) + + def assert_parse_error(gml): + pytest.raises(nx.NetworkXError, nx.parse_gml, gml) + + assert_parse_error(["graph [\n\n", "]"]) + assert_parse_error("") + assert_parse_error('Creator ""') + assert_parse_error("0") + assert_parse_error("graph ]") + assert_parse_error("graph [ 1 ]") + assert_parse_error("graph [ 1.E+2 ]") + assert_parse_error('graph [ "A" ]') + assert_parse_error("graph [ ] graph ]") + assert_parse_error("graph [ ] graph [ ]") + assert_parse_error("graph [ data [1, 2, 3] ]") + assert_parse_error("graph [ node [ ] ]") + assert_parse_error("graph [ node [ id 0 ] ]") + nx.parse_gml('graph [ node [ id "a" ] ]', label="id") + assert_parse_error("graph [ node [ id 0 label 0 ] node [ id 0 label 1 ] ]") + assert_parse_error("graph [ node [ id 0 label 0 ] node [ id 1 label 0 ] ]") + assert_parse_error("graph [ node [ id 0 label 0 ] edge [ ] ]") + assert_parse_error("graph [ node [ id 0 label 0 ] edge [ source 0 ] ]") + nx.parse_gml("graph [edge [ source 0 target 0 ] node [ id 0 label 0 ] ]") + assert_parse_error("graph [ node [ id 0 label 0 ] edge [ source 1 target 0 ] ]") + assert_parse_error("graph [ node [ id 0 label 0 ] edge [ source 0 target 1 ] ]") + assert_parse_error( + "graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] " + "edge [ source 0 target 1 ] edge [ source 1 target 0 ] ]" + ) + nx.parse_gml( + "graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] " + "edge [ source 0 target 1 ] edge [ source 1 target 0 ] " + "directed 1 ]" + ) + nx.parse_gml( + "graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] " + "edge [ source 0 target 1 ] edge [ source 0 target 1 ]" + "multigraph 1 ]" + ) + nx.parse_gml( + "graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] " + "edge [ source 0 target 1 key 0 ] edge [ source 0 target 1 ]" + "multigraph 1 ]" + ) + assert_parse_error( + "graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] " + "edge [ source 0 target 1 key 0 ] edge [ source 0 target 1 key 0 ]" + "multigraph 1 ]" + ) + nx.parse_gml( + "graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] " + "edge [ source 0 target 1 key 0 ] edge [ source 1 target 0 key 0 ]" + "directed 1 multigraph 1 ]" + ) + + # Tests for string convertible alphanumeric id and label values + nx.parse_gml("graph [edge [ source a target a ] node [ id a label b ] ]") + nx.parse_gml( + "graph [ node [ id n42 label 0 ] node [ id x43 label 1 ]" + "edge [ source n42 target x43 key 0 ]" + "edge [ source x43 target n42 key 0 ]" + "directed 1 multigraph 1 ]" + ) + assert_parse_error( + "graph [edge [ source '\u4200' target '\u4200' ] " + + "node [ id '\u4200' label b ] ]" + ) + + def assert_generate_error(*args, **kwargs): + pytest.raises( + nx.NetworkXError, lambda: list(nx.generate_gml(*args, **kwargs)) + ) + + G = nx.Graph() + G.graph[3] = 3 + assert_generate_error(G) + G = nx.Graph() + G.graph["3"] = 3 + assert_generate_error(G) + G = nx.Graph() + G.graph["data"] = frozenset([1, 2, 3]) + assert_generate_error(G, stringizer=literal_stringizer) + + def test_label_kwarg(self): + G = nx.parse_gml(self.simple_data, label="id") + assert sorted(G.nodes) == [1, 2, 3] + labels = [G.nodes[n]["label"] for n in sorted(G.nodes)] + assert labels == ["Node 1", "Node 2", "Node 3"] + + G = nx.parse_gml(self.simple_data, label=None) + assert sorted(G.nodes) == [1, 2, 3] + labels = [G.nodes[n]["label"] for n in sorted(G.nodes)] + assert labels == ["Node 1", "Node 2", "Node 3"] + + def test_outofrange_integers(self, tmp_path): + # GML restricts integers to 32 signed bits. + # Check that we honor this restriction on export + G = nx.Graph() + # Test export for numbers that barely fit or don't fit into 32 bits, + # and 3 numbers in the middle + numbers = { + "toosmall": (-(2**31)) - 1, + "small": -(2**31), + "med1": -4, + "med2": 0, + "med3": 17, + "big": (2**31) - 1, + "toobig": 2**31, + } + G.add_node("Node", **numbers) + + fname = tmp_path / "test.gml" + nx.write_gml(G, fname) + # Check that the export wrote the nonfitting numbers as strings + G2 = nx.read_gml(fname) + for attr, value in G2.nodes["Node"].items(): + if attr == "toosmall" or attr == "toobig": + assert isinstance(value, str) + else: + assert isinstance(value, int) + + def test_multiline(self): + # example from issue #6836 + multiline_example = """ +graph +[ + node + [ + id 0 + label "multiline node" + label2 "multiline1 + multiline2 + multiline3" + alt_name "id 0" + ] +] +""" + G = nx.parse_gml(multiline_example) + assert G.nodes["multiline node"] == { + "label2": "multiline1 multiline2 multiline3", + "alt_name": "id 0", + } + + +@contextmanager +def byte_file(): + _file_handle = io.BytesIO() + yield _file_handle + _file_handle.seek(0) + + +class TestPropertyLists: + def test_writing_graph_with_multi_element_property_list(self): + g = nx.Graph() + g.add_node("n1", properties=["element", 0, 1, 2.5, True, False]) + with byte_file() as f: + nx.write_gml(g, f) + result = f.read().decode() + + assert result == dedent( + """\ + graph [ + node [ + id 0 + label "n1" + properties "element" + properties 0 + properties 1 + properties 2.5 + properties 1 + properties 0 + ] + ] + """ + ) + + def test_writing_graph_with_one_element_property_list(self): + g = nx.Graph() + g.add_node("n1", properties=["element"]) + with byte_file() as f: + nx.write_gml(g, f) + result = f.read().decode() + + assert result == dedent( + """\ + graph [ + node [ + id 0 + label "n1" + properties "_networkx_list_start" + properties "element" + ] + ] + """ + ) + + def test_reading_graph_with_list_property(self): + with byte_file() as f: + f.write( + dedent( + """ + graph [ + node [ + id 0 + label "n1" + properties "element" + properties 0 + properties 1 + properties 2.5 + ] + ] + """ + ).encode("ascii") + ) + f.seek(0) + graph = nx.read_gml(f) + assert graph.nodes(data=True)["n1"] == {"properties": ["element", 0, 1, 2.5]} + + def test_reading_graph_with_single_element_list_property(self): + with byte_file() as f: + f.write( + dedent( + """ + graph [ + node [ + id 0 + label "n1" + properties "_networkx_list_start" + properties "element" + ] + ] + """ + ).encode("ascii") + ) + f.seek(0) + graph = nx.read_gml(f) + assert graph.nodes(data=True)["n1"] == {"properties": ["element"]} + + +@pytest.mark.parametrize("coll", ([], ())) +def test_stringize_empty_list_tuple(coll): + G = nx.path_graph(2) + G.nodes[0]["test"] = coll # test serializing an empty collection + f = io.BytesIO() + nx.write_gml(G, f) # Smoke test - should not raise + f.seek(0) + H = nx.read_gml(f) + assert H.nodes["0"]["test"] == coll # Check empty list round-trips properly + # Check full round-tripping. Note that nodes are loaded as strings by + # default, so there needs to be some remapping prior to comparison + H = nx.relabel_nodes(H, {"0": 0, "1": 1}) + assert nx.utils.graphs_equal(G, H) + # Same as above, but use destringizer for node remapping. Should have no + # effect on node attr + f.seek(0) + H = nx.read_gml(f, destringizer=int) + assert nx.utils.graphs_equal(G, H) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_graph6.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_graph6.py new file mode 100644 index 0000000000000000000000000000000000000000..d680c2153d678250b4aa9b32f6ad7d0f6d8e80f6 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_graph6.py @@ -0,0 +1,181 @@ +from io import BytesIO + +import pytest + +import networkx as nx +import networkx.readwrite.graph6 as g6 +from networkx.utils import edges_equal, nodes_equal + + +def test_from_graph6_invariant_to_trailing_newline(): + """See gh-7557""" + G = nx.from_graph6_bytes(b">>graph6<>graph6<>graph6<<\nP~~~~~~~~~~~~~~~~~~~~~~{") + + +class TestGraph6Utils: + def test_n_data_n_conversion(self): + for i in [0, 1, 42, 62, 63, 64, 258047, 258048, 7744773, 68719476735]: + assert g6.data_to_n(g6.n_to_data(i))[0] == i + assert g6.data_to_n(g6.n_to_data(i))[1] == [] + assert g6.data_to_n(g6.n_to_data(i) + [42, 43])[1] == [42, 43] + + +class TestFromGraph6Bytes: + def test_from_graph6_bytes(self): + data = b"DF{" + G = nx.from_graph6_bytes(data) + assert nodes_equal(G.nodes(), [0, 1, 2, 3, 4]) + assert edges_equal( + G.edges(), [(0, 3), (0, 4), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] + ) + + def test_read_equals_from_bytes(self): + data = b"DF{" + G = nx.from_graph6_bytes(data) + fh = BytesIO(data) + Gin = nx.read_graph6(fh) + assert nodes_equal(G.nodes(), Gin.nodes()) + assert edges_equal(G.edges(), Gin.edges()) + + +class TestReadGraph6: + def test_read_many_graph6(self): + """Test for reading many graphs from a file into a list.""" + data = b"DF{\nD`{\nDqK\nD~{\n" + fh = BytesIO(data) + glist = nx.read_graph6(fh) + assert len(glist) == 4 + for G in glist: + assert sorted(G) == list(range(5)) + + +class TestWriteGraph6: + """Unit tests for writing a graph to a file in graph6 format.""" + + def test_null_graph(self): + result = BytesIO() + nx.write_graph6(nx.null_graph(), result) + assert result.getvalue() == b">>graph6<>graph6<<@\n" + + def test_complete_graph(self): + result = BytesIO() + nx.write_graph6(nx.complete_graph(4), result) + assert result.getvalue() == b">>graph6<>graph6<>graph6<>graph6<>graph6<<@\n" + + def test_complete_graph(self): + assert g6.to_graph6_bytes(nx.complete_graph(4)) == b">>graph6<>graph6< + + + + + + + + + + + + + + + + + + + + + + + + + + +""" + cls.simple_directed_graph = nx.DiGraph() + cls.simple_directed_graph.add_node("n10") + cls.simple_directed_graph.add_edge("n0", "n2", id="foo") + cls.simple_directed_graph.add_edge("n0", "n2") + cls.simple_directed_graph.add_edges_from( + [ + ("n1", "n2"), + ("n2", "n3"), + ("n3", "n5"), + ("n3", "n4"), + ("n4", "n6"), + ("n6", "n5"), + ("n5", "n7"), + ("n6", "n8"), + ("n8", "n7"), + ("n8", "n9"), + ] + ) + cls.simple_directed_fh = io.BytesIO(cls.simple_directed_data.encode("UTF-8")) + + cls.attribute_data = """ + + + yellow + + + + + green + + + + blue + + + red + + + + turquoise + + + 1.0 + + + 1.0 + + + 2.0 + + + + + + 1.1 + + + +""" + cls.attribute_graph = nx.DiGraph(id="G") + cls.attribute_graph.graph["node_default"] = {"color": "yellow"} + cls.attribute_graph.add_node("n0", color="green") + cls.attribute_graph.add_node("n2", color="blue") + cls.attribute_graph.add_node("n3", color="red") + cls.attribute_graph.add_node("n4") + cls.attribute_graph.add_node("n5", color="turquoise") + cls.attribute_graph.add_edge("n0", "n2", id="e0", weight=1.0) + cls.attribute_graph.add_edge("n0", "n1", id="e1", weight=1.0) + cls.attribute_graph.add_edge("n1", "n3", id="e2", weight=2.0) + cls.attribute_graph.add_edge("n3", "n2", id="e3") + cls.attribute_graph.add_edge("n2", "n4", id="e4") + cls.attribute_graph.add_edge("n3", "n5", id="e5") + cls.attribute_graph.add_edge("n5", "n4", id="e6", weight=1.1) + cls.attribute_fh = io.BytesIO(cls.attribute_data.encode("UTF-8")) + + cls.node_attribute_default_data = """ + + false + 0 + 0 + 0.0 + 0.0 + Foo + + + + + + + """ + cls.node_attribute_default_graph = nx.DiGraph(id="G") + cls.node_attribute_default_graph.graph["node_default"] = { + "boolean_attribute": False, + "int_attribute": 0, + "long_attribute": 0, + "float_attribute": 0.0, + "double_attribute": 0.0, + "string_attribute": "Foo", + } + cls.node_attribute_default_graph.add_node("n0") + cls.node_attribute_default_graph.add_node("n1") + cls.node_attribute_default_graph.add_edge("n0", "n1", id="e0") + cls.node_attribute_default_fh = io.BytesIO( + cls.node_attribute_default_data.encode("UTF-8") + ) + + cls.attribute_named_key_ids_data = """ + + + + + + + val1 + val2 + + + val_one + val2 + + + edge_value + + + +""" + cls.attribute_named_key_ids_graph = nx.DiGraph() + cls.attribute_named_key_ids_graph.add_node("0", prop1="val1", prop2="val2") + cls.attribute_named_key_ids_graph.add_node("1", prop1="val_one", prop2="val2") + cls.attribute_named_key_ids_graph.add_edge("0", "1", edge_prop="edge_value") + fh = io.BytesIO(cls.attribute_named_key_ids_data.encode("UTF-8")) + cls.attribute_named_key_ids_fh = fh + + cls.attribute_numeric_type_data = """ + + + + + + 1 + + + 2.0 + + + 1 + + + k + + + 1.0 + + + +""" + cls.attribute_numeric_type_graph = nx.DiGraph() + cls.attribute_numeric_type_graph.add_node("n0", weight=1) + cls.attribute_numeric_type_graph.add_node("n1", weight=2.0) + cls.attribute_numeric_type_graph.add_edge("n0", "n1", weight=1) + cls.attribute_numeric_type_graph.add_edge("n1", "n1", weight=1.0) + fh = io.BytesIO(cls.attribute_numeric_type_data.encode("UTF-8")) + cls.attribute_numeric_type_fh = fh + + cls.simple_undirected_data = """ + + + + + + + + + + +""" + # + cls.simple_undirected_graph = nx.Graph() + cls.simple_undirected_graph.add_node("n10") + cls.simple_undirected_graph.add_edge("n0", "n2", id="foo") + cls.simple_undirected_graph.add_edges_from([("n1", "n2"), ("n2", "n3")]) + fh = io.BytesIO(cls.simple_undirected_data.encode("UTF-8")) + cls.simple_undirected_fh = fh + + cls.undirected_multigraph_data = """ + + + + + + + + + + +""" + cls.undirected_multigraph = nx.MultiGraph() + cls.undirected_multigraph.add_node("n10") + cls.undirected_multigraph.add_edge("n0", "n2", id="e0") + cls.undirected_multigraph.add_edge("n1", "n2", id="e1") + cls.undirected_multigraph.add_edge("n2", "n1", id="e2") + fh = io.BytesIO(cls.undirected_multigraph_data.encode("UTF-8")) + cls.undirected_multigraph_fh = fh + + cls.undirected_multigraph_no_multiedge_data = """ + + + + + + + + + + +""" + cls.undirected_multigraph_no_multiedge = nx.MultiGraph() + cls.undirected_multigraph_no_multiedge.add_node("n10") + cls.undirected_multigraph_no_multiedge.add_edge("n0", "n2", id="e0") + cls.undirected_multigraph_no_multiedge.add_edge("n1", "n2", id="e1") + cls.undirected_multigraph_no_multiedge.add_edge("n2", "n3", id="e2") + fh = io.BytesIO(cls.undirected_multigraph_no_multiedge_data.encode("UTF-8")) + cls.undirected_multigraph_no_multiedge_fh = fh + + cls.multigraph_only_ids_for_multiedges_data = """ + + + + + + + + + + +""" + cls.multigraph_only_ids_for_multiedges = nx.MultiGraph() + cls.multigraph_only_ids_for_multiedges.add_node("n10") + cls.multigraph_only_ids_for_multiedges.add_edge("n0", "n2") + cls.multigraph_only_ids_for_multiedges.add_edge("n1", "n2", id="e1") + cls.multigraph_only_ids_for_multiedges.add_edge("n2", "n1", id="e2") + fh = io.BytesIO(cls.multigraph_only_ids_for_multiedges_data.encode("UTF-8")) + cls.multigraph_only_ids_for_multiedges_fh = fh + + +class TestReadGraphML(BaseGraphML): + def test_read_simple_directed_graphml(self): + G = self.simple_directed_graph + H = nx.read_graphml(self.simple_directed_fh) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(G.edges()) == sorted(H.edges()) + assert sorted(G.edges(data=True)) == sorted(H.edges(data=True)) + self.simple_directed_fh.seek(0) + + PG = nx.parse_graphml(self.simple_directed_data) + assert sorted(G.nodes()) == sorted(PG.nodes()) + assert sorted(G.edges()) == sorted(PG.edges()) + assert sorted(G.edges(data=True)) == sorted(PG.edges(data=True)) + + def test_read_simple_undirected_graphml(self): + G = self.simple_undirected_graph + H = nx.read_graphml(self.simple_undirected_fh) + assert nodes_equal(G.nodes(), H.nodes()) + assert edges_equal(G.edges(), H.edges()) + self.simple_undirected_fh.seek(0) + + PG = nx.parse_graphml(self.simple_undirected_data) + assert nodes_equal(G.nodes(), PG.nodes()) + assert edges_equal(G.edges(), PG.edges()) + + def test_read_undirected_multigraph_graphml(self): + G = self.undirected_multigraph + H = nx.read_graphml(self.undirected_multigraph_fh) + assert nodes_equal(G.nodes(), H.nodes()) + assert edges_equal(G.edges(), H.edges()) + self.undirected_multigraph_fh.seek(0) + + PG = nx.parse_graphml(self.undirected_multigraph_data) + assert nodes_equal(G.nodes(), PG.nodes()) + assert edges_equal(G.edges(), PG.edges()) + + def test_read_undirected_multigraph_no_multiedge_graphml(self): + G = self.undirected_multigraph_no_multiedge + H = nx.read_graphml(self.undirected_multigraph_no_multiedge_fh) + assert nodes_equal(G.nodes(), H.nodes()) + assert edges_equal(G.edges(), H.edges()) + self.undirected_multigraph_no_multiedge_fh.seek(0) + + PG = nx.parse_graphml(self.undirected_multigraph_no_multiedge_data) + assert nodes_equal(G.nodes(), PG.nodes()) + assert edges_equal(G.edges(), PG.edges()) + + def test_read_undirected_multigraph_only_ids_for_multiedges_graphml(self): + G = self.multigraph_only_ids_for_multiedges + H = nx.read_graphml(self.multigraph_only_ids_for_multiedges_fh) + assert nodes_equal(G.nodes(), H.nodes()) + assert edges_equal(G.edges(), H.edges()) + self.multigraph_only_ids_for_multiedges_fh.seek(0) + + PG = nx.parse_graphml(self.multigraph_only_ids_for_multiedges_data) + assert nodes_equal(G.nodes(), PG.nodes()) + assert edges_equal(G.edges(), PG.edges()) + + def test_read_attribute_graphml(self): + G = self.attribute_graph + H = nx.read_graphml(self.attribute_fh) + assert nodes_equal(G.nodes(True), sorted(H.nodes(data=True))) + ge = sorted(G.edges(data=True)) + he = sorted(H.edges(data=True)) + for a, b in zip(ge, he): + assert a == b + self.attribute_fh.seek(0) + + PG = nx.parse_graphml(self.attribute_data) + assert sorted(G.nodes(True)) == sorted(PG.nodes(data=True)) + ge = sorted(G.edges(data=True)) + he = sorted(PG.edges(data=True)) + for a, b in zip(ge, he): + assert a == b + + def test_node_default_attribute_graphml(self): + G = self.node_attribute_default_graph + H = nx.read_graphml(self.node_attribute_default_fh) + assert G.graph["node_default"] == H.graph["node_default"] + + def test_directed_edge_in_undirected(self): + s = """ + + + + + + + + +""" + fh = io.BytesIO(s.encode("UTF-8")) + pytest.raises(nx.NetworkXError, nx.read_graphml, fh) + pytest.raises(nx.NetworkXError, nx.parse_graphml, s) + + def test_undirected_edge_in_directed(self): + s = """ + + + + + + + + +""" + fh = io.BytesIO(s.encode("UTF-8")) + pytest.raises(nx.NetworkXError, nx.read_graphml, fh) + pytest.raises(nx.NetworkXError, nx.parse_graphml, s) + + def test_key_raise(self): + s = """ + + + yellow + + + + + green + + + + blue + + + 1.0 + + + +""" + fh = io.BytesIO(s.encode("UTF-8")) + pytest.raises(nx.NetworkXError, nx.read_graphml, fh) + pytest.raises(nx.NetworkXError, nx.parse_graphml, s) + + def test_hyperedge_raise(self): + s = """ + + + yellow + + + + + green + + + + blue + + + + + + + + +""" + fh = io.BytesIO(s.encode("UTF-8")) + pytest.raises(nx.NetworkXError, nx.read_graphml, fh) + pytest.raises(nx.NetworkXError, nx.parse_graphml, s) + + def test_multigraph_keys(self): + # Test that reading multigraphs uses edge id attributes as keys + s = """ + + + + + + + + +""" + fh = io.BytesIO(s.encode("UTF-8")) + G = nx.read_graphml(fh) + expected = [("n0", "n1", "e0"), ("n0", "n1", "e1")] + assert sorted(G.edges(keys=True)) == expected + fh.seek(0) + H = nx.parse_graphml(s) + assert sorted(H.edges(keys=True)) == expected + + def test_preserve_multi_edge_data(self): + """ + Test that data and keys of edges are preserved on consequent + write and reads + """ + G = nx.MultiGraph() + G.add_node(1) + G.add_node(2) + G.add_edges_from( + [ + # edges with no data, no keys: + (1, 2), + # edges with only data: + (1, 2, {"key": "data_key1"}), + (1, 2, {"id": "data_id2"}), + (1, 2, {"key": "data_key3", "id": "data_id3"}), + # edges with both data and keys: + (1, 2, 103, {"key": "data_key4"}), + (1, 2, 104, {"id": "data_id5"}), + (1, 2, 105, {"key": "data_key6", "id": "data_id7"}), + ] + ) + fh = io.BytesIO() + nx.write_graphml(G, fh) + fh.seek(0) + H = nx.read_graphml(fh, node_type=int) + assert edges_equal(G.edges(data=True, keys=True), H.edges(data=True, keys=True)) + assert G._adj == H._adj + + Gadj = { + str(node): { + str(nbr): {str(ekey): dd for ekey, dd in key_dict.items()} + for nbr, key_dict in nbr_dict.items() + } + for node, nbr_dict in G._adj.items() + } + fh.seek(0) + HH = nx.read_graphml(fh, node_type=str, edge_key_type=str) + assert Gadj == HH._adj + + fh.seek(0) + string_fh = fh.read() + HH = nx.parse_graphml(string_fh, node_type=str, edge_key_type=str) + assert Gadj == HH._adj + + def test_yfiles_extension(self): + data = """ + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + 2 + + + + + + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + +""" + fh = io.BytesIO(data.encode("UTF-8")) + G = nx.read_graphml(fh, force_multigraph=True) + assert list(G.edges()) == [("n0", "n1")] + assert G.has_edge("n0", "n1", key="e0") + assert G.nodes["n0"]["label"] == "1" + assert G.nodes["n1"]["label"] == "2" + assert G.nodes["n2"]["label"] == "3" + assert G.nodes["n0"]["shape_type"] == "rectangle" + assert G.nodes["n1"]["shape_type"] == "rectangle" + assert G.nodes["n2"]["shape_type"] == "com.yworks.flowchart.terminator" + assert G.nodes["n2"]["description"] == "description\nline1\nline2" + fh.seek(0) + G = nx.read_graphml(fh) + assert list(G.edges()) == [("n0", "n1")] + assert G["n0"]["n1"]["id"] == "e0" + assert G.nodes["n0"]["label"] == "1" + assert G.nodes["n1"]["label"] == "2" + assert G.nodes["n2"]["label"] == "3" + assert G.nodes["n0"]["shape_type"] == "rectangle" + assert G.nodes["n1"]["shape_type"] == "rectangle" + assert G.nodes["n2"]["shape_type"] == "com.yworks.flowchart.terminator" + assert G.nodes["n2"]["description"] == "description\nline1\nline2" + + H = nx.parse_graphml(data, force_multigraph=True) + assert list(H.edges()) == [("n0", "n1")] + assert H.has_edge("n0", "n1", key="e0") + assert H.nodes["n0"]["label"] == "1" + assert H.nodes["n1"]["label"] == "2" + assert H.nodes["n2"]["label"] == "3" + + H = nx.parse_graphml(data) + assert list(H.edges()) == [("n0", "n1")] + assert H["n0"]["n1"]["id"] == "e0" + assert H.nodes["n0"]["label"] == "1" + assert H.nodes["n1"]["label"] == "2" + assert H.nodes["n2"]["label"] == "3" + + def test_bool(self): + s = """ + + + false + + + + true + + + + false + + + FaLsE + + + True + + + 0 + + + 1 + + + +""" + fh = io.BytesIO(s.encode("UTF-8")) + G = nx.read_graphml(fh) + H = nx.parse_graphml(s) + for graph in [G, H]: + assert graph.nodes["n0"]["test"] + assert not graph.nodes["n2"]["test"] + assert not graph.nodes["n3"]["test"] + assert graph.nodes["n4"]["test"] + assert not graph.nodes["n5"]["test"] + assert graph.nodes["n6"]["test"] + + def test_graphml_header_line(self): + good = """ + + + false + + + + true + + + +""" + bad = """ + + + false + + + + true + + + +""" + ugly = """ + + + false + + + + true + + + +""" + for s in (good, bad): + fh = io.BytesIO(s.encode("UTF-8")) + G = nx.read_graphml(fh) + H = nx.parse_graphml(s) + for graph in [G, H]: + assert graph.nodes["n0"]["test"] + + fh = io.BytesIO(ugly.encode("UTF-8")) + pytest.raises(nx.NetworkXError, nx.read_graphml, fh) + pytest.raises(nx.NetworkXError, nx.parse_graphml, ugly) + + def test_read_attributes_with_groups(self): + data = """\ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + Group 3 + + + + + + + + + + Folder 3 + + + + + + + + + + + + + + + + + + + + + Group 1 + + + + + + + + + + Folder 1 + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + Group 2 + + + + + + + + + + Folder 2 + + + + + + + + + + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + 6 + + + + + + + + + + + + + + + + + + + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" + # verify that nodes / attributes are correctly read when part of a group + fh = io.BytesIO(data.encode("UTF-8")) + G = nx.read_graphml(fh) + data = [x for _, x in G.nodes(data=True)] + assert len(data) == 9 + for node_data in data: + assert node_data["CustomProperty"] != "" + + def test_long_attribute_type(self): + # test that graphs with attr.type="long" (as produced by botch and + # dose3) can be parsed + s = """ + + + + + 4284 + + +""" + fh = io.BytesIO(s.encode("UTF-8")) + G = nx.read_graphml(fh) + expected = [("n1", {"cudfversion": 4284})] + assert sorted(G.nodes(data=True)) == expected + fh.seek(0) + H = nx.parse_graphml(s) + assert sorted(H.nodes(data=True)) == expected + + +class TestWriteGraphML(BaseGraphML): + writer = staticmethod(nx.write_graphml_lxml) + + @classmethod + def setup_class(cls): + BaseGraphML.setup_class() + _ = pytest.importorskip("lxml.etree") + + def test_write_interface(self): + try: + import lxml.etree + + assert nx.write_graphml == nx.write_graphml_lxml + except ImportError: + assert nx.write_graphml == nx.write_graphml_xml + + def test_write_read_simple_directed_graphml(self): + G = self.simple_directed_graph + G.graph["hi"] = "there" + fh = io.BytesIO() + self.writer(G, fh) + fh.seek(0) + H = nx.read_graphml(fh) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(G.edges()) == sorted(H.edges()) + assert sorted(G.edges(data=True)) == sorted(H.edges(data=True)) + self.simple_directed_fh.seek(0) + + def test_GraphMLWriter_add_graphs(self): + gmlw = GraphMLWriter() + G = self.simple_directed_graph + H = G.copy() + gmlw.add_graphs([G, H]) + + def test_write_read_simple_no_prettyprint(self): + G = self.simple_directed_graph + G.graph["hi"] = "there" + G.graph["id"] = "1" + fh = io.BytesIO() + self.writer(G, fh, prettyprint=False) + fh.seek(0) + H = nx.read_graphml(fh) + assert sorted(G.nodes()) == sorted(H.nodes()) + assert sorted(G.edges()) == sorted(H.edges()) + assert sorted(G.edges(data=True)) == sorted(H.edges(data=True)) + self.simple_directed_fh.seek(0) + + def test_write_read_attribute_named_key_ids_graphml(self): + from xml.etree.ElementTree import parse + + G = self.attribute_named_key_ids_graph + fh = io.BytesIO() + self.writer(G, fh, named_key_ids=True) + fh.seek(0) + H = nx.read_graphml(fh) + fh.seek(0) + + assert nodes_equal(G.nodes(), H.nodes()) + assert edges_equal(G.edges(), H.edges(), directed=True) + assert edges_equal(G.edges(data=True), H.edges(data=True), directed=True) + self.attribute_named_key_ids_fh.seek(0) + + xml = parse(fh) + # Children are the key elements, and the graph element + children = list(xml.getroot()) + assert len(children) == 4 + + keys = [child.items() for child in children[:3]] + + assert len(keys) == 3 + assert ("id", "edge_prop") in keys[0] + assert ("attr.name", "edge_prop") in keys[0] + assert ("id", "prop2") in keys[1] + assert ("attr.name", "prop2") in keys[1] + assert ("id", "prop1") in keys[2] + assert ("attr.name", "prop1") in keys[2] + + # Confirm the read graph nodes/edge are identical when compared to + # default writing behavior. + default_behavior_fh = io.BytesIO() + nx.write_graphml(G, default_behavior_fh) + default_behavior_fh.seek(0) + H = nx.read_graphml(default_behavior_fh) + + named_key_ids_behavior_fh = io.BytesIO() + nx.write_graphml(G, named_key_ids_behavior_fh, named_key_ids=True) + named_key_ids_behavior_fh.seek(0) + J = nx.read_graphml(named_key_ids_behavior_fh) + + assert all(n1 == n2 for (n1, n2) in zip(H.nodes, J.nodes)) + assert all(e1 == e2 for (e1, e2) in zip(H.edges, J.edges)) + + def test_write_read_attribute_numeric_type_graphml(self): + from xml.etree.ElementTree import parse + + G = self.attribute_numeric_type_graph + fh = io.BytesIO() + self.writer(G, fh, infer_numeric_types=True) + fh.seek(0) + H = nx.read_graphml(fh) + fh.seek(0) + + assert nodes_equal(G.nodes(), H.nodes()) + assert edges_equal(G.edges(), H.edges(), directed=True) + assert edges_equal(G.edges(data=True), H.edges(data=True), directed=True) + self.attribute_numeric_type_fh.seek(0) + + xml = parse(fh) + # Children are the key elements, and the graph element + children = list(xml.getroot()) + assert len(children) == 3 + + keys = [child.items() for child in children[:2]] + + assert len(keys) == 2 + assert ("attr.type", "double") in keys[0] + assert ("attr.type", "double") in keys[1] + + def test_more_multigraph_keys(self, tmp_path): + """Writing keys as edge id attributes means keys become strings. + The original keys are stored as data, so read them back in + if `str(key) == edge_id` + This allows the adjacency to remain the same. + """ + G = nx.MultiGraph() + G.add_edges_from([("a", "b", 2), ("a", "b", 3)]) + fname = tmp_path / "test.graphml" + self.writer(G, fname) + H = nx.read_graphml(fname) + assert H.is_multigraph() + assert edges_equal(G.edges(keys=True), H.edges(keys=True)) + assert G._adj == H._adj + + def test_default_attribute(self): + G = nx.Graph(name="Fred") + G.add_node(1, label=1, color="green") + nx.add_path(G, [0, 1, 2, 3]) + G.add_edge(1, 2, weight=3) + G.graph["node_default"] = {"color": "yellow"} + G.graph["edge_default"] = {"weight": 7} + fh = io.BytesIO() + self.writer(G, fh) + fh.seek(0) + H = nx.read_graphml(fh, node_type=int) + assert nodes_equal(G.nodes(), H.nodes()) + assert edges_equal(G.edges(), H.edges()) + assert G.graph == H.graph + + def test_mixed_type_attributes(self): + G = nx.MultiGraph() + G.add_node("n0", special=False) + G.add_node("n1", special=0) + G.add_edge("n0", "n1", special=False) + G.add_edge("n0", "n1", special=0) + fh = io.BytesIO() + self.writer(G, fh) + fh.seek(0) + H = nx.read_graphml(fh) + assert not H.nodes["n0"]["special"] + assert H.nodes["n1"]["special"] == 0 + assert not H.edges["n0", "n1", 0]["special"] + assert H.edges["n0", "n1", 1]["special"] == 0 + + def test_str_number_mixed_type_attributes(self): + G = nx.MultiGraph() + G.add_node("n0", special="hello") + G.add_node("n1", special=0) + G.add_edge("n0", "n1", special="hello") + G.add_edge("n0", "n1", special=0) + fh = io.BytesIO() + self.writer(G, fh) + fh.seek(0) + H = nx.read_graphml(fh) + assert H.nodes["n0"]["special"] == "hello" + assert H.nodes["n1"]["special"] == 0 + assert H.edges["n0", "n1", 0]["special"] == "hello" + assert H.edges["n0", "n1", 1]["special"] == 0 + + def test_mixed_int_type_number_attributes(self): + np = pytest.importorskip("numpy") + G = nx.MultiGraph() + G.add_node("n0", special=np.int64(0)) + G.add_node("n1", special=1) + G.add_edge("n0", "n1", special=np.int64(2)) + G.add_edge("n0", "n1", special=3) + fh = io.BytesIO() + self.writer(G, fh) + fh.seek(0) + H = nx.read_graphml(fh) + assert H.nodes["n0"]["special"] == 0 + assert H.nodes["n1"]["special"] == 1 + assert H.edges["n0", "n1", 0]["special"] == 2 + assert H.edges["n0", "n1", 1]["special"] == 3 + + def test_multigraph_to_graph(self, tmp_path): + # test converting multigraph to graph if no parallel edges found + G = nx.MultiGraph() + G.add_edges_from([("a", "b", 2), ("b", "c", 3)]) # no multiedges + fname = tmp_path / "test.graphml" + self.writer(G, fname) + H = nx.read_graphml(fname) + assert not H.is_multigraph() + H = nx.read_graphml(fname, force_multigraph=True) + assert H.is_multigraph() + + # add a multiedge + G.add_edge("a", "b", "e-id") + fname = tmp_path / "test.graphml" + self.writer(G, fname) + H = nx.read_graphml(fname) + assert H.is_multigraph() + H = nx.read_graphml(fname, force_multigraph=True) + assert H.is_multigraph() + + def test_write_generate_edge_id_from_attribute(self, tmp_path): + from xml.etree.ElementTree import parse + + G = nx.Graph() + G.add_edges_from([("a", "b"), ("b", "c"), ("a", "c")]) + edge_attributes = {e: str(e) for e in G.edges} + nx.set_edge_attributes(G, edge_attributes, "eid") + fname = tmp_path / "test.graphml" + # set edge_id_from_attribute e.g. "eid" for write_graphml() + self.writer(G, fname, edge_id_from_attribute="eid") + # set edge_id_from_attribute e.g. "eid" for generate_graphml() + generator = nx.generate_graphml(G, edge_id_from_attribute="eid") + + H = nx.read_graphml(fname) + assert nodes_equal(G.nodes(), H.nodes()) + assert edges_equal(G.edges(), H.edges()) + # NetworkX adds explicit edge "id" from file as attribute + nx.set_edge_attributes(G, edge_attributes, "id") + assert edges_equal(G.edges(data=True), H.edges(data=True)) + + tree = parse(fname) + children = list(tree.getroot()) + assert len(children) == 2 + edge_ids = [ + edge.attrib["id"] + for edge in tree.getroot().findall( + ".//{http://graphml.graphdrawing.org/xmlns}edge" + ) + ] + # verify edge id value is equal to specified attribute value + assert sorted(edge_ids) == sorted(edge_attributes.values()) + + # check graphml generated from generate_graphml() + data = "".join(generator) + J = nx.parse_graphml(data) + assert sorted(G.nodes()) == sorted(J.nodes()) + assert sorted(G.edges()) == sorted(J.edges()) + # NetworkX adds explicit edge "id" from file as attribute + nx.set_edge_attributes(G, edge_attributes, "id") + assert edges_equal(G.edges(data=True), J.edges(data=True)) + + def test_multigraph_write_generate_edge_id_from_attribute(self, tmp_path): + from xml.etree.ElementTree import parse + + G = nx.MultiGraph() + G.add_edges_from([("a", "b"), ("b", "c"), ("a", "c"), ("a", "b")]) + edge_attributes = {e: str(e) for e in G.edges} + nx.set_edge_attributes(G, edge_attributes, "eid") + fname = tmp_path / "test.graphml" + # set edge_id_from_attribute e.g. "eid" for write_graphml() + self.writer(G, fname, edge_id_from_attribute="eid") + # set edge_id_from_attribute e.g. "eid" for generate_graphml() + generator = nx.generate_graphml(G, edge_id_from_attribute="eid") + + H = nx.read_graphml(fname) + assert H.is_multigraph() + H = nx.read_graphml(fname, force_multigraph=True) + assert H.is_multigraph() + + assert nodes_equal(G.nodes(), H.nodes()) + assert edges_equal(G.edges(), H.edges()) + assert sorted(data.get("eid") for u, v, data in H.edges(data=True)) == sorted( + edge_attributes.values() + ) + # NetworkX uses edge_ids as keys in multigraphs if no key + assert sorted(key for u, v, key in H.edges(keys=True)) == sorted( + edge_attributes.values() + ) + + tree = parse(fname) + children = list(tree.getroot()) + assert len(children) == 2 + edge_ids = [ + edge.attrib["id"] + for edge in tree.getroot().findall( + ".//{http://graphml.graphdrawing.org/xmlns}edge" + ) + ] + # verify edge id value is equal to specified attribute value + assert sorted(edge_ids) == sorted(edge_attributes.values()) + + # check graphml generated from generate_graphml() + graphml_data = "".join(generator) + J = nx.parse_graphml(graphml_data) + assert J.is_multigraph() + + assert nodes_equal(G.nodes(), J.nodes()) + assert edges_equal(G.edges(), J.edges()) + assert sorted(data.get("eid") for u, v, data in J.edges(data=True)) == sorted( + edge_attributes.values() + ) + # NetworkX uses edge_ids as keys in multigraphs if no key + assert sorted(key for u, v, key in J.edges(keys=True)) == sorted( + edge_attributes.values() + ) + + def test_numpy_float64(self, tmp_path): + np = pytest.importorskip("numpy") + wt = np.float64(3.4) + G = nx.Graph([(1, 2, {"weight": wt})]) + fname = tmp_path / "test.graphml" + self.writer(G, fname) + H = nx.read_graphml(fname, node_type=int) + assert G.edges == H.edges + wtG = G[1][2]["weight"] + wtH = H[1][2]["weight"] + assert wtG == pytest.approx(wtH, abs=1e-6) + assert type(wtG) is np.float64 + assert type(wtH) is float + + def test_numpy_float32(self, tmp_path): + np = pytest.importorskip("numpy") + wt = np.float32(3.4) + G = nx.Graph([(1, 2, {"weight": wt})]) + fname = tmp_path / "test.graphml" + self.writer(G, fname) + H = nx.read_graphml(fname, node_type=int) + assert G.edges == H.edges + wtG = G[1][2]["weight"] + wtH = H[1][2]["weight"] + assert wtG == pytest.approx(wtH, abs=1e-6) + assert type(wtG) is np.float32 + assert type(wtH) is float + + def test_numpy_float64_inference(self, tmp_path): + np = pytest.importorskip("numpy") + G = self.attribute_numeric_type_graph + G.edges[("n1", "n1")]["weight"] = np.float64(1.1) + fname = tmp_path / "test.graphml" + self.writer(G, fname, infer_numeric_types=True) + H = nx.read_graphml(fname) + assert G._adj == H._adj + + def test_unicode_attributes(self, tmp_path): + G = nx.Graph() + name1 = chr(2344) + chr(123) + chr(6543) + name2 = chr(5543) + chr(1543) + chr(324) + node_type = str + G.add_edge(name1, "Radiohead", foo=name2) + fname = tmp_path / "test.graphml" + self.writer(G, fname) + H = nx.read_graphml(fname, node_type=node_type) + assert G._adj == H._adj + + def test_unicode_escape(self): + # test for handling json escaped strings in python 2 Issue #1880 + import json + + a = {"a": '{"a": "123"}'} # an object with many chars to escape + sa = json.dumps(a) + G = nx.Graph() + G.graph["test"] = sa + fh = io.BytesIO() + self.writer(G, fh) + fh.seek(0) + H = nx.read_graphml(fh) + assert G.graph["test"] == H.graph["test"] + + +class TestXMLGraphML(TestWriteGraphML): + writer = staticmethod(nx.write_graphml_xml) + + @classmethod + def setup_class(cls): + TestWriteGraphML.setup_class() + + +def test_exception_for_unsupported_datatype_node_attr(): + """Test that a detailed exception is raised when an attribute is of a type + not supported by GraphML, e.g. a list""" + pytest.importorskip("lxml.etree") + # node attribute + G = nx.Graph() + G.add_node(0, my_list_attribute=[0, 1, 2]) + fh = io.BytesIO() + with pytest.raises(TypeError, match="GraphML does not support"): + nx.write_graphml(G, fh) + + +def test_exception_for_unsupported_datatype_edge_attr(): + """Test that a detailed exception is raised when an attribute is of a type + not supported by GraphML, e.g. a list""" + pytest.importorskip("lxml.etree") + # edge attribute + G = nx.Graph() + G.add_edge(0, 1, my_list_attribute=[0, 1, 2]) + fh = io.BytesIO() + with pytest.raises(TypeError, match="GraphML does not support"): + nx.write_graphml(G, fh) + + +def test_exception_for_unsupported_datatype_graph_attr(): + """Test that a detailed exception is raised when an attribute is of a type + not supported by GraphML, e.g. a list""" + pytest.importorskip("lxml.etree") + # graph attribute + G = nx.Graph() + G.graph["my_list_attribute"] = [0, 1, 2] + fh = io.BytesIO() + with pytest.raises(TypeError, match="GraphML does not support"): + nx.write_graphml(G, fh) + + +def test_empty_attribute(): + """Tests that a GraphML string with an empty attribute can be parsed + correctly.""" + s = """ + + + + + + aaa + bbb + + + ccc + + + + """ + fh = io.BytesIO(s.encode("UTF-8")) + G = nx.read_graphml(fh) + assert G.nodes["0"] == {"foo": "aaa", "bar": "bbb"} + assert G.nodes["1"] == {"foo": "ccc", "bar": ""} diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_leda.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_leda.py new file mode 100644 index 0000000000000000000000000000000000000000..8ac5ecc34bf9b42bd49e316bdc72e0e56c76a616 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_leda.py @@ -0,0 +1,30 @@ +import io + +import networkx as nx + + +class TestLEDA: + def test_parse_leda(self): + data = """#header section \nLEDA.GRAPH \nstring\nint\n-1\n#nodes section\n5 \n|{v1}| \n|{v2}| \n|{v3}| \n|{v4}| \n|{v5}| \n\n#edges section\n7 \n1 2 0 |{4}| \n1 3 0 |{3}| \n2 3 0 |{2}| \n3 4 0 |{3}| \n3 5 0 |{7}| \n4 5 0 |{6}| \n5 1 0 |{foo}|""" + G = nx.parse_leda(data) + G = nx.parse_leda(data.split("\n")) + assert sorted(G.nodes()) == ["v1", "v2", "v3", "v4", "v5"] + assert sorted(G.edges(data=True)) == [ + ("v1", "v2", {"label": "4"}), + ("v1", "v3", {"label": "3"}), + ("v2", "v3", {"label": "2"}), + ("v3", "v4", {"label": "3"}), + ("v3", "v5", {"label": "7"}), + ("v4", "v5", {"label": "6"}), + ("v5", "v1", {"label": "foo"}), + ] + + def test_read_LEDA(self): + fh = io.BytesIO() + data = """#header section \nLEDA.GRAPH \nstring\nint\n-1\n#nodes section\n5 \n|{v1}| \n|{v2}| \n|{v3}| \n|{v4}| \n|{v5}| \n\n#edges section\n7 \n1 2 0 |{4}| \n1 3 0 |{3}| \n2 3 0 |{2}| \n3 4 0 |{3}| \n3 5 0 |{7}| \n4 5 0 |{6}| \n5 1 0 |{foo}|""" + G = nx.parse_leda(data) + fh.write(data.encode("UTF-8")) + fh.seek(0) + Gin = nx.read_leda(fh) + assert sorted(G.nodes()) == sorted(Gin.nodes()) + assert sorted(G.edges()) == sorted(Gin.edges()) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_p2g.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_p2g.py new file mode 100644 index 0000000000000000000000000000000000000000..c6e36bfbca87db83a3732d737355f051e3821a1e --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_p2g.py @@ -0,0 +1,63 @@ +import io + +import networkx as nx +from networkx.readwrite.p2g import read_p2g, write_p2g +from networkx.utils import edges_equal + + +class TestP2G: + @classmethod + def setup_class(cls): + cls.G = nx.Graph(name="test") + e = [("a", "b"), ("b", "c"), ("c", "d"), ("d", "e"), ("e", "f"), ("a", "f")] + cls.G.add_edges_from(e) + cls.G.add_node("g") + cls.DG = nx.DiGraph(cls.G) + + def test_read_p2g(self): + s = b"""\ +name +3 4 +a +1 2 +b + +c +0 2 +""" + bytesIO = io.BytesIO(s) + DG = read_p2g(bytesIO) + assert DG.name == "name" + assert sorted(DG) == ["a", "b", "c"] + assert edges_equal( + DG.edges(), [("a", "c"), ("a", "b"), ("c", "a"), ("c", "c")], directed=True + ) + + def test_write_p2g(self): + s = b"""foo +3 2 +1 +1 +2 +2 +3 + +""" + fh = io.BytesIO() + G = nx.DiGraph() + G.name = "foo" + G.add_edges_from([(1, 2), (2, 3)]) + write_p2g(G, fh) + fh.seek(0) + r = fh.read() + assert r == s + + def test_write_read_p2g(self): + fh = io.BytesIO() + G = nx.DiGraph() + G.name = "foo" + G.add_edges_from([("a", "b"), ("b", "c")]) + write_p2g(G, fh) + fh.seek(0) + H = read_p2g(fh) + assert edges_equal(G.edges(), H.edges(), directed=True) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_pajek.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_pajek.py new file mode 100644 index 0000000000000000000000000000000000000000..9cce4d5a8c0fa120fe1239851046c41eb7eb7014 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_pajek.py @@ -0,0 +1,128 @@ +""" +Pajek tests +""" + +import networkx as nx +from networkx.utils import edges_equal, nodes_equal + + +class TestPajek: + @classmethod + def setup_class(cls): + cls.data = """*network Tralala\n*vertices 4\n 1 "A1" 0.0938 0.0896 ellipse x_fact 1 y_fact 1\n 2 "Bb" 0.8188 0.2458 ellipse x_fact 1 y_fact 1\n 3 "C" 0.3688 0.7792 ellipse x_fact 1\n 4 "D2" 0.9583 0.8563 ellipse x_fact 1\n*arcs\n1 1 1 h2 0 w 3 c Blue s 3 a1 -130 k1 0.6 a2 -130 k2 0.6 ap 0.5 l "Bezier loop" lc BlueViolet fos 20 lr 58 lp 0.3 la 360\n2 1 1 h2 0 a1 120 k1 1.3 a2 -120 k2 0.3 ap 25 l "Bezier arc" lphi 270 la 180 lr 19 lp 0.5\n1 2 1 h2 0 a1 40 k1 2.8 a2 30 k2 0.8 ap 25 l "Bezier arc" lphi 90 la 0 lp 0.65\n4 2 -1 h2 0 w 1 k1 -2 k2 250 ap 25 l "Circular arc" c Red lc OrangeRed\n3 4 1 p Dashed h2 0 w 2 c OliveGreen ap 25 l "Straight arc" lc PineGreen\n1 3 1 p Dashed h2 0 w 5 k1 -1 k2 -20 ap 25 l "Oval arc" c Brown lc Black\n3 3 -1 h1 6 w 1 h2 12 k1 -2 k2 -15 ap 0.5 l "Circular loop" c Red lc OrangeRed lphi 270 la 180""" + cls.G = nx.MultiDiGraph() + cls.G.add_nodes_from(["A1", "Bb", "C", "D2"]) + cls.G.add_edges_from( + [ + ("A1", "A1"), + ("A1", "Bb"), + ("A1", "C"), + ("Bb", "A1"), + ("C", "C"), + ("C", "D2"), + ("D2", "Bb"), + ] + ) + + cls.G.graph["name"] = "Tralala" + + def test_parse_pajek_simple(self): + # Example without node positions or shape + data = """*Vertices 2\n1 "1"\n2 "2"\n*Edges\n1 2\n2 1""" + G = nx.parse_pajek(data) + assert sorted(G.nodes()) == ["1", "2"] + assert edges_equal(G.edges(), [("1", "2"), ("1", "2")]) + + def test_parse_pajek(self): + G = nx.parse_pajek(self.data) + assert sorted(G.nodes()) == ["A1", "Bb", "C", "D2"] + assert edges_equal( + G.edges(), + [ + ("A1", "A1"), + ("A1", "Bb"), + ("A1", "C"), + ("Bb", "A1"), + ("C", "C"), + ("C", "D2"), + ("D2", "Bb"), + ], + directed=True, + ) + + def test_parse_pajek_mat(self): + data = """*Vertices 3\n1 "one"\n2 "two"\n3 "three"\n*Matrix\n1 1 0\n0 1 0\n0 1 0\n""" + G = nx.parse_pajek(data) + assert set(G.nodes()) == {"one", "two", "three"} + assert G.nodes["two"] == {"id": "2"} + assert edges_equal( + G.edges(), + [("one", "one"), ("one", "two"), ("two", "two"), ("three", "two")], + directed=True, + ) + + def test_read_pajek(self, tmp_path): + G = nx.parse_pajek(self.data) + # Read data from file + fname = tmp_path / "test.pjk" + with open(fname, "wb") as fh: + fh.write(self.data.encode("UTF-8")) + + Gin = nx.read_pajek(fname) + assert sorted(G.nodes()) == sorted(Gin.nodes()) + assert edges_equal(G.edges(), Gin.edges(), directed=True) + assert self.G.graph == Gin.graph + for n in G: + assert G.nodes[n] == Gin.nodes[n] + + def test_write_pajek(self): + import io + + G = nx.parse_pajek(self.data) + fh = io.BytesIO() + nx.write_pajek(G, fh) + fh.seek(0) + H = nx.read_pajek(fh) + assert nodes_equal(list(G), list(H)) + assert edges_equal(G.edges(), H.edges(), directed=True) + # Graph name is left out for now, therefore it is not tested. + # assert_equal(G.graph, H.graph) + + def test_ignored_attribute(self): + import io + + G = nx.Graph() + fh = io.BytesIO() + G.add_node(1, int_attr=1) + G.add_node(2, empty_attr=" ") + G.add_edge(1, 2, int_attr=2) + G.add_edge(2, 3, empty_attr=" ") + + import warnings + + with warnings.catch_warnings(record=True) as w: + nx.write_pajek(G, fh) + assert len(w) == 4 + + def test_noname(self): + # Make sure we can parse a line such as: *network + # Issue #952 + line = "*network\n" + other_lines = self.data.split("\n")[1:] + data = line + "\n".join(other_lines) + G = nx.parse_pajek(data) + + def test_unicode(self): + import io + + G = nx.Graph() + name1 = chr(2344) + chr(123) + chr(6543) + name2 = chr(5543) + chr(1543) + chr(324) + G.add_edge(name1, "Radiohead", foo=name2) + fh = io.BytesIO() + nx.write_pajek(G, fh) + fh.seek(0) + H = nx.read_pajek(fh) + assert nodes_equal(list(G), list(H)) + assert edges_equal(list(G.edges()), list(H.edges())) + assert G.graph == H.graph diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_sparse6.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_sparse6.py new file mode 100644 index 0000000000000000000000000000000000000000..52cd271d060bd00a4c70e0e21fbdb33990078951 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_sparse6.py @@ -0,0 +1,166 @@ +from io import BytesIO + +import pytest + +import networkx as nx +from networkx.utils import edges_equal, nodes_equal + + +class TestSparseGraph6: + def test_from_sparse6_bytes(self): + data = b":Q___eDcdFcDeFcE`GaJ`IaHbKNbLM" + G = nx.from_sparse6_bytes(data) + assert nodes_equal( + sorted(G.nodes()), + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], + ) + assert edges_equal( + G.edges(), + [ + (0, 1), + (0, 2), + (0, 3), + (1, 12), + (1, 14), + (2, 13), + (2, 15), + (3, 16), + (3, 17), + (4, 7), + (4, 9), + (4, 11), + (5, 6), + (5, 8), + (5, 9), + (6, 10), + (6, 11), + (7, 8), + (7, 10), + (8, 12), + (9, 15), + (10, 14), + (11, 13), + (12, 16), + (13, 17), + (14, 17), + (15, 16), + ], + ) + + def test_from_bytes_multigraph_graph(self): + graph_data = b":An" + G = nx.from_sparse6_bytes(graph_data) + assert isinstance(G, nx.Graph) + multigraph_data = b":Ab" + M = nx.from_sparse6_bytes(multigraph_data) + assert isinstance(M, nx.MultiGraph) + + def test_read_sparse6(self): + data = b":Q___eDcdFcDeFcE`GaJ`IaHbKNbLM" + G = nx.from_sparse6_bytes(data) + fh = BytesIO(data) + Gin = nx.read_sparse6(fh) + assert nodes_equal(G.nodes(), Gin.nodes()) + assert edges_equal(G.edges(), Gin.edges()) + + def test_read_many_graph6(self): + # Read many graphs into list + data = b":Q___eDcdFcDeFcE`GaJ`IaHbKNbLM\n:Q___dCfDEdcEgcbEGbFIaJ`JaHN`IM" + fh = BytesIO(data) + glist = nx.read_sparse6(fh) + assert len(glist) == 2 + for G in glist: + assert nodes_equal( + G.nodes(), + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], + ) + + +class TestWriteSparse6: + """Unit tests for writing graphs in the sparse6 format. + + Most of the test cases were checked against the sparse6 encoder in Sage. + + """ + + def test_null_graph(self): + G = nx.null_graph() + result = BytesIO() + nx.write_sparse6(G, result) + assert result.getvalue() == b">>sparse6<<:?\n" + + def test_trivial_graph(self): + G = nx.trivial_graph() + result = BytesIO() + nx.write_sparse6(G, result) + assert result.getvalue() == b">>sparse6<<:@\n" + + def test_empty_graph(self): + G = nx.empty_graph(5) + result = BytesIO() + nx.write_sparse6(G, result) + assert result.getvalue() == b">>sparse6<<:D\n" + + def test_large_empty_graph(self): + G = nx.empty_graph(68) + result = BytesIO() + nx.write_sparse6(G, result) + assert result.getvalue() == b">>sparse6<<:~?@C\n" + + def test_very_large_empty_graph(self): + G = nx.empty_graph(258049) + result = BytesIO() + nx.write_sparse6(G, result) + assert result.getvalue() == b">>sparse6<<:~~???~?@\n" + + def test_complete_graph(self): + G = nx.complete_graph(4) + result = BytesIO() + nx.write_sparse6(G, result) + assert result.getvalue() == b">>sparse6<<:CcKI\n" + + def test_no_header(self): + G = nx.complete_graph(4) + result = BytesIO() + nx.write_sparse6(G, result, header=False) + assert result.getvalue() == b":CcKI\n" + + def test_padding(self): + codes = (b":Cdv", b":DaYn", b":EaYnN", b":FaYnL", b":GaYnLz") + for n, code in enumerate(codes, start=4): + G = nx.path_graph(n) + result = BytesIO() + nx.write_sparse6(G, result, header=False) + assert result.getvalue() == code + b"\n" + + def test_complete_bipartite(self): + G = nx.complete_bipartite_graph(6, 9) + result = BytesIO() + nx.write_sparse6(G, result) + # Compared with sage + expected = b">>sparse6<<:Nk" + b"?G`cJ" * 9 + b"\n" + assert result.getvalue() == expected + + def test_read_write_inverse(self): + for i in list(range(13)) + [31, 47, 62, 63, 64, 72]: + m = min(2 * i, i * i // 2) + g = nx.random_graphs.gnm_random_graph(i, m, seed=i) + gstr = BytesIO() + nx.write_sparse6(g, gstr, header=False) + # Strip the trailing newline. + gstr = gstr.getvalue().rstrip() + g2 = nx.from_sparse6_bytes(gstr) + assert g2.order() == g.order() + assert edges_equal(g2.edges(), g.edges()) + + def test_no_directed_graphs(self): + with pytest.raises(nx.NetworkXNotImplemented): + nx.write_sparse6(nx.DiGraph(), BytesIO()) + + def test_write_path(self, tmp_path): + # Get a valid temporary file name + fullfilename = str(tmp_path / "test.s6") + # file should be closed now, so write_sparse6 can open it + nx.write_sparse6(nx.null_graph(), fullfilename) + with open(fullfilename, mode="rb") as fh: + assert fh.read() == b">>sparse6<<:?\n" diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_text.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_text.py new file mode 100644 index 0000000000000000000000000000000000000000..b2b744828c916a37784059c869cc990a2473305a --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/readwrite/tests/test_text.py @@ -0,0 +1,1742 @@ +import random +from itertools import product +from textwrap import dedent + +import pytest + +import networkx as nx + + +def test_generate_network_text_forest_directed(): + # Create a directed forest with labels + graph = nx.balanced_tree(r=2, h=2, create_using=nx.DiGraph) + for node in graph.nodes: + graph.nodes[node]["label"] = "node_" + chr(ord("a") + node) + + node_target = dedent( + """ + ╙── 0 + ├─╼ 1 + │ ├─╼ 3 + │ └─╼ 4 + └─╼ 2 + ├─╼ 5 + └─╼ 6 + """ + ).strip() + + label_target = dedent( + """ + ╙── node_a + ├─╼ node_b + │ ├─╼ node_d + │ └─╼ node_e + └─╼ node_c + ├─╼ node_f + └─╼ node_g + """ + ).strip() + + # Basic node case + ret = nx.generate_network_text(graph, with_labels=False) + assert "\n".join(ret) == node_target + + # Basic label case + ret = nx.generate_network_text(graph, with_labels=True) + assert "\n".join(ret) == label_target + + +def test_write_network_text_empty_graph(): + def _graph_str(g, **kw): + printbuf = [] + nx.write_network_text(g, printbuf.append, end="", **kw) + return "\n".join(printbuf) + + assert _graph_str(nx.DiGraph()) == "╙" + assert _graph_str(nx.Graph()) == "╙" + assert _graph_str(nx.DiGraph(), ascii_only=True) == "+" + assert _graph_str(nx.Graph(), ascii_only=True) == "+" + + +def test_write_network_text_within_forest_glyph(): + g = nx.DiGraph() + g.add_nodes_from([1, 2, 3, 4]) + g.add_edge(2, 4) + lines = [] + write = lines.append + nx.write_network_text(g, path=write, end="") + nx.write_network_text(g, path=write, ascii_only=True, end="") + text = "\n".join(lines) + target = dedent( + """ + ╟── 1 + ╟── 2 + ╎ └─╼ 4 + ╙── 3 + +-- 1 + +-- 2 + : L-> 4 + +-- 3 + """ + ).strip() + assert text == target + + +def test_generate_network_text_directed_multi_tree(): + tree1 = nx.balanced_tree(r=2, h=2, create_using=nx.DiGraph) + tree2 = nx.balanced_tree(r=2, h=2, create_using=nx.DiGraph) + forest = nx.disjoint_union_all([tree1, tree2]) + ret = "\n".join(nx.generate_network_text(forest)) + + target = dedent( + """ + ╟── 0 + ╎ ├─╼ 1 + ╎ │ ├─╼ 3 + ╎ │ └─╼ 4 + ╎ └─╼ 2 + ╎ ├─╼ 5 + ╎ └─╼ 6 + ╙── 7 + ├─╼ 8 + │ ├─╼ 10 + │ └─╼ 11 + └─╼ 9 + ├─╼ 12 + └─╼ 13 + """ + ).strip() + assert ret == target + + tree3 = nx.balanced_tree(r=2, h=2, create_using=nx.DiGraph) + forest = nx.disjoint_union_all([tree1, tree2, tree3]) + ret = "\n".join(nx.generate_network_text(forest, sources=[0, 14, 7])) + + target = dedent( + """ + ╟── 0 + ╎ ├─╼ 1 + ╎ │ ├─╼ 3 + ╎ │ └─╼ 4 + ╎ └─╼ 2 + ╎ ├─╼ 5 + ╎ └─╼ 6 + ╟── 14 + ╎ ├─╼ 15 + ╎ │ ├─╼ 17 + ╎ │ └─╼ 18 + ╎ └─╼ 16 + ╎ ├─╼ 19 + ╎ └─╼ 20 + ╙── 7 + ├─╼ 8 + │ ├─╼ 10 + │ └─╼ 11 + └─╼ 9 + ├─╼ 12 + └─╼ 13 + """ + ).strip() + assert ret == target + + ret = "\n".join( + nx.generate_network_text(forest, sources=[0, 14, 7], ascii_only=True) + ) + + target = dedent( + """ + +-- 0 + : |-> 1 + : | |-> 3 + : | L-> 4 + : L-> 2 + : |-> 5 + : L-> 6 + +-- 14 + : |-> 15 + : | |-> 17 + : | L-> 18 + : L-> 16 + : |-> 19 + : L-> 20 + +-- 7 + |-> 8 + | |-> 10 + | L-> 11 + L-> 9 + |-> 12 + L-> 13 + """ + ).strip() + assert ret == target + + +def test_generate_network_text_undirected_multi_tree(): + tree1 = nx.balanced_tree(r=2, h=2, create_using=nx.Graph) + tree2 = nx.balanced_tree(r=2, h=2, create_using=nx.Graph) + tree2 = nx.relabel_nodes(tree2, {n: n + len(tree1) for n in tree2.nodes}) + forest = nx.union(tree1, tree2) + ret = "\n".join(nx.generate_network_text(forest, sources=[0, 7])) + + target = dedent( + """ + ╟── 0 + ╎ ├── 1 + ╎ │ ├── 3 + ╎ │ └── 4 + ╎ └── 2 + ╎ ├── 5 + ╎ └── 6 + ╙── 7 + ├── 8 + │ ├── 10 + │ └── 11 + └── 9 + ├── 12 + └── 13 + """ + ).strip() + assert ret == target + + ret = "\n".join(nx.generate_network_text(forest, sources=[0, 7], ascii_only=True)) + + target = dedent( + """ + +-- 0 + : |-- 1 + : | |-- 3 + : | L-- 4 + : L-- 2 + : |-- 5 + : L-- 6 + +-- 7 + |-- 8 + | |-- 10 + | L-- 11 + L-- 9 + |-- 12 + L-- 13 + """ + ).strip() + assert ret == target + + +def test_generate_network_text_forest_undirected(): + # Create a directed forest + graph = nx.balanced_tree(r=2, h=2, create_using=nx.Graph) + + node_target0 = dedent( + """ + ╙── 0 + ├── 1 + │ ├── 3 + │ └── 4 + └── 2 + ├── 5 + └── 6 + """ + ).strip() + + # defined starting point + ret = "\n".join(nx.generate_network_text(graph, sources=[0])) + assert ret == node_target0 + + # defined starting point + node_target2 = dedent( + """ + ╙── 2 + ├── 0 + │ └── 1 + │ ├── 3 + │ └── 4 + ├── 5 + └── 6 + """ + ).strip() + ret = "\n".join(nx.generate_network_text(graph, sources=[2])) + assert ret == node_target2 + + +def test_generate_network_text_overspecified_sources(): + """ + When sources are directly specified, we won't be able to determine when we + are in the last component, so there will always be a trailing, leftmost + pipe. + """ + graph = nx.disjoint_union_all( + [ + nx.balanced_tree(r=2, h=1, create_using=nx.DiGraph), + nx.balanced_tree(r=1, h=2, create_using=nx.DiGraph), + nx.balanced_tree(r=2, h=1, create_using=nx.DiGraph), + ] + ) + + # defined starting point + target1 = dedent( + """ + ╟── 0 + ╎ ├─╼ 1 + ╎ └─╼ 2 + ╟── 3 + ╎ └─╼ 4 + ╎ └─╼ 5 + ╟── 6 + ╎ ├─╼ 7 + ╎ └─╼ 8 + """ + ).strip() + + target2 = dedent( + """ + ╟── 0 + ╎ ├─╼ 1 + ╎ └─╼ 2 + ╟── 3 + ╎ └─╼ 4 + ╎ └─╼ 5 + ╙── 6 + ├─╼ 7 + └─╼ 8 + """ + ).strip() + + got1 = "\n".join(nx.generate_network_text(graph, sources=graph.nodes)) + got2 = "\n".join(nx.generate_network_text(graph)) + assert got1 == target1 + assert got2 == target2 + + +def test_write_network_text_iterative_add_directed_edges(): + """ + Walk through the cases going from a disconnected to fully connected graph + """ + graph = nx.DiGraph() + graph.add_nodes_from([1, 2, 3, 4]) + lines = [] + write = lines.append + write("--- initial state ---") + nx.write_network_text(graph, path=write, end="") + for i, j in product(graph.nodes, graph.nodes): + write(f"--- add_edge({i}, {j}) ---") + graph.add_edge(i, j) + nx.write_network_text(graph, path=write, end="") + text = "\n".join(lines) + # defined starting point + target = dedent( + """ + --- initial state --- + ╟── 1 + ╟── 2 + ╟── 3 + ╙── 4 + --- add_edge(1, 1) --- + ╟── 1 ╾ 1 + ╎ └─╼ ... + ╟── 2 + ╟── 3 + ╙── 4 + --- add_edge(1, 2) --- + ╟── 1 ╾ 1 + ╎ ├─╼ 2 + ╎ └─╼ ... + ╟── 3 + ╙── 4 + --- add_edge(1, 3) --- + ╟── 1 ╾ 1 + ╎ ├─╼ 2 + ╎ ├─╼ 3 + ╎ └─╼ ... + ╙── 4 + --- add_edge(1, 4) --- + ╙── 1 ╾ 1 + ├─╼ 2 + ├─╼ 3 + ├─╼ 4 + └─╼ ... + --- add_edge(2, 1) --- + ╙── 2 ╾ 1 + └─╼ 1 ╾ 1 + ├─╼ 3 + ├─╼ 4 + └─╼ ... + --- add_edge(2, 2) --- + ╙── 1 ╾ 1, 2 + ├─╼ 2 ╾ 2 + │ └─╼ ... + ├─╼ 3 + ├─╼ 4 + └─╼ ... + --- add_edge(2, 3) --- + ╙── 1 ╾ 1, 2 + ├─╼ 2 ╾ 2 + │ ├─╼ 3 ╾ 1 + │ └─╼ ... + ├─╼ 4 + └─╼ ... + --- add_edge(2, 4) --- + ╙── 1 ╾ 1, 2 + ├─╼ 2 ╾ 2 + │ ├─╼ 3 ╾ 1 + │ ├─╼ 4 ╾ 1 + │ └─╼ ... + └─╼ ... + --- add_edge(3, 1) --- + ╙── 2 ╾ 1, 2 + ├─╼ 1 ╾ 1, 3 + │ ├─╼ 3 ╾ 2 + │ │ └─╼ ... + │ ├─╼ 4 ╾ 2 + │ └─╼ ... + └─╼ ... + --- add_edge(3, 2) --- + ╙── 3 ╾ 1, 2 + ├─╼ 1 ╾ 1, 2 + │ ├─╼ 2 ╾ 2, 3 + │ │ ├─╼ 4 ╾ 1 + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- add_edge(3, 3) --- + ╙── 1 ╾ 1, 2, 3 + ├─╼ 2 ╾ 2, 3 + │ ├─╼ 3 ╾ 1, 3 + │ │ └─╼ ... + │ ├─╼ 4 ╾ 1 + │ └─╼ ... + └─╼ ... + --- add_edge(3, 4) --- + ╙── 1 ╾ 1, 2, 3 + ├─╼ 2 ╾ 2, 3 + │ ├─╼ 3 ╾ 1, 3 + │ │ ├─╼ 4 ╾ 1, 2 + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- add_edge(4, 1) --- + ╙── 2 ╾ 1, 2, 3 + ├─╼ 1 ╾ 1, 3, 4 + │ ├─╼ 3 ╾ 2, 3 + │ │ ├─╼ 4 ╾ 1, 2 + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- add_edge(4, 2) --- + ╙── 3 ╾ 1, 2, 3 + ├─╼ 1 ╾ 1, 2, 4 + │ ├─╼ 2 ╾ 2, 3, 4 + │ │ ├─╼ 4 ╾ 1, 3 + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- add_edge(4, 3) --- + ╙── 4 ╾ 1, 2, 3 + ├─╼ 1 ╾ 1, 2, 3 + │ ├─╼ 2 ╾ 2, 3, 4 + │ │ ├─╼ 3 ╾ 1, 3, 4 + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- add_edge(4, 4) --- + ╙── 1 ╾ 1, 2, 3, 4 + ├─╼ 2 ╾ 2, 3, 4 + │ ├─╼ 3 ╾ 1, 3, 4 + │ │ ├─╼ 4 ╾ 1, 2, 4 + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + """ + ).strip() + assert target == text + + +def test_write_network_text_iterative_add_undirected_edges(): + """ + Walk through the cases going from a disconnected to fully connected graph + """ + graph = nx.Graph() + graph.add_nodes_from([1, 2, 3, 4]) + lines = [] + write = lines.append + write("--- initial state ---") + nx.write_network_text(graph, path=write, end="") + for i, j in product(graph.nodes, graph.nodes): + if i == j: + continue + write(f"--- add_edge({i}, {j}) ---") + graph.add_edge(i, j) + nx.write_network_text(graph, path=write, end="") + text = "\n".join(lines) + target = dedent( + """ + --- initial state --- + ╟── 1 + ╟── 2 + ╟── 3 + ╙── 4 + --- add_edge(1, 2) --- + ╟── 3 + ╟── 4 + ╙── 1 + └── 2 + --- add_edge(1, 3) --- + ╟── 4 + ╙── 2 + └── 1 + └── 3 + --- add_edge(1, 4) --- + ╙── 2 + └── 1 + ├── 3 + └── 4 + --- add_edge(2, 1) --- + ╙── 2 + └── 1 + ├── 3 + └── 4 + --- add_edge(2, 3) --- + ╙── 4 + └── 1 + ├── 2 + │ └── 3 ─ 1 + └── ... + --- add_edge(2, 4) --- + ╙── 3 + ├── 1 + │ ├── 2 ─ 3 + │ │ └── 4 ─ 1 + │ └── ... + └── ... + --- add_edge(3, 1) --- + ╙── 3 + ├── 1 + │ ├── 2 ─ 3 + │ │ └── 4 ─ 1 + │ └── ... + └── ... + --- add_edge(3, 2) --- + ╙── 3 + ├── 1 + │ ├── 2 ─ 3 + │ │ └── 4 ─ 1 + │ └── ... + └── ... + --- add_edge(3, 4) --- + ╙── 1 + ├── 2 + │ ├── 3 ─ 1 + │ │ └── 4 ─ 1, 2 + │ └── ... + └── ... + --- add_edge(4, 1) --- + ╙── 1 + ├── 2 + │ ├── 3 ─ 1 + │ │ └── 4 ─ 1, 2 + │ └── ... + └── ... + --- add_edge(4, 2) --- + ╙── 1 + ├── 2 + │ ├── 3 ─ 1 + │ │ └── 4 ─ 1, 2 + │ └── ... + └── ... + --- add_edge(4, 3) --- + ╙── 1 + ├── 2 + │ ├── 3 ─ 1 + │ │ └── 4 ─ 1, 2 + │ └── ... + └── ... + """ + ).strip() + assert target == text + + +def test_write_network_text_iterative_add_random_directed_edges(): + """ + Walk through the cases going from a disconnected to fully connected graph + """ + + rng = random.Random(724466096) + graph = nx.DiGraph() + graph.add_nodes_from([1, 2, 3, 4, 5]) + possible_edges = list(product(graph.nodes, graph.nodes)) + rng.shuffle(possible_edges) + graph.add_edges_from(possible_edges[0:8]) + lines = [] + write = lines.append + write("--- initial state ---") + nx.write_network_text(graph, path=write, end="") + for i, j in possible_edges[8:12]: + write(f"--- add_edge({i}, {j}) ---") + graph.add_edge(i, j) + nx.write_network_text(graph, path=write, end="") + text = "\n".join(lines) + target = dedent( + """ + --- initial state --- + ╙── 3 ╾ 5 + └─╼ 2 ╾ 2 + ├─╼ 4 ╾ 4 + │ ├─╼ 5 + │ │ ├─╼ 1 ╾ 1 + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- add_edge(4, 1) --- + ╙── 3 ╾ 5 + └─╼ 2 ╾ 2 + ├─╼ 4 ╾ 4 + │ ├─╼ 5 + │ │ ├─╼ 1 ╾ 1, 4 + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- add_edge(2, 1) --- + ╙── 3 ╾ 5 + └─╼ 2 ╾ 2 + ├─╼ 4 ╾ 4 + │ ├─╼ 5 + │ │ ├─╼ 1 ╾ 1, 4, 2 + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- add_edge(5, 2) --- + ╙── 3 ╾ 5 + └─╼ 2 ╾ 2, 5 + ├─╼ 4 ╾ 4 + │ ├─╼ 5 + │ │ ├─╼ 1 ╾ 1, 4, 2 + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- add_edge(1, 5) --- + ╙── 3 ╾ 5 + └─╼ 2 ╾ 2, 5 + ├─╼ 4 ╾ 4 + │ ├─╼ 5 ╾ 1 + │ │ ├─╼ 1 ╾ 1, 4, 2 + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + + """ + ).strip() + assert target == text + + +def test_write_network_text_nearly_forest(): + g = nx.DiGraph() + g.add_edge(1, 2) + g.add_edge(1, 5) + g.add_edge(2, 3) + g.add_edge(3, 4) + g.add_edge(5, 6) + g.add_edge(6, 7) + g.add_edge(6, 8) + orig = g.copy() + g.add_edge(1, 8) # forward edge + g.add_edge(4, 2) # back edge + g.add_edge(6, 3) # cross edge + lines = [] + write = lines.append + write("--- directed case ---") + nx.write_network_text(orig, path=write, end="") + write("--- add (1, 8), (4, 2), (6, 3) ---") + nx.write_network_text(g, path=write, end="") + write("--- undirected case ---") + nx.write_network_text(orig.to_undirected(), path=write, sources=[1], end="") + write("--- add (1, 8), (4, 2), (6, 3) ---") + nx.write_network_text(g.to_undirected(), path=write, sources=[1], end="") + text = "\n".join(lines) + target = dedent( + """ + --- directed case --- + ╙── 1 + ├─╼ 2 + │ └─╼ 3 + │ └─╼ 4 + └─╼ 5 + └─╼ 6 + ├─╼ 7 + └─╼ 8 + --- add (1, 8), (4, 2), (6, 3) --- + ╙── 1 + ├─╼ 2 ╾ 4 + │ └─╼ 3 ╾ 6 + │ └─╼ 4 + │ └─╼ ... + ├─╼ 5 + │ └─╼ 6 + │ ├─╼ 7 + │ ├─╼ 8 ╾ 1 + │ └─╼ ... + └─╼ ... + --- undirected case --- + ╙── 1 + ├── 2 + │ └── 3 + │ └── 4 + └── 5 + └── 6 + ├── 7 + └── 8 + --- add (1, 8), (4, 2), (6, 3) --- + ╙── 1 + ├── 2 + │ ├── 3 + │ │ ├── 4 ─ 2 + │ │ └── 6 + │ │ ├── 5 ─ 1 + │ │ ├── 7 + │ │ └── 8 ─ 1 + │ └── ... + └── ... + """ + ).strip() + assert target == text + + +def test_write_network_text_complete_graph_ascii_only(): + graph = nx.generators.complete_graph(5, create_using=nx.DiGraph) + lines = [] + write = lines.append + write("--- directed case ---") + nx.write_network_text(graph, path=write, ascii_only=True, end="") + write("--- undirected case ---") + nx.write_network_text(graph.to_undirected(), path=write, ascii_only=True, end="") + text = "\n".join(lines) + target = dedent( + """ + --- directed case --- + +-- 0 <- 1, 2, 3, 4 + |-> 1 <- 2, 3, 4 + | |-> 2 <- 0, 3, 4 + | | |-> 3 <- 0, 1, 4 + | | | |-> 4 <- 0, 1, 2 + | | | | L-> ... + | | | L-> ... + | | L-> ... + | L-> ... + L-> ... + --- undirected case --- + +-- 0 + |-- 1 + | |-- 2 - 0 + | | |-- 3 - 0, 1 + | | | L-- 4 - 0, 1, 2 + | | L-- ... + | L-- ... + L-- ... + """ + ).strip() + assert target == text + + +def test_write_network_text_with_labels(): + graph = nx.generators.complete_graph(5, create_using=nx.DiGraph) + for n in graph.nodes: + graph.nodes[n]["label"] = f"Node(n={n})" + lines = [] + write = lines.append + nx.write_network_text(graph, path=write, with_labels=True, ascii_only=False, end="") + text = "\n".join(lines) + # Non trees with labels can get somewhat out of hand with network text + # because we need to immediately show every non-tree edge to the right + target = dedent( + """ + ╙── Node(n=0) ╾ Node(n=1), Node(n=2), Node(n=3), Node(n=4) + ├─╼ Node(n=1) ╾ Node(n=2), Node(n=3), Node(n=4) + │ ├─╼ Node(n=2) ╾ Node(n=0), Node(n=3), Node(n=4) + │ │ ├─╼ Node(n=3) ╾ Node(n=0), Node(n=1), Node(n=4) + │ │ │ ├─╼ Node(n=4) ╾ Node(n=0), Node(n=1), Node(n=2) + │ │ │ │ └─╼ ... + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + """ + ).strip() + assert target == text + + +def test_write_network_text_complete_graphs(): + lines = [] + write = lines.append + for k in [0, 1, 2, 3, 4, 5]: + g = nx.generators.complete_graph(k) + write(f"--- undirected k={k} ---") + nx.write_network_text(g, path=write, end="") + + for k in [0, 1, 2, 3, 4, 5]: + g = nx.generators.complete_graph(k, nx.DiGraph) + write(f"--- directed k={k} ---") + nx.write_network_text(g, path=write, end="") + text = "\n".join(lines) + target = dedent( + """ + --- undirected k=0 --- + ╙ + --- undirected k=1 --- + ╙── 0 + --- undirected k=2 --- + ╙── 0 + └── 1 + --- undirected k=3 --- + ╙── 0 + ├── 1 + │ └── 2 ─ 0 + └── ... + --- undirected k=4 --- + ╙── 0 + ├── 1 + │ ├── 2 ─ 0 + │ │ └── 3 ─ 0, 1 + │ └── ... + └── ... + --- undirected k=5 --- + ╙── 0 + ├── 1 + │ ├── 2 ─ 0 + │ │ ├── 3 ─ 0, 1 + │ │ │ └── 4 ─ 0, 1, 2 + │ │ └── ... + │ └── ... + └── ... + --- directed k=0 --- + ╙ + --- directed k=1 --- + ╙── 0 + --- directed k=2 --- + ╙── 0 ╾ 1 + └─╼ 1 + └─╼ ... + --- directed k=3 --- + ╙── 0 ╾ 1, 2 + ├─╼ 1 ╾ 2 + │ ├─╼ 2 ╾ 0 + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- directed k=4 --- + ╙── 0 ╾ 1, 2, 3 + ├─╼ 1 ╾ 2, 3 + │ ├─╼ 2 ╾ 0, 3 + │ │ ├─╼ 3 ╾ 0, 1 + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- directed k=5 --- + ╙── 0 ╾ 1, 2, 3, 4 + ├─╼ 1 ╾ 2, 3, 4 + │ ├─╼ 2 ╾ 0, 3, 4 + │ │ ├─╼ 3 ╾ 0, 1, 4 + │ │ │ ├─╼ 4 ╾ 0, 1, 2 + │ │ │ │ └─╼ ... + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + """ + ).strip() + assert target == text + + +def test_write_network_text_multiple_sources(): + g = nx.DiGraph() + g.add_edge(1, 2) + g.add_edge(1, 3) + g.add_edge(2, 4) + g.add_edge(3, 5) + g.add_edge(3, 6) + g.add_edge(5, 4) + g.add_edge(4, 1) + g.add_edge(1, 5) + lines = [] + write = lines.append + # Use each node as the starting point to demonstrate how the representation + # changes. + nodes = sorted(g.nodes()) + for n in nodes: + write(f"--- source node: {n} ---") + nx.write_network_text(g, path=write, sources=[n], end="") + text = "\n".join(lines) + target = dedent( + """ + --- source node: 1 --- + ╙── 1 ╾ 4 + ├─╼ 2 + │ └─╼ 4 ╾ 5 + │ └─╼ ... + ├─╼ 3 + │ ├─╼ 5 ╾ 1 + │ │ └─╼ ... + │ └─╼ 6 + └─╼ ... + --- source node: 2 --- + ╙── 2 ╾ 1 + └─╼ 4 ╾ 5 + └─╼ 1 + ├─╼ 3 + │ ├─╼ 5 ╾ 1 + │ │ └─╼ ... + │ └─╼ 6 + └─╼ ... + --- source node: 3 --- + ╙── 3 ╾ 1 + ├─╼ 5 ╾ 1 + │ └─╼ 4 ╾ 2 + │ └─╼ 1 + │ ├─╼ 2 + │ │ └─╼ ... + │ └─╼ ... + └─╼ 6 + --- source node: 4 --- + ╙── 4 ╾ 2, 5 + └─╼ 1 + ├─╼ 2 + │ └─╼ ... + ├─╼ 3 + │ ├─╼ 5 ╾ 1 + │ │ └─╼ ... + │ └─╼ 6 + └─╼ ... + --- source node: 5 --- + ╙── 5 ╾ 3, 1 + └─╼ 4 ╾ 2 + └─╼ 1 + ├─╼ 2 + │ └─╼ ... + ├─╼ 3 + │ ├─╼ 6 + │ └─╼ ... + └─╼ ... + --- source node: 6 --- + ╙── 6 ╾ 3 + """ + ).strip() + assert target == text + + +def test_write_network_text_star_graph(): + graph = nx.star_graph(5, create_using=nx.Graph) + lines = [] + write = lines.append + nx.write_network_text(graph, path=write, end="") + text = "\n".join(lines) + target = dedent( + """ + ╙── 1 + └── 0 + ├── 2 + ├── 3 + ├── 4 + └── 5 + """ + ).strip() + assert target == text + + +def test_write_network_text_path_graph(): + graph = nx.path_graph(3, create_using=nx.Graph) + lines = [] + write = lines.append + nx.write_network_text(graph, path=write, end="") + text = "\n".join(lines) + target = dedent( + """ + ╙── 0 + └── 1 + └── 2 + """ + ).strip() + assert target == text + + +def test_write_network_text_lollipop_graph(): + graph = nx.lollipop_graph(4, 2, create_using=nx.Graph) + lines = [] + write = lines.append + nx.write_network_text(graph, path=write, end="") + text = "\n".join(lines) + target = dedent( + """ + ╙── 5 + └── 4 + └── 3 + ├── 0 + │ ├── 1 ─ 3 + │ │ └── 2 ─ 0, 3 + │ └── ... + └── ... + """ + ).strip() + assert target == text + + +def test_write_network_text_wheel_graph(): + graph = nx.wheel_graph(7, create_using=nx.Graph) + lines = [] + write = lines.append + nx.write_network_text(graph, path=write, end="") + text = "\n".join(lines) + target = dedent( + """ + ╙── 1 + ├── 0 + │ ├── 2 ─ 1 + │ │ └── 3 ─ 0 + │ │ └── 4 ─ 0 + │ │ └── 5 ─ 0 + │ │ └── 6 ─ 0, 1 + │ └── ... + └── ... + """ + ).strip() + assert target == text + + +def test_write_network_text_circular_ladder_graph(): + graph = nx.circular_ladder_graph(4, create_using=nx.Graph) + lines = [] + write = lines.append + nx.write_network_text(graph, path=write, end="") + text = "\n".join(lines) + target = dedent( + """ + ╙── 0 + ├── 1 + │ ├── 2 + │ │ ├── 3 ─ 0 + │ │ │ └── 7 + │ │ │ ├── 6 ─ 2 + │ │ │ │ └── 5 ─ 1 + │ │ │ │ └── 4 ─ 0, 7 + │ │ │ └── ... + │ │ └── ... + │ └── ... + └── ... + """ + ).strip() + assert target == text + + +def test_write_network_text_dorogovtsev_goltsev_mendes_graph(): + graph = nx.dorogovtsev_goltsev_mendes_graph(4, create_using=nx.Graph) + lines = [] + write = lines.append + nx.write_network_text(graph, path=write, end="") + text = "\n".join(lines) + target = dedent( + """ + ╙── 15 + ├── 0 + │ ├── 1 ─ 15 + │ │ ├── 2 ─ 0 + │ │ │ ├── 4 ─ 0 + │ │ │ │ ├── 9 ─ 0 + │ │ │ │ │ ├── 22 ─ 0 + │ │ │ │ │ └── 38 ─ 4 + │ │ │ │ ├── 13 ─ 2 + │ │ │ │ │ ├── 34 ─ 2 + │ │ │ │ │ └── 39 ─ 4 + │ │ │ │ ├── 18 ─ 0 + │ │ │ │ ├── 30 ─ 2 + │ │ │ │ └── ... + │ │ │ ├── 5 ─ 1 + │ │ │ │ ├── 12 ─ 1 + │ │ │ │ │ ├── 29 ─ 1 + │ │ │ │ │ └── 40 ─ 5 + │ │ │ │ ├── 14 ─ 2 + │ │ │ │ │ ├── 35 ─ 2 + │ │ │ │ │ └── 41 ─ 5 + │ │ │ │ ├── 25 ─ 1 + │ │ │ │ ├── 31 ─ 2 + │ │ │ │ └── ... + │ │ │ ├── 7 ─ 0 + │ │ │ │ ├── 20 ─ 0 + │ │ │ │ └── 32 ─ 2 + │ │ │ ├── 10 ─ 1 + │ │ │ │ ├── 27 ─ 1 + │ │ │ │ └── 33 ─ 2 + │ │ │ ├── 16 ─ 0 + │ │ │ ├── 23 ─ 1 + │ │ │ └── ... + │ │ ├── 3 ─ 0 + │ │ │ ├── 8 ─ 0 + │ │ │ │ ├── 21 ─ 0 + │ │ │ │ └── 36 ─ 3 + │ │ │ ├── 11 ─ 1 + │ │ │ │ ├── 28 ─ 1 + │ │ │ │ └── 37 ─ 3 + │ │ │ ├── 17 ─ 0 + │ │ │ ├── 24 ─ 1 + │ │ │ └── ... + │ │ ├── 6 ─ 0 + │ │ │ ├── 19 ─ 0 + │ │ │ └── 26 ─ 1 + │ │ └── ... + │ └── ... + └── ... + """ + ).strip() + assert target == text + + +def test_write_network_text_tree_max_depth(): + orig = nx.balanced_tree(r=1, h=3, create_using=nx.DiGraph) + lines = [] + write = lines.append + write("--- directed case, max_depth=0 ---") + nx.write_network_text(orig, path=write, end="", max_depth=0) + write("--- directed case, max_depth=1 ---") + nx.write_network_text(orig, path=write, end="", max_depth=1) + write("--- directed case, max_depth=2 ---") + nx.write_network_text(orig, path=write, end="", max_depth=2) + write("--- directed case, max_depth=3 ---") + nx.write_network_text(orig, path=write, end="", max_depth=3) + write("--- directed case, max_depth=4 ---") + nx.write_network_text(orig, path=write, end="", max_depth=4) + write("--- undirected case, max_depth=0 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=0) + write("--- undirected case, max_depth=1 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=1) + write("--- undirected case, max_depth=2 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=2) + write("--- undirected case, max_depth=3 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=3) + write("--- undirected case, max_depth=4 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=4) + text = "\n".join(lines) + target = dedent( + """ + --- directed case, max_depth=0 --- + ╙ ... + --- directed case, max_depth=1 --- + ╙── 0 + └─╼ ... + --- directed case, max_depth=2 --- + ╙── 0 + └─╼ 1 + └─╼ ... + --- directed case, max_depth=3 --- + ╙── 0 + └─╼ 1 + └─╼ 2 + └─╼ ... + --- directed case, max_depth=4 --- + ╙── 0 + └─╼ 1 + └─╼ 2 + └─╼ 3 + --- undirected case, max_depth=0 --- + ╙ ... + --- undirected case, max_depth=1 --- + ╙── 0 ─ 1 + └── ... + --- undirected case, max_depth=2 --- + ╙── 0 + └── 1 ─ 2 + └── ... + --- undirected case, max_depth=3 --- + ╙── 0 + └── 1 + └── 2 ─ 3 + └── ... + --- undirected case, max_depth=4 --- + ╙── 0 + └── 1 + └── 2 + └── 3 + """ + ).strip() + assert target == text + + +def test_write_network_text_graph_max_depth(): + orig = nx.erdos_renyi_graph(10, 0.15, directed=True, seed=40392) + lines = [] + write = lines.append + write("--- directed case, max_depth=None ---") + nx.write_network_text(orig, path=write, end="", max_depth=None) + write("--- directed case, max_depth=0 ---") + nx.write_network_text(orig, path=write, end="", max_depth=0) + write("--- directed case, max_depth=1 ---") + nx.write_network_text(orig, path=write, end="", max_depth=1) + write("--- directed case, max_depth=2 ---") + nx.write_network_text(orig, path=write, end="", max_depth=2) + write("--- directed case, max_depth=3 ---") + nx.write_network_text(orig, path=write, end="", max_depth=3) + write("--- undirected case, max_depth=None ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=None) + write("--- undirected case, max_depth=0 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=0) + write("--- undirected case, max_depth=1 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=1) + write("--- undirected case, max_depth=2 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=2) + write("--- undirected case, max_depth=3 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=3) + text = "\n".join(lines) + target = dedent( + """ + --- directed case, max_depth=None --- + ╟── 4 + ╎ ├─╼ 0 ╾ 3 + ╎ ├─╼ 5 ╾ 7 + ╎ │ └─╼ 3 + ╎ │ ├─╼ 1 ╾ 9 + ╎ │ │ └─╼ 9 ╾ 6 + ╎ │ │ ├─╼ 6 + ╎ │ │ │ └─╼ ... + ╎ │ │ ├─╼ 7 ╾ 4 + ╎ │ │ │ ├─╼ 2 + ╎ │ │ │ └─╼ ... + ╎ │ │ └─╼ ... + ╎ │ └─╼ ... + ╎ └─╼ ... + ╙── 8 + --- directed case, max_depth=0 --- + ╙ ... + --- directed case, max_depth=1 --- + ╟── 4 + ╎ └─╼ ... + ╙── 8 + --- directed case, max_depth=2 --- + ╟── 4 + ╎ ├─╼ 0 ╾ 3 + ╎ ├─╼ 5 ╾ 7 + ╎ │ └─╼ ... + ╎ └─╼ 7 ╾ 9 + ╎ └─╼ ... + ╙── 8 + --- directed case, max_depth=3 --- + ╟── 4 + ╎ ├─╼ 0 ╾ 3 + ╎ ├─╼ 5 ╾ 7 + ╎ │ └─╼ 3 + ╎ │ └─╼ ... + ╎ └─╼ 7 ╾ 9 + ╎ ├─╼ 2 + ╎ └─╼ ... + ╙── 8 + --- undirected case, max_depth=None --- + ╟── 8 + ╙── 2 + └── 7 + ├── 4 + │ ├── 0 + │ │ └── 3 + │ │ ├── 1 + │ │ │ └── 9 ─ 7 + │ │ │ └── 6 + │ │ └── 5 ─ 4, 7 + │ └── ... + └── ... + --- undirected case, max_depth=0 --- + ╙ ... + --- undirected case, max_depth=1 --- + ╟── 8 + ╙── 2 ─ 7 + └── ... + --- undirected case, max_depth=2 --- + ╟── 8 + ╙── 2 + └── 7 ─ 4, 5, 9 + └── ... + --- undirected case, max_depth=3 --- + ╟── 8 + ╙── 2 + └── 7 + ├── 4 ─ 0, 5 + │ └── ... + ├── 5 ─ 4, 3 + │ └── ... + └── 9 ─ 1, 6 + └── ... + """ + ).strip() + assert target == text + + +def test_write_network_text_clique_max_depth(): + orig = nx.complete_graph(5, nx.DiGraph) + lines = [] + write = lines.append + write("--- directed case, max_depth=None ---") + nx.write_network_text(orig, path=write, end="", max_depth=None) + write("--- directed case, max_depth=0 ---") + nx.write_network_text(orig, path=write, end="", max_depth=0) + write("--- directed case, max_depth=1 ---") + nx.write_network_text(orig, path=write, end="", max_depth=1) + write("--- directed case, max_depth=2 ---") + nx.write_network_text(orig, path=write, end="", max_depth=2) + write("--- directed case, max_depth=3 ---") + nx.write_network_text(orig, path=write, end="", max_depth=3) + write("--- undirected case, max_depth=None ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=None) + write("--- undirected case, max_depth=0 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=0) + write("--- undirected case, max_depth=1 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=1) + write("--- undirected case, max_depth=2 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=2) + write("--- undirected case, max_depth=3 ---") + nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=3) + text = "\n".join(lines) + target = dedent( + """ + --- directed case, max_depth=None --- + ╙── 0 ╾ 1, 2, 3, 4 + ├─╼ 1 ╾ 2, 3, 4 + │ ├─╼ 2 ╾ 0, 3, 4 + │ │ ├─╼ 3 ╾ 0, 1, 4 + │ │ │ ├─╼ 4 ╾ 0, 1, 2 + │ │ │ │ └─╼ ... + │ │ │ └─╼ ... + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- directed case, max_depth=0 --- + ╙ ... + --- directed case, max_depth=1 --- + ╙── 0 ╾ 1, 2, 3, 4 + └─╼ ... + --- directed case, max_depth=2 --- + ╙── 0 ╾ 1, 2, 3, 4 + ├─╼ 1 ╾ 2, 3, 4 + │ └─╼ ... + ├─╼ 2 ╾ 1, 3, 4 + │ └─╼ ... + ├─╼ 3 ╾ 1, 2, 4 + │ └─╼ ... + └─╼ 4 ╾ 1, 2, 3 + └─╼ ... + --- directed case, max_depth=3 --- + ╙── 0 ╾ 1, 2, 3, 4 + ├─╼ 1 ╾ 2, 3, 4 + │ ├─╼ 2 ╾ 0, 3, 4 + │ │ └─╼ ... + │ ├─╼ 3 ╾ 0, 2, 4 + │ │ └─╼ ... + │ ├─╼ 4 ╾ 0, 2, 3 + │ │ └─╼ ... + │ └─╼ ... + └─╼ ... + --- undirected case, max_depth=None --- + ╙── 0 + ├── 1 + │ ├── 2 ─ 0 + │ │ ├── 3 ─ 0, 1 + │ │ │ └── 4 ─ 0, 1, 2 + │ │ └── ... + │ └── ... + └── ... + --- undirected case, max_depth=0 --- + ╙ ... + --- undirected case, max_depth=1 --- + ╙── 0 ─ 1, 2, 3, 4 + └── ... + --- undirected case, max_depth=2 --- + ╙── 0 + ├── 1 ─ 2, 3, 4 + │ └── ... + ├── 2 ─ 1, 3, 4 + │ └── ... + ├── 3 ─ 1, 2, 4 + │ └── ... + └── 4 ─ 1, 2, 3 + --- undirected case, max_depth=3 --- + ╙── 0 + ├── 1 + │ ├── 2 ─ 0, 3, 4 + │ │ └── ... + │ ├── 3 ─ 0, 2, 4 + │ │ └── ... + │ └── 4 ─ 0, 2, 3 + └── ... + """ + ).strip() + assert target == text + + +def test_write_network_text_custom_label(): + # Create a directed forest with labels + graph = nx.erdos_renyi_graph(5, 0.4, directed=True, seed=359222358) + for node in graph.nodes: + graph.nodes[node]["label"] = f"Node({node})" + graph.nodes[node]["chr"] = chr(node + ord("a") - 1) + if node % 2 == 0: + graph.nodes[node]["part"] = chr(node + ord("a")) + + lines = [] + write = lines.append + write("--- when with_labels=True, uses the 'label' attr ---") + nx.write_network_text(graph, path=write, with_labels=True, end="", max_depth=None) + write("--- when with_labels=False, uses str(node) value ---") + nx.write_network_text(graph, path=write, with_labels=False, end="", max_depth=None) + write("--- when with_labels is a string, use that attr ---") + nx.write_network_text(graph, path=write, with_labels="chr", end="", max_depth=None) + write("--- fallback to str(node) when the attr does not exist ---") + nx.write_network_text(graph, path=write, with_labels="part", end="", max_depth=None) + + text = "\n".join(lines) + target = dedent( + """ + --- when with_labels=True, uses the 'label' attr --- + ╙── Node(1) + └─╼ Node(3) ╾ Node(2) + ├─╼ Node(0) + │ ├─╼ Node(2) ╾ Node(3), Node(4) + │ │ └─╼ ... + │ └─╼ Node(4) + │ └─╼ ... + └─╼ ... + --- when with_labels=False, uses str(node) value --- + ╙── 1 + └─╼ 3 ╾ 2 + ├─╼ 0 + │ ├─╼ 2 ╾ 3, 4 + │ │ └─╼ ... + │ └─╼ 4 + │ └─╼ ... + └─╼ ... + --- when with_labels is a string, use that attr --- + ╙── a + └─╼ c ╾ b + ├─╼ ` + │ ├─╼ b ╾ c, d + │ │ └─╼ ... + │ └─╼ d + │ └─╼ ... + └─╼ ... + --- fallback to str(node) when the attr does not exist --- + ╙── 1 + └─╼ 3 ╾ c + ├─╼ a + │ ├─╼ c ╾ 3, e + │ │ └─╼ ... + │ └─╼ e + │ └─╼ ... + └─╼ ... + """ + ).strip() + assert target == text + + +def test_write_network_text_vertical_chains(): + graph1 = nx.lollipop_graph(4, 2, create_using=nx.Graph) + graph1.add_edge(0, -1) + graph1.add_edge(-1, -2) + graph1.add_edge(-2, -3) + + graph2 = graph1.to_directed() + graph2.remove_edges_from([(u, v) for u, v in graph2.edges if v > u]) + + lines = [] + write = lines.append + write("--- Undirected UTF ---") + nx.write_network_text(graph1, path=write, end="", vertical_chains=True) + write("--- Undirected ASCI ---") + nx.write_network_text( + graph1, path=write, end="", vertical_chains=True, ascii_only=True + ) + write("--- Directed UTF ---") + nx.write_network_text(graph2, path=write, end="", vertical_chains=True) + write("--- Directed ASCI ---") + nx.write_network_text( + graph2, path=write, end="", vertical_chains=True, ascii_only=True + ) + + text = "\n".join(lines) + target = dedent( + """ + --- Undirected UTF --- + ╙── 5 + │ + 4 + │ + 3 + ├── 0 + │ ├── 1 ─ 3 + │ │ │ + │ │ 2 ─ 0, 3 + │ ├── -1 + │ │ │ + │ │ -2 + │ │ │ + │ │ -3 + │ └── ... + └── ... + --- Undirected ASCI --- + +-- 5 + | + 4 + | + 3 + |-- 0 + | |-- 1 - 3 + | | | + | | 2 - 0, 3 + | |-- -1 + | | | + | | -2 + | | | + | | -3 + | L-- ... + L-- ... + --- Directed UTF --- + ╙── 5 + ╽ + 4 + ╽ + 3 + ├─╼ 0 ╾ 1, 2 + │ ╽ + │ -1 + │ ╽ + │ -2 + │ ╽ + │ -3 + ├─╼ 1 ╾ 2 + │ └─╼ ... + └─╼ 2 + └─╼ ... + --- Directed ASCI --- + +-- 5 + ! + 4 + ! + 3 + |-> 0 <- 1, 2 + | ! + | -1 + | ! + | -2 + | ! + | -3 + |-> 1 <- 2 + | L-> ... + L-> 2 + L-> ... + """ + ).strip() + assert target == text + + +def test_collapse_directed(): + graph = nx.balanced_tree(r=2, h=3, create_using=nx.DiGraph) + lines = [] + write = lines.append + write("--- Original ---") + nx.write_network_text(graph, path=write, end="") + graph.nodes[1]["collapse"] = True + write("--- Collapse Node 1 ---") + nx.write_network_text(graph, path=write, end="") + write("--- Add alternate path (5, 3) to collapsed zone") + graph.add_edge(5, 3) + nx.write_network_text(graph, path=write, end="") + write("--- Collapse Node 0 ---") + graph.nodes[0]["collapse"] = True + nx.write_network_text(graph, path=write, end="") + text = "\n".join(lines) + target = dedent( + """ + --- Original --- + ╙── 0 + ├─╼ 1 + │ ├─╼ 3 + │ │ ├─╼ 7 + │ │ └─╼ 8 + │ └─╼ 4 + │ ├─╼ 9 + │ └─╼ 10 + └─╼ 2 + ├─╼ 5 + │ ├─╼ 11 + │ └─╼ 12 + └─╼ 6 + ├─╼ 13 + └─╼ 14 + --- Collapse Node 1 --- + ╙── 0 + ├─╼ 1 + │ └─╼ ... + └─╼ 2 + ├─╼ 5 + │ ├─╼ 11 + │ └─╼ 12 + └─╼ 6 + ├─╼ 13 + └─╼ 14 + --- Add alternate path (5, 3) to collapsed zone + ╙── 0 + ├─╼ 1 + │ └─╼ ... + └─╼ 2 + ├─╼ 5 + │ ├─╼ 11 + │ ├─╼ 12 + │ └─╼ 3 ╾ 1 + │ ├─╼ 7 + │ └─╼ 8 + └─╼ 6 + ├─╼ 13 + └─╼ 14 + --- Collapse Node 0 --- + ╙── 0 + └─╼ ... + """ + ).strip() + assert target == text + + +def test_collapse_undirected(): + graph = nx.balanced_tree(r=2, h=3, create_using=nx.Graph) + lines = [] + write = lines.append + write("--- Original ---") + nx.write_network_text(graph, path=write, end="", sources=[0]) + graph.nodes[1]["collapse"] = True + write("--- Collapse Node 1 ---") + nx.write_network_text(graph, path=write, end="", sources=[0]) + write("--- Add alternate path (5, 3) to collapsed zone") + graph.add_edge(5, 3) + nx.write_network_text(graph, path=write, end="", sources=[0]) + write("--- Collapse Node 0 ---") + graph.nodes[0]["collapse"] = True + nx.write_network_text(graph, path=write, end="", sources=[0]) + text = "\n".join(lines) + target = dedent( + """ + --- Original --- + ╙── 0 + ├── 1 + │ ├── 3 + │ │ ├── 7 + │ │ └── 8 + │ └── 4 + │ ├── 9 + │ └── 10 + └── 2 + ├── 5 + │ ├── 11 + │ └── 12 + └── 6 + ├── 13 + └── 14 + --- Collapse Node 1 --- + ╙── 0 + ├── 1 ─ 3, 4 + │ └── ... + └── 2 + ├── 5 + │ ├── 11 + │ └── 12 + └── 6 + ├── 13 + └── 14 + --- Add alternate path (5, 3) to collapsed zone + ╙── 0 + ├── 1 ─ 3, 4 + │ └── ... + └── 2 + ├── 5 + │ ├── 11 + │ ├── 12 + │ └── 3 ─ 1 + │ ├── 7 + │ └── 8 + └── 6 + ├── 13 + └── 14 + --- Collapse Node 0 --- + ╙── 0 ─ 1, 2 + └── ... + """ + ).strip() + assert target == text + + +def generate_test_graphs(): + """ + Generate a gauntlet of different test graphs with different properties + """ + import random + + rng = random.Random(976689776) + num_randomized = 3 + + for directed in [0, 1]: + cls = nx.DiGraph if directed else nx.Graph + + for num_nodes in range(17): + # Disconnected graph + graph = cls() + graph.add_nodes_from(range(num_nodes)) + yield graph + + # Randomize graphs + if num_nodes > 0: + for p in [0.1, 0.3, 0.5, 0.7, 0.9]: + for seed in range(num_randomized): + graph = nx.erdos_renyi_graph( + num_nodes, p, directed=directed, seed=rng + ) + yield graph + + yield nx.complete_graph(num_nodes, cls) + + yield nx.path_graph(3, create_using=cls) + yield nx.balanced_tree(r=1, h=3, create_using=cls) + if not directed: + yield nx.circular_ladder_graph(4, create_using=cls) + yield nx.star_graph(5, create_using=cls) + yield nx.lollipop_graph(4, 2, create_using=cls) + yield nx.wheel_graph(7, create_using=cls) + yield nx.dorogovtsev_goltsev_mendes_graph(4, create_using=cls) + + +@pytest.mark.parametrize( + ("vertical_chains", "ascii_only"), + tuple( + [ + (vertical_chains, ascii_only) + for vertical_chains in [0, 1] + for ascii_only in [0, 1] + ] + ), +) +def test_network_text_round_trip(vertical_chains, ascii_only): + """ + Write the graph to network text format, then parse it back in, assert it is + the same as the original graph. Passing this test is strong validation of + both the format generator and parser. + """ + from networkx.readwrite.text import _parse_network_text + + for graph in generate_test_graphs(): + graph = nx.relabel_nodes(graph, {n: str(n) for n in graph.nodes}) + lines = list( + nx.generate_network_text( + graph, vertical_chains=vertical_chains, ascii_only=ascii_only + ) + ) + new = _parse_network_text(lines) + try: + assert new.nodes == graph.nodes + assert new.edges == graph.edges + except Exception: + nx.write_network_text(graph) + raise diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_all_random_functions.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_all_random_functions.py new file mode 100644 index 0000000000000000000000000000000000000000..fb3a73d0666b01bd1a90a4759670f912590aaf6b --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_all_random_functions.py @@ -0,0 +1,248 @@ +import random + +import pytest + +import networkx as nx +from networkx.algorithms import approximation as approx +from networkx.algorithms import threshold + +np = pytest.importorskip("numpy") + +progress = 0 + +# store the random numbers after setting a global seed +np.random.seed(42) +np_rv = np.random.rand() +random.seed(42) +py_rv = random.random() + + +def t(f, *args, **kwds): + """call one function and check if global RNG changed""" + global progress + progress += 1 + print(progress, ",", end="") + + f(*args, **kwds) + + after_np_rv = np.random.rand() + # if np_rv != after_np_rv: + # print(np_rv, after_np_rv, "don't match np!") + assert np_rv == after_np_rv + np.random.seed(42) + + after_py_rv = random.random() + # if py_rv != after_py_rv: + # print(py_rv, after_py_rv, "don't match py!") + assert py_rv == after_py_rv + random.seed(42) + + +def run_all_random_functions(seed): + n = 20 + m = 10 + k = l = 2 + s = v = 10 + p = q = p1 = p2 = p_in = p_out = 0.4 + alpha = radius = theta = 0.75 + sizes = (20, 20, 10) + colors = [1, 2, 3] + G = nx.barbell_graph(12, 20) + H = nx.cycle_graph(3) + H.add_weighted_edges_from((u, v, 0.2) for u, v in H.edges) + deg_sequence = [3, 2, 1, 3, 2, 1, 3, 2, 1, 2, 1, 2, 1] + in_degree_sequence = w = sequence = aseq = bseq = deg_sequence + + # print("starting...") + t(nx.maximal_independent_set, G, seed=seed) + t(nx.rich_club_coefficient, G, seed=seed, normalized=False) + t(nx.random_reference, G, seed=seed) + t(nx.lattice_reference, G, seed=seed) + t(nx.sigma, G, 1, 2, seed=seed) + t(nx.omega, G, 1, 2, seed=seed) + # print("out of smallworld.py") + t(nx.double_edge_swap, G, seed=seed) + # print("starting connected_double_edge_swap") + t(nx.connected_double_edge_swap, nx.complete_graph(9), seed=seed) + # print("ending connected_double_edge_swap") + t(nx.random_layout, G, seed=seed) + t(nx.fruchterman_reingold_layout, G, seed=seed) + t(nx.algebraic_connectivity, G, seed=seed) + t(nx.fiedler_vector, G, seed=seed) + t(nx.spectral_ordering, G, seed=seed) + # print('starting average_clustering') + t(approx.average_clustering, G, seed=seed) + t(approx.simulated_annealing_tsp, H, "greedy", source=1, seed=seed) + t(approx.threshold_accepting_tsp, H, "greedy", source=1, seed=seed) + t( + approx.traveling_salesman_problem, + H, + method=lambda G, weight: approx.simulated_annealing_tsp( + G, "greedy", weight, seed=seed + ), + ) + t( + approx.traveling_salesman_problem, + H, + method=lambda G, weight: approx.threshold_accepting_tsp( + G, "greedy", weight, seed=seed + ), + ) + t(nx.betweenness_centrality, G, seed=seed) + t(nx.edge_betweenness_centrality, G, seed=seed) + t(nx.approximate_current_flow_betweenness_centrality, G, seed=seed) + # print("kernighan") + t(nx.algorithms.community.kernighan_lin_bisection, G, seed=seed) + # nx.algorithms.community.asyn_lpa_communities(G, seed=seed) + t(nx.algorithms.tree.greedy_branching, G, seed=seed) + # print('done with graph argument functions') + + t(nx.spectral_graph_forge, G, alpha, seed=seed) + t(nx.algorithms.community.asyn_fluidc, G, k, max_iter=1, seed=seed) + t( + nx.algorithms.connectivity.edge_augmentation.greedy_k_edge_augmentation, + G, + k, + seed=seed, + ) + t(nx.algorithms.coloring.strategy_random_sequential, G, colors, seed=seed) + + t(nx.configuration_model, deg_sequence, seed=seed) + t( + nx.directed_configuration_model, + in_degree_sequence, + in_degree_sequence, + seed=seed, + ) + t(nx.expected_degree_graph, w, seed=seed) + t(nx.random_degree_sequence_graph, sequence, seed=seed) + joint_degrees = { + 1: {4: 1}, + 2: {2: 2, 3: 2, 4: 2}, + 3: {2: 2, 4: 1}, + 4: {1: 1, 2: 2, 3: 1}, + } + t(nx.joint_degree_graph, joint_degrees, seed=seed) + joint_degree_sequence = [ + (1, 0), + (1, 0), + (1, 0), + (2, 0), + (1, 0), + (2, 1), + (0, 1), + (0, 1), + ] + t(nx.random_clustered_graph, joint_degree_sequence, seed=seed) + constructor = [(3, 3, 0.5), (10, 10, 0.7)] + t(nx.random_shell_graph, constructor, seed=seed) + mapping = {1: 0.4, 2: 0.3, 3: 0.3} + t(nx.utils.random_weighted_sample, mapping, k, seed=seed) + t(nx.utils.weighted_choice, mapping, seed=seed) + t(nx.algorithms.bipartite.configuration_model, aseq, bseq, seed=seed) + t(nx.algorithms.bipartite.preferential_attachment_graph, aseq, p, seed=seed) + + def kernel_integral(u, w, z): + return z - w + + t(nx.random_kernel_graph, n, kernel_integral, seed=seed) + + sizes = [75, 75, 300] + probs = [[0.25, 0.05, 0.02], [0.05, 0.35, 0.07], [0.02, 0.07, 0.40]] + t(nx.stochastic_block_model, sizes, probs, seed=seed) + t(nx.random_partition_graph, sizes, p_in, p_out, seed=seed) + + # print("starting generator functions") + t(threshold.random_threshold_sequence, n, p, seed=seed) + t(nx.tournament.random_tournament, n, seed=seed) + t(nx.relaxed_caveman_graph, l, k, p, seed=seed) + t(nx.planted_partition_graph, l, k, p_in, p_out, seed=seed) + t(nx.gaussian_random_partition_graph, n, s, v, p_in, p_out, seed=seed) + t(nx.gn_graph, n, seed=seed) + t(nx.gnr_graph, n, p, seed=seed) + t(nx.gnc_graph, n, seed=seed) + t(nx.scale_free_graph, n, seed=seed) + t(nx.directed.random_uniform_k_out_graph, n, k, seed=seed) + t(nx.random_k_out_graph, n, k, alpha, seed=seed) + N = 1000 + t(nx.partial_duplication_graph, N, n, p, q, seed=seed) + t(nx.duplication_divergence_graph, n, p, seed=seed) + t(nx.random_geometric_graph, n, radius, seed=seed) + t(nx.soft_random_geometric_graph, n, radius, seed=seed) + t(nx.geographical_threshold_graph, n, theta, seed=seed) + t(nx.waxman_graph, n, seed=seed) + t(nx.navigable_small_world_graph, n, seed=seed) + t(nx.thresholded_random_geometric_graph, n, radius, theta, seed=seed) + t(nx.uniform_random_intersection_graph, n, m, p, seed=seed) + t(nx.k_random_intersection_graph, n, m, k, seed=seed) + + t(nx.general_random_intersection_graph, n, 2, [0.1, 0.5], seed=seed) + t(nx.fast_gnp_random_graph, n, p, seed=seed) + t(nx.gnp_random_graph, n, p, seed=seed) + t(nx.dense_gnm_random_graph, n, m, seed=seed) + t(nx.gnm_random_graph, n, m, seed=seed) + t(nx.newman_watts_strogatz_graph, n, k, p, seed=seed) + t(nx.watts_strogatz_graph, n, k, p, seed=seed) + t(nx.connected_watts_strogatz_graph, n, k, p, seed=seed) + t(nx.random_regular_graph, 3, n, seed=seed) + t(nx.barabasi_albert_graph, n, m, seed=seed) + t(nx.extended_barabasi_albert_graph, n, m, p, q, seed=seed) + t(nx.powerlaw_cluster_graph, n, m, p, seed=seed) + t(nx.random_lobster_graph, n, p1, p2, seed=seed) + t(nx.random_powerlaw_tree, 5, seed=seed, tries=5000) + t(nx.random_powerlaw_tree_sequence, 5, seed=seed, tries=5000) + t(nx.random_labeled_tree, n, seed=seed) + t(nx.utils.powerlaw_sequence, n, seed=seed) + t(nx.utils.zipf_rv, 2.3, seed=seed) + cdist = [0.2, 0.4, 0.5, 0.7, 0.9, 1.0] + t(nx.utils.discrete_sequence, n, cdistribution=cdist, seed=seed) + t(nx.algorithms.bipartite.random_graph, n, m, p, seed=seed) + t(nx.algorithms.bipartite.gnmk_random_graph, n, m, k, seed=seed) + LFR = nx.generators.LFR_benchmark_graph + t( + LFR, + 25, + 3, + 1.5, + 0.1, + average_degree=3, + min_community=10, + seed=seed, + max_community=20, + ) + t(nx.random_internet_as_graph, n, seed=seed) + # print("done") + + +# choose to test an integer seed, or whether a single RNG can be everywhere +# np_rng = np.random.RandomState(14) +# seed = np_rng +# seed = 14 + + +@pytest.mark.slow +# print("NetworkX Version:", nx.__version__) +def test_rng_interface(): + global progress + + # try different kinds of seeds + for seed in [14, np.random.RandomState(14)]: + np.random.seed(42) + random.seed(42) + run_all_random_functions(seed) + progress = 0 + + # check that both global RNGs are unaffected + after_np_rv = np.random.rand() + # if np_rv != after_np_rv: + # print(np_rv, after_np_rv, "don't match np!") + assert np_rv == after_np_rv + after_py_rv = random.random() + # if py_rv != after_py_rv: + # print(py_rv, after_py_rv, "don't match py!") + assert py_rv == after_py_rv + + +# print("\nDone testing seed:", seed) + +# test_rng_interface() diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert.py new file mode 100644 index 0000000000000000000000000000000000000000..44bed9438945a39bb5eb85477301f58cfcd70cf0 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert.py @@ -0,0 +1,321 @@ +import pytest + +import networkx as nx +from networkx.convert import ( + from_dict_of_dicts, + from_dict_of_lists, + to_dict_of_dicts, + to_dict_of_lists, + to_networkx_graph, +) +from networkx.generators.classic import barbell_graph, cycle_graph +from networkx.utils import edges_equal, graphs_equal, nodes_equal + + +class TestConvert: + def edgelists_equal(self, e1, e2): + return sorted(sorted(e) for e in e1) == sorted(sorted(e) for e in e2) + + def test_simple_graphs(self): + for dest, source in [ + (to_dict_of_dicts, from_dict_of_dicts), + (to_dict_of_lists, from_dict_of_lists), + ]: + G = barbell_graph(10, 3) + G.graph = {} + dod = dest(G) + + # Dict of [dicts, lists] + GG = source(dod) + assert graphs_equal(G, GG) + GW = to_networkx_graph(dod) + assert graphs_equal(G, GW) + GI = nx.Graph(dod) + assert graphs_equal(G, GI) + + # With nodelist keyword + P4 = nx.path_graph(4) + P3 = nx.path_graph(3) + P4.graph = {} + P3.graph = {} + dod = dest(P4, nodelist=[0, 1, 2]) + Gdod = nx.Graph(dod) + assert graphs_equal(Gdod, P3) + + def test_exceptions(self): + # NX graph + class G: + adj = None + + pytest.raises(nx.NetworkXError, to_networkx_graph, G) + + # pygraphviz agraph + class G: + is_strict = None + + pytest.raises(nx.NetworkXError, to_networkx_graph, G) + + # Dict of [dicts, lists] + G = {"a": 0} + pytest.raises(TypeError, to_networkx_graph, G) + + # list or generator of edges + class G: + next = None + + pytest.raises(nx.NetworkXError, to_networkx_graph, G) + + # no match + pytest.raises(nx.NetworkXError, to_networkx_graph, "a") + + def test_digraphs(self): + for dest, source in [ + (to_dict_of_dicts, from_dict_of_dicts), + (to_dict_of_lists, from_dict_of_lists), + ]: + G = cycle_graph(10) + + # Dict of [dicts, lists] + dod = dest(G) + GG = source(dod) + assert nodes_equal(sorted(G.nodes()), sorted(GG.nodes())) + assert edges_equal(sorted(G.edges()), sorted(GG.edges())) + GW = to_networkx_graph(dod) + assert nodes_equal(sorted(G.nodes()), sorted(GW.nodes())) + assert edges_equal(sorted(G.edges()), sorted(GW.edges())) + GI = nx.Graph(dod) + assert nodes_equal(sorted(G.nodes()), sorted(GI.nodes())) + assert edges_equal(sorted(G.edges()), sorted(GI.edges())) + + G = cycle_graph(10, create_using=nx.DiGraph) + dod = dest(G) + GG = source(dod, create_using=nx.DiGraph) + assert sorted(G.nodes()) == sorted(GG.nodes()) + assert sorted(G.edges()) == sorted(GG.edges()) + GW = to_networkx_graph(dod, create_using=nx.DiGraph) + assert sorted(G.nodes()) == sorted(GW.nodes()) + assert sorted(G.edges()) == sorted(GW.edges()) + GI = nx.DiGraph(dod) + assert sorted(G.nodes()) == sorted(GI.nodes()) + assert sorted(G.edges()) == sorted(GI.edges()) + + def test_graph(self): + g = nx.cycle_graph(10) + G = nx.Graph() + G.add_nodes_from(g) + G.add_weighted_edges_from((u, v, u) for u, v in g.edges()) + + # Dict of dicts + dod = to_dict_of_dicts(G) + GG = from_dict_of_dicts(dod, create_using=nx.Graph) + assert nodes_equal(sorted(G.nodes()), sorted(GG.nodes())) + assert edges_equal(sorted(G.edges()), sorted(GG.edges())) + GW = to_networkx_graph(dod, create_using=nx.Graph) + assert nodes_equal(sorted(G.nodes()), sorted(GW.nodes())) + assert edges_equal(sorted(G.edges()), sorted(GW.edges())) + GI = nx.Graph(dod) + assert sorted(G.nodes()) == sorted(GI.nodes()) + assert sorted(G.edges()) == sorted(GI.edges()) + + # Dict of lists + dol = to_dict_of_lists(G) + GG = from_dict_of_lists(dol, create_using=nx.Graph) + # dict of lists throws away edge data so set it to none + enone = [(u, v, {}) for (u, v, d) in G.edges(data=True)] + assert nodes_equal(sorted(G.nodes()), sorted(GG.nodes())) + assert edges_equal(enone, sorted(GG.edges(data=True))) + GW = to_networkx_graph(dol, create_using=nx.Graph) + assert nodes_equal(sorted(G.nodes()), sorted(GW.nodes())) + assert edges_equal(enone, sorted(GW.edges(data=True))) + GI = nx.Graph(dol) + assert nodes_equal(sorted(G.nodes()), sorted(GI.nodes())) + assert edges_equal(enone, sorted(GI.edges(data=True))) + + def test_with_multiedges_self_loops(self): + G = cycle_graph(10) + XG = nx.Graph() + XG.add_nodes_from(G) + XG.add_weighted_edges_from((u, v, u) for u, v in G.edges()) + XGM = nx.MultiGraph() + XGM.add_nodes_from(G) + XGM.add_weighted_edges_from((u, v, u) for u, v in G.edges()) + XGM.add_edge(0, 1, weight=2) # multiedge + XGS = nx.Graph() + XGS.add_nodes_from(G) + XGS.add_weighted_edges_from((u, v, u) for u, v in G.edges()) + XGS.add_edge(0, 0, weight=100) # self loop + + # Dict of dicts + # with self loops, OK + dod = to_dict_of_dicts(XGS) + GG = from_dict_of_dicts(dod, create_using=nx.Graph) + assert nodes_equal(XGS.nodes(), GG.nodes()) + assert edges_equal(XGS.edges(), GG.edges()) + GW = to_networkx_graph(dod, create_using=nx.Graph) + assert nodes_equal(XGS.nodes(), GW.nodes()) + assert edges_equal(XGS.edges(), GW.edges()) + GI = nx.Graph(dod) + assert nodes_equal(XGS.nodes(), GI.nodes()) + assert edges_equal(XGS.edges(), GI.edges()) + + # Dict of lists + # with self loops, OK + dol = to_dict_of_lists(XGS) + GG = from_dict_of_lists(dol, create_using=nx.Graph) + # dict of lists throws away edge data so set it to none + enone = [(u, v, {}) for (u, v, d) in XGS.edges(data=True)] + assert nodes_equal(sorted(XGS.nodes()), sorted(GG.nodes())) + assert edges_equal(enone, sorted(GG.edges(data=True))) + GW = to_networkx_graph(dol, create_using=nx.Graph) + assert nodes_equal(sorted(XGS.nodes()), sorted(GW.nodes())) + assert edges_equal(enone, sorted(GW.edges(data=True))) + GI = nx.Graph(dol) + assert nodes_equal(sorted(XGS.nodes()), sorted(GI.nodes())) + assert edges_equal(enone, sorted(GI.edges(data=True))) + + # Dict of dicts + # with multiedges, OK + dod = to_dict_of_dicts(XGM) + GG = from_dict_of_dicts(dod, create_using=nx.MultiGraph, multigraph_input=True) + assert nodes_equal(sorted(XGM.nodes()), sorted(GG.nodes())) + assert edges_equal(sorted(XGM.edges()), sorted(GG.edges())) + GW = to_networkx_graph(dod, create_using=nx.MultiGraph, multigraph_input=True) + assert nodes_equal(sorted(XGM.nodes()), sorted(GW.nodes())) + assert edges_equal(sorted(XGM.edges()), sorted(GW.edges())) + GI = nx.MultiGraph(dod) + assert nodes_equal(sorted(XGM.nodes()), sorted(GI.nodes())) + assert sorted(XGM.edges()) == sorted(GI.edges()) + GE = from_dict_of_dicts(dod, create_using=nx.MultiGraph, multigraph_input=False) + assert nodes_equal(sorted(XGM.nodes()), sorted(GE.nodes())) + assert sorted(XGM.edges()) != sorted(GE.edges()) + GI = nx.MultiGraph(XGM) + assert nodes_equal(sorted(XGM.nodes()), sorted(GI.nodes())) + assert edges_equal(sorted(XGM.edges()), sorted(GI.edges())) + GM = nx.MultiGraph(G) + assert nodes_equal(sorted(GM.nodes()), sorted(G.nodes())) + assert edges_equal(sorted(GM.edges()), sorted(G.edges())) + + # Dict of lists + # with multiedges, OK, but better write as DiGraph else you'll + # get double edges + dol = to_dict_of_lists(G) + GG = from_dict_of_lists(dol, create_using=nx.MultiGraph) + assert nodes_equal(sorted(G.nodes()), sorted(GG.nodes())) + assert edges_equal(sorted(G.edges()), sorted(GG.edges())) + GW = to_networkx_graph(dol, create_using=nx.MultiGraph) + assert nodes_equal(sorted(G.nodes()), sorted(GW.nodes())) + assert edges_equal(sorted(G.edges()), sorted(GW.edges())) + GI = nx.MultiGraph(dol) + assert nodes_equal(sorted(G.nodes()), sorted(GI.nodes())) + assert edges_equal(sorted(G.edges()), sorted(GI.edges())) + + def test_edgelists(self): + P = nx.path_graph(4) + e = [(0, 1), (1, 2), (2, 3)] + G = nx.Graph(e) + assert nodes_equal(sorted(G.nodes()), sorted(P.nodes())) + assert edges_equal(sorted(G.edges()), sorted(P.edges())) + assert edges_equal(sorted(G.edges(data=True)), sorted(P.edges(data=True))) + + e = [(0, 1, {}), (1, 2, {}), (2, 3, {})] + G = nx.Graph(e) + assert nodes_equal(sorted(G.nodes()), sorted(P.nodes())) + assert edges_equal(sorted(G.edges()), sorted(P.edges())) + assert edges_equal(sorted(G.edges(data=True)), sorted(P.edges(data=True))) + + e = ((n, n + 1) for n in range(3)) + G = nx.Graph(e) + assert nodes_equal(sorted(G.nodes()), sorted(P.nodes())) + assert edges_equal(sorted(G.edges()), sorted(P.edges())) + assert edges_equal(sorted(G.edges(data=True)), sorted(P.edges(data=True))) + + def test_directed_to_undirected(self): + edges1 = [(0, 1), (1, 2), (2, 0)] + edges2 = [(0, 1), (1, 2), (0, 2)] + assert self.edgelists_equal(nx.Graph(nx.DiGraph(edges1)).edges(), edges1) + assert self.edgelists_equal(nx.Graph(nx.DiGraph(edges2)).edges(), edges1) + assert self.edgelists_equal(nx.MultiGraph(nx.DiGraph(edges1)).edges(), edges1) + assert self.edgelists_equal(nx.MultiGraph(nx.DiGraph(edges2)).edges(), edges1) + + assert self.edgelists_equal( + nx.MultiGraph(nx.MultiDiGraph(edges1)).edges(), edges1 + ) + assert self.edgelists_equal( + nx.MultiGraph(nx.MultiDiGraph(edges2)).edges(), edges1 + ) + + assert self.edgelists_equal(nx.Graph(nx.MultiDiGraph(edges1)).edges(), edges1) + assert self.edgelists_equal(nx.Graph(nx.MultiDiGraph(edges2)).edges(), edges1) + + def test_attribute_dict_integrity(self): + # we must not replace dict-like graph data structures with dicts + G = nx.Graph() + G.add_nodes_from("abc") + H = to_networkx_graph(G, create_using=nx.Graph) + assert list(H.nodes) == list(G.nodes) + H = nx.DiGraph(G) + assert list(H.nodes) == list(G.nodes) + + def test_to_edgelist(self): + G = nx.Graph([(1, 1)]) + elist = nx.to_edgelist(G, nodelist=list(G)) + assert edges_equal(G.edges(data=True), elist) + + def test_custom_node_attr_dict_safekeeping(self): + class custom_dict(dict): + pass + + class Custom(nx.Graph): + node_attr_dict_factory = custom_dict + + g = nx.Graph() + g.add_node(1, weight=1) + + h = Custom(g) + assert isinstance(g._node[1], dict) + assert isinstance(h._node[1], custom_dict) + + # this raise exception + # h._node.update((n, dd.copy()) for n, dd in g.nodes.items()) + # assert isinstance(h._node[1], custom_dict) + + +@pytest.mark.parametrize( + "edgelist", + ( + # Graph with no edge data + [(0, 1), (1, 2)], + # Graph with edge data + [(0, 1, {"weight": 1.0}), (1, 2, {"weight": 2.0})], + ), +) +def test_to_dict_of_dicts_with_edgedata_param(edgelist): + G = nx.Graph() + G.add_edges_from(edgelist) + # Innermost dict value == edge_data when edge_data != None. + # In the case when G has edge data, it is overwritten + expected = {0: {1: 10}, 1: {0: 10, 2: 10}, 2: {1: 10}} + assert nx.to_dict_of_dicts(G, edge_data=10) == expected + + +def test_to_dict_of_dicts_with_edgedata_and_nodelist(): + G = nx.path_graph(5) + nodelist = [2, 3, 4] + expected = {2: {3: 10}, 3: {2: 10, 4: 10}, 4: {3: 10}} + assert nx.to_dict_of_dicts(G, nodelist=nodelist, edge_data=10) == expected + + +def test_to_dict_of_dicts_with_edgedata_multigraph(): + """Multi edge data overwritten when edge_data != None""" + G = nx.MultiGraph() + G.add_edge(0, 1, key="a") + G.add_edge(0, 1, key="b") + # Multi edge data lost when edge_data is not None + expected = {0: {1: 10}, 1: {0: 10}} + assert nx.to_dict_of_dicts(G, edge_data=10) == expected + + +def test_to_networkx_graph_non_edgelist(): + invalid_edgelist = [1, 2, 3] + with pytest.raises(nx.NetworkXError, match="Input is not a valid edge list"): + nx.to_networkx_graph(invalid_edgelist) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert_numpy.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert_numpy.py new file mode 100644 index 0000000000000000000000000000000000000000..0a554fd4b2d5e00e69a0537fbd04e877a95b6593 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert_numpy.py @@ -0,0 +1,531 @@ +import itertools + +import pytest + +import networkx as nx +from networkx.utils import graphs_equal + +np = pytest.importorskip("numpy") +npt = pytest.importorskip("numpy.testing") + + +class TestConvertNumpyArray: + def setup_method(self): + self.G1 = nx.barbell_graph(10, 3) + self.G2 = nx.cycle_graph(10, create_using=nx.DiGraph) + self.G3 = self.create_weighted(nx.Graph()) + self.G4 = self.create_weighted(nx.DiGraph()) + + def create_weighted(self, G): + g = nx.cycle_graph(4) + G.add_nodes_from(g) + G.add_weighted_edges_from((u, v, 10 + u) for u, v in g.edges()) + return G + + def assert_equal(self, G1, G2): + assert sorted(G1.nodes()) == sorted(G2.nodes()) + assert sorted(G1.edges()) == sorted(G2.edges()) + + def identity_conversion(self, G, A, create_using): + assert A.sum() > 0 + GG = nx.from_numpy_array(A, create_using=create_using) + self.assert_equal(G, GG) + GW = nx.to_networkx_graph(A, create_using=create_using) + self.assert_equal(G, GW) + GI = nx.empty_graph(0, create_using).__class__(A) + self.assert_equal(G, GI) + + def test_shape(self): + "Conversion from non-square array." + A = np.array([[1, 2, 3], [4, 5, 6]]) + pytest.raises(nx.NetworkXError, nx.from_numpy_array, A) + + def test_identity_graph_array(self): + "Conversion from graph to array to graph." + A = nx.to_numpy_array(self.G1) + self.identity_conversion(self.G1, A, nx.Graph()) + + def test_identity_digraph_array(self): + """Conversion from digraph to array to digraph.""" + A = nx.to_numpy_array(self.G2) + self.identity_conversion(self.G2, A, nx.DiGraph()) + + def test_identity_weighted_graph_array(self): + """Conversion from weighted graph to array to weighted graph.""" + A = nx.to_numpy_array(self.G3) + self.identity_conversion(self.G3, A, nx.Graph()) + + def test_identity_weighted_digraph_array(self): + """Conversion from weighted digraph to array to weighted digraph.""" + A = nx.to_numpy_array(self.G4) + self.identity_conversion(self.G4, A, nx.DiGraph()) + + def test_nodelist(self): + """Conversion from graph to array to graph with nodelist.""" + P4 = nx.path_graph(4) + P3 = nx.path_graph(3) + nodelist = list(P3) + A = nx.to_numpy_array(P4, nodelist=nodelist) + GA = nx.Graph(A) + self.assert_equal(GA, P3) + + # Make nodelist ambiguous by containing duplicates. + nodelist += [nodelist[0]] + pytest.raises(nx.NetworkXError, nx.to_numpy_array, P3, nodelist=nodelist) + + # Make nodelist invalid by including nonexistent nodes + nodelist = [-1, 0, 1] + with pytest.raises( + nx.NetworkXError, + match=f"Nodes {nodelist - P3.nodes} in nodelist is not in G", + ): + nx.to_numpy_array(P3, nodelist=nodelist) + + def test_weight_keyword(self): + WP4 = nx.Graph() + WP4.add_edges_from((n, n + 1, {"weight": 0.5, "other": 0.3}) for n in range(3)) + P4 = nx.path_graph(4) + A = nx.to_numpy_array(P4) + np.testing.assert_equal(A, nx.to_numpy_array(WP4, weight=None)) + np.testing.assert_equal(0.5 * A, nx.to_numpy_array(WP4)) + np.testing.assert_equal(0.3 * A, nx.to_numpy_array(WP4, weight="other")) + + def test_from_numpy_array_type(self): + A = np.array([[1]]) + G = nx.from_numpy_array(A) + assert isinstance(G[0][0]["weight"], int) + + A = np.array([[1]]).astype(float) + G = nx.from_numpy_array(A) + assert isinstance(G[0][0]["weight"], float) + + A = np.array([[1]]).astype(str) + G = nx.from_numpy_array(A) + assert isinstance(G[0][0]["weight"], str) + + A = np.array([[1]]).astype(bool) + G = nx.from_numpy_array(A) + assert isinstance(G[0][0]["weight"], bool) + + A = np.array([[1]]).astype(complex) + G = nx.from_numpy_array(A) + assert isinstance(G[0][0]["weight"], complex) + + A = np.array([[1]]).astype(object) + pytest.raises(TypeError, nx.from_numpy_array, A) + + A = np.array([[[1, 1, 1], [1, 1, 1]], [[1, 1, 1], [1, 1, 1]]]) + with pytest.raises( + nx.NetworkXError, match=f"Input array must be 2D, not {A.ndim}" + ): + g = nx.from_numpy_array(A) + + def test_from_numpy_array_dtype(self): + dt = [("weight", float), ("cost", int)] + A = np.array([[(1.0, 2)]], dtype=dt) + G = nx.from_numpy_array(A) + assert isinstance(G[0][0]["weight"], float) + assert isinstance(G[0][0]["cost"], int) + assert G[0][0]["cost"] == 2 + assert G[0][0]["weight"] == 1.0 + + def test_from_numpy_array_parallel_edges(self): + """Tests that the :func:`networkx.from_numpy_array` function + interprets integer weights as the number of parallel edges when + creating a multigraph. + + """ + A = np.array([[1, 1], [1, 2]]) + # First, with a simple graph, each integer entry in the adjacency + # matrix is interpreted as the weight of a single edge in the graph. + expected = nx.DiGraph() + edges = [(0, 0), (0, 1), (1, 0)] + expected.add_weighted_edges_from([(u, v, 1) for (u, v) in edges]) + expected.add_edge(1, 1, weight=2) + actual = nx.from_numpy_array(A, parallel_edges=True, create_using=nx.DiGraph) + assert graphs_equal(actual, expected) + actual = nx.from_numpy_array(A, parallel_edges=False, create_using=nx.DiGraph) + assert graphs_equal(actual, expected) + # Now each integer entry in the adjacency matrix is interpreted as the + # number of parallel edges in the graph if the appropriate keyword + # argument is specified. + edges = [(0, 0), (0, 1), (1, 0), (1, 1), (1, 1)] + expected = nx.MultiDiGraph() + expected.add_weighted_edges_from([(u, v, 1) for (u, v) in edges]) + actual = nx.from_numpy_array( + A, parallel_edges=True, create_using=nx.MultiDiGraph + ) + assert graphs_equal(actual, expected) + expected = nx.MultiDiGraph() + expected.add_edges_from(set(edges), weight=1) + # The sole self-loop (edge 0) on vertex 1 should have weight 2. + expected[1][1][0]["weight"] = 2 + actual = nx.from_numpy_array( + A, parallel_edges=False, create_using=nx.MultiDiGraph + ) + assert graphs_equal(actual, expected) + + @pytest.mark.parametrize( + "dt", + ( + None, # default + int, # integer dtype + np.dtype( + [("weight", "f8"), ("color", "i1")] + ), # Structured dtype with named fields + ), + ) + def test_from_numpy_array_no_edge_attr(self, dt): + A = np.array([[0, 1], [1, 0]], dtype=dt) + G = nx.from_numpy_array(A, edge_attr=None) + assert "weight" not in G.edges[0, 1] + assert len(G.edges[0, 1]) == 0 + + def test_from_numpy_array_multiedge_no_edge_attr(self): + A = np.array([[0, 2], [2, 0]]) + G = nx.from_numpy_array(A, create_using=nx.MultiDiGraph, edge_attr=None) + assert all("weight" not in e for _, e in G[0][1].items()) + assert len(G[0][1][0]) == 0 + + def test_from_numpy_array_custom_edge_attr(self): + A = np.array([[0, 2], [3, 0]]) + G = nx.from_numpy_array(A, edge_attr="cost") + assert "weight" not in G.edges[0, 1] + assert G.edges[0, 1]["cost"] == 3 + + def test_symmetric(self): + """Tests that a symmetric array has edges added only once to an + undirected multigraph when using :func:`networkx.from_numpy_array`. + + """ + A = np.array([[0, 1], [1, 0]]) + G = nx.from_numpy_array(A, create_using=nx.MultiGraph) + expected = nx.MultiGraph() + expected.add_edge(0, 1, weight=1) + assert graphs_equal(G, expected) + + def test_dtype_int_graph(self): + """Test that setting dtype int actually gives an integer array. + + For more information, see GitHub pull request #1363. + + """ + G = nx.complete_graph(3) + A = nx.to_numpy_array(G, dtype=int) + assert A.dtype == int + + def test_dtype_int_multigraph(self): + """Test that setting dtype int actually gives an integer array. + + For more information, see GitHub pull request #1363. + + """ + G = nx.MultiGraph(nx.complete_graph(3)) + A = nx.to_numpy_array(G, dtype=int) + assert A.dtype == int + + +@pytest.fixture +def multigraph_test_graph(): + G = nx.MultiGraph() + G.add_edge(1, 2, weight=7) + G.add_edge(1, 2, weight=70) + return G + + +@pytest.mark.parametrize(("operator", "expected"), ((sum, 77), (min, 7), (max, 70))) +def test_numpy_multigraph(multigraph_test_graph, operator, expected): + A = nx.to_numpy_array(multigraph_test_graph, multigraph_weight=operator) + assert A[1, 0] == expected + + +def test_to_numpy_array_multigraph_nodelist(multigraph_test_graph): + G = multigraph_test_graph + G.add_edge(0, 1, weight=3) + A = nx.to_numpy_array(G, nodelist=[1, 2]) + assert A.shape == (2, 2) + assert A[1, 0] == 77 + + +@pytest.mark.parametrize( + "G, expected", + [ + (nx.Graph(), np.array([[0, 1 + 2j], [1 + 2j, 0]], dtype=complex)), + (nx.DiGraph(), np.array([[0, 1 + 2j], [0, 0]], dtype=complex)), + ], +) +def test_to_numpy_array_complex_weights(G, expected): + G.add_edge(0, 1, weight=1 + 2j) + A = nx.to_numpy_array(G, dtype=complex) + npt.assert_array_equal(A, expected) + + +def test_to_numpy_array_arbitrary_weights(): + G = nx.DiGraph() + w = 922337203685477580102 # Out of range for int64 + G.add_edge(0, 1, weight=922337203685477580102) # val not representable by int64 + A = nx.to_numpy_array(G, dtype=object) + expected = np.array([[0, w], [0, 0]], dtype=object) + npt.assert_array_equal(A, expected) + + # Undirected + A = nx.to_numpy_array(G.to_undirected(), dtype=object) + expected = np.array([[0, w], [w, 0]], dtype=object) + npt.assert_array_equal(A, expected) + + +@pytest.mark.parametrize( + "func, expected", + ((min, -1), (max, 10), (sum, 11), (np.mean, 11 / 3), (np.median, 2)), +) +def test_to_numpy_array_multiweight_reduction(func, expected): + """Test various functions for reducing multiedge weights.""" + G = nx.MultiDiGraph() + weights = [-1, 2, 10.0] + for w in weights: + G.add_edge(0, 1, weight=w) + A = nx.to_numpy_array(G, multigraph_weight=func, dtype=float) + assert np.allclose(A, [[0, expected], [0, 0]]) + + # Undirected case + A = nx.to_numpy_array(G.to_undirected(), multigraph_weight=func, dtype=float) + assert np.allclose(A, [[0, expected], [expected, 0]]) + + +@pytest.mark.parametrize( + ("G, expected"), + [ + (nx.Graph(), [[(0, 0), (10, 5)], [(10, 5), (0, 0)]]), + (nx.DiGraph(), [[(0, 0), (10, 5)], [(0, 0), (0, 0)]]), + ], +) +def test_to_numpy_array_structured_dtype_attrs_from_fields(G, expected): + """When `dtype` is structured (i.e. has names) and `weight` is None, use + the named fields of the dtype to look up edge attributes.""" + G.add_edge(0, 1, weight=10, cost=5.0) + dtype = np.dtype([("weight", int), ("cost", int)]) + A = nx.to_numpy_array(G, dtype=dtype, weight=None) + expected = np.asarray(expected, dtype=dtype) + npt.assert_array_equal(A, expected) + + +def test_to_numpy_array_structured_dtype_single_attr_default(): + G = nx.path_graph(3) + dtype = np.dtype([("weight", float)]) # A single named field + A = nx.to_numpy_array(G, dtype=dtype, weight=None) + expected = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=float) + npt.assert_array_equal(A["weight"], expected) + + +@pytest.mark.parametrize( + ("field_name", "expected_attr_val"), + [ + ("weight", 1), + ("cost", 3), + ], +) +def test_to_numpy_array_structured_dtype_single_attr(field_name, expected_attr_val): + G = nx.Graph() + G.add_edge(0, 1, cost=3) + dtype = np.dtype([(field_name, float)]) + A = nx.to_numpy_array(G, dtype=dtype, weight=None) + expected = np.array([[0, expected_attr_val], [expected_attr_val, 0]], dtype=float) + npt.assert_array_equal(A[field_name], expected) + + +@pytest.mark.parametrize("graph_type", (nx.Graph, nx.DiGraph)) +@pytest.mark.parametrize( + "edge", + [ + (0, 1), # No edge attributes + (0, 1, {"weight": 10}), # One edge attr + (0, 1, {"weight": 5, "flow": -4}), # Multiple but not all edge attrs + (0, 1, {"weight": 2.0, "cost": 10, "flow": -45}), # All attrs + ], +) +def test_to_numpy_array_structured_dtype_multiple_fields(graph_type, edge): + G = graph_type([edge]) + dtype = np.dtype([("weight", float), ("cost", float), ("flow", float)]) + A = nx.to_numpy_array(G, dtype=dtype, weight=None) + for attr in dtype.names: + expected = nx.to_numpy_array(G, dtype=float, weight=attr) + npt.assert_array_equal(A[attr], expected) + + +@pytest.mark.parametrize("G", (nx.Graph(), nx.DiGraph())) +def test_to_numpy_array_structured_dtype_scalar_nonedge(G): + G.add_edge(0, 1, weight=10) + dtype = np.dtype([("weight", float), ("cost", float)]) + A = nx.to_numpy_array(G, dtype=dtype, weight=None, nonedge=np.nan) + for attr in dtype.names: + expected = nx.to_numpy_array(G, dtype=float, weight=attr, nonedge=np.nan) + npt.assert_array_equal(A[attr], expected) + + +@pytest.mark.parametrize("G", (nx.Graph(), nx.DiGraph())) +def test_to_numpy_array_structured_dtype_nonedge_ary(G): + """Similar to the scalar case, except has a different non-edge value for + each named field.""" + G.add_edge(0, 1, weight=10) + dtype = np.dtype([("weight", float), ("cost", float)]) + nonedges = np.array([(0, np.inf)], dtype=dtype) + A = nx.to_numpy_array(G, dtype=dtype, weight=None, nonedge=nonedges) + for attr in dtype.names: + nonedge = nonedges[attr] + expected = nx.to_numpy_array(G, dtype=float, weight=attr, nonedge=nonedge) + npt.assert_array_equal(A[attr], expected) + + +def test_to_numpy_array_structured_dtype_with_weight_raises(): + """Using both a structured dtype (with named fields) and specifying a `weight` + parameter is ambiguous.""" + G = nx.path_graph(3) + dtype = np.dtype([("weight", int), ("cost", int)]) + exception_msg = "Specifying `weight` not supported for structured dtypes" + with pytest.raises(ValueError, match=exception_msg): + nx.to_numpy_array(G, dtype=dtype) # Default is weight="weight" + with pytest.raises(ValueError, match=exception_msg): + nx.to_numpy_array(G, dtype=dtype, weight="cost") + + +@pytest.mark.parametrize("graph_type", (nx.MultiGraph, nx.MultiDiGraph)) +def test_to_numpy_array_structured_multigraph_raises(graph_type): + G = nx.path_graph(3, create_using=graph_type) + dtype = np.dtype([("weight", int), ("cost", int)]) + with pytest.raises(nx.NetworkXError, match="Structured arrays are not supported"): + nx.to_numpy_array(G, dtype=dtype, weight=None) + + +def test_from_numpy_array_nodelist_bad_size(): + """An exception is raised when `len(nodelist) != A.shape[0]`.""" + n = 5 # Number of nodes + A = np.diag(np.ones(n - 1), k=1) # Adj. matrix for P_n + expected = nx.path_graph(n) + + assert graphs_equal(nx.from_numpy_array(A, edge_attr=None), expected) + nodes = list(range(n)) + assert graphs_equal( + nx.from_numpy_array(A, edge_attr=None, nodelist=nodes), expected + ) + + # Too many node labels + nodes = list(range(n + 1)) + with pytest.raises(ValueError, match="nodelist must have the same length as A"): + nx.from_numpy_array(A, nodelist=nodes) + + # Too few node labels + nodes = list(range(n - 1)) + with pytest.raises(ValueError, match="nodelist must have the same length as A"): + nx.from_numpy_array(A, nodelist=nodes) + + +@pytest.mark.parametrize( + "nodes", + ( + [4, 3, 2, 1, 0], + [9, 7, 1, 2, 8], + ["a", "b", "c", "d", "e"], + [(0, 0), (1, 1), (2, 3), (0, 2), (3, 1)], + ["A", 2, 7, "spam", (1, 3)], + ), +) +def test_from_numpy_array_nodelist(nodes): + A = np.diag(np.ones(4), k=1) + # Without edge attributes + expected = nx.relabel_nodes( + nx.path_graph(5), mapping=dict(enumerate(nodes)), copy=True + ) + G = nx.from_numpy_array(A, edge_attr=None, nodelist=nodes) + assert graphs_equal(G, expected) + + # With edge attributes + nx.set_edge_attributes(expected, 1.0, name="weight") + G = nx.from_numpy_array(A, nodelist=nodes) + assert graphs_equal(G, expected) + + +@pytest.mark.parametrize( + "nodes", + ( + [4, 3, 2, 1, 0], + [9, 7, 1, 2, 8], + ["a", "b", "c", "d", "e"], + [(0, 0), (1, 1), (2, 3), (0, 2), (3, 1)], + ["A", 2, 7, "spam", (1, 3)], + ), +) +def test_from_numpy_array_nodelist_directed(nodes): + A = np.diag(np.ones(4), k=1) + # Without edge attributes + H = nx.DiGraph([(0, 1), (1, 2), (2, 3), (3, 4)]) + expected = nx.relabel_nodes(H, mapping=dict(enumerate(nodes)), copy=True) + G = nx.from_numpy_array(A, create_using=nx.DiGraph, edge_attr=None, nodelist=nodes) + assert graphs_equal(G, expected) + + # With edge attributes + nx.set_edge_attributes(expected, 1.0, name="weight") + G = nx.from_numpy_array(A, create_using=nx.DiGraph, nodelist=nodes) + assert graphs_equal(G, expected) + + +@pytest.mark.parametrize( + "nodes", + ( + [4, 3, 2, 1, 0], + [9, 7, 1, 2, 8], + ["a", "b", "c", "d", "e"], + [(0, 0), (1, 1), (2, 3), (0, 2), (3, 1)], + ["A", 2, 7, "spam", (1, 3)], + ), +) +def test_from_numpy_array_nodelist_multigraph(nodes): + A = np.array( + [ + [0, 1, 0, 0, 0], + [1, 0, 2, 0, 0], + [0, 2, 0, 3, 0], + [0, 0, 3, 0, 4], + [0, 0, 0, 4, 0], + ] + ) + + H = nx.MultiGraph() + for i, edge in enumerate(((0, 1), (1, 2), (2, 3), (3, 4))): + H.add_edges_from(itertools.repeat(edge, i + 1)) + expected = nx.relabel_nodes(H, mapping=dict(enumerate(nodes)), copy=True) + + G = nx.from_numpy_array( + A, + parallel_edges=True, + create_using=nx.MultiGraph, + edge_attr=None, + nodelist=nodes, + ) + assert graphs_equal(G, expected) + + +@pytest.mark.parametrize( + "nodes", + ( + [4, 3, 2, 1, 0], + [9, 7, 1, 2, 8], + ["a", "b", "c", "d", "e"], + [(0, 0), (1, 1), (2, 3), (0, 2), (3, 1)], + ["A", 2, 7, "spam", (1, 3)], + ), +) +@pytest.mark.parametrize("graph", (nx.complete_graph, nx.cycle_graph, nx.wheel_graph)) +def test_from_numpy_array_nodelist_rountrip(graph, nodes): + G = graph(5) + A = nx.to_numpy_array(G) + expected = nx.relabel_nodes(G, mapping=dict(enumerate(nodes)), copy=True) + H = nx.from_numpy_array(A, edge_attr=None, nodelist=nodes) + assert graphs_equal(H, expected) + + # With an isolated node + G = graph(4) + G.add_node("foo") + A = nx.to_numpy_array(G) + expected = nx.relabel_nodes(G, mapping=dict(zip(G.nodes, nodes)), copy=True) + H = nx.from_numpy_array(A, edge_attr=None, nodelist=nodes) + assert graphs_equal(H, expected) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert_pandas.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert_pandas.py new file mode 100644 index 0000000000000000000000000000000000000000..eaa8d695f868dbb551d3a3819cedd590a25492f8 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert_pandas.py @@ -0,0 +1,349 @@ +import pytest + +import networkx as nx +from networkx.utils import edges_equal, graphs_equal, nodes_equal + +np = pytest.importorskip("numpy") +pd = pytest.importorskip("pandas") + + +class TestConvertPandas: + def setup_method(self): + self.rng = np.random.RandomState(seed=5) + ints = self.rng.randint(1, 11, size=(3, 2)) + a = ["A", "B", "C"] + b = ["D", "A", "E"] + df = pd.DataFrame(ints, columns=["weight", "cost"]) + df[0] = a # Column label 0 (int) + df["b"] = b # Column label 'b' (str) + self.df = df + + mdf = pd.DataFrame([[4, 16, "A", "D"]], columns=["weight", "cost", 0, "b"]) + self.mdf = pd.concat([df, mdf]) + + def test_exceptions(self): + G = pd.DataFrame(["a"]) # adj + pytest.raises(nx.NetworkXError, nx.to_networkx_graph, G) + G = pd.DataFrame(["a", 0.0]) # elist + pytest.raises(nx.NetworkXError, nx.to_networkx_graph, G) + df = pd.DataFrame([[1, 1], [1, 0]], dtype=int, index=[1, 2], columns=["a", "b"]) + pytest.raises(nx.NetworkXError, nx.from_pandas_adjacency, df) + + def test_from_edgelist_all_attr(self): + Gtrue = nx.Graph( + [ + ("E", "C", {"cost": 9, "weight": 10}), + ("B", "A", {"cost": 1, "weight": 7}), + ("A", "D", {"cost": 7, "weight": 4}), + ] + ) + G = nx.from_pandas_edgelist(self.df, 0, "b", True) + assert graphs_equal(G, Gtrue) + # MultiGraph + MGtrue = nx.MultiGraph(Gtrue) + MGtrue.add_edge("A", "D", cost=16, weight=4) + MG = nx.from_pandas_edgelist(self.mdf, 0, "b", True, nx.MultiGraph()) + assert graphs_equal(MG, MGtrue) + + def test_from_edgelist_multi_attr(self): + Gtrue = nx.Graph( + [ + ("E", "C", {"cost": 9, "weight": 10}), + ("B", "A", {"cost": 1, "weight": 7}), + ("A", "D", {"cost": 7, "weight": 4}), + ] + ) + G = nx.from_pandas_edgelist(self.df, 0, "b", ["weight", "cost"]) + assert graphs_equal(G, Gtrue) + + def test_from_edgelist_multi_attr_incl_target(self): + Gtrue = nx.Graph( + [ + ("E", "C", {0: "C", "b": "E", "weight": 10}), + ("B", "A", {0: "B", "b": "A", "weight": 7}), + ("A", "D", {0: "A", "b": "D", "weight": 4}), + ] + ) + G = nx.from_pandas_edgelist(self.df, 0, "b", [0, "b", "weight"]) + assert graphs_equal(G, Gtrue) + + def test_from_edgelist_multidigraph_and_edge_attr(self): + # example from issue #2374 + edges = [ + ("X1", "X4", {"Co": "zA", "Mi": 0, "St": "X1"}), + ("X1", "X4", {"Co": "zB", "Mi": 54, "St": "X2"}), + ("X1", "X4", {"Co": "zB", "Mi": 49, "St": "X3"}), + ("X1", "X4", {"Co": "zB", "Mi": 44, "St": "X4"}), + ("Y1", "Y3", {"Co": "zC", "Mi": 0, "St": "Y1"}), + ("Y1", "Y3", {"Co": "zC", "Mi": 34, "St": "Y2"}), + ("Y1", "Y3", {"Co": "zC", "Mi": 29, "St": "X2"}), + ("Y1", "Y3", {"Co": "zC", "Mi": 24, "St": "Y3"}), + ("Z1", "Z3", {"Co": "zD", "Mi": 0, "St": "Z1"}), + ("Z1", "Z3", {"Co": "zD", "Mi": 14, "St": "X3"}), + ] + Gtrue = nx.MultiDiGraph(edges) + data = { + "O": ["X1", "X1", "X1", "X1", "Y1", "Y1", "Y1", "Y1", "Z1", "Z1"], + "D": ["X4", "X4", "X4", "X4", "Y3", "Y3", "Y3", "Y3", "Z3", "Z3"], + "St": ["X1", "X2", "X3", "X4", "Y1", "Y2", "X2", "Y3", "Z1", "X3"], + "Co": ["zA", "zB", "zB", "zB", "zC", "zC", "zC", "zC", "zD", "zD"], + "Mi": [0, 54, 49, 44, 0, 34, 29, 24, 0, 14], + } + df = pd.DataFrame.from_dict(data) + G1 = nx.from_pandas_edgelist( + df, source="O", target="D", edge_attr=True, create_using=nx.MultiDiGraph + ) + G2 = nx.from_pandas_edgelist( + df, + source="O", + target="D", + edge_attr=["St", "Co", "Mi"], + create_using=nx.MultiDiGraph, + ) + assert graphs_equal(G1, Gtrue) + assert graphs_equal(G2, Gtrue) + + def test_from_edgelist_one_attr(self): + Gtrue = nx.Graph( + [ + ("E", "C", {"weight": 10}), + ("B", "A", {"weight": 7}), + ("A", "D", {"weight": 4}), + ] + ) + G = nx.from_pandas_edgelist(self.df, 0, "b", "weight") + assert graphs_equal(G, Gtrue) + + def test_from_edgelist_int_attr_name(self): + # note: this also tests that edge_attr can be `source` + Gtrue = nx.Graph( + [("E", "C", {0: "C"}), ("B", "A", {0: "B"}), ("A", "D", {0: "A"})] + ) + G = nx.from_pandas_edgelist(self.df, 0, "b", 0) + assert graphs_equal(G, Gtrue) + + def test_from_edgelist_invalid_attr(self): + pytest.raises( + nx.NetworkXError, nx.from_pandas_edgelist, self.df, 0, "b", "misspell" + ) + pytest.raises(nx.NetworkXError, nx.from_pandas_edgelist, self.df, 0, "b", 1) + # see Issue #3562 + edgeframe = pd.DataFrame([[0, 1], [1, 2], [2, 0]], columns=["s", "t"]) + pytest.raises( + nx.NetworkXError, nx.from_pandas_edgelist, edgeframe, "s", "t", True + ) + pytest.raises( + nx.NetworkXError, nx.from_pandas_edgelist, edgeframe, "s", "t", "weight" + ) + pytest.raises( + nx.NetworkXError, + nx.from_pandas_edgelist, + edgeframe, + "s", + "t", + ["weight", "size"], + ) + + def test_from_edgelist_no_attr(self): + Gtrue = nx.Graph([("E", "C", {}), ("B", "A", {}), ("A", "D", {})]) + G = nx.from_pandas_edgelist(self.df, 0, "b") + assert graphs_equal(G, Gtrue) + + def test_from_edgelist(self): + # Pandas DataFrame + G = nx.cycle_graph(10) + G.add_weighted_edges_from((u, v, u) for u, v in list(G.edges)) + + edgelist = nx.to_edgelist(G) + source = [s for s, t, d in edgelist] + target = [t for s, t, d in edgelist] + weight = [d["weight"] for s, t, d in edgelist] + edges = pd.DataFrame({"source": source, "target": target, "weight": weight}) + + GG = nx.from_pandas_edgelist(edges, edge_attr="weight") + assert nodes_equal(G.nodes(), GG.nodes()) + assert edges_equal(G.edges(), GG.edges()) + GW = nx.to_networkx_graph(edges, create_using=nx.Graph) + assert nodes_equal(G.nodes(), GW.nodes()) + assert edges_equal(G.edges(), GW.edges()) + + def test_to_edgelist_default_source_or_target_col_exists(self): + G = nx.path_graph(10) + G.add_weighted_edges_from((u, v, u) for u, v in list(G.edges)) + nx.set_edge_attributes(G, 0, name="source") + pytest.raises(nx.NetworkXError, nx.to_pandas_edgelist, G) + + # drop source column to test an exception raised for the target column + for u, v, d in G.edges(data=True): + d.pop("source", None) + + nx.set_edge_attributes(G, 0, name="target") + pytest.raises(nx.NetworkXError, nx.to_pandas_edgelist, G) + + def test_to_edgelist_custom_source_or_target_col_exists(self): + G = nx.path_graph(10) + G.add_weighted_edges_from((u, v, u) for u, v in list(G.edges)) + nx.set_edge_attributes(G, 0, name="source_col_name") + pytest.raises( + nx.NetworkXError, nx.to_pandas_edgelist, G, source="source_col_name" + ) + + # drop source column to test an exception raised for the target column + for u, v, d in G.edges(data=True): + d.pop("source_col_name", None) + + nx.set_edge_attributes(G, 0, name="target_col_name") + pytest.raises( + nx.NetworkXError, nx.to_pandas_edgelist, G, target="target_col_name" + ) + + def test_to_edgelist_edge_key_col_exists(self): + G = nx.path_graph(10, create_using=nx.MultiGraph) + G.add_weighted_edges_from((u, v, u) for u, v in list(G.edges())) + nx.set_edge_attributes(G, 0, name="edge_key_name") + pytest.raises( + nx.NetworkXError, nx.to_pandas_edgelist, G, edge_key="edge_key_name" + ) + + def test_from_adjacency(self): + nodelist = [1, 2] + dftrue = pd.DataFrame( + [[1, 1], [1, 0]], dtype=int, index=nodelist, columns=nodelist + ) + G = nx.Graph([(1, 1), (1, 2)]) + df = nx.to_pandas_adjacency(G, dtype=int) + pd.testing.assert_frame_equal(df, dftrue) + + @pytest.mark.parametrize("graph", [nx.Graph, nx.MultiGraph]) + def test_roundtrip(self, graph): + # edgelist + Gtrue = graph([(1, 1), (1, 2)]) + df = nx.to_pandas_edgelist(Gtrue) + G = nx.from_pandas_edgelist(df, create_using=graph) + assert graphs_equal(Gtrue, G) + # adjacency + adj = {1: {1: {"weight": 1}, 2: {"weight": 1}}, 2: {1: {"weight": 1}}} + Gtrue = graph(adj) + df = nx.to_pandas_adjacency(Gtrue, dtype=int) + G = nx.from_pandas_adjacency(df, create_using=graph) + assert graphs_equal(Gtrue, G) + + def test_from_adjacency_named(self): + # example from issue #3105 + data = { + "A": {"A": 0, "B": 0, "C": 0}, + "B": {"A": 1, "B": 0, "C": 0}, + "C": {"A": 0, "B": 1, "C": 0}, + } + dftrue = pd.DataFrame(data, dtype=np.intp) + df = dftrue[["A", "C", "B"]] + G = nx.from_pandas_adjacency(df, create_using=nx.DiGraph()) + df = nx.to_pandas_adjacency(G, dtype=np.intp) + pd.testing.assert_frame_equal(df, dftrue) + + @pytest.mark.parametrize("edge_attr", [["attr2", "attr3"], True]) + def test_edgekey_with_multigraph(self, edge_attr): + df = pd.DataFrame( + { + "source": {"A": "N1", "B": "N2", "C": "N1", "D": "N1"}, + "target": {"A": "N2", "B": "N3", "C": "N1", "D": "N2"}, + "attr1": {"A": "F1", "B": "F2", "C": "F3", "D": "F4"}, + "attr2": {"A": 1, "B": 0, "C": 0, "D": 0}, + "attr3": {"A": 0, "B": 1, "C": 0, "D": 1}, + } + ) + Gtrue = nx.MultiGraph( + [ + ("N1", "N2", "F1", {"attr2": 1, "attr3": 0}), + ("N2", "N3", "F2", {"attr2": 0, "attr3": 1}), + ("N1", "N1", "F3", {"attr2": 0, "attr3": 0}), + ("N1", "N2", "F4", {"attr2": 0, "attr3": 1}), + ] + ) + # example from issue #4065 + G = nx.from_pandas_edgelist( + df, + source="source", + target="target", + edge_attr=edge_attr, + edge_key="attr1", + create_using=nx.MultiGraph(), + ) + assert graphs_equal(G, Gtrue) + + df_roundtrip = nx.to_pandas_edgelist(G, edge_key="attr1") + df_roundtrip = df_roundtrip.sort_values("attr1") + df_roundtrip.index = ["A", "B", "C", "D"] + pd.testing.assert_frame_equal( + df, df_roundtrip[["source", "target", "attr1", "attr2", "attr3"]] + ) + + def test_edgekey_with_normal_graph_no_action(self): + Gtrue = nx.Graph( + [ + ("E", "C", {"cost": 9, "weight": 10}), + ("B", "A", {"cost": 1, "weight": 7}), + ("A", "D", {"cost": 7, "weight": 4}), + ] + ) + G = nx.from_pandas_edgelist(self.df, 0, "b", True, edge_key="weight") + assert graphs_equal(G, Gtrue) + + def test_nonexisting_edgekey_raises(self): + with pytest.raises(nx.exception.NetworkXError): + nx.from_pandas_edgelist( + self.df, + source="source", + target="target", + edge_key="Not_real", + edge_attr=True, + create_using=nx.MultiGraph(), + ) + + def test_multigraph_with_edgekey_no_edgeattrs(self): + Gtrue = nx.MultiGraph() + Gtrue.add_edge(0, 1, key=0) + Gtrue.add_edge(0, 1, key=3) + df = nx.to_pandas_edgelist(Gtrue, edge_key="key") + expected = pd.DataFrame({"source": [0, 0], "target": [1, 1], "key": [0, 3]}) + pd.testing.assert_frame_equal(expected, df) + G = nx.from_pandas_edgelist(df, edge_key="key", create_using=nx.MultiGraph) + assert graphs_equal(Gtrue, G) + + +def test_to_pandas_adjacency_with_nodelist(): + G = nx.complete_graph(5) + nodelist = [1, 4] + expected = pd.DataFrame( + [[0, 1], [1, 0]], dtype=int, index=nodelist, columns=nodelist + ) + pd.testing.assert_frame_equal( + expected, nx.to_pandas_adjacency(G, nodelist, dtype=int) + ) + + +def test_to_pandas_edgelist_with_nodelist(): + G = nx.Graph() + G.add_edges_from([(0, 1), (1, 2), (1, 3)], weight=2.0) + G.add_edge(0, 5, weight=100) + df = nx.to_pandas_edgelist(G, nodelist=[1, 2]) + assert 0 not in df["source"].to_numpy() + assert 100 not in df["weight"].to_numpy() + + +def test_from_pandas_adjacency_with_index_collisions(): + """See gh-7407""" + df = pd.DataFrame( + [ + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1], + [0, 0, 0, 0], + ], + index=[1010001, 2, 1, 1010002], + columns=[1010001, 2, 1, 1010002], + ) + G = nx.from_pandas_adjacency(df, create_using=nx.DiGraph) + expected = nx.DiGraph([(1010001, 2), (2, 1), (1, 1010002)]) + assert nodes_equal(G.nodes, expected.nodes) + assert edges_equal(G.edges, expected.edges, directed=True) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert_scipy.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert_scipy.py new file mode 100644 index 0000000000000000000000000000000000000000..2575027046c61612c1be3c36a5b7877c28e71d92 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_convert_scipy.py @@ -0,0 +1,281 @@ +import pytest + +import networkx as nx +from networkx.utils import graphs_equal + +np = pytest.importorskip("numpy") +sp = pytest.importorskip("scipy") + + +class TestConvertScipy: + def setup_method(self): + self.G1 = nx.barbell_graph(10, 3) + self.G2 = nx.cycle_graph(10, create_using=nx.DiGraph) + + self.G3 = self.create_weighted(nx.Graph()) + self.G4 = self.create_weighted(nx.DiGraph()) + + def test_exceptions(self): + class G: + format = None + + pytest.raises(nx.NetworkXError, nx.to_networkx_graph, G) + + def create_weighted(self, G): + g = nx.cycle_graph(4) + e = list(g.edges()) + source = [u for u, v in e] + dest = [v for u, v in e] + weight = [s + 10 for s in source] + ex = zip(source, dest, weight) + G.add_weighted_edges_from(ex) + return G + + def identity_conversion(self, G, A, create_using): + GG = nx.from_scipy_sparse_array(A, create_using=create_using) + assert nx.is_isomorphic(G, GG) + + GW = nx.to_networkx_graph(A, create_using=create_using) + assert nx.is_isomorphic(G, GW) + + GI = nx.empty_graph(0, create_using).__class__(A) + assert nx.is_isomorphic(G, GI) + + ACSR = A.tocsr() + GI = nx.empty_graph(0, create_using).__class__(ACSR) + assert nx.is_isomorphic(G, GI) + + ACOO = A.tocoo() + GI = nx.empty_graph(0, create_using).__class__(ACOO) + assert nx.is_isomorphic(G, GI) + + ACSC = A.tocsc() + GI = nx.empty_graph(0, create_using).__class__(ACSC) + assert nx.is_isomorphic(G, GI) + + AD = A.todense() + GI = nx.empty_graph(0, create_using).__class__(AD) + assert nx.is_isomorphic(G, GI) + + AA = A.toarray() + GI = nx.empty_graph(0, create_using).__class__(AA) + assert nx.is_isomorphic(G, GI) + + def test_shape(self): + "Conversion from non-square sparse array." + A = sp.sparse.lil_array([[1, 2, 3], [4, 5, 6]]) + pytest.raises(nx.NetworkXError, nx.from_scipy_sparse_array, A) + + def test_identity_graph_matrix(self): + "Conversion from graph to sparse matrix to graph." + A = nx.to_scipy_sparse_array(self.G1) + self.identity_conversion(self.G1, A, nx.Graph()) + + def test_identity_digraph_matrix(self): + "Conversion from digraph to sparse matrix to digraph." + A = nx.to_scipy_sparse_array(self.G2) + self.identity_conversion(self.G2, A, nx.DiGraph()) + + def test_identity_weighted_graph_matrix(self): + """Conversion from weighted graph to sparse matrix to weighted graph.""" + A = nx.to_scipy_sparse_array(self.G3) + self.identity_conversion(self.G3, A, nx.Graph()) + + def test_identity_weighted_digraph_matrix(self): + """Conversion from weighted digraph to sparse matrix to weighted digraph.""" + A = nx.to_scipy_sparse_array(self.G4) + self.identity_conversion(self.G4, A, nx.DiGraph()) + + def test_nodelist(self): + """Conversion from graph to sparse matrix to graph with nodelist.""" + P4 = nx.path_graph(4) + P3 = nx.path_graph(3) + nodelist = list(P3.nodes()) + A = nx.to_scipy_sparse_array(P4, nodelist=nodelist) + GA = nx.Graph(A) + assert nx.is_isomorphic(GA, P3) + + pytest.raises(nx.NetworkXError, nx.to_scipy_sparse_array, P3, nodelist=[]) + # Test nodelist duplicates. + long_nl = nodelist + [0] + pytest.raises(nx.NetworkXError, nx.to_scipy_sparse_array, P3, nodelist=long_nl) + + # Test nodelist contains non-nodes + non_nl = [-1, 0, 1, 2] + pytest.raises(nx.NetworkXError, nx.to_scipy_sparse_array, P3, nodelist=non_nl) + + def test_weight_keyword(self): + WP4 = nx.Graph() + WP4.add_edges_from((n, n + 1, {"weight": 0.5, "other": 0.3}) for n in range(3)) + P4 = nx.path_graph(4) + A = nx.to_scipy_sparse_array(P4) + np.testing.assert_equal( + A.todense(), nx.to_scipy_sparse_array(WP4, weight=None).todense() + ) + np.testing.assert_equal( + 0.5 * A.todense(), nx.to_scipy_sparse_array(WP4).todense() + ) + np.testing.assert_equal( + 0.3 * A.todense(), nx.to_scipy_sparse_array(WP4, weight="other").todense() + ) + + def test_format_keyword(self): + WP4 = nx.Graph() + WP4.add_edges_from((n, n + 1, {"weight": 0.5, "other": 0.3}) for n in range(3)) + P4 = nx.path_graph(4) + A = nx.to_scipy_sparse_array(P4, format="csr") + np.testing.assert_equal( + A.todense(), nx.to_scipy_sparse_array(WP4, weight=None).todense() + ) + + A = nx.to_scipy_sparse_array(P4, format="csc") + np.testing.assert_equal( + A.todense(), nx.to_scipy_sparse_array(WP4, weight=None).todense() + ) + + A = nx.to_scipy_sparse_array(P4, format="coo") + np.testing.assert_equal( + A.todense(), nx.to_scipy_sparse_array(WP4, weight=None).todense() + ) + + A = nx.to_scipy_sparse_array(P4, format="bsr") + np.testing.assert_equal( + A.todense(), nx.to_scipy_sparse_array(WP4, weight=None).todense() + ) + + A = nx.to_scipy_sparse_array(P4, format="lil") + np.testing.assert_equal( + A.todense(), nx.to_scipy_sparse_array(WP4, weight=None).todense() + ) + + A = nx.to_scipy_sparse_array(P4, format="dia") + np.testing.assert_equal( + A.todense(), nx.to_scipy_sparse_array(WP4, weight=None).todense() + ) + + A = nx.to_scipy_sparse_array(P4, format="dok") + np.testing.assert_equal( + A.todense(), nx.to_scipy_sparse_array(WP4, weight=None).todense() + ) + + def test_format_keyword_raise(self): + with pytest.raises(nx.NetworkXError): + WP4 = nx.Graph() + WP4.add_edges_from( + (n, n + 1, {"weight": 0.5, "other": 0.3}) for n in range(3) + ) + P4 = nx.path_graph(4) + nx.to_scipy_sparse_array(P4, format="any_other") + + def test_null_raise(self): + with pytest.raises(nx.NetworkXError): + nx.to_scipy_sparse_array(nx.Graph()) + + def test_empty(self): + G = nx.Graph() + G.add_node(1) + M = nx.to_scipy_sparse_array(G) + np.testing.assert_equal(M.toarray(), np.array([[0]])) + + def test_ordering(self): + G = nx.DiGraph() + G.add_edge(1, 2) + G.add_edge(2, 3) + G.add_edge(3, 1) + M = nx.to_scipy_sparse_array(G, nodelist=[3, 2, 1]) + np.testing.assert_equal( + M.toarray(), np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]]) + ) + + def test_selfloop_graph(self): + G = nx.Graph([(1, 1)]) + M = nx.to_scipy_sparse_array(G) + np.testing.assert_equal(M.toarray(), np.array([[1]])) + + G.add_edges_from([(2, 3), (3, 4)]) + M = nx.to_scipy_sparse_array(G, nodelist=[2, 3, 4]) + np.testing.assert_equal( + M.toarray(), np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]]) + ) + + def test_selfloop_digraph(self): + G = nx.DiGraph([(1, 1)]) + M = nx.to_scipy_sparse_array(G) + np.testing.assert_equal(M.toarray(), np.array([[1]])) + + G.add_edges_from([(2, 3), (3, 4)]) + M = nx.to_scipy_sparse_array(G, nodelist=[2, 3, 4]) + np.testing.assert_equal( + M.toarray(), np.array([[0, 1, 0], [0, 0, 1], [0, 0, 0]]) + ) + + def test_from_scipy_sparse_array_parallel_edges(self): + """Tests that the :func:`networkx.from_scipy_sparse_array` function + interprets integer weights as the number of parallel edges when + creating a multigraph. + + """ + A = sp.sparse.csr_array([[1, 1], [1, 2]]) + # First, with a simple graph, each integer entry in the adjacency + # matrix is interpreted as the weight of a single edge in the graph. + expected = nx.DiGraph() + edges = [(0, 0), (0, 1), (1, 0)] + expected.add_weighted_edges_from([(u, v, 1) for (u, v) in edges]) + expected.add_edge(1, 1, weight=2) + actual = nx.from_scipy_sparse_array( + A, parallel_edges=True, create_using=nx.DiGraph + ) + assert graphs_equal(actual, expected) + actual = nx.from_scipy_sparse_array( + A, parallel_edges=False, create_using=nx.DiGraph + ) + assert graphs_equal(actual, expected) + # Now each integer entry in the adjacency matrix is interpreted as the + # number of parallel edges in the graph if the appropriate keyword + # argument is specified. + edges = [(0, 0), (0, 1), (1, 0), (1, 1), (1, 1)] + expected = nx.MultiDiGraph() + expected.add_weighted_edges_from([(u, v, 1) for (u, v) in edges]) + actual = nx.from_scipy_sparse_array( + A, parallel_edges=True, create_using=nx.MultiDiGraph + ) + assert graphs_equal(actual, expected) + expected = nx.MultiDiGraph() + expected.add_edges_from(set(edges), weight=1) + # The sole self-loop (edge 0) on vertex 1 should have weight 2. + expected[1][1][0]["weight"] = 2 + actual = nx.from_scipy_sparse_array( + A, parallel_edges=False, create_using=nx.MultiDiGraph + ) + assert graphs_equal(actual, expected) + + def test_symmetric(self): + """Tests that a symmetric matrix has edges added only once to an + undirected multigraph when using + :func:`networkx.from_scipy_sparse_array`. + + """ + A = sp.sparse.csr_array([[0, 1], [1, 0]]) + G = nx.from_scipy_sparse_array(A, create_using=nx.MultiGraph) + expected = nx.MultiGraph() + expected.add_edge(0, 1, weight=1) + assert graphs_equal(G, expected) + + +@pytest.mark.parametrize("sparse_format", ("csr", "csc", "dok")) +def test_from_scipy_sparse_array_formats(sparse_format): + """Test all formats supported by _generate_weighted_edges.""" + # trinode complete graph with non-uniform edge weights + expected = nx.Graph() + expected.add_edges_from( + [ + (0, 1, {"weight": 3}), + (0, 2, {"weight": 2}), + (1, 0, {"weight": 3}), + (1, 2, {"weight": 1}), + (2, 0, {"weight": 2}), + (2, 1, {"weight": 1}), + ] + ) + A = sp.sparse.coo_array([[0, 3, 2], [3, 0, 1], [2, 1, 0]]).asformat(sparse_format) + assert graphs_equal(expected, nx.from_scipy_sparse_array(A)) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_exceptions.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..cf59983cb8d12a119f5744ebc8b11e7cb9075366 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_exceptions.py @@ -0,0 +1,40 @@ +import pytest + +import networkx as nx + +# smoke tests for exceptions + + +def test_raises_networkxexception(): + with pytest.raises(nx.NetworkXException): + raise nx.NetworkXException + + +def test_raises_networkxerr(): + with pytest.raises(nx.NetworkXError): + raise nx.NetworkXError + + +def test_raises_networkx_pointless_concept(): + with pytest.raises(nx.NetworkXPointlessConcept): + raise nx.NetworkXPointlessConcept + + +def test_raises_networkxalgorithmerr(): + with pytest.raises(nx.NetworkXAlgorithmError): + raise nx.NetworkXAlgorithmError + + +def test_raises_networkx_unfeasible(): + with pytest.raises(nx.NetworkXUnfeasible): + raise nx.NetworkXUnfeasible + + +def test_raises_networkx_no_path(): + with pytest.raises(nx.NetworkXNoPath): + raise nx.NetworkXNoPath + + +def test_raises_networkx_unbounded(): + with pytest.raises(nx.NetworkXUnbounded): + raise nx.NetworkXUnbounded diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_import.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_import.py new file mode 100644 index 0000000000000000000000000000000000000000..32aafdf2a4dafc85cee088138590b84f4c627b5e --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_import.py @@ -0,0 +1,11 @@ +import pytest + + +def test_namespace_alias(): + with pytest.raises(ImportError): + from networkx import nx + + +def test_namespace_nesting(): + with pytest.raises(ImportError): + from networkx import networkx diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_lazy_imports.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_lazy_imports.py new file mode 100644 index 0000000000000000000000000000000000000000..ec09ac2fcda5c9ce8b1f9c6f1d0fba58eb54742e --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_lazy_imports.py @@ -0,0 +1,96 @@ +import sys +import types + +import pytest + +import networkx.lazy_imports as lazy + + +def test_lazy_import_basics(): + math = lazy._lazy_import("math") + anything_not_real = lazy._lazy_import("anything_not_real") + + # Now test that accessing attributes does what it should + assert math.sin(math.pi) == pytest.approx(0, 1e-6) + # poor-mans pytest.raises for testing errors on attribute access + try: + anything_not_real.pi + assert False # Should not get here + except ModuleNotFoundError: + pass + assert isinstance(anything_not_real, lazy.DelayedImportErrorModule) + # see if it changes for second access + try: + anything_not_real.pi + assert False # Should not get here + except ModuleNotFoundError: + pass + + +def test_lazy_import_impact_on_sys_modules(): + math = lazy._lazy_import("math") + anything_not_real = lazy._lazy_import("anything_not_real") + + assert isinstance(math, types.ModuleType) + assert "math" in sys.modules + assert type(anything_not_real) is lazy.DelayedImportErrorModule + assert "anything_not_real" not in sys.modules + + # only do this if numpy is installed + np_test = pytest.importorskip("numpy") + np = lazy._lazy_import("numpy") + assert isinstance(np, types.ModuleType) + assert "numpy" in sys.modules + + np.pi # trigger load of numpy + + assert isinstance(np, types.ModuleType) + assert "numpy" in sys.modules + + +def test_lazy_import_nonbuiltins(): + sp = lazy._lazy_import("scipy") + np = lazy._lazy_import("numpy") + if isinstance(sp, lazy.DelayedImportErrorModule): + try: + sp.special.erf + assert False + except ModuleNotFoundError: + pass + elif isinstance(np, lazy.DelayedImportErrorModule): + try: + np.sin(np.pi) + assert False + except ModuleNotFoundError: + pass + else: + assert sp.special.erf(np.pi) == pytest.approx(1, 1e-4) + + +def test_lazy_attach(): + name = "mymod" + submods = ["mysubmodule", "anothersubmodule"] + myall = {"not_real_submod": ["some_var_or_func"]} + + locls = { + "attach": lazy.attach, + "name": name, + "submods": submods, + "myall": myall, + } + s = "__getattr__, __lazy_dir__, __all__ = attach(name, submods, myall)" + + exec(s, {}, locls) + expected = { + "attach": lazy.attach, + "name": name, + "submods": submods, + "myall": myall, + "__getattr__": None, + "__lazy_dir__": None, + "__all__": None, + } + assert locls.keys() == expected.keys() + for k, v in expected.items(): + if v is not None: + assert locls[k] == v diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_relabel.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_relabel.py new file mode 100644 index 0000000000000000000000000000000000000000..7a70ec11e6a4b2ed3e7371e1adaee90ece46f2c7 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_relabel.py @@ -0,0 +1,349 @@ +import pytest + +import networkx as nx +from networkx.generators.classic import empty_graph +from networkx.utils import edges_equal, nodes_equal + + +class TestRelabel: + def test_convert_node_labels_to_integers(self): + # test that empty graph converts fine for all options + G = empty_graph() + H = nx.convert_node_labels_to_integers(G, 100) + assert list(H.nodes()) == [] + assert list(H.edges()) == [] + + for opt in ["default", "sorted", "increasing degree", "decreasing degree"]: + G = empty_graph() + H = nx.convert_node_labels_to_integers(G, 100, ordering=opt) + assert list(H.nodes()) == [] + assert list(H.edges()) == [] + + G = empty_graph() + G.add_edges_from([("A", "B"), ("A", "C"), ("B", "C"), ("C", "D")]) + H = nx.convert_node_labels_to_integers(G) + degH = (d for n, d in H.degree()) + degG = (d for n, d in G.degree()) + assert sorted(degH) == sorted(degG) + + H = nx.convert_node_labels_to_integers(G, 1000) + degH = (d for n, d in H.degree()) + degG = (d for n, d in G.degree()) + assert sorted(degH) == sorted(degG) + assert nodes_equal(H.nodes(), [1000, 1001, 1002, 1003]) + + H = nx.convert_node_labels_to_integers(G, ordering="increasing degree") + degH = (d for n, d in H.degree()) + degG = (d for n, d in G.degree()) + assert sorted(degH) == sorted(degG) + assert H.degree(0) == 1 + assert H.degree(1) == 2 + assert H.degree(2) == 2 + assert H.degree(3) == 3 + + H = nx.convert_node_labels_to_integers(G, ordering="decreasing degree") + degH = (d for n, d in H.degree()) + degG = (d for n, d in G.degree()) + assert sorted(degH) == sorted(degG) + assert H.degree(0) == 3 + assert H.degree(1) == 2 + assert H.degree(2) == 2 + assert H.degree(3) == 1 + + H = nx.convert_node_labels_to_integers( + G, ordering="increasing degree", label_attribute="label" + ) + degH = (d for n, d in H.degree()) + degG = (d for n, d in G.degree()) + assert sorted(degH) == sorted(degG) + assert H.degree(0) == 1 + assert H.degree(1) == 2 + assert H.degree(2) == 2 + assert H.degree(3) == 3 + + # check mapping + assert H.nodes[3]["label"] == "C" + assert H.nodes[0]["label"] == "D" + assert H.nodes[1]["label"] == "A" or H.nodes[2]["label"] == "A" + assert H.nodes[1]["label"] == "B" or H.nodes[2]["label"] == "B" + + def test_convert_to_integers2(self): + G = empty_graph() + G.add_edges_from([("C", "D"), ("A", "B"), ("A", "C"), ("B", "C")]) + H = nx.convert_node_labels_to_integers(G, ordering="sorted") + degH = (d for n, d in H.degree()) + degG = (d for n, d in G.degree()) + assert sorted(degH) == sorted(degG) + + H = nx.convert_node_labels_to_integers( + G, ordering="sorted", label_attribute="label" + ) + assert H.nodes[0]["label"] == "A" + assert H.nodes[1]["label"] == "B" + assert H.nodes[2]["label"] == "C" + assert H.nodes[3]["label"] == "D" + + def test_convert_to_integers_raise(self): + with pytest.raises(nx.NetworkXError): + G = nx.Graph() + H = nx.convert_node_labels_to_integers(G, ordering="increasing age") + + def test_relabel_nodes_copy(self): + G = nx.empty_graph() + G.add_edges_from([("A", "B"), ("A", "C"), ("B", "C"), ("C", "D")]) + mapping = {"A": "aardvark", "B": "bear", "C": "cat", "D": "dog"} + H = nx.relabel_nodes(G, mapping) + assert nodes_equal(H.nodes(), ["aardvark", "bear", "cat", "dog"]) + + def test_relabel_nodes_function(self): + G = nx.empty_graph() + G.add_edges_from([("A", "B"), ("A", "C"), ("B", "C"), ("C", "D")]) + # function mapping no longer encouraged but works + + def mapping(n): + return ord(n) + + H = nx.relabel_nodes(G, mapping) + assert nodes_equal(H.nodes(), [65, 66, 67, 68]) + + def test_relabel_nodes_callable_type(self): + G = nx.path_graph(4) + H = nx.relabel_nodes(G, str) + assert nodes_equal(H.nodes, ["0", "1", "2", "3"]) + + @pytest.mark.parametrize("non_mc", ("0123", ["0", "1", "2", "3"])) + def test_relabel_nodes_non_mapping_or_callable(self, non_mc): + """If `mapping` is neither a Callable or a Mapping, an exception + should be raised.""" + G = nx.path_graph(4) + with pytest.raises(AttributeError): + nx.relabel_nodes(G, non_mc) + + def test_relabel_nodes_graph(self): + G = nx.Graph([("A", "B"), ("A", "C"), ("B", "C"), ("C", "D")]) + mapping = {"A": "aardvark", "B": "bear", "C": "cat", "D": "dog"} + H = nx.relabel_nodes(G, mapping) + assert nodes_equal(H.nodes(), ["aardvark", "bear", "cat", "dog"]) + + def test_relabel_nodes_orderedgraph(self): + G = nx.Graph() + G.add_nodes_from([1, 2, 3]) + G.add_edges_from([(1, 3), (2, 3)]) + mapping = {1: "a", 2: "b", 3: "c"} + H = nx.relabel_nodes(G, mapping) + assert list(H.nodes) == ["a", "b", "c"] + + def test_relabel_nodes_digraph(self): + G = nx.DiGraph([("A", "B"), ("A", "C"), ("B", "C"), ("C", "D")]) + mapping = {"A": "aardvark", "B": "bear", "C": "cat", "D": "dog"} + H = nx.relabel_nodes(G, mapping, copy=False) + assert nodes_equal(H.nodes(), ["aardvark", "bear", "cat", "dog"]) + + def test_relabel_nodes_multigraph(self): + G = nx.MultiGraph([("a", "b"), ("a", "b")]) + mapping = {"a": "aardvark", "b": "bear"} + G = nx.relabel_nodes(G, mapping, copy=False) + assert nodes_equal(G.nodes(), ["aardvark", "bear"]) + assert edges_equal(G.edges(), [("aardvark", "bear"), ("aardvark", "bear")]) + + def test_relabel_nodes_multidigraph(self): + G = nx.MultiDiGraph([("a", "b"), ("a", "b")]) + mapping = {"a": "aardvark", "b": "bear"} + G = nx.relabel_nodes(G, mapping, copy=False) + assert nodes_equal(G.nodes(), ["aardvark", "bear"]) + assert edges_equal( + G.edges(), [("aardvark", "bear"), ("aardvark", "bear")], directed=True + ) + + def test_relabel_isolated_nodes_to_same(self): + G = nx.Graph() + G.add_nodes_from(range(4)) + mapping = {1: 1} + H = nx.relabel_nodes(G, mapping, copy=False) + assert nodes_equal(H.nodes(), list(range(4))) + + def test_relabel_nodes_missing(self): + G = nx.Graph([("A", "B"), ("A", "C"), ("B", "C"), ("C", "D")]) + mapping = {0: "aardvark"} + # copy=True + H = nx.relabel_nodes(G, mapping, copy=True) + assert nodes_equal(H.nodes, G.nodes) + # copy=False + GG = G.copy() + nx.relabel_nodes(G, mapping, copy=False) + assert nodes_equal(G.nodes, GG.nodes) + + def test_relabel_copy_name(self): + G = nx.Graph() + H = nx.relabel_nodes(G, {}, copy=True) + assert H.graph == G.graph + H = nx.relabel_nodes(G, {}, copy=False) + assert H.graph == G.graph + G.name = "first" + H = nx.relabel_nodes(G, {}, copy=True) + assert H.graph == G.graph + H = nx.relabel_nodes(G, {}, copy=False) + assert H.graph == G.graph + + def test_relabel_toposort(self): + K5 = nx.complete_graph(4) + G = nx.complete_graph(4) + G = nx.relabel_nodes(G, {i: i + 1 for i in range(4)}, copy=False) + assert nx.is_isomorphic(K5, G) + G = nx.complete_graph(4) + G = nx.relabel_nodes(G, {i: i - 1 for i in range(4)}, copy=False) + assert nx.is_isomorphic(K5, G) + + def test_relabel_selfloop(self): + G = nx.DiGraph([(1, 1), (1, 2), (2, 3)]) + G = nx.relabel_nodes(G, {1: "One", 2: "Two", 3: "Three"}, copy=False) + assert nodes_equal(G.nodes(), ["One", "Three", "Two"]) + G = nx.MultiDiGraph([(1, 1), (1, 2), (2, 3)]) + G = nx.relabel_nodes(G, {1: "One", 2: "Two", 3: "Three"}, copy=False) + assert nodes_equal(G.nodes(), ["One", "Three", "Two"]) + G = nx.MultiDiGraph([(1, 1)]) + G = nx.relabel_nodes(G, {1: 0}, copy=False) + assert nodes_equal(G.nodes(), [0]) + + def test_relabel_multidigraph_inout_merge_nodes(self): + for MG in (nx.MultiGraph, nx.MultiDiGraph): + for cc in (True, False): + G = MG([(0, 4), (1, 4), (4, 2), (4, 3)]) + G[0][4][0]["value"] = "a" + G[1][4][0]["value"] = "b" + G[4][2][0]["value"] = "c" + G[4][3][0]["value"] = "d" + G.add_edge(0, 4, key="x", value="e") + G.add_edge(4, 3, key="x", value="f") + mapping = {0: 9, 1: 9, 2: 9, 3: 9} + H = nx.relabel_nodes(G, mapping, copy=cc) + # No ordering on keys enforced + assert {"value": "a"} in H[9][4].values() + assert {"value": "b"} in H[9][4].values() + assert {"value": "c"} in H[4][9].values() + assert len(H[4][9]) == 3 if G.is_directed() else 6 + assert {"value": "d"} in H[4][9].values() + assert {"value": "e"} in H[9][4].values() + assert {"value": "f"} in H[4][9].values() + assert len(H[9][4]) == 3 if G.is_directed() else 6 + + def test_relabel_multigraph_merge_inplace(self): + G = nx.MultiGraph([(0, 1), (0, 2), (0, 3), (0, 1), (0, 2), (0, 3)]) + G[0][1][0]["value"] = "a" + G[0][2][0]["value"] = "b" + G[0][3][0]["value"] = "c" + mapping = {1: 4, 2: 4, 3: 4} + nx.relabel_nodes(G, mapping, copy=False) + # No ordering on keys enforced + assert {"value": "a"} in G[0][4].values() + assert {"value": "b"} in G[0][4].values() + assert {"value": "c"} in G[0][4].values() + + def test_relabel_multidigraph_merge_inplace(self): + G = nx.MultiDiGraph([(0, 1), (0, 2), (0, 3)]) + G[0][1][0]["value"] = "a" + G[0][2][0]["value"] = "b" + G[0][3][0]["value"] = "c" + mapping = {1: 4, 2: 4, 3: 4} + nx.relabel_nodes(G, mapping, copy=False) + # No ordering on keys enforced + assert {"value": "a"} in G[0][4].values() + assert {"value": "b"} in G[0][4].values() + assert {"value": "c"} in G[0][4].values() + + def test_relabel_multidigraph_inout_copy(self): + G = nx.MultiDiGraph([(0, 4), (1, 4), (4, 2), (4, 3)]) + G[0][4][0]["value"] = "a" + G[1][4][0]["value"] = "b" + G[4][2][0]["value"] = "c" + G[4][3][0]["value"] = "d" + G.add_edge(0, 4, key="x", value="e") + G.add_edge(4, 3, key="x", value="f") + mapping = {0: 9, 1: 9, 2: 9, 3: 9} + H = nx.relabel_nodes(G, mapping, copy=True) + # No ordering on keys enforced + assert {"value": "a"} in H[9][4].values() + assert {"value": "b"} in H[9][4].values() + assert {"value": "c"} in H[4][9].values() + assert len(H[4][9]) == 3 + assert {"value": "d"} in H[4][9].values() + assert {"value": "e"} in H[9][4].values() + assert {"value": "f"} in H[4][9].values() + assert len(H[9][4]) == 3 + + def test_relabel_multigraph_merge_copy(self): + G = nx.MultiGraph([(0, 1), (0, 2), (0, 3)]) + G[0][1][0]["value"] = "a" + G[0][2][0]["value"] = "b" + G[0][3][0]["value"] = "c" + mapping = {1: 4, 2: 4, 3: 4} + H = nx.relabel_nodes(G, mapping, copy=True) + assert {"value": "a"} in H[0][4].values() + assert {"value": "b"} in H[0][4].values() + assert {"value": "c"} in H[0][4].values() + + def test_relabel_multidigraph_merge_copy(self): + G = nx.MultiDiGraph([(0, 1), (0, 2), (0, 3)]) + G[0][1][0]["value"] = "a" + G[0][2][0]["value"] = "b" + G[0][3][0]["value"] = "c" + mapping = {1: 4, 2: 4, 3: 4} + H = nx.relabel_nodes(G, mapping, copy=True) + assert {"value": "a"} in H[0][4].values() + assert {"value": "b"} in H[0][4].values() + assert {"value": "c"} in H[0][4].values() + + def test_relabel_multigraph_nonnumeric_key(self): + for MG in (nx.MultiGraph, nx.MultiDiGraph): + for cc in (True, False): + G = nx.MultiGraph() + G.add_edge(0, 1, key="I", value="a") + G.add_edge(0, 2, key="II", value="b") + G.add_edge(0, 3, key="II", value="c") + mapping = {1: 4, 2: 4, 3: 4} + nx.relabel_nodes(G, mapping, copy=False) + assert {"value": "a"} in G[0][4].values() + assert {"value": "b"} in G[0][4].values() + assert {"value": "c"} in G[0][4].values() + assert 0 in G[0][4] + assert "I" in G[0][4] + assert "II" in G[0][4] + + def test_relabel_circular(self): + G = nx.path_graph(3) + mapping = {0: 1, 1: 0} + H = nx.relabel_nodes(G, mapping, copy=True) + with pytest.raises(nx.NetworkXUnfeasible): + H = nx.relabel_nodes(G, mapping, copy=False) + + def test_relabel_preserve_node_order_full_mapping_with_copy_true(self): + G = nx.path_graph(3) + original_order = list(G.nodes()) + mapping = {2: "a", 1: "b", 0: "c"} # dictionary keys out of order on purpose + H = nx.relabel_nodes(G, mapping, copy=True) + new_order = list(H.nodes()) + assert [mapping.get(i, i) for i in original_order] == new_order + + def test_relabel_preserve_node_order_full_mapping_with_copy_false(self): + G = nx.path_graph(3) + original_order = list(G) + mapping = {2: "a", 1: "b", 0: "c"} # dictionary keys out of order on purpose + H = nx.relabel_nodes(G, mapping, copy=False) + new_order = list(H) + assert [mapping.get(i, i) for i in original_order] == new_order + + def test_relabel_preserve_node_order_partial_mapping_with_copy_true(self): + G = nx.path_graph(3) + original_order = list(G) + mapping = {1: "a", 0: "b"} # partial mapping and keys out of order on purpose + H = nx.relabel_nodes(G, mapping, copy=True) + new_order = list(H) + assert [mapping.get(i, i) for i in original_order] == new_order + + def test_relabel_preserve_node_order_partial_mapping_with_copy_false(self): + G = nx.path_graph(3) + original_order = list(G) + mapping = {1: "a", 0: "b"} # partial mapping and keys out of order on purpose + H = nx.relabel_nodes(G, mapping, copy=False) + new_order = list(H) + assert [mapping.get(i, i) for i in original_order] != new_order diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_removed_functions_exception_messages.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_removed_functions_exception_messages.py new file mode 100644 index 0000000000000000000000000000000000000000..4746345627689ef18d39660f51204622dec5dbdb --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/networkx/tests/test_removed_functions_exception_messages.py @@ -0,0 +1,8 @@ +import pytest + +import networkx as nx + + +def test_random_tree(): + with pytest.raises(AttributeError, match=".*Use `nx.random_labeled_tree` instead"): + nx.random_tree(3) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/nvidia_nccl_cu12-2.27.5.dist-info/licenses/License.txt b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/nvidia_nccl_cu12-2.27.5.dist-info/licenses/License.txt new file mode 100644 index 0000000000000000000000000000000000000000..bcd1867a02a6a8c1e592b92e2e50f34e531f2d87 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/nvidia_nccl_cu12-2.27.5.dist-info/licenses/License.txt @@ -0,0 +1,39 @@ + + Copyright (c) 2015-2020, NVIDIA CORPORATION. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of NVIDIA CORPORATION, Lawrence Berkeley National + Laboratory, the U.S. Department of Energy, nor the names of their + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + The U.S. Department of Energy funded the development of this software + under subcontract 7078610 with Lawrence Berkeley National Laboratory. + + +This code also includes files from the NVIDIA Tools Extension SDK project. + +See: + + https://github.com/NVIDIA/NVTX + +for more information and license details. diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..265e3cae8598d6394b74a509ff93a0ec18fe7cd3 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_find_distributions.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_find_distributions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..957171e27438fbb734c583372a18fe2964ee2e86 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_find_distributions.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_integration_zope_interface.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_integration_zope_interface.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca29dff048bda707c0e8ebbdaa4568c5cc1024a4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_integration_zope_interface.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_markers.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_markers.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f972159c0987dac6d8772b534e258f6d2a9b3e6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_markers.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_pkg_resources.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_pkg_resources.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..259a049c0bc56ff4ac91c960a88f9a49d576e41c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_pkg_resources.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_resources.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_resources.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d95dd6dbe1eb22c208c9c2395f121d663d447933 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_resources.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_working_set.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_working_set.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..186a3a5385acbf0a55c231ad7e1e195ae2b92dae Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/__pycache__/test_working_set.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package-source/__pycache__/setup.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package-source/__pycache__/setup.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24f3870e55091c7b58d293acb5d5e0567ff5beea Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package-source/__pycache__/setup.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package-source/setup.cfg b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package-source/setup.cfg new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package-source/setup.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package-source/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..ce9080640c0cf4a5b42274ac0c91278d6df17643 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package-source/setup.py @@ -0,0 +1,7 @@ +import setuptools + +setuptools.setup( + name="my-test-package", + version="1.0", + zip_safe=True, +) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/PKG-INFO b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/PKG-INFO new file mode 100644 index 0000000000000000000000000000000000000000..7328e3f7d18d31422d13b4fd63a7ef746956b7db --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/PKG-INFO @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: my-test-package +Version: 1.0 +Summary: UNKNOWN +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/SOURCES.txt b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/SOURCES.txt new file mode 100644 index 0000000000000000000000000000000000000000..3c4ee1676d4fec9f10f3c0f58c2d992d97975b85 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/SOURCES.txt @@ -0,0 +1,7 @@ +setup.cfg +setup.py +my_test_package.egg-info/PKG-INFO +my_test_package.egg-info/SOURCES.txt +my_test_package.egg-info/dependency_links.txt +my_test_package.egg-info/top_level.txt +my_test_package.egg-info/zip-safe \ No newline at end of file diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/dependency_links.txt b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/dependency_links.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/top_level.txt b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/top_level.txt @@ -0,0 +1 @@ + diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/zip-safe b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/zip-safe new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/zip-safe @@ -0,0 +1 @@ + diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_zipped-egg/my_test_package-1.0-py3.7.egg b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_zipped-egg/my_test_package-1.0-py3.7.egg new file mode 100644 index 0000000000000000000000000000000000000000..5115b8957da8213d02b718649c8702ac88bf0e72 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/data/my-test-package_zipped-egg/my_test_package-1.0-py3.7.egg differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_find_distributions.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_find_distributions.py new file mode 100644 index 0000000000000000000000000000000000000000..301b36d6cdbf128f839db473aa6b191eba694937 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_find_distributions.py @@ -0,0 +1,56 @@ +import shutil +from pathlib import Path + +import pytest + +import pkg_resources + +TESTS_DATA_DIR = Path(__file__).parent / 'data' + + +class TestFindDistributions: + @pytest.fixture + def target_dir(self, tmpdir): + target_dir = tmpdir.mkdir('target') + # place a .egg named directory in the target that is not an egg: + target_dir.mkdir('not.an.egg') + return target_dir + + def test_non_egg_dir_named_egg(self, target_dir): + dists = pkg_resources.find_distributions(str(target_dir)) + assert not list(dists) + + def test_standalone_egg_directory(self, target_dir): + shutil.copytree( + TESTS_DATA_DIR / 'my-test-package_unpacked-egg', + target_dir, + dirs_exist_ok=True, + ) + dists = pkg_resources.find_distributions(str(target_dir)) + assert [dist.project_name for dist in dists] == ['my-test-package'] + dists = pkg_resources.find_distributions(str(target_dir), only=True) + assert not list(dists) + + def test_zipped_egg(self, target_dir): + shutil.copytree( + TESTS_DATA_DIR / 'my-test-package_zipped-egg', + target_dir, + dirs_exist_ok=True, + ) + dists = pkg_resources.find_distributions(str(target_dir)) + assert [dist.project_name for dist in dists] == ['my-test-package'] + dists = pkg_resources.find_distributions(str(target_dir), only=True) + assert not list(dists) + + def test_zipped_sdist_one_level_removed(self, target_dir): + shutil.copytree( + TESTS_DATA_DIR / 'my-test-package-zip', target_dir, dirs_exist_ok=True + ) + dists = pkg_resources.find_distributions( + str(target_dir / "my-test-package.zip") + ) + assert [dist.project_name for dist in dists] == ['my-test-package'] + dists = pkg_resources.find_distributions( + str(target_dir / "my-test-package.zip"), only=True + ) + assert not list(dists) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_integration_zope_interface.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_integration_zope_interface.py new file mode 100644 index 0000000000000000000000000000000000000000..4e37c3401b50c9f7387647303990887c7ce670f5 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_integration_zope_interface.py @@ -0,0 +1,54 @@ +import platform +from inspect import cleandoc + +import jaraco.path +import pytest + +pytestmark = pytest.mark.integration + + +# For the sake of simplicity this test uses fixtures defined in +# `setuptools.test.fixtures`, +# and it also exercise conditions considered deprecated... +# So if needed this test can be deleted. +@pytest.mark.skipif( + platform.system() != "Linux", + reason="only demonstrated to fail on Linux in #4399", +) +def test_interop_pkg_resources_iter_entry_points(tmp_path, venv): + """ + Importing pkg_resources.iter_entry_points on console_scripts + seems to cause trouble with zope-interface, when deprecates installation method + is used. See #4399. + """ + project = { + "pkg": { + "foo.py": cleandoc( + """ + from pkg_resources import iter_entry_points + + def bar(): + print("Print me if you can") + """ + ), + "setup.py": cleandoc( + """ + from setuptools import setup, find_packages + + setup( + install_requires=["zope-interface==6.4.post2"], + entry_points={ + "console_scripts": [ + "foo=foo:bar", + ], + }, + ) + """ + ), + } + } + jaraco.path.build(project, prefix=tmp_path) + cmd = ["pip", "install", "-e", ".", "--no-use-pep517"] + venv.run(cmd, cwd=tmp_path / "pkg") # Needs this version of pkg_resources installed + out = venv.run(["foo"]) + assert "Print me if you can" in out diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_markers.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_markers.py new file mode 100644 index 0000000000000000000000000000000000000000..9306d5b3483e8913b4a04d702091fb5efbc3f444 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_markers.py @@ -0,0 +1,8 @@ +from unittest import mock + +from pkg_resources import evaluate_marker + + +@mock.patch('platform.python_version', return_value='2.7.10') +def test_ordering(python_version_mock): + assert evaluate_marker("python_full_version > '2.7.3'") is True diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_pkg_resources.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_pkg_resources.py new file mode 100644 index 0000000000000000000000000000000000000000..cfc9b16c0f187175a0fa504f0b07968c0551333b --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_pkg_resources.py @@ -0,0 +1,485 @@ +from __future__ import annotations + +import builtins +import datetime +import inspect +import os +import plistlib +import stat +import subprocess +import sys +import tempfile +import zipfile +from unittest import mock + +import pytest + +import pkg_resources +from pkg_resources import DistInfoDistribution, Distribution, EggInfoDistribution + +import distutils.command.install_egg_info +import distutils.dist + + +class EggRemover(str): + def __call__(self): + if self in sys.path: + sys.path.remove(self) + if os.path.exists(self): + os.remove(self) + + +class TestZipProvider: + finalizers: list[EggRemover] = [] + + ref_time = datetime.datetime(2013, 5, 12, 13, 25, 0) + "A reference time for a file modification" + + @classmethod + def setup_class(cls): + "create a zip egg and add it to sys.path" + egg = tempfile.NamedTemporaryFile(suffix='.egg', delete=False) + zip_egg = zipfile.ZipFile(egg, 'w') + zip_info = zipfile.ZipInfo() + zip_info.filename = 'mod.py' + zip_info.date_time = cls.ref_time.timetuple() + zip_egg.writestr(zip_info, 'x = 3\n') + zip_info = zipfile.ZipInfo() + zip_info.filename = 'data.dat' + zip_info.date_time = cls.ref_time.timetuple() + zip_egg.writestr(zip_info, 'hello, world!') + zip_info = zipfile.ZipInfo() + zip_info.filename = 'subdir/mod2.py' + zip_info.date_time = cls.ref_time.timetuple() + zip_egg.writestr(zip_info, 'x = 6\n') + zip_info = zipfile.ZipInfo() + zip_info.filename = 'subdir/data2.dat' + zip_info.date_time = cls.ref_time.timetuple() + zip_egg.writestr(zip_info, 'goodbye, world!') + zip_egg.close() + egg.close() + + sys.path.append(egg.name) + subdir = os.path.join(egg.name, 'subdir') + sys.path.append(subdir) + cls.finalizers.append(EggRemover(subdir)) + cls.finalizers.append(EggRemover(egg.name)) + + @classmethod + def teardown_class(cls): + for finalizer in cls.finalizers: + finalizer() + + def test_resource_listdir(self): + import mod # pyright: ignore[reportMissingImports] # Temporary package for test + + zp = pkg_resources.ZipProvider(mod) + + expected_root = ['data.dat', 'mod.py', 'subdir'] + assert sorted(zp.resource_listdir('')) == expected_root + + expected_subdir = ['data2.dat', 'mod2.py'] + assert sorted(zp.resource_listdir('subdir')) == expected_subdir + assert sorted(zp.resource_listdir('subdir/')) == expected_subdir + + assert zp.resource_listdir('nonexistent') == [] + assert zp.resource_listdir('nonexistent/') == [] + + import mod2 # pyright: ignore[reportMissingImports] # Temporary package for test + + zp2 = pkg_resources.ZipProvider(mod2) + + assert sorted(zp2.resource_listdir('')) == expected_subdir + + assert zp2.resource_listdir('subdir') == [] + assert zp2.resource_listdir('subdir/') == [] + + def test_resource_filename_rewrites_on_change(self): + """ + If a previous call to get_resource_filename has saved the file, but + the file has been subsequently mutated with different file of the + same size and modification time, it should not be overwritten on a + subsequent call to get_resource_filename. + """ + import mod # pyright: ignore[reportMissingImports] # Temporary package for test + + manager = pkg_resources.ResourceManager() + zp = pkg_resources.ZipProvider(mod) + filename = zp.get_resource_filename(manager, 'data.dat') + actual = datetime.datetime.fromtimestamp(os.stat(filename).st_mtime) + assert actual == self.ref_time + f = open(filename, 'w', encoding="utf-8") + f.write('hello, world?') + f.close() + ts = self.ref_time.timestamp() + os.utime(filename, (ts, ts)) + filename = zp.get_resource_filename(manager, 'data.dat') + with open(filename, encoding="utf-8") as f: + assert f.read() == 'hello, world!' + manager.cleanup_resources() + + +class TestResourceManager: + def test_get_cache_path(self): + mgr = pkg_resources.ResourceManager() + path = mgr.get_cache_path('foo') + type_ = str(type(path)) + message = "Unexpected type from get_cache_path: " + type_ + assert isinstance(path, str), message + + def test_get_cache_path_race(self, tmpdir): + # Patch to os.path.isdir to create a race condition + def patched_isdir(dirname, unpatched_isdir=pkg_resources.isdir): + patched_isdir.dirnames.append(dirname) + + was_dir = unpatched_isdir(dirname) + if not was_dir: + os.makedirs(dirname) + return was_dir + + patched_isdir.dirnames = [] + + # Get a cache path with a "race condition" + mgr = pkg_resources.ResourceManager() + mgr.set_extraction_path(str(tmpdir)) + + archive_name = os.sep.join(('foo', 'bar', 'baz')) + with mock.patch.object(pkg_resources, 'isdir', new=patched_isdir): + mgr.get_cache_path(archive_name) + + # Because this test relies on the implementation details of this + # function, these assertions are a sentinel to ensure that the + # test suite will not fail silently if the implementation changes. + called_dirnames = patched_isdir.dirnames + assert len(called_dirnames) == 2 + assert called_dirnames[0].split(os.sep)[-2:] == ['foo', 'bar'] + assert called_dirnames[1].split(os.sep)[-1:] == ['foo'] + + """ + Tests to ensure that pkg_resources runs independently from setuptools. + """ + + def test_setuptools_not_imported(self): + """ + In a separate Python environment, import pkg_resources and assert + that action doesn't cause setuptools to be imported. + """ + lines = ( + 'import pkg_resources', + 'import sys', + ('assert "setuptools" not in sys.modules, "setuptools was imported"'), + ) + cmd = [sys.executable, '-c', '; '.join(lines)] + subprocess.check_call(cmd) + + +def make_test_distribution(metadata_path, metadata): + """ + Make a test Distribution object, and return it. + + :param metadata_path: the path to the metadata file that should be + created. This should be inside a distribution directory that should + also be created. For example, an argument value might end with + ".dist-info/METADATA". + :param metadata: the desired contents of the metadata file, as bytes. + """ + dist_dir = os.path.dirname(metadata_path) + os.mkdir(dist_dir) + with open(metadata_path, 'wb') as f: + f.write(metadata) + dists = list(pkg_resources.distributions_from_metadata(dist_dir)) + (dist,) = dists + + return dist + + +def test_get_metadata__bad_utf8(tmpdir): + """ + Test a metadata file with bytes that can't be decoded as utf-8. + """ + filename = 'METADATA' + # Convert the tmpdir LocalPath object to a string before joining. + metadata_path = os.path.join(str(tmpdir), 'foo.dist-info', filename) + # Encode a non-ascii string with the wrong encoding (not utf-8). + metadata = 'née'.encode('iso-8859-1') + dist = make_test_distribution(metadata_path, metadata=metadata) + + with pytest.raises(UnicodeDecodeError) as excinfo: + dist.get_metadata(filename) + + exc = excinfo.value + actual = str(exc) + expected = ( + # The error message starts with "'utf-8' codec ..." However, the + # spelling of "utf-8" can vary (e.g. "utf8") so we don't include it + "codec can't decode byte 0xe9 in position 1: " + 'invalid continuation byte in METADATA file at path: ' + ) + assert expected in actual, f'actual: {actual}' + assert actual.endswith(metadata_path), f'actual: {actual}' + + +def make_distribution_no_version(tmpdir, basename): + """ + Create a distribution directory with no file containing the version. + """ + dist_dir = tmpdir / basename + dist_dir.ensure_dir() + # Make the directory non-empty so distributions_from_metadata() + # will detect it and yield it. + dist_dir.join('temp.txt').ensure() + + dists = list(pkg_resources.distributions_from_metadata(dist_dir)) + assert len(dists) == 1 + (dist,) = dists + + return dist, dist_dir + + +@pytest.mark.parametrize( + ("suffix", "expected_filename", "expected_dist_type"), + [ + ('egg-info', 'PKG-INFO', EggInfoDistribution), + ('dist-info', 'METADATA', DistInfoDistribution), + ], +) +@pytest.mark.xfail( + sys.version_info[:2] == (3, 12) and sys.version_info.releaselevel != 'final', + reason="https://github.com/python/cpython/issues/103632", +) +def test_distribution_version_missing( + tmpdir, suffix, expected_filename, expected_dist_type +): + """ + Test Distribution.version when the "Version" header is missing. + """ + basename = f'foo.{suffix}' + dist, dist_dir = make_distribution_no_version(tmpdir, basename) + + expected_text = ( + f"Missing 'Version:' header and/or {expected_filename} file at path: " + ) + metadata_path = os.path.join(dist_dir, expected_filename) + + # Now check the exception raised when the "version" attribute is accessed. + with pytest.raises(ValueError) as excinfo: + dist.version + + err = str(excinfo.value) + # Include a string expression after the assert so the full strings + # will be visible for inspection on failure. + assert expected_text in err, str((expected_text, err)) + + # Also check the args passed to the ValueError. + msg, dist = excinfo.value.args + assert expected_text in msg + # Check that the message portion contains the path. + assert metadata_path in msg, str((metadata_path, msg)) + assert type(dist) is expected_dist_type + + +@pytest.mark.xfail( + sys.version_info[:2] == (3, 12) and sys.version_info.releaselevel != 'final', + reason="https://github.com/python/cpython/issues/103632", +) +def test_distribution_version_missing_undetected_path(): + """ + Test Distribution.version when the "Version" header is missing and + the path can't be detected. + """ + # Create a Distribution object with no metadata argument, which results + # in an empty metadata provider. + dist = Distribution('/foo') + with pytest.raises(ValueError) as excinfo: + dist.version + + msg, dist = excinfo.value.args + expected = ( + "Missing 'Version:' header and/or PKG-INFO file at path: [could not detect]" + ) + assert msg == expected + + +@pytest.mark.parametrize('only', [False, True]) +def test_dist_info_is_not_dir(tmp_path, only): + """Test path containing a file with dist-info extension.""" + dist_info = tmp_path / 'foobar.dist-info' + dist_info.touch() + assert not pkg_resources.dist_factory(str(tmp_path), str(dist_info), only) + + +def test_macos_vers_fallback(monkeypatch, tmp_path): + """Regression test for pkg_resources._macos_vers""" + orig_open = builtins.open + + # Pretend we need to use the plist file + monkeypatch.setattr('platform.mac_ver', mock.Mock(return_value=('', (), ''))) + + # Create fake content for the fake plist file + with open(tmp_path / 'fake.plist', 'wb') as fake_file: + plistlib.dump({"ProductVersion": "11.4"}, fake_file) + + # Pretend the fake file exists + monkeypatch.setattr('os.path.exists', mock.Mock(return_value=True)) + + def fake_open(file, *args, **kwargs): + return orig_open(tmp_path / 'fake.plist', *args, **kwargs) + + # Ensure that the _macos_vers works correctly + with mock.patch('builtins.open', mock.Mock(side_effect=fake_open)) as m: + pkg_resources._macos_vers.cache_clear() + assert pkg_resources._macos_vers() == ["11", "4"] + pkg_resources._macos_vers.cache_clear() + + m.assert_called() + + +class TestDeepVersionLookupDistutils: + @pytest.fixture + def env(self, tmpdir): + """ + Create a package environment, similar to a virtualenv, + in which packages are installed. + """ + + class Environment(str): + pass + + env = Environment(tmpdir) + tmpdir.chmod(stat.S_IRWXU) + subs = 'home', 'lib', 'scripts', 'data', 'egg-base' + env.paths = dict((dirname, str(tmpdir / dirname)) for dirname in subs) + list(map(os.mkdir, env.paths.values())) + return env + + def create_foo_pkg(self, env, version): + """ + Create a foo package installed (distutils-style) to env.paths['lib'] + as version. + """ + ld = "This package has unicode metadata! ❄" + attrs = dict(name='foo', version=version, long_description=ld) + dist = distutils.dist.Distribution(attrs) + iei_cmd = distutils.command.install_egg_info.install_egg_info(dist) + iei_cmd.initialize_options() + iei_cmd.install_dir = env.paths['lib'] + iei_cmd.finalize_options() + iei_cmd.run() + + def test_version_resolved_from_egg_info(self, env): + version = '1.11.0.dev0+2329eae' + self.create_foo_pkg(env, version) + + # this requirement parsing will raise a VersionConflict unless the + # .egg-info file is parsed (see #419 on BitBucket) + req = pkg_resources.Requirement.parse('foo>=1.9') + dist = pkg_resources.WorkingSet([env.paths['lib']]).find(req) + assert dist.version == version + + @pytest.mark.parametrize( + ("unnormalized", "normalized"), + [ + ('foo', 'foo'), + ('foo/', 'foo'), + ('foo/bar', 'foo/bar'), + ('foo/bar/', 'foo/bar'), + ], + ) + def test_normalize_path_trailing_sep(self, unnormalized, normalized): + """Ensure the trailing slash is cleaned for path comparison. + + See pypa/setuptools#1519. + """ + result_from_unnormalized = pkg_resources.normalize_path(unnormalized) + result_from_normalized = pkg_resources.normalize_path(normalized) + assert result_from_unnormalized == result_from_normalized + + @pytest.mark.skipif( + os.path.normcase('A') != os.path.normcase('a'), + reason='Testing case-insensitive filesystems.', + ) + @pytest.mark.parametrize( + ("unnormalized", "normalized"), + [ + ('MiXeD/CasE', 'mixed/case'), + ], + ) + def test_normalize_path_normcase(self, unnormalized, normalized): + """Ensure mixed case is normalized on case-insensitive filesystems.""" + result_from_unnormalized = pkg_resources.normalize_path(unnormalized) + result_from_normalized = pkg_resources.normalize_path(normalized) + assert result_from_unnormalized == result_from_normalized + + @pytest.mark.skipif( + os.path.sep != '\\', + reason='Testing systems using backslashes as path separators.', + ) + @pytest.mark.parametrize( + ("unnormalized", "expected"), + [ + ('forward/slash', 'forward\\slash'), + ('forward/slash/', 'forward\\slash'), + ('backward\\slash\\', 'backward\\slash'), + ], + ) + def test_normalize_path_backslash_sep(self, unnormalized, expected): + """Ensure path seps are cleaned on backslash path sep systems.""" + result = pkg_resources.normalize_path(unnormalized) + assert result.endswith(expected) + + +class TestWorkdirRequire: + def fake_site_packages(self, tmp_path, monkeypatch, dist_files): + site_packages = tmp_path / "site-packages" + site_packages.mkdir() + for file, content in self.FILES.items(): + path = site_packages / file + path.parent.mkdir(exist_ok=True, parents=True) + path.write_text(inspect.cleandoc(content), encoding="utf-8") + + monkeypatch.setattr(sys, "path", [site_packages]) + return os.fspath(site_packages) + + FILES = { + "pkg1_mod-1.2.3.dist-info/METADATA": """ + Metadata-Version: 2.4 + Name: pkg1.mod + Version: 1.2.3 + """, + "pkg2.mod-0.42.dist-info/METADATA": """ + Metadata-Version: 2.1 + Name: pkg2.mod + Version: 0.42 + """, + "pkg3_mod.egg-info/PKG-INFO": """ + Name: pkg3.mod + Version: 1.2.3.4 + """, + "pkg4.mod.egg-info/PKG-INFO": """ + Name: pkg4.mod + Version: 0.42.1 + """, + } + + @pytest.mark.parametrize( + ("version", "requirement"), + [ + ("1.2.3", "pkg1.mod>=1"), + ("0.42", "pkg2.mod>=0.4"), + ("1.2.3.4", "pkg3.mod<=2"), + ("0.42.1", "pkg4.mod>0.2,<1"), + ], + ) + def test_require_non_normalised_name( + self, tmp_path, monkeypatch, version, requirement + ): + # https://github.com/pypa/setuptools/issues/4853 + site_packages = self.fake_site_packages(tmp_path, monkeypatch, self.FILES) + ws = pkg_resources.WorkingSet([site_packages]) + + for req in [requirement, requirement.replace(".", "-")]: + [dist] = ws.require(req) + assert dist.version == version + assert os.path.samefile( + os.path.commonpath([dist.location, site_packages]), site_packages + ) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_resources.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_resources.py new file mode 100644 index 0000000000000000000000000000000000000000..70436c08812df9a36d4fe5d40fb0b3bc07f02db9 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_resources.py @@ -0,0 +1,869 @@ +import itertools +import os +import platform +import string +import sys + +import pytest +from packaging.specifiers import SpecifierSet + +import pkg_resources +from pkg_resources import ( + Distribution, + EntryPoint, + Requirement, + VersionConflict, + WorkingSet, + parse_requirements, + parse_version, + safe_name, + safe_version, +) + + +# from Python 3.6 docs. Available from itertools on Python 3.10 +def pairwise(iterable): + "s -> (s0,s1), (s1,s2), (s2, s3), ..." + a, b = itertools.tee(iterable) + next(b, None) + return zip(a, b) + + +class Metadata(pkg_resources.EmptyProvider): + """Mock object to return metadata as if from an on-disk distribution""" + + def __init__(self, *pairs) -> None: + self.metadata = dict(pairs) + + def has_metadata(self, name) -> bool: + return name in self.metadata + + def get_metadata(self, name): + return self.metadata[name] + + def get_metadata_lines(self, name): + return pkg_resources.yield_lines(self.get_metadata(name)) + + +dist_from_fn = pkg_resources.Distribution.from_filename + + +class TestDistro: + def testCollection(self): + # empty path should produce no distributions + ad = pkg_resources.Environment([], platform=None, python=None) + assert list(ad) == [] + assert ad['FooPkg'] == [] + ad.add(dist_from_fn("FooPkg-1.3_1.egg")) + ad.add(dist_from_fn("FooPkg-1.4-py2.4-win32.egg")) + ad.add(dist_from_fn("FooPkg-1.2-py2.4.egg")) + + # Name is in there now + assert ad['FooPkg'] + # But only 1 package + assert list(ad) == ['foopkg'] + + # Distributions sort by version + expected = ['1.4', '1.3-1', '1.2'] + assert [dist.version for dist in ad['FooPkg']] == expected + + # Removing a distribution leaves sequence alone + ad.remove(ad['FooPkg'][1]) + assert [dist.version for dist in ad['FooPkg']] == ['1.4', '1.2'] + + # And inserting adds them in order + ad.add(dist_from_fn("FooPkg-1.9.egg")) + assert [dist.version for dist in ad['FooPkg']] == ['1.9', '1.4', '1.2'] + + ws = WorkingSet([]) + foo12 = dist_from_fn("FooPkg-1.2-py2.4.egg") + foo14 = dist_from_fn("FooPkg-1.4-py2.4-win32.egg") + (req,) = parse_requirements("FooPkg>=1.3") + + # Nominal case: no distros on path, should yield all applicable + assert ad.best_match(req, ws).version == '1.9' + # If a matching distro is already installed, should return only that + ws.add(foo14) + assert ad.best_match(req, ws).version == '1.4' + + # If the first matching distro is unsuitable, it's a version conflict + ws = WorkingSet([]) + ws.add(foo12) + ws.add(foo14) + with pytest.raises(VersionConflict): + ad.best_match(req, ws) + + # If more than one match on the path, the first one takes precedence + ws = WorkingSet([]) + ws.add(foo14) + ws.add(foo12) + ws.add(foo14) + assert ad.best_match(req, ws).version == '1.4' + + def checkFooPkg(self, d): + assert d.project_name == "FooPkg" + assert d.key == "foopkg" + assert d.version == "1.3.post1" + assert d.py_version == "2.4" + assert d.platform == "win32" + assert d.parsed_version == parse_version("1.3-1") + + def testDistroBasics(self): + d = Distribution( + "/some/path", + project_name="FooPkg", + version="1.3-1", + py_version="2.4", + platform="win32", + ) + self.checkFooPkg(d) + + d = Distribution("/some/path") + assert d.py_version == f'{sys.version_info.major}.{sys.version_info.minor}' + assert d.platform is None + + def testDistroParse(self): + d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg") + self.checkFooPkg(d) + d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg-info") + self.checkFooPkg(d) + + def testDistroMetadata(self): + d = Distribution( + "/some/path", + project_name="FooPkg", + py_version="2.4", + platform="win32", + metadata=Metadata(('PKG-INFO', "Metadata-Version: 1.0\nVersion: 1.3-1\n")), + ) + self.checkFooPkg(d) + + def distRequires(self, txt): + return Distribution("/foo", metadata=Metadata(('depends.txt', txt))) + + def checkRequires(self, dist, txt, extras=()): + assert list(dist.requires(extras)) == list(parse_requirements(txt)) + + def testDistroDependsSimple(self): + for v in "Twisted>=1.5", "Twisted>=1.5\nZConfig>=2.0": + self.checkRequires(self.distRequires(v), v) + + needs_object_dir = pytest.mark.skipif( + not hasattr(object, '__dir__'), + reason='object.__dir__ necessary for self.__dir__ implementation', + ) + + def test_distribution_dir(self): + d = pkg_resources.Distribution() + dir(d) + + @needs_object_dir + def test_distribution_dir_includes_provider_dir(self): + d = pkg_resources.Distribution() + before = d.__dir__() + assert 'test_attr' not in before + d._provider.test_attr = None + after = d.__dir__() + assert len(after) == len(before) + 1 + assert 'test_attr' in after + + @needs_object_dir + def test_distribution_dir_ignores_provider_dir_leading_underscore(self): + d = pkg_resources.Distribution() + before = d.__dir__() + assert '_test_attr' not in before + d._provider._test_attr = None + after = d.__dir__() + assert len(after) == len(before) + assert '_test_attr' not in after + + def testResolve(self): + ad = pkg_resources.Environment([]) + ws = WorkingSet([]) + # Resolving no requirements -> nothing to install + assert list(ws.resolve([], ad)) == [] + # Request something not in the collection -> DistributionNotFound + with pytest.raises(pkg_resources.DistributionNotFound): + ws.resolve(parse_requirements("Foo"), ad) + + Foo = Distribution.from_filename( + "/foo_dir/Foo-1.2.egg", + metadata=Metadata(('depends.txt', "[bar]\nBaz>=2.0")), + ) + ad.add(Foo) + ad.add(Distribution.from_filename("Foo-0.9.egg")) + + # Request thing(s) that are available -> list to activate + for i in range(3): + targets = list(ws.resolve(parse_requirements("Foo"), ad)) + assert targets == [Foo] + list(map(ws.add, targets)) + with pytest.raises(VersionConflict): + ws.resolve(parse_requirements("Foo==0.9"), ad) + ws = WorkingSet([]) # reset + + # Request an extra that causes an unresolved dependency for "Baz" + with pytest.raises(pkg_resources.DistributionNotFound): + ws.resolve(parse_requirements("Foo[bar]"), ad) + Baz = Distribution.from_filename( + "/foo_dir/Baz-2.1.egg", metadata=Metadata(('depends.txt', "Foo")) + ) + ad.add(Baz) + + # Activation list now includes resolved dependency + assert list(ws.resolve(parse_requirements("Foo[bar]"), ad)) == [Foo, Baz] + # Requests for conflicting versions produce VersionConflict + with pytest.raises(VersionConflict) as vc: + ws.resolve(parse_requirements("Foo==1.2\nFoo!=1.2"), ad) + + msg = 'Foo 0.9 is installed but Foo==1.2 is required' + assert vc.value.report() == msg + + def test_environment_marker_evaluation_negative(self): + """Environment markers are evaluated at resolution time.""" + ad = pkg_resources.Environment([]) + ws = WorkingSet([]) + res = ws.resolve(parse_requirements("Foo;python_version<'2'"), ad) + assert list(res) == [] + + def test_environment_marker_evaluation_positive(self): + ad = pkg_resources.Environment([]) + ws = WorkingSet([]) + Foo = Distribution.from_filename("/foo_dir/Foo-1.2.dist-info") + ad.add(Foo) + res = ws.resolve(parse_requirements("Foo;python_version>='2'"), ad) + assert list(res) == [Foo] + + def test_environment_marker_evaluation_called(self): + """ + If one package foo requires bar without any extras, + markers should pass for bar without extras. + """ + (parent_req,) = parse_requirements("foo") + (req,) = parse_requirements("bar;python_version>='2'") + req_extras = pkg_resources._ReqExtras({req: parent_req.extras}) + assert req_extras.markers_pass(req) + + (parent_req,) = parse_requirements("foo[]") + (req,) = parse_requirements("bar;python_version>='2'") + req_extras = pkg_resources._ReqExtras({req: parent_req.extras}) + assert req_extras.markers_pass(req) + + def test_marker_evaluation_with_extras(self): + """Extras are also evaluated as markers at resolution time.""" + ad = pkg_resources.Environment([]) + ws = WorkingSet([]) + Foo = Distribution.from_filename( + "/foo_dir/Foo-1.2.dist-info", + metadata=Metadata(( + "METADATA", + "Provides-Extra: baz\nRequires-Dist: quux; extra=='baz'", + )), + ) + ad.add(Foo) + assert list(ws.resolve(parse_requirements("Foo"), ad)) == [Foo] + quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info") + ad.add(quux) + res = list(ws.resolve(parse_requirements("Foo[baz]"), ad)) + assert res == [Foo, quux] + + def test_marker_evaluation_with_extras_normlized(self): + """Extras are also evaluated as markers at resolution time.""" + ad = pkg_resources.Environment([]) + ws = WorkingSet([]) + Foo = Distribution.from_filename( + "/foo_dir/Foo-1.2.dist-info", + metadata=Metadata(( + "METADATA", + "Provides-Extra: baz-lightyear\n" + "Requires-Dist: quux; extra=='baz-lightyear'", + )), + ) + ad.add(Foo) + assert list(ws.resolve(parse_requirements("Foo"), ad)) == [Foo] + quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info") + ad.add(quux) + res = list(ws.resolve(parse_requirements("Foo[baz-lightyear]"), ad)) + assert res == [Foo, quux] + + def test_marker_evaluation_with_multiple_extras(self): + ad = pkg_resources.Environment([]) + ws = WorkingSet([]) + Foo = Distribution.from_filename( + "/foo_dir/Foo-1.2.dist-info", + metadata=Metadata(( + "METADATA", + "Provides-Extra: baz\n" + "Requires-Dist: quux; extra=='baz'\n" + "Provides-Extra: bar\n" + "Requires-Dist: fred; extra=='bar'\n", + )), + ) + ad.add(Foo) + quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info") + ad.add(quux) + fred = Distribution.from_filename("/foo_dir/fred-0.1.dist-info") + ad.add(fred) + res = list(ws.resolve(parse_requirements("Foo[baz,bar]"), ad)) + assert sorted(res) == [fred, quux, Foo] + + def test_marker_evaluation_with_extras_loop(self): + ad = pkg_resources.Environment([]) + ws = WorkingSet([]) + a = Distribution.from_filename( + "/foo_dir/a-0.2.dist-info", + metadata=Metadata(("METADATA", "Requires-Dist: c[a]")), + ) + b = Distribution.from_filename( + "/foo_dir/b-0.3.dist-info", + metadata=Metadata(("METADATA", "Requires-Dist: c[b]")), + ) + c = Distribution.from_filename( + "/foo_dir/c-1.0.dist-info", + metadata=Metadata(( + "METADATA", + "Provides-Extra: a\n" + "Requires-Dist: b;extra=='a'\n" + "Provides-Extra: b\n" + "Requires-Dist: foo;extra=='b'", + )), + ) + foo = Distribution.from_filename("/foo_dir/foo-0.1.dist-info") + for dist in (a, b, c, foo): + ad.add(dist) + res = list(ws.resolve(parse_requirements("a"), ad)) + assert res == [a, c, b, foo] + + @pytest.mark.xfail( + sys.version_info[:2] == (3, 12) and sys.version_info.releaselevel != 'final', + reason="https://github.com/python/cpython/issues/103632", + ) + def testDistroDependsOptions(self): + d = self.distRequires( + """ + Twisted>=1.5 + [docgen] + ZConfig>=2.0 + docutils>=0.3 + [fastcgi] + fcgiapp>=0.1""" + ) + self.checkRequires(d, "Twisted>=1.5") + self.checkRequires( + d, "Twisted>=1.5 ZConfig>=2.0 docutils>=0.3".split(), ["docgen"] + ) + self.checkRequires(d, "Twisted>=1.5 fcgiapp>=0.1".split(), ["fastcgi"]) + self.checkRequires( + d, + "Twisted>=1.5 ZConfig>=2.0 docutils>=0.3 fcgiapp>=0.1".split(), + ["docgen", "fastcgi"], + ) + self.checkRequires( + d, + "Twisted>=1.5 fcgiapp>=0.1 ZConfig>=2.0 docutils>=0.3".split(), + ["fastcgi", "docgen"], + ) + with pytest.raises(pkg_resources.UnknownExtra): + d.requires(["foo"]) + + +class TestWorkingSet: + def test_find_conflicting(self): + ws = WorkingSet([]) + Foo = Distribution.from_filename("/foo_dir/Foo-1.2.egg") + ws.add(Foo) + + # create a requirement that conflicts with Foo 1.2 + req = next(parse_requirements("Foo<1.2")) + + with pytest.raises(VersionConflict) as vc: + ws.find(req) + + msg = 'Foo 1.2 is installed but Foo<1.2 is required' + assert vc.value.report() == msg + + def test_resolve_conflicts_with_prior(self): + """ + A ContextualVersionConflict should be raised when a requirement + conflicts with a prior requirement for a different package. + """ + # Create installation where Foo depends on Baz 1.0 and Bar depends on + # Baz 2.0. + ws = WorkingSet([]) + md = Metadata(('depends.txt', "Baz==1.0")) + Foo = Distribution.from_filename("/foo_dir/Foo-1.0.egg", metadata=md) + ws.add(Foo) + md = Metadata(('depends.txt', "Baz==2.0")) + Bar = Distribution.from_filename("/foo_dir/Bar-1.0.egg", metadata=md) + ws.add(Bar) + Baz = Distribution.from_filename("/foo_dir/Baz-1.0.egg") + ws.add(Baz) + Baz = Distribution.from_filename("/foo_dir/Baz-2.0.egg") + ws.add(Baz) + + with pytest.raises(VersionConflict) as vc: + ws.resolve(parse_requirements("Foo\nBar\n")) + + msg = "Baz 1.0 is installed but Baz==2.0 is required by " + msg += repr(set(['Bar'])) + assert vc.value.report() == msg + + +class TestEntryPoints: + def assertfields(self, ep): + assert ep.name == "foo" + assert ep.module_name == "pkg_resources.tests.test_resources" + assert ep.attrs == ("TestEntryPoints",) + assert ep.extras == ("x",) + assert ep.load() is TestEntryPoints + expect = "foo = pkg_resources.tests.test_resources:TestEntryPoints [x]" + assert str(ep) == expect + + def setup_method(self, method): + self.dist = Distribution.from_filename( + "FooPkg-1.2-py2.4.egg", metadata=Metadata(('requires.txt', '[x]')) + ) + + def testBasics(self): + ep = EntryPoint( + "foo", + "pkg_resources.tests.test_resources", + ["TestEntryPoints"], + ["x"], + self.dist, + ) + self.assertfields(ep) + + def testParse(self): + s = "foo = pkg_resources.tests.test_resources:TestEntryPoints [x]" + ep = EntryPoint.parse(s, self.dist) + self.assertfields(ep) + + ep = EntryPoint.parse("bar baz= spammity[PING]") + assert ep.name == "bar baz" + assert ep.module_name == "spammity" + assert ep.attrs == () + assert ep.extras == ("ping",) + + ep = EntryPoint.parse(" fizzly = wocka:foo") + assert ep.name == "fizzly" + assert ep.module_name == "wocka" + assert ep.attrs == ("foo",) + assert ep.extras == () + + # plus in the name + spec = "html+mako = mako.ext.pygmentplugin:MakoHtmlLexer" + ep = EntryPoint.parse(spec) + assert ep.name == 'html+mako' + + reject_specs = "foo", "x=a:b:c", "q=x/na", "fez=pish:tush-z", "x=f[a]>2" + + @pytest.mark.parametrize("reject_spec", reject_specs) + def test_reject_spec(self, reject_spec): + with pytest.raises(ValueError): + EntryPoint.parse(reject_spec) + + def test_printable_name(self): + """ + Allow any printable character in the name. + """ + # Create a name with all printable characters; strip the whitespace. + name = string.printable.strip() + spec = "{name} = module:attr".format(**locals()) + ep = EntryPoint.parse(spec) + assert ep.name == name + + def checkSubMap(self, m): + assert len(m) == len(self.submap_expect) + for key, ep in self.submap_expect.items(): + assert m.get(key).name == ep.name + assert m.get(key).module_name == ep.module_name + assert sorted(m.get(key).attrs) == sorted(ep.attrs) + assert sorted(m.get(key).extras) == sorted(ep.extras) + + submap_expect = dict( + feature1=EntryPoint('feature1', 'somemodule', ['somefunction']), + feature2=EntryPoint( + 'feature2', 'another.module', ['SomeClass'], ['extra1', 'extra2'] + ), + feature3=EntryPoint('feature3', 'this.module', extras=['something']), + ) + submap_str = """ + # define features for blah blah + feature1 = somemodule:somefunction + feature2 = another.module:SomeClass [extra1,extra2] + feature3 = this.module [something] + """ + + def testParseList(self): + self.checkSubMap(EntryPoint.parse_group("xyz", self.submap_str)) + with pytest.raises(ValueError): + EntryPoint.parse_group("x a", "foo=bar") + with pytest.raises(ValueError): + EntryPoint.parse_group("x", ["foo=baz", "foo=bar"]) + + def testParseMap(self): + m = EntryPoint.parse_map({'xyz': self.submap_str}) + self.checkSubMap(m['xyz']) + assert list(m.keys()) == ['xyz'] + m = EntryPoint.parse_map("[xyz]\n" + self.submap_str) + self.checkSubMap(m['xyz']) + assert list(m.keys()) == ['xyz'] + with pytest.raises(ValueError): + EntryPoint.parse_map(["[xyz]", "[xyz]"]) + with pytest.raises(ValueError): + EntryPoint.parse_map(self.submap_str) + + def testDeprecationWarnings(self): + ep = EntryPoint( + "foo", "pkg_resources.tests.test_resources", ["TestEntryPoints"], ["x"] + ) + with pytest.warns(pkg_resources.PkgResourcesDeprecationWarning): + ep.load(require=False) + + +class TestRequirements: + def testBasics(self): + r = Requirement.parse("Twisted>=1.2") + assert str(r) == "Twisted>=1.2" + assert repr(r) == "Requirement.parse('Twisted>=1.2')" + assert r == Requirement("Twisted>=1.2") + assert r == Requirement("twisTed>=1.2") + assert r != Requirement("Twisted>=2.0") + assert r != Requirement("Zope>=1.2") + assert r != Requirement("Zope>=3.0") + assert r != Requirement("Twisted[extras]>=1.2") + + def testOrdering(self): + r1 = Requirement("Twisted==1.2c1,>=1.2") + r2 = Requirement("Twisted>=1.2,==1.2c1") + assert r1 == r2 + assert str(r1) == str(r2) + assert str(r2) == "Twisted==1.2c1,>=1.2" + assert Requirement("Twisted") != Requirement( + "Twisted @ https://localhost/twisted.zip" + ) + + def testBasicContains(self): + r = Requirement("Twisted>=1.2") + foo_dist = Distribution.from_filename("FooPkg-1.3_1.egg") + twist11 = Distribution.from_filename("Twisted-1.1.egg") + twist12 = Distribution.from_filename("Twisted-1.2.egg") + assert parse_version('1.2') in r + assert parse_version('1.1') not in r + assert '1.2' in r + assert '1.1' not in r + assert foo_dist not in r + assert twist11 not in r + assert twist12 in r + + def testOptionsAndHashing(self): + r1 = Requirement.parse("Twisted[foo,bar]>=1.2") + r2 = Requirement.parse("Twisted[bar,FOO]>=1.2") + assert r1 == r2 + assert set(r1.extras) == set(("foo", "bar")) + assert set(r2.extras) == set(("foo", "bar")) + assert hash(r1) == hash(r2) + assert hash(r1) == hash(( + "twisted", + None, + SpecifierSet(">=1.2"), + frozenset(["foo", "bar"]), + None, + )) + assert hash( + Requirement.parse("Twisted @ https://localhost/twisted.zip") + ) == hash(( + "twisted", + "https://localhost/twisted.zip", + SpecifierSet(), + frozenset(), + None, + )) + + def testVersionEquality(self): + r1 = Requirement.parse("foo==0.3a2") + r2 = Requirement.parse("foo!=0.3a4") + d = Distribution.from_filename + + assert d("foo-0.3a4.egg") not in r1 + assert d("foo-0.3a1.egg") not in r1 + assert d("foo-0.3a4.egg") not in r2 + + assert d("foo-0.3a2.egg") in r1 + assert d("foo-0.3a2.egg") in r2 + assert d("foo-0.3a3.egg") in r2 + assert d("foo-0.3a5.egg") in r2 + + def testSetuptoolsProjectName(self): + """ + The setuptools project should implement the setuptools package. + """ + + assert Requirement.parse('setuptools').project_name == 'setuptools' + # setuptools 0.7 and higher means setuptools. + assert Requirement.parse('setuptools == 0.7').project_name == 'setuptools' + assert Requirement.parse('setuptools == 0.7a1').project_name == 'setuptools' + assert Requirement.parse('setuptools >= 0.7').project_name == 'setuptools' + + +class TestParsing: + def testEmptyParse(self): + assert list(parse_requirements('')) == [] + + def testYielding(self): + for inp, out in [ + ([], []), + ('x', ['x']), + ([[]], []), + (' x\n y', ['x', 'y']), + (['x\n\n', 'y'], ['x', 'y']), + ]: + assert list(pkg_resources.yield_lines(inp)) == out + + def testSplitting(self): + sample = """ + x + [Y] + z + + a + [b ] + # foo + c + [ d] + [q] + v + """ + assert list(pkg_resources.split_sections(sample)) == [ + (None, ["x"]), + ("Y", ["z", "a"]), + ("b", ["c"]), + ("d", []), + ("q", ["v"]), + ] + with pytest.raises(ValueError): + list(pkg_resources.split_sections("[foo")) + + def testSafeName(self): + assert safe_name("adns-python") == "adns-python" + assert safe_name("WSGI Utils") == "WSGI-Utils" + assert safe_name("WSGI Utils") == "WSGI-Utils" + assert safe_name("Money$$$Maker") == "Money-Maker" + assert safe_name("peak.web") != "peak-web" + + def testSafeVersion(self): + assert safe_version("1.2-1") == "1.2.post1" + assert safe_version("1.2 alpha") == "1.2.alpha" + assert safe_version("2.3.4 20050521") == "2.3.4.20050521" + assert safe_version("Money$$$Maker") == "Money-Maker" + assert safe_version("peak.web") == "peak.web" + + def testSimpleRequirements(self): + assert list(parse_requirements('Twis-Ted>=1.2-1')) == [ + Requirement('Twis-Ted>=1.2-1') + ] + assert list(parse_requirements('Twisted >=1.2, \\ # more\n<2.0')) == [ + Requirement('Twisted>=1.2,<2.0') + ] + assert Requirement.parse("FooBar==1.99a3") == Requirement("FooBar==1.99a3") + with pytest.raises(ValueError): + Requirement.parse(">=2.3") + with pytest.raises(ValueError): + Requirement.parse("x\\") + with pytest.raises(ValueError): + Requirement.parse("x==2 q") + with pytest.raises(ValueError): + Requirement.parse("X==1\nY==2") + with pytest.raises(ValueError): + Requirement.parse("#") + + def test_requirements_with_markers(self): + assert Requirement.parse("foobar;os_name=='a'") == Requirement.parse( + "foobar;os_name=='a'" + ) + assert Requirement.parse( + "name==1.1;python_version=='2.7'" + ) != Requirement.parse("name==1.1;python_version=='3.6'") + assert Requirement.parse( + "name==1.0;python_version=='2.7'" + ) != Requirement.parse("name==1.2;python_version=='2.7'") + assert Requirement.parse( + "name[foo]==1.0;python_version=='3.6'" + ) != Requirement.parse("name[foo,bar]==1.0;python_version=='3.6'") + + def test_local_version(self): + parse_requirements('foo==1.0+org1') + + def test_spaces_between_multiple_versions(self): + parse_requirements('foo>=1.0, <3') + parse_requirements('foo >= 1.0, < 3') + + @pytest.mark.parametrize( + ("lower", "upper"), + [ + ('1.2-rc1', '1.2rc1'), + ('0.4', '0.4.0'), + ('0.4.0.0', '0.4.0'), + ('0.4.0-0', '0.4-0'), + ('0post1', '0.0post1'), + ('0pre1', '0.0c1'), + ('0.0.0preview1', '0c1'), + ('0.0c1', '0-rc1'), + ('1.2a1', '1.2.a.1'), + ('1.2.a', '1.2a'), + ], + ) + def testVersionEquality(self, lower, upper): + assert parse_version(lower) == parse_version(upper) + + torture = """ + 0.80.1-3 0.80.1-2 0.80.1-1 0.79.9999+0.80.0pre4-1 + 0.79.9999+0.80.0pre2-3 0.79.9999+0.80.0pre2-2 + 0.77.2-1 0.77.1-1 0.77.0-1 + """ + + @pytest.mark.parametrize( + ("lower", "upper"), + [ + ('2.1', '2.1.1'), + ('2a1', '2b0'), + ('2a1', '2.1'), + ('2.3a1', '2.3'), + ('2.1-1', '2.1-2'), + ('2.1-1', '2.1.1'), + ('2.1', '2.1post4'), + ('2.1a0-20040501', '2.1'), + ('1.1', '02.1'), + ('3.2', '3.2.post0'), + ('3.2post1', '3.2post2'), + ('0.4', '4.0'), + ('0.0.4', '0.4.0'), + ('0post1', '0.4post1'), + ('2.1.0-rc1', '2.1.0'), + ('2.1dev', '2.1a0'), + ] + + list(pairwise(reversed(torture.split()))), + ) + def testVersionOrdering(self, lower, upper): + assert parse_version(lower) < parse_version(upper) + + def testVersionHashable(self): + """ + Ensure that our versions stay hashable even though we've subclassed + them and added some shim code to them. + """ + assert hash(parse_version("1.0")) == hash(parse_version("1.0")) + + +class TestNamespaces: + ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n" + + @pytest.fixture + def symlinked_tmpdir(self, tmpdir): + """ + Where available, return the tempdir as a symlink, + which as revealed in #231 is more fragile than + a natural tempdir. + """ + if not hasattr(os, 'symlink'): + yield str(tmpdir) + return + + link_name = str(tmpdir) + '-linked' + os.symlink(str(tmpdir), link_name) + try: + yield type(tmpdir)(link_name) + finally: + os.unlink(link_name) + + @pytest.fixture(autouse=True) + def patched_path(self, tmpdir): + """ + Patch sys.path to include the 'site-pkgs' dir. Also + restore pkg_resources._namespace_packages to its + former state. + """ + saved_ns_pkgs = pkg_resources._namespace_packages.copy() + saved_sys_path = sys.path[:] + site_pkgs = tmpdir.mkdir('site-pkgs') + sys.path.append(str(site_pkgs)) + try: + yield + finally: + pkg_resources._namespace_packages = saved_ns_pkgs + sys.path = saved_sys_path + + issue591 = pytest.mark.xfail(platform.system() == 'Windows', reason="#591") + + @issue591 + def test_two_levels_deep(self, symlinked_tmpdir): + """ + Test nested namespace packages + Create namespace packages in the following tree : + site-packages-1/pkg1/pkg2 + site-packages-2/pkg1/pkg2 + Check both are in the _namespace_packages dict and that their __path__ + is correct + """ + real_tmpdir = symlinked_tmpdir.realpath() + tmpdir = symlinked_tmpdir + sys.path.append(str(tmpdir / 'site-pkgs2')) + site_dirs = tmpdir / 'site-pkgs', tmpdir / 'site-pkgs2' + for site in site_dirs: + pkg1 = site / 'pkg1' + pkg2 = pkg1 / 'pkg2' + pkg2.ensure_dir() + (pkg1 / '__init__.py').write_text(self.ns_str, encoding='utf-8') + (pkg2 / '__init__.py').write_text(self.ns_str, encoding='utf-8') + with pytest.warns(DeprecationWarning, match="pkg_resources.declare_namespace"): + import pkg1 # pyright: ignore[reportMissingImports] # Temporary package for test + assert "pkg1" in pkg_resources._namespace_packages + # attempt to import pkg2 from site-pkgs2 + with pytest.warns(DeprecationWarning, match="pkg_resources.declare_namespace"): + import pkg1.pkg2 # pyright: ignore[reportMissingImports] # Temporary package for test + # check the _namespace_packages dict + assert "pkg1.pkg2" in pkg_resources._namespace_packages + assert pkg_resources._namespace_packages["pkg1"] == ["pkg1.pkg2"] + # check the __path__ attribute contains both paths + expected = [ + str(real_tmpdir / "site-pkgs" / "pkg1" / "pkg2"), + str(real_tmpdir / "site-pkgs2" / "pkg1" / "pkg2"), + ] + assert pkg1.pkg2.__path__ == expected + + @issue591 + def test_path_order(self, symlinked_tmpdir): + """ + Test that if multiple versions of the same namespace package subpackage + are on different sys.path entries, that only the one earliest on + sys.path is imported, and that the namespace package's __path__ is in + the correct order. + + Regression test for https://github.com/pypa/setuptools/issues/207 + """ + + tmpdir = symlinked_tmpdir + site_dirs = ( + tmpdir / "site-pkgs", + tmpdir / "site-pkgs2", + tmpdir / "site-pkgs3", + ) + + vers_str = "__version__ = %r" + + for number, site in enumerate(site_dirs, 1): + if number > 1: + sys.path.append(str(site)) + nspkg = site / 'nspkg' + subpkg = nspkg / 'subpkg' + subpkg.ensure_dir() + (nspkg / '__init__.py').write_text(self.ns_str, encoding='utf-8') + (subpkg / '__init__.py').write_text(vers_str % number, encoding='utf-8') + + with pytest.warns(DeprecationWarning, match="pkg_resources.declare_namespace"): + import nspkg # pyright: ignore[reportMissingImports] # Temporary package for test + import nspkg.subpkg # pyright: ignore[reportMissingImports] # Temporary package for test + expected = [str(site.realpath() / 'nspkg') for site in site_dirs] + assert nspkg.__path__ == expected + assert nspkg.subpkg.__version__ == 1 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_working_set.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_working_set.py new file mode 100644 index 0000000000000000000000000000000000000000..ed20c59dd3bb100b69f323e3ef66bd037ac3804c --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_working_set.py @@ -0,0 +1,505 @@ +import functools +import inspect +import re +import textwrap + +import pytest + +import pkg_resources + +from .test_resources import Metadata + + +def strip_comments(s): + return '\n'.join( + line + for line in s.split('\n') + if line.strip() and not line.strip().startswith('#') + ) + + +def parse_distributions(s): + """ + Parse a series of distribution specs of the form: + {project_name}-{version} + [optional, indented requirements specification] + + Example: + + foo-0.2 + bar-1.0 + foo>=3.0 + [feature] + baz + + yield 2 distributions: + - project_name=foo, version=0.2 + - project_name=bar, version=1.0, + requires=['foo>=3.0', 'baz; extra=="feature"'] + """ + s = s.strip() + for spec in re.split(r'\n(?=[^\s])', s): + if not spec: + continue + fields = spec.split('\n', 1) + assert 1 <= len(fields) <= 2 + name, version = fields.pop(0).rsplit('-', 1) + if fields: + requires = textwrap.dedent(fields.pop(0)) + metadata = Metadata(('requires.txt', requires)) + else: + metadata = None + dist = pkg_resources.Distribution( + project_name=name, version=version, metadata=metadata + ) + yield dist + + +class FakeInstaller: + def __init__(self, installable_dists) -> None: + self._installable_dists = installable_dists + + def __call__(self, req): + return next( + iter(filter(lambda dist: dist in req, self._installable_dists)), None + ) + + +def parametrize_test_working_set_resolve(*test_list): + idlist = [] + argvalues = [] + for test in test_list: + ( + name, + installed_dists, + installable_dists, + requirements, + expected1, + expected2, + ) = ( + strip_comments(s.lstrip()) + for s in textwrap.dedent(test).lstrip().split('\n\n', 5) + ) + installed_dists = list(parse_distributions(installed_dists)) + installable_dists = list(parse_distributions(installable_dists)) + requirements = list(pkg_resources.parse_requirements(requirements)) + for id_, replace_conflicting, expected in ( + (name, False, expected1), + (name + '_replace_conflicting', True, expected2), + ): + idlist.append(id_) + expected = strip_comments(expected.strip()) + if re.match(r'\w+$', expected): + expected = getattr(pkg_resources, expected) + assert issubclass(expected, Exception) + else: + expected = list(parse_distributions(expected)) + argvalues.append( + pytest.param( + installed_dists, + installable_dists, + requirements, + replace_conflicting, + expected, + ) + ) + return pytest.mark.parametrize( + ( + "installed_dists", + "installable_dists", + "requirements", + "replace_conflicting", + "resolved_dists_or_exception", + ), + argvalues, + ids=idlist, + ) + + +@parametrize_test_working_set_resolve( + """ + # id + noop + + # installed + + # installable + + # wanted + + # resolved + + # resolved [replace conflicting] + """, + """ + # id + already_installed + + # installed + foo-3.0 + + # installable + + # wanted + foo>=2.1,!=3.1,<4 + + # resolved + foo-3.0 + + # resolved [replace conflicting] + foo-3.0 + """, + """ + # id + installable_not_installed + + # installed + + # installable + foo-3.0 + foo-4.0 + + # wanted + foo>=2.1,!=3.1,<4 + + # resolved + foo-3.0 + + # resolved [replace conflicting] + foo-3.0 + """, + """ + # id + not_installable + + # installed + + # installable + + # wanted + foo>=2.1,!=3.1,<4 + + # resolved + DistributionNotFound + + # resolved [replace conflicting] + DistributionNotFound + """, + """ + # id + no_matching_version + + # installed + + # installable + foo-3.1 + + # wanted + foo>=2.1,!=3.1,<4 + + # resolved + DistributionNotFound + + # resolved [replace conflicting] + DistributionNotFound + """, + """ + # id + installable_with_installed_conflict + + # installed + foo-3.1 + + # installable + foo-3.5 + + # wanted + foo>=2.1,!=3.1,<4 + + # resolved + VersionConflict + + # resolved [replace conflicting] + foo-3.5 + """, + """ + # id + not_installable_with_installed_conflict + + # installed + foo-3.1 + + # installable + + # wanted + foo>=2.1,!=3.1,<4 + + # resolved + VersionConflict + + # resolved [replace conflicting] + DistributionNotFound + """, + """ + # id + installed_with_installed_require + + # installed + foo-3.9 + baz-0.1 + foo>=2.1,!=3.1,<4 + + # installable + + # wanted + baz + + # resolved + foo-3.9 + baz-0.1 + + # resolved [replace conflicting] + foo-3.9 + baz-0.1 + """, + """ + # id + installed_with_conflicting_installed_require + + # installed + foo-5 + baz-0.1 + foo>=2.1,!=3.1,<4 + + # installable + + # wanted + baz + + # resolved + VersionConflict + + # resolved [replace conflicting] + DistributionNotFound + """, + """ + # id + installed_with_installable_conflicting_require + + # installed + foo-5 + baz-0.1 + foo>=2.1,!=3.1,<4 + + # installable + foo-2.9 + + # wanted + baz + + # resolved + VersionConflict + + # resolved [replace conflicting] + baz-0.1 + foo-2.9 + """, + """ + # id + installed_with_installable_require + + # installed + baz-0.1 + foo>=2.1,!=3.1,<4 + + # installable + foo-3.9 + + # wanted + baz + + # resolved + foo-3.9 + baz-0.1 + + # resolved [replace conflicting] + foo-3.9 + baz-0.1 + """, + """ + # id + installable_with_installed_require + + # installed + foo-3.9 + + # installable + baz-0.1 + foo>=2.1,!=3.1,<4 + + # wanted + baz + + # resolved + foo-3.9 + baz-0.1 + + # resolved [replace conflicting] + foo-3.9 + baz-0.1 + """, + """ + # id + installable_with_installable_require + + # installed + + # installable + foo-3.9 + baz-0.1 + foo>=2.1,!=3.1,<4 + + # wanted + baz + + # resolved + foo-3.9 + baz-0.1 + + # resolved [replace conflicting] + foo-3.9 + baz-0.1 + """, + """ + # id + installable_with_conflicting_installable_require + + # installed + foo-5 + + # installable + foo-2.9 + baz-0.1 + foo>=2.1,!=3.1,<4 + + # wanted + baz + + # resolved + VersionConflict + + # resolved [replace conflicting] + baz-0.1 + foo-2.9 + """, + """ + # id + conflicting_installables + + # installed + + # installable + foo-2.9 + foo-5.0 + + # wanted + foo>=2.1,!=3.1,<4 + foo>=4 + + # resolved + VersionConflict + + # resolved [replace conflicting] + VersionConflict + """, + """ + # id + installables_with_conflicting_requires + + # installed + + # installable + foo-2.9 + dep==1.0 + baz-5.0 + dep==2.0 + dep-1.0 + dep-2.0 + + # wanted + foo + baz + + # resolved + VersionConflict + + # resolved [replace conflicting] + VersionConflict + """, + """ + # id + installables_with_conflicting_nested_requires + + # installed + + # installable + foo-2.9 + dep1 + dep1-1.0 + subdep<1.0 + baz-5.0 + dep2 + dep2-1.0 + subdep>1.0 + subdep-0.9 + subdep-1.1 + + # wanted + foo + baz + + # resolved + VersionConflict + + # resolved [replace conflicting] + VersionConflict + """, + """ + # id + wanted_normalized_name_installed_canonical + + # installed + foo.bar-3.6 + + # installable + + # wanted + foo-bar==3.6 + + # resolved + foo.bar-3.6 + + # resolved [replace conflicting] + foo.bar-3.6 + """, +) +def test_working_set_resolve( + installed_dists, + installable_dists, + requirements, + replace_conflicting, + resolved_dists_or_exception, +): + ws = pkg_resources.WorkingSet([]) + list(map(ws.add, installed_dists)) + resolve_call = functools.partial( + ws.resolve, + requirements, + installer=FakeInstaller(installable_dists), + replace_conflicting=replace_conflicting, + ) + if inspect.isclass(resolved_dists_or_exception): + with pytest.raises(resolved_dists_or_exception): + resolve_call() + else: + assert sorted(resolve_call()) == sorted(resolved_dists_or_exception) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pygments-2.19.1.dist-info/licenses/AUTHORS b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pygments-2.19.1.dist-info/licenses/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..811c66ae178b354c0a0eb9bd5e7a9ac63b4b056c --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pygments-2.19.1.dist-info/licenses/AUTHORS @@ -0,0 +1,291 @@ +Pygments is written and maintained by Georg Brandl . + +Major developers are Tim Hatch and Armin Ronacher +. + +Other contributors, listed alphabetically, are: + +* Sam Aaron -- Ioke lexer +* Jean Abou Samra -- LilyPond lexer +* João Abecasis -- JSLT lexer +* Ali Afshar -- image formatter +* Thomas Aglassinger -- Easytrieve, JCL, Rexx, Transact-SQL and VBScript + lexers +* Maxence Ahlouche -- PostgreSQL Explain lexer +* Muthiah Annamalai -- Ezhil lexer +* Nikolay Antipov -- OpenSCAD lexer +* Kumar Appaiah -- Debian control lexer +* Andreas Amann -- AppleScript lexer +* Timothy Armstrong -- Dart lexer fixes +* Jeffrey Arnold -- R/S, Rd, BUGS, Jags, and Stan lexers +* Eiríkr Åsheim -- Uxntal lexer +* Jeremy Ashkenas -- CoffeeScript lexer +* José Joaquín Atria -- Praat lexer +* Stefan Matthias Aust -- Smalltalk lexer +* Lucas Bajolet -- Nit lexer +* Ben Bangert -- Mako lexers +* Max Battcher -- Darcs patch lexer +* Thomas Baruchel -- APL lexer +* Tim Baumann -- (Literate) Agda lexer +* Paul Baumgart, 280 North, Inc. -- Objective-J lexer +* Michael Bayer -- Myghty lexers +* Thomas Beale -- Archetype lexers +* John Benediktsson -- Factor lexer +* David Benjamin, Google LLC -- TLS lexer +* Trevor Bergeron -- mIRC formatter +* Vincent Bernat -- LessCSS lexer +* Christopher Bertels -- Fancy lexer +* Sébastien Bigaret -- QVT Operational lexer +* Jarrett Billingsley -- MiniD lexer +* Adam Blinkinsop -- Haskell, Redcode lexers +* Stéphane Blondon -- Procfile, SGF and Sieve lexers +* Frits van Bommel -- assembler lexers +* Pierre Bourdon -- bugfixes +* Martijn Braam -- Kernel log lexer, BARE lexer +* JD Browne, Google LLC -- GoogleSQL lexer +* Matthias Bussonnier -- ANSI style handling for terminal-256 formatter +* chebee7i -- Python traceback lexer improvements +* Hiram Chirino -- Scaml and Jade lexers +* Mauricio Caceres -- SAS and Stata lexers. +* Michael Camilleri, John Gabriele, sogaiu -- Janet lexer +* Daren Chandisingh -- Gleam lexer +* Ian Cooper -- VGL lexer +* David Corbett -- Inform, Jasmin, JSGF, Snowball, and TADS 3 lexers +* Leaf Corcoran -- MoonScript lexer +* Fraser Cormack -- TableGen lexer +* Gabriel Corona -- ASN.1 lexer +* Christopher Creutzig -- MuPAD lexer +* Daniël W. Crompton -- Pike lexer +* Pete Curry -- bugfixes +* Bryan Davis -- EBNF lexer +* Bruno Deferrari -- Shen lexer +* Walter Dörwald -- UL4 lexer +* Luke Drummond -- Meson lexer +* Giedrius Dubinskas -- HTML formatter improvements +* Owen Durni -- Haxe lexer +* Alexander Dutton, Oxford University Computing Services -- SPARQL lexer +* James Edwards -- Terraform lexer +* Nick Efford -- Python 3 lexer +* Sven Efftinge -- Xtend lexer +* Artem Egorkine -- terminal256 formatter +* Matthew Fernandez -- CAmkES lexer +* Paweł Fertyk -- GDScript lexer, HTML formatter improvements +* Michael Ficarra -- CPSA lexer +* James H. Fisher -- PostScript lexer +* Amanda Fitch, Google LLC -- GoogleSQL lexer +* William S. Fulton -- SWIG lexer +* Carlos Galdino -- Elixir and Elixir Console lexers +* Michael Galloy -- IDL lexer +* Naveen Garg -- Autohotkey lexer +* Simon Garnotel -- FreeFem++ lexer +* Laurent Gautier -- R/S lexer +* Alex Gaynor -- PyPy log lexer +* Richard Gerkin -- Igor Pro lexer +* Alain Gilbert -- TypeScript lexer +* Alex Gilding -- BlitzBasic lexer +* GitHub, Inc -- DASM16, Augeas, TOML, and Slash lexers +* Bertrand Goetzmann -- Groovy lexer +* Krzysiek Goj -- Scala lexer +* Rostyslav Golda -- FloScript lexer +* Andrey Golovizin -- BibTeX lexers +* Matt Good -- Genshi, Cheetah lexers +* Michał Górny -- vim modeline support +* Alex Gosse -- TrafficScript lexer +* Patrick Gotthardt -- PHP namespaces support +* Hubert Gruniaux -- C and C++ lexer improvements +* Olivier Guibe -- Asymptote lexer +* Phil Hagelberg -- Fennel lexer +* Florian Hahn -- Boogie lexer +* Martin Harriman -- SNOBOL lexer +* Matthew Harrison -- SVG formatter +* Steven Hazel -- Tcl lexer +* Dan Michael Heggø -- Turtle lexer +* Aslak Hellesøy -- Gherkin lexer +* Greg Hendershott -- Racket lexer +* Justin Hendrick -- ParaSail lexer +* Jordi Gutiérrez Hermoso -- Octave lexer +* David Hess, Fish Software, Inc. -- Objective-J lexer +* Ken Hilton -- Typographic Number Theory and Arrow lexers +* Varun Hiremath -- Debian control lexer +* Rob Hoelz -- Perl 6 lexer +* Doug Hogan -- Mscgen lexer +* Ben Hollis -- Mason lexer +* Max Horn -- GAP lexer +* Fred Hornsey -- OMG IDL Lexer +* Alastair Houghton -- Lexer inheritance facility +* Tim Howard -- BlitzMax lexer +* Dustin Howett -- Logos lexer +* Ivan Inozemtsev -- Fantom lexer +* Hiroaki Itoh -- Shell console rewrite, Lexers for PowerShell session, + MSDOS session, BC, WDiff +* Brian R. Jackson -- Tea lexer +* Christian Jann -- ShellSession lexer +* Jonas Camillus Jeppesen -- Line numbers and line highlighting for + RTF-formatter +* Dennis Kaarsemaker -- sources.list lexer +* Dmitri Kabak -- Inferno Limbo lexer +* Igor Kalnitsky -- vhdl lexer +* Colin Kennedy - USD lexer +* Alexander Kit -- MaskJS lexer +* Pekka Klärck -- Robot Framework lexer +* Gerwin Klein -- Isabelle lexer +* Eric Knibbe -- Lasso lexer +* Stepan Koltsov -- Clay lexer +* Oliver Kopp - Friendly grayscale style +* Adam Koprowski -- Opa lexer +* Benjamin Kowarsch -- Modula-2 lexer +* Domen Kožar -- Nix lexer +* Oleh Krekel -- Emacs Lisp lexer +* Alexander Kriegisch -- Kconfig and AspectJ lexers +* Marek Kubica -- Scheme lexer +* Jochen Kupperschmidt -- Markdown processor +* Gerd Kurzbach -- Modelica lexer +* Jon Larimer, Google Inc. -- Smali lexer +* Olov Lassus -- Dart lexer +* Matt Layman -- TAP lexer +* Dan Lazin, Google LLC -- GoogleSQL lexer +* Kristian Lyngstøl -- Varnish lexers +* Sylvestre Ledru -- Scilab lexer +* Chee Sing Lee -- Flatline lexer +* Mark Lee -- Vala lexer +* Thomas Linder Puls -- Visual Prolog lexer +* Pete Lomax -- Phix lexer +* Valentin Lorentz -- C++ lexer improvements +* Ben Mabey -- Gherkin lexer +* Angus MacArthur -- QML lexer +* Louis Mandel -- X10 lexer +* Louis Marchand -- Eiffel lexer +* Simone Margaritelli -- Hybris lexer +* Tim Martin - World of Warcraft TOC lexer +* Kirk McDonald -- D lexer +* Gordon McGregor -- SystemVerilog lexer +* Stephen McKamey -- Duel/JBST lexer +* Brian McKenna -- F# lexer +* Charles McLaughlin -- Puppet lexer +* Kurt McKee -- Tera Term macro lexer, PostgreSQL updates, MySQL overhaul, JSON lexer +* Joe Eli McIlvain -- Savi lexer +* Lukas Meuser -- BBCode formatter, Lua lexer +* Cat Miller -- Pig lexer +* Paul Miller -- LiveScript lexer +* Hong Minhee -- HTTP lexer +* Michael Mior -- Awk lexer +* Bruce Mitchener -- Dylan lexer rewrite +* Reuben Morais -- SourcePawn lexer +* Jon Morton -- Rust lexer +* Paulo Moura -- Logtalk lexer +* Mher Movsisyan -- DTD lexer +* Dejan Muhamedagic -- Crmsh lexer +* Adrien Nayrat -- PostgreSQL Explain lexer +* Ana Nelson -- Ragel, ANTLR, R console lexers +* David Neto, Google LLC -- WebGPU Shading Language lexer +* Kurt Neufeld -- Markdown lexer +* Nam T. Nguyen -- Monokai style +* Jesper Noehr -- HTML formatter "anchorlinenos" +* Mike Nolta -- Julia lexer +* Avery Nortonsmith -- Pointless lexer +* Jonas Obrist -- BBCode lexer +* Edward O'Callaghan -- Cryptol lexer +* David Oliva -- Rebol lexer +* Pat Pannuto -- nesC lexer +* Jon Parise -- Protocol buffers and Thrift lexers +* Benjamin Peterson -- Test suite refactoring +* Ronny Pfannschmidt -- BBCode lexer +* Dominik Picheta -- Nimrod lexer +* Andrew Pinkham -- RTF Formatter Refactoring +* Clément Prévost -- UrbiScript lexer +* Tanner Prynn -- cmdline -x option and loading lexers from files +* Oleh Prypin -- Crystal lexer (based on Ruby lexer) +* Nick Psaris -- K and Q lexers +* Xidorn Quan -- Web IDL lexer +* Elias Rabel -- Fortran fixed form lexer +* raichoo -- Idris lexer +* Daniel Ramirez -- GDScript lexer +* Kashif Rasul -- CUDA lexer +* Nathan Reed -- HLSL lexer +* Justin Reidy -- MXML lexer +* Jonathon Reinhart, Google LLC -- Soong lexer +* Norman Richards -- JSON lexer +* Corey Richardson -- Rust lexer updates +* Fabrizio Riguzzi -- cplint leder +* Lubomir Rintel -- GoodData MAQL and CL lexers +* Andre Roberge -- Tango style +* Georg Rollinger -- HSAIL lexer +* Michiel Roos -- TypoScript lexer +* Konrad Rudolph -- LaTeX formatter enhancements +* Mario Ruggier -- Evoque lexers +* Miikka Salminen -- Lovelace style, Hexdump lexer, lexer enhancements +* Stou Sandalski -- NumPy, FORTRAN, tcsh and XSLT lexers +* Matteo Sasso -- Common Lisp lexer +* Joe Schafer -- Ada lexer +* Max Schillinger -- TiddlyWiki5 lexer +* Andrew Schmidt -- X++ lexer +* Ken Schutte -- Matlab lexers +* René Schwaiger -- Rainbow Dash style +* Sebastian Schweizer -- Whiley lexer +* Tassilo Schweyer -- Io, MOOCode lexers +* Pablo Seminario -- PromQL lexer +* Ted Shaw -- AutoIt lexer +* Joerg Sieker -- ABAP lexer +* Robert Simmons -- Standard ML lexer +* Kirill Simonov -- YAML lexer +* Corbin Simpson -- Monte lexer +* Ville Skyttä -- ASCII armored lexer +* Alexander Smishlajev -- Visual FoxPro lexer +* Steve Spigarelli -- XQuery lexer +* Jerome St-Louis -- eC lexer +* Camil Staps -- Clean and NuSMV lexers; Solarized style +* James Strachan -- Kotlin lexer +* Tom Stuart -- Treetop lexer +* Colin Sullivan -- SuperCollider lexer +* Ben Swift -- Extempore lexer +* tatt61880 -- Kuin lexer +* Edoardo Tenani -- Arduino lexer +* Tiberius Teng -- default style overhaul +* Jeremy Thurgood -- Erlang, Squid config lexers +* Brian Tiffin -- OpenCOBOL lexer +* Bob Tolbert -- Hy lexer +* Doug Torrance -- Macaulay2 lexer +* Matthias Trute -- Forth lexer +* Tuoa Spi T4 -- Bdd lexer +* Erick Tryzelaar -- Felix lexer +* Alexander Udalov -- Kotlin lexer improvements +* Thomas Van Doren -- Chapel lexer +* Dave Van Ee -- Uxntal lexer updates +* Daniele Varrazzo -- PostgreSQL lexers +* Abe Voelker -- OpenEdge ABL lexer +* Pepijn de Vos -- HTML formatter CTags support +* Matthias Vallentin -- Bro lexer +* Benoît Vinot -- AMPL lexer +* Linh Vu Hong -- RSL lexer +* Taavi Väänänen -- Debian control lexer +* Immanuel Washington -- Smithy lexer +* Nathan Weizenbaum -- Haml and Sass lexers +* Nathan Whetsell -- Csound lexers +* Dietmar Winkler -- Modelica lexer +* Nils Winter -- Smalltalk lexer +* Davy Wybiral -- Clojure lexer +* Whitney Young -- ObjectiveC lexer +* Diego Zamboni -- CFengine3 lexer +* Enrique Zamudio -- Ceylon lexer +* Alex Zimin -- Nemerle lexer +* Rob Zimmerman -- Kal lexer +* Evgenii Zheltonozhskii -- Maple lexer +* Vincent Zurczak -- Roboconf lexer +* Hubert Gruniaux -- C and C++ lexer improvements +* Thomas Symalla -- AMDGPU Lexer +* 15b3 -- Image Formatter improvements +* Fabian Neumann -- CDDL lexer +* Thomas Duboucher -- CDDL lexer +* Philipp Imhof -- Pango Markup formatter +* Thomas Voss -- Sed lexer +* Martin Fischer -- WCAG contrast testing +* Marc Auberer -- Spice lexer +* Amr Hesham -- Carbon lexer +* diskdance -- Wikitext lexer +* vanillajonathan -- PRQL lexer +* Nikolay Antipov -- OpenSCAD lexer +* Markus Meyer, Nextron Systems -- YARA lexer +* Hannes Römer -- Mojo lexer +* Jan Frederik Schaefer -- PDDL lexer + +Many thanks for all contributions! diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pygments-2.19.1.dist-info/licenses/LICENSE b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pygments-2.19.1.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..446a1a805c8a949579fb8a9799f2bec7777349dc --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pygments-2.19.1.dist-info/licenses/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2006-2022 by the respective authors (see AUTHORS file). +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..38412e4766a3e6e963437a0f3c1275eb4152616e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/exceptions.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/exceptions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f35cc86031cf7e0334eefb388e176f6a1387fa93 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/exceptions.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/lazy.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/lazy.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13455f3d1bea1dc9b5645eb271f654841fabf85c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/lazy.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/reference.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/reference.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..174d8a628cbe2758f2e499087ea53c643e1788dc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/reference.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/tzfile.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/tzfile.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f625a861896c1dc5597a248f0310f9238ea2565f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/tzfile.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/tzinfo.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/tzinfo.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4ed9c95337202c04268bc28ad0226c896a9ad6e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/__pycache__/tzinfo.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Adak b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Adak new file mode 100644 index 0000000000000000000000000000000000000000..43236498f681cc06f64ca2afa613880331fe6fbb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Adak differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Anchorage b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Anchorage new file mode 100644 index 0000000000000000000000000000000000000000..9bbb2fd3b361ea8aa4c126d14df5fa370343a63f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Anchorage differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Anguilla b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Anguilla new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Anguilla differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Antigua b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Antigua new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Antigua differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Araguaina b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Araguaina new file mode 100644 index 0000000000000000000000000000000000000000..919723dc2ca581b4f95154d4192d8f732cc55a45 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Araguaina differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Buenos_Aires b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Buenos_Aires new file mode 100644 index 0000000000000000000000000000000000000000..cc82e69898f161842b5001f10a84d3ac127c5c6f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Buenos_Aires differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Catamarca b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Catamarca new file mode 100644 index 0000000000000000000000000000000000000000..7268eb3738e5b3ba906f962533f48016cf3dcabc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Catamarca differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/ComodRivadavia b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/ComodRivadavia new file mode 100644 index 0000000000000000000000000000000000000000..7268eb3738e5b3ba906f962533f48016cf3dcabc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/ComodRivadavia differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Cordoba b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Cordoba new file mode 100644 index 0000000000000000000000000000000000000000..2ad6ea5db204d599266412558f5a1fae076fc41a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Cordoba differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Jujuy b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Jujuy new file mode 100644 index 0000000000000000000000000000000000000000..7ca0b46f680b80780981aab0699e64dd04070fe7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Jujuy differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/La_Rioja b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/La_Rioja new file mode 100644 index 0000000000000000000000000000000000000000..a6a6694f3317a25e7bc4c66502e9f396fa106509 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/La_Rioja differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Mendoza b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Mendoza new file mode 100644 index 0000000000000000000000000000000000000000..3232c80e2003489921578f7acbabc73fb9148205 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Mendoza differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Rio_Gallegos b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Rio_Gallegos new file mode 100644 index 0000000000000000000000000000000000000000..8b1a2816ab136098d10a3d294993ea56b6c432dc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Rio_Gallegos differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Salta b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Salta new file mode 100644 index 0000000000000000000000000000000000000000..7072dec22958ad5ac74ba3457a178a4faadaf570 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Salta differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/San_Juan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/San_Juan new file mode 100644 index 0000000000000000000000000000000000000000..f3e185c3ab516065c52557aaceaaeacae1f8b221 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/San_Juan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/San_Luis b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/San_Luis new file mode 100644 index 0000000000000000000000000000000000000000..2d1da3ae3d6f9c6f92a8ddf01c2ff51ae28e4de2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/San_Luis differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Tucuman b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Tucuman new file mode 100644 index 0000000000000000000000000000000000000000..c6449f582a7804ecf66858a7fceda207c5d979be Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Tucuman differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Ushuaia b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Ushuaia new file mode 100644 index 0000000000000000000000000000000000000000..e74ce049c793c96e855ebb15779887a48622bf26 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Argentina/Ushuaia differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Aruba b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Aruba new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Aruba differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Asuncion b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Asuncion new file mode 100644 index 0000000000000000000000000000000000000000..891279d4db7f89ee8cf063b64b6e87a29ea86821 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Asuncion differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Atikokan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Atikokan new file mode 100644 index 0000000000000000000000000000000000000000..9964b9a33452f4b636f43703b7cdec4891cbda5f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Atikokan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Atka b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Atka new file mode 100644 index 0000000000000000000000000000000000000000..43236498f681cc06f64ca2afa613880331fe6fbb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Atka differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Bahia b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Bahia new file mode 100644 index 0000000000000000000000000000000000000000..0b65e49fca21f1be92c3ab0dfa4cd05137f028b2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Bahia differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Bahia_Banderas b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Bahia_Banderas new file mode 100644 index 0000000000000000000000000000000000000000..ae4a8a754617b8b918daffb6a45a067df2fd2fe6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Bahia_Banderas differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Barbados b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Barbados new file mode 100644 index 0000000000000000000000000000000000000000..00cd045ac86d6060e9e8b8dc0460caa49d2479b5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Barbados differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Belem b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Belem new file mode 100644 index 0000000000000000000000000000000000000000..0ae1202682c94ee52f74a795099f6a11d34e0d1e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Belem differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Belize b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Belize new file mode 100644 index 0000000000000000000000000000000000000000..e6f5dfa6a8d82523e8cb12f17cf73560bc09a383 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Belize differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Blanc-Sablon b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Blanc-Sablon new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Blanc-Sablon differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Boa_Vista b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Boa_Vista new file mode 100644 index 0000000000000000000000000000000000000000..08d518b151425f85458727fbf69f6e601f12be86 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Boa_Vista differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Bogota b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Bogota new file mode 100644 index 0000000000000000000000000000000000000000..331a1b7c4c3af257841900fe076e5393e15db100 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Bogota differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Boise b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Boise new file mode 100644 index 0000000000000000000000000000000000000000..aad1d991c49c2e0fa28be3da4de447af33c8df1c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Boise differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Buenos_Aires b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Buenos_Aires new file mode 100644 index 0000000000000000000000000000000000000000..cc82e69898f161842b5001f10a84d3ac127c5c6f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Buenos_Aires differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cambridge_Bay b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cambridge_Bay new file mode 100644 index 0000000000000000000000000000000000000000..7e58a203c6bdc9045092f879f8f58aa960084cad Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cambridge_Bay differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cancun b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cancun new file mode 100644 index 0000000000000000000000000000000000000000..e7acbff18a2469c79f4ce77064adeb189d60bf10 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cancun differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Catamarca b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Catamarca new file mode 100644 index 0000000000000000000000000000000000000000..7268eb3738e5b3ba906f962533f48016cf3dcabc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Catamarca differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cayenne b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cayenne new file mode 100644 index 0000000000000000000000000000000000000000..e898594276143fa4cfd5d3815c4598b9e58dba07 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cayenne differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cayman b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cayman new file mode 100644 index 0000000000000000000000000000000000000000..9964b9a33452f4b636f43703b7cdec4891cbda5f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cayman differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Chicago b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Chicago new file mode 100644 index 0000000000000000000000000000000000000000..c6981a06b1d9c26f447518efe265a6454726eae7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Chicago differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Chihuahua b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Chihuahua new file mode 100644 index 0000000000000000000000000000000000000000..e0910396704ffda1d7f39e70a369249aeb4b0353 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Chihuahua differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Ciudad_Juarez b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Ciudad_Juarez new file mode 100644 index 0000000000000000000000000000000000000000..eb1e53961c1ebe1e147dd42248753ad30817a349 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Ciudad_Juarez differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Coral_Harbour b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Coral_Harbour new file mode 100644 index 0000000000000000000000000000000000000000..9964b9a33452f4b636f43703b7cdec4891cbda5f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Coral_Harbour differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cordoba b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cordoba new file mode 100644 index 0000000000000000000000000000000000000000..2ad6ea5db204d599266412558f5a1fae076fc41a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cordoba differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Creston b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Creston new file mode 100644 index 0000000000000000000000000000000000000000..ab37e845566aa95659b7b85be0051d0c67a7e53a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Creston differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cuiaba b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cuiaba new file mode 100644 index 0000000000000000000000000000000000000000..26e97f6ebfc60c1517244840b77dbaedcbfabaaa Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Cuiaba differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Curacao b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Curacao new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Curacao differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Danmarkshavn b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Danmarkshavn new file mode 100644 index 0000000000000000000000000000000000000000..9549adcb657569ea304592a4070ceecb4550a4db Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Danmarkshavn differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Dawson b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Dawson new file mode 100644 index 0000000000000000000000000000000000000000..343b63227d2185863cd720bf449de000bbc794d0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Dawson differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Dawson_Creek b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Dawson_Creek new file mode 100644 index 0000000000000000000000000000000000000000..db9e3396557652707c0c2232e119e13a2dd172fb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Dawson_Creek differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Denver b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Denver new file mode 100644 index 0000000000000000000000000000000000000000..abb2b974a47eb3e5c8b4f5d4370baf4898b239ab Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Denver differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Detroit b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Detroit new file mode 100644 index 0000000000000000000000000000000000000000..e104faa46545ee873295cde34e1d46bccad8647c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Detroit differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Dominica b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Dominica new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Dominica differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Edmonton b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Edmonton new file mode 100644 index 0000000000000000000000000000000000000000..cd78a6f8be1dd55ac5afd25bbae39bd5706e42d1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Edmonton differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Eirunepe b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Eirunepe new file mode 100644 index 0000000000000000000000000000000000000000..d4c46e3091fe37b7db8d8b67d383302cd667987e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Eirunepe differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/El_Salvador b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/El_Salvador new file mode 100644 index 0000000000000000000000000000000000000000..e2f22304aad56062cfb66d23f3a8c296689286ed Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/El_Salvador differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Ensenada b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Ensenada new file mode 100644 index 0000000000000000000000000000000000000000..63dfdf48a68d02240737ecd6af081e02eb0b6317 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Ensenada differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Fort_Nelson b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Fort_Nelson new file mode 100644 index 0000000000000000000000000000000000000000..5a0b7f1ca032be1adf8ba91f863e727c5ec6a026 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Fort_Nelson differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Fort_Wayne b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Fort_Wayne new file mode 100644 index 0000000000000000000000000000000000000000..a84b6e99671f7305d1c459956e16a4dd772fc60e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Fort_Wayne differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Fortaleza b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Fortaleza new file mode 100644 index 0000000000000000000000000000000000000000..bee1a95152cbc37db7117d996d370ff9d3f11f79 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Fortaleza differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Glace_Bay b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Glace_Bay new file mode 100644 index 0000000000000000000000000000000000000000..48412a4cbf9241ea83887876b1b8b22c367ff4fd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Glace_Bay differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Godthab b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Godthab new file mode 100644 index 0000000000000000000000000000000000000000..29958cf12a9df7cf775e3337b4894e4cf4b82f58 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Godthab differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Goose_Bay b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Goose_Bay new file mode 100644 index 0000000000000000000000000000000000000000..a3f299079aebb8524bf77e7f92e0a7e6d0a7b6fb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Goose_Bay differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Grand_Turk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Grand_Turk new file mode 100644 index 0000000000000000000000000000000000000000..06da1a6d7a3eeec0e82f7c5815a8fed4252e16b2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Grand_Turk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Grenada b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Grenada new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Grenada differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guadeloupe b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guadeloupe new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guadeloupe differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guatemala b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guatemala new file mode 100644 index 0000000000000000000000000000000000000000..407138caf94e467b52d925f96ad80b506e16d9ec Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guatemala differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guayaquil b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guayaquil new file mode 100644 index 0000000000000000000000000000000000000000..40831be11e0ab028ada80cecf5fdc0e2a233ee17 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guayaquil differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guyana b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guyana new file mode 100644 index 0000000000000000000000000000000000000000..9b7036723053b8e8e3888b0497528fe714b5b735 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Guyana differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Halifax b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Halifax new file mode 100644 index 0000000000000000000000000000000000000000..756099abe6cee44295a5566ad6cd0c352fb82e64 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Halifax differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Havana b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Havana new file mode 100644 index 0000000000000000000000000000000000000000..b69ac4510784f23ee794cd6d11e62315a7318e5e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Havana differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Hermosillo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Hermosillo new file mode 100644 index 0000000000000000000000000000000000000000..86bd1a20a3fca3908723ffbe0201d3b162474066 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Hermosillo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Indianapolis b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Indianapolis new file mode 100644 index 0000000000000000000000000000000000000000..a84b6e99671f7305d1c459956e16a4dd772fc60e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Indianapolis differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Knox b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Knox new file mode 100644 index 0000000000000000000000000000000000000000..025d132dd48ba978c6fedf86d70173127be49d49 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Knox differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Marengo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Marengo new file mode 100644 index 0000000000000000000000000000000000000000..677bbff6a9d89180cfd2dd3279a1c412610b6540 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Marengo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Petersburg b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Petersburg new file mode 100644 index 0000000000000000000000000000000000000000..3082de00c2e0bfe89d4ac5e093d9e5921aa63610 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Petersburg differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Tell_City b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Tell_City new file mode 100644 index 0000000000000000000000000000000000000000..103c5cb31795edc15d548ef4ca71f1e04e2996b5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Tell_City differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Vevay b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Vevay new file mode 100644 index 0000000000000000000000000000000000000000..315b4c45aef1f241d025900544133c085fe4f69d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Vevay differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Vincennes b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Vincennes new file mode 100644 index 0000000000000000000000000000000000000000..35a24133446b9ee1e8f8a7931519d93517130315 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Vincennes differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Winamac b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Winamac new file mode 100644 index 0000000000000000000000000000000000000000..6d4e19377e9f70c3782daa223753c640c60ab1eb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indiana/Winamac differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indianapolis b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indianapolis new file mode 100644 index 0000000000000000000000000000000000000000..a84b6e99671f7305d1c459956e16a4dd772fc60e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Indianapolis differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Inuvik b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Inuvik new file mode 100644 index 0000000000000000000000000000000000000000..04c2df456ff0f879a419331dc3e9f4d4f68f0ecd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Inuvik differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Iqaluit b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Iqaluit new file mode 100644 index 0000000000000000000000000000000000000000..0b47b9032f11d4ea7dd6ac51aa329f7a98253638 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Iqaluit differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Jamaica b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Jamaica new file mode 100644 index 0000000000000000000000000000000000000000..2a9b7fd52d37a1ffe9fc589daa04d88c6c71a6e0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Jamaica differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Jujuy b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Jujuy new file mode 100644 index 0000000000000000000000000000000000000000..7ca0b46f680b80780981aab0699e64dd04070fe7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Jujuy differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Juneau b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Juneau new file mode 100644 index 0000000000000000000000000000000000000000..451f3490096338f40e601628ac70f04112ace51d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Juneau differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Kentucky/Louisville b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Kentucky/Louisville new file mode 100644 index 0000000000000000000000000000000000000000..3a335b37165d2b3d6a09a1716cb158e272087c9f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Kentucky/Louisville differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Kentucky/Monticello b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Kentucky/Monticello new file mode 100644 index 0000000000000000000000000000000000000000..576f16bb2b21a7e0871a7222241ad65e533bb93a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Kentucky/Monticello differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Knox_IN b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Knox_IN new file mode 100644 index 0000000000000000000000000000000000000000..025d132dd48ba978c6fedf86d70173127be49d49 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Knox_IN differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Kralendijk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Kralendijk new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Kralendijk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/La_Paz b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/La_Paz new file mode 100644 index 0000000000000000000000000000000000000000..374586ea67601c4512b52859ff4e73bb30dbecc0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/La_Paz differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Lima b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Lima new file mode 100644 index 0000000000000000000000000000000000000000..c13bb6be45a3be6cc747d056c571623528dc1e34 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Lima differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Los_Angeles b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Los_Angeles new file mode 100644 index 0000000000000000000000000000000000000000..610e7af5fc13d9784de30d272c7c39d7938873a0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Los_Angeles differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Louisville b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Louisville new file mode 100644 index 0000000000000000000000000000000000000000..3a335b37165d2b3d6a09a1716cb158e272087c9f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Louisville differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Lower_Princes b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Lower_Princes new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Lower_Princes differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Maceio b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Maceio new file mode 100644 index 0000000000000000000000000000000000000000..437a47310ec174736b0efbbe9e7e9a8cc26c150c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Maceio differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Managua b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Managua new file mode 100644 index 0000000000000000000000000000000000000000..e0242bff6e5df45de8b235abb4a8405fbb8ba6a6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Managua differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Manaus b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Manaus new file mode 100644 index 0000000000000000000000000000000000000000..2708baea5af1d5169a1cebd00c4762d6bb937fda Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Manaus differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Marigot b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Marigot new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Marigot differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Martinique b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Martinique new file mode 100644 index 0000000000000000000000000000000000000000..8df43dcf1c9f63d3ea9f056f062ea97e5c7c0b57 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Martinique differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Matamoros b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Matamoros new file mode 100644 index 0000000000000000000000000000000000000000..bbe04e86610a302d0a4deb36dd56f17673f2d3dc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Matamoros differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Mazatlan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Mazatlan new file mode 100644 index 0000000000000000000000000000000000000000..06fa22749d0a3157b5a693f0797086f78e1201c5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Mazatlan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Mendoza b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Mendoza new file mode 100644 index 0000000000000000000000000000000000000000..3232c80e2003489921578f7acbabc73fb9148205 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Mendoza differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Menominee b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Menominee new file mode 100644 index 0000000000000000000000000000000000000000..314613866de53e1457f6cbf2fb617be7e4955edf Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Menominee differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Merida b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Merida new file mode 100644 index 0000000000000000000000000000000000000000..17654cb59991e52537f87d9d9a2b56396f9c5c7e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Merida differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Metlakatla b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Metlakatla new file mode 100644 index 0000000000000000000000000000000000000000..1e94be3d552ea0d6e29824469866c2a51a187be9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Metlakatla differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Mexico_City b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Mexico_City new file mode 100644 index 0000000000000000000000000000000000000000..68176daa4976b015fb79026f3053e74e4a7457ab Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Mexico_City differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Miquelon b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Miquelon new file mode 100644 index 0000000000000000000000000000000000000000..5eccd861071d4eccb76fe0d8f5195bd1a7f646b7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Miquelon differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Moncton b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Moncton new file mode 100644 index 0000000000000000000000000000000000000000..9df8d0f2ec9fc8f1974d83cdd8155c79340007ed Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Moncton differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Monterrey b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Monterrey new file mode 100644 index 0000000000000000000000000000000000000000..5eb723c80949d0cf2a99603ea6aba4688ade6b21 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Monterrey differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Montevideo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Montevideo new file mode 100644 index 0000000000000000000000000000000000000000..e7bbfbb8c332fee14ae1b4aa07cc4d128e6a3ca7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Montevideo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Montreal b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Montreal new file mode 100644 index 0000000000000000000000000000000000000000..6752c5b05285678b86aea170f0921fc5f5e57738 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Montreal differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Montserrat b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Montserrat new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Montserrat differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Nassau b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Nassau new file mode 100644 index 0000000000000000000000000000000000000000..6752c5b05285678b86aea170f0921fc5f5e57738 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Nassau differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/New_York b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/New_York new file mode 100644 index 0000000000000000000000000000000000000000..a8b9ab1992257d721ad627b14f535c3d4b020888 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/New_York differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Nipigon b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Nipigon new file mode 100644 index 0000000000000000000000000000000000000000..6752c5b05285678b86aea170f0921fc5f5e57738 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Nipigon differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Noronha b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Noronha new file mode 100644 index 0000000000000000000000000000000000000000..73b4b336ab55544e6061409261c16cacc39aff61 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Noronha differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/North_Dakota/Beulah b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/North_Dakota/Beulah new file mode 100644 index 0000000000000000000000000000000000000000..33e317e25b127335de68052f57d33ceed620524e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/North_Dakota/Beulah differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/North_Dakota/Center b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/North_Dakota/Center new file mode 100644 index 0000000000000000000000000000000000000000..17fe13bcc1c73ecbc6738499667816f54c164e39 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/North_Dakota/Center differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/North_Dakota/New_Salem b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/North_Dakota/New_Salem new file mode 100644 index 0000000000000000000000000000000000000000..12dbe801aeb06823483525727f6f6695dec1bc24 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/North_Dakota/New_Salem differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Nuuk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Nuuk new file mode 100644 index 0000000000000000000000000000000000000000..29958cf12a9df7cf775e3337b4894e4cf4b82f58 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Nuuk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Ojinaga b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Ojinaga new file mode 100644 index 0000000000000000000000000000000000000000..f97946d1e269bf9c83fd4a02591b7ef04e8eb6a8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Ojinaga differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Panama b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Panama new file mode 100644 index 0000000000000000000000000000000000000000..9964b9a33452f4b636f43703b7cdec4891cbda5f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Panama differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Pangnirtung b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Pangnirtung new file mode 100644 index 0000000000000000000000000000000000000000..0b47b9032f11d4ea7dd6ac51aa329f7a98253638 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Pangnirtung differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Paramaribo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Paramaribo new file mode 100644 index 0000000000000000000000000000000000000000..f1b82b4f9a546fd067cf043ba5d35da6fbe41fbe Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Paramaribo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Phoenix b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Phoenix new file mode 100644 index 0000000000000000000000000000000000000000..ab37e845566aa95659b7b85be0051d0c67a7e53a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Phoenix differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Port-au-Prince b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Port-au-Prince new file mode 100644 index 0000000000000000000000000000000000000000..287f1439266639f9564149d6e162feaba3fbed86 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Port-au-Prince differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Port_of_Spain b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Port_of_Spain new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Port_of_Spain differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Porto_Acre b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Porto_Acre new file mode 100644 index 0000000000000000000000000000000000000000..cdda168cb97b1d45a4f1b7791a74523b74c88e6d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Porto_Acre differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Porto_Velho b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Porto_Velho new file mode 100644 index 0000000000000000000000000000000000000000..e00398602c634e6f1e9c0bc0e12b064f343ffe0c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Porto_Velho differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Puerto_Rico b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Puerto_Rico new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Puerto_Rico differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Punta_Arenas b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Punta_Arenas new file mode 100644 index 0000000000000000000000000000000000000000..411a839b84d3c629bf7eb623024077efe614ed07 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Punta_Arenas differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rainy_River b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rainy_River new file mode 100644 index 0000000000000000000000000000000000000000..ac40299f6b27043e8f2454ac594b0ec184c1a237 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rainy_River differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rankin_Inlet b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rankin_Inlet new file mode 100644 index 0000000000000000000000000000000000000000..e2714921a8f3c05189d20a9151931fb6eadf493b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rankin_Inlet differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Recife b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Recife new file mode 100644 index 0000000000000000000000000000000000000000..5bf6c211c19b7cd37107a2e3b317c2a7195c2947 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Recife differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Regina b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Regina new file mode 100644 index 0000000000000000000000000000000000000000..20c9c84df491e4072ec4c5d2c931a7433d9fd394 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Regina differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Resolute b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Resolute new file mode 100644 index 0000000000000000000000000000000000000000..19668900dea9249c1714b8838e44ac2070069138 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Resolute differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rio_Branco b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rio_Branco new file mode 100644 index 0000000000000000000000000000000000000000..cdda168cb97b1d45a4f1b7791a74523b74c88e6d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rio_Branco differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rosario b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rosario new file mode 100644 index 0000000000000000000000000000000000000000..2ad6ea5db204d599266412558f5a1fae076fc41a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Rosario differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santa_Isabel b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santa_Isabel new file mode 100644 index 0000000000000000000000000000000000000000..63dfdf48a68d02240737ecd6af081e02eb0b6317 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santa_Isabel differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santarem b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santarem new file mode 100644 index 0000000000000000000000000000000000000000..001638c2f2a964eb2cc75660f66a1bcc447d7a57 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santarem differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santiago b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santiago new file mode 100644 index 0000000000000000000000000000000000000000..010c6bd04cae79078540da560ce38400bfe0ade6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santiago differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santo_Domingo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santo_Domingo new file mode 100644 index 0000000000000000000000000000000000000000..4fe36fd4c11f998ba3f626c5e23d97bd82d12791 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Santo_Domingo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Sao_Paulo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Sao_Paulo new file mode 100644 index 0000000000000000000000000000000000000000..67935ff4da8f527e03cd05ed2aa20e601e10f921 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Sao_Paulo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Scoresbysund b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Scoresbysund new file mode 100644 index 0000000000000000000000000000000000000000..9bf411ef5ad5f81f3863223ea75117404d5d1421 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Scoresbysund differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Shiprock b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Shiprock new file mode 100644 index 0000000000000000000000000000000000000000..abb2b974a47eb3e5c8b4f5d4370baf4898b239ab Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Shiprock differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Sitka b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Sitka new file mode 100644 index 0000000000000000000000000000000000000000..31f7061371910ad42e4310b7a646ba1a98b6cba4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Sitka differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/St_Barthelemy b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/St_Barthelemy new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/St_Barthelemy differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/St_Thomas b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/St_Thomas new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/St_Thomas differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/St_Vincent b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/St_Vincent new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/St_Vincent differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Swift_Current b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Swift_Current new file mode 100644 index 0000000000000000000000000000000000000000..8e9ef255eeb11515b84126d9ee5c0c6b3c72f2a0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Swift_Current differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Tegucigalpa b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Tegucigalpa new file mode 100644 index 0000000000000000000000000000000000000000..2adacb2e500e2f9621b2debc1756d308747b67f6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Tegucigalpa differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Thule b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Thule new file mode 100644 index 0000000000000000000000000000000000000000..6f802f1c2acf9cc73481ae86c9e099fcfc28cf25 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Thule differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Tijuana b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Tijuana new file mode 100644 index 0000000000000000000000000000000000000000..63dfdf48a68d02240737ecd6af081e02eb0b6317 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Tijuana differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Toronto b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Toronto new file mode 100644 index 0000000000000000000000000000000000000000..6752c5b05285678b86aea170f0921fc5f5e57738 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Toronto differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Tortola b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Tortola new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Tortola differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Virgin b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Virgin new file mode 100644 index 0000000000000000000000000000000000000000..a662a57137b69e8ba445e899566222cdd422a764 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Virgin differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Whitehorse b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Whitehorse new file mode 100644 index 0000000000000000000000000000000000000000..318c4a8e4003bcff00f9a21e294e7815f170235b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Whitehorse differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Winnipeg b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Winnipeg new file mode 100644 index 0000000000000000000000000000000000000000..ac40299f6b27043e8f2454ac594b0ec184c1a237 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Winnipeg differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Yakutat b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Yakutat new file mode 100644 index 0000000000000000000000000000000000000000..da209f9f0a07625ec83d4ec84917216347f5687f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Yakutat differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Yellowknife b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Yellowknife new file mode 100644 index 0000000000000000000000000000000000000000..cd78a6f8be1dd55ac5afd25bbae39bd5706e42d1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/America/Yellowknife differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Casey b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Casey new file mode 100644 index 0000000000000000000000000000000000000000..586a7653ef20d04440bfcb6645454ef215a1bba4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Casey differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Davis b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Davis new file mode 100644 index 0000000000000000000000000000000000000000..d4d47b24647bcabc981440f0859e94228428798d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Davis differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Palmer b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Palmer new file mode 100644 index 0000000000000000000000000000000000000000..9c8fd317e0537afd4066001f6700cd6490fbe5a8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Palmer differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Rothera b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Rothera new file mode 100644 index 0000000000000000000000000000000000000000..241cc44d507c50777f7225df197765e522f22313 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Rothera differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/South_Pole b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/South_Pole new file mode 100644 index 0000000000000000000000000000000000000000..6575fdce31183d8238b18f2f30ab5b9227c7071c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/South_Pole differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Troll b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Troll new file mode 100644 index 0000000000000000000000000000000000000000..a1dcea14de9cfb95311ebe94e8a1096c27800941 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Antarctica/Troll differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Aden b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Aden new file mode 100644 index 0000000000000000000000000000000000000000..8c8062471dce91a5be827d6908795ee7391a4afc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Aden differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Almaty b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Almaty new file mode 100644 index 0000000000000000000000000000000000000000..91c916a3a5d7949cc304532fe3fb2eac117ab2ef Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Almaty differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Amman b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Amman new file mode 100644 index 0000000000000000000000000000000000000000..0a8e350a334bbee29b155fb9944c6831460d973e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Amman differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Anadyr b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Anadyr new file mode 100644 index 0000000000000000000000000000000000000000..35c531c0709fabace97e52cacef74b4cfbbcd820 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Anadyr differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Aqtau b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Aqtau new file mode 100644 index 0000000000000000000000000000000000000000..0e1c16d32eca7652aa7e1392e606cf5b54e26bc5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Aqtau differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Aqtobe b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Aqtobe new file mode 100644 index 0000000000000000000000000000000000000000..3b5d6eb41883a7b32819f387b4c03c93e9d489cf Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Aqtobe differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ashkhabad b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ashkhabad new file mode 100644 index 0000000000000000000000000000000000000000..2bd1cb3da0f5a11024f1609b09ae68645e6ae75c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ashkhabad differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Atyrau b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Atyrau new file mode 100644 index 0000000000000000000000000000000000000000..e7ea9c545a56ae0b0fabd02e47748004a6d87c3b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Atyrau differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Baghdad b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Baghdad new file mode 100644 index 0000000000000000000000000000000000000000..c0e607234a07cd2650aabc1fd022bd5d4f99b175 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Baghdad differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Bahrain b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Bahrain new file mode 100644 index 0000000000000000000000000000000000000000..098997e7dd972ca4acedc535c4a645ee966baa33 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Bahrain differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Baku b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Baku new file mode 100644 index 0000000000000000000000000000000000000000..ae0ce4e7c3d273b537fa3653784e73be68ebb441 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Baku differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Bangkok b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Bangkok new file mode 100644 index 0000000000000000000000000000000000000000..fa799db39e7625dd74bd9caa5c29b4819a7cbd3f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Bangkok differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Barnaul b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Barnaul new file mode 100644 index 0000000000000000000000000000000000000000..2f6b8101d474642410af84260fb2b88c493945b1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Barnaul differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Beirut b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Beirut new file mode 100644 index 0000000000000000000000000000000000000000..fb266ede2279b6aff913538d9d5aae3935e53aeb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Beirut differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Brunei b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Brunei new file mode 100644 index 0000000000000000000000000000000000000000..098c6a0b0afc2c3ef3a6937104d270074ff2a9b6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Brunei differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Calcutta b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Calcutta new file mode 100644 index 0000000000000000000000000000000000000000..0014046d29a38e9b8006f746fea794d7f71eb479 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Calcutta differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Chita b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Chita new file mode 100644 index 0000000000000000000000000000000000000000..75b3d7b3a6b3bf2b7459532fce1142912b897efd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Chita differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Choibalsan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Choibalsan new file mode 100644 index 0000000000000000000000000000000000000000..c5f4bb0b3858f7078b35cb7a63021d7dc0262605 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Choibalsan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Chongqing b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Chongqing new file mode 100644 index 0000000000000000000000000000000000000000..91f6f8bc2e234bafd484146986bdb289082c3588 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Chongqing differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Colombo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Colombo new file mode 100644 index 0000000000000000000000000000000000000000..353fe2aa3564c79809e05e12711f90669e5e2388 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Colombo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dacca b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dacca new file mode 100644 index 0000000000000000000000000000000000000000..3cf597d83f90403132573d78247e6d02e66d0583 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dacca differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Damascus b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Damascus new file mode 100644 index 0000000000000000000000000000000000000000..afd956c878856e0e239887963b32ddb8327ccf38 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Damascus differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dhaka b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dhaka new file mode 100644 index 0000000000000000000000000000000000000000..3cf597d83f90403132573d78247e6d02e66d0583 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dhaka differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dili b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dili new file mode 100644 index 0000000000000000000000000000000000000000..c1af113af0a87e5c96033c83f199161062073bf0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dili differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dubai b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dubai new file mode 100644 index 0000000000000000000000000000000000000000..b3ac791aef4e73d6d644c40c614f37f15d462cdd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dubai differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dushanbe b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dushanbe new file mode 100644 index 0000000000000000000000000000000000000000..89e875beaef780b2ceae08ee4703cd813f33d6a4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Dushanbe differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Famagusta b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Famagusta new file mode 100644 index 0000000000000000000000000000000000000000..653b146a60e5e5641a07bfc82f9590dad1ed69f5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Famagusta differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Gaza b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Gaza new file mode 100644 index 0000000000000000000000000000000000000000..1e8cdb617524e026f1e936195dabf54bae3a3ef8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Gaza differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Harbin b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Harbin new file mode 100644 index 0000000000000000000000000000000000000000..91f6f8bc2e234bafd484146986bdb289082c3588 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Harbin differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Hebron b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Hebron new file mode 100644 index 0000000000000000000000000000000000000000..6023fa1c30a0902bc3b99bfc860e068a92f1b337 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Hebron differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ho_Chi_Minh b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ho_Chi_Minh new file mode 100644 index 0000000000000000000000000000000000000000..a213d290e1a920271e924506a57191f1f4bfc4c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ho_Chi_Minh differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Hong_Kong b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Hong_Kong new file mode 100644 index 0000000000000000000000000000000000000000..f9f7b134dd5c35e4718c6fa3697024cb95442c53 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Hong_Kong differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Hovd b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Hovd new file mode 100644 index 0000000000000000000000000000000000000000..8b9abca344daf199b554888fc4fff562a7a18e4a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Hovd differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Irkutsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Irkutsk new file mode 100644 index 0000000000000000000000000000000000000000..e74a4d3f6b3a799b0fd12272c3aae0f084fb2783 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Irkutsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Istanbul b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Istanbul new file mode 100644 index 0000000000000000000000000000000000000000..7c2336dd80c3c9cbf71cb53d2b2c1f89a65a8ba5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Istanbul differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Jayapura b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Jayapura new file mode 100644 index 0000000000000000000000000000000000000000..3002c82022f7e9a4ff1ad545ea617106a13b24e0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Jayapura differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Jerusalem b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Jerusalem new file mode 100644 index 0000000000000000000000000000000000000000..1ebd0664aa29c0abd722661f761031ec0304631c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Jerusalem differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kabul b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kabul new file mode 100644 index 0000000000000000000000000000000000000000..661efc83294edbe5f615daa87a1f4a5590aae167 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kabul differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kamchatka b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kamchatka new file mode 100644 index 0000000000000000000000000000000000000000..99776f515fd53a86a6886311d91ff33b401396c3 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kamchatka differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Karachi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Karachi new file mode 100644 index 0000000000000000000000000000000000000000..ba65c0e8d31cb1d59935878af29baac722f45936 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Karachi differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kashgar b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kashgar new file mode 100644 index 0000000000000000000000000000000000000000..62bdcac14db3f464ff561e32db2c6b55c0cb1866 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kashgar differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kathmandu b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kathmandu new file mode 100644 index 0000000000000000000000000000000000000000..751cf4a8939e898f8abe4358a98b2a5f59f65e21 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kathmandu differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Katmandu b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Katmandu new file mode 100644 index 0000000000000000000000000000000000000000..751cf4a8939e898f8abe4358a98b2a5f59f65e21 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Katmandu differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Khandyga b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Khandyga new file mode 100644 index 0000000000000000000000000000000000000000..7cdc99a9803f4e1ce3c5f7f9e6cd761f178536ae Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Khandyga differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kolkata b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kolkata new file mode 100644 index 0000000000000000000000000000000000000000..0014046d29a38e9b8006f746fea794d7f71eb479 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kolkata differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Krasnoyarsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Krasnoyarsk new file mode 100644 index 0000000000000000000000000000000000000000..4c27b2decd1159cf47285f0b18b5ed5178641e82 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Krasnoyarsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kuala_Lumpur b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kuala_Lumpur new file mode 100644 index 0000000000000000000000000000000000000000..3d9f191e3acad56fb4f73ab44a74c50cdf91c12e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kuala_Lumpur differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kuching b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kuching new file mode 100644 index 0000000000000000000000000000000000000000..098c6a0b0afc2c3ef3a6937104d270074ff2a9b6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kuching differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kuwait b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kuwait new file mode 100644 index 0000000000000000000000000000000000000000..8c8062471dce91a5be827d6908795ee7391a4afc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Kuwait differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Macao b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Macao new file mode 100644 index 0000000000000000000000000000000000000000..cac65063d0dbf48e37c547fba3b67f34110d5a90 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Macao differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Macau b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Macau new file mode 100644 index 0000000000000000000000000000000000000000..cac65063d0dbf48e37c547fba3b67f34110d5a90 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Macau differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Magadan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Magadan new file mode 100644 index 0000000000000000000000000000000000000000..70c198baf743457c58a8fe4d1f28186d8541a505 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Magadan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Makassar b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Makassar new file mode 100644 index 0000000000000000000000000000000000000000..556ba866933d37f3cfcf8042045d64e209bae30f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Makassar differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Manila b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Manila new file mode 100644 index 0000000000000000000000000000000000000000..f4f4b04efa2b6a442d4072b3899f4dae69bdd771 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Manila differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Muscat b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Muscat new file mode 100644 index 0000000000000000000000000000000000000000..b3ac791aef4e73d6d644c40c614f37f15d462cdd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Muscat differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Nicosia b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Nicosia new file mode 100644 index 0000000000000000000000000000000000000000..f7f10ab7665e94ca44fd8cd98a362cd4b304eff1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Nicosia differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Novokuznetsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Novokuznetsk new file mode 100644 index 0000000000000000000000000000000000000000..a5e1b79600d21019a3b93f3e2d796129d9b1d655 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Novokuznetsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Novosibirsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Novosibirsk new file mode 100644 index 0000000000000000000000000000000000000000..4ac7582ad5ee895bf9b354436142fd7ece1996ee Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Novosibirsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Oral b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Oral new file mode 100644 index 0000000000000000000000000000000000000000..3b9ecacf6eef72366df1cc847c0d4666efc8a48c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Oral differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Phnom_Penh b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Phnom_Penh new file mode 100644 index 0000000000000000000000000000000000000000..fa799db39e7625dd74bd9caa5c29b4819a7cbd3f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Phnom_Penh differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Pontianak b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Pontianak new file mode 100644 index 0000000000000000000000000000000000000000..12ce24cbeae404efe6921081d21289be452ff88d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Pontianak differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Pyongyang b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Pyongyang new file mode 100644 index 0000000000000000000000000000000000000000..7ad7e0b2cf8fa4fc844fe8cc9c58e4f3018cead1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Pyongyang differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Qatar b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Qatar new file mode 100644 index 0000000000000000000000000000000000000000..098997e7dd972ca4acedc535c4a645ee966baa33 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Qatar differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Qostanay b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Qostanay new file mode 100644 index 0000000000000000000000000000000000000000..f8baf676496adea298f078d6d5931ba7aa64e902 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Qostanay differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Rangoon b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Rangoon new file mode 100644 index 0000000000000000000000000000000000000000..eef37b42e8a0e7179f8113bea01f4a71d668e8ef Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Rangoon differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Riyadh b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Riyadh new file mode 100644 index 0000000000000000000000000000000000000000..8c8062471dce91a5be827d6908795ee7391a4afc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Riyadh differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Saigon b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Saigon new file mode 100644 index 0000000000000000000000000000000000000000..a213d290e1a920271e924506a57191f1f4bfc4c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Saigon differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Sakhalin b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Sakhalin new file mode 100644 index 0000000000000000000000000000000000000000..beb77b449654decdfec1f6bfc16fafc8bc8ceeaa Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Sakhalin differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Samarkand b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Samarkand new file mode 100644 index 0000000000000000000000000000000000000000..8a93767bfef2cecbeee15db413a0a7c277e761a1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Samarkand differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Seoul b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Seoul new file mode 100644 index 0000000000000000000000000000000000000000..96199e73e73aafacd89e48cb2855a96d7a134e1d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Seoul differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Singapore b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Singapore new file mode 100644 index 0000000000000000000000000000000000000000..3d9f191e3acad56fb4f73ab44a74c50cdf91c12e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Singapore differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Srednekolymsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Srednekolymsk new file mode 100644 index 0000000000000000000000000000000000000000..d21e7eeed5408affb3277bde903d6f5f2090ea61 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Srednekolymsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Taipei b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Taipei new file mode 100644 index 0000000000000000000000000000000000000000..24c43444b6751343d2915843d03e55753d4d7359 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Taipei differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tashkent b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tashkent new file mode 100644 index 0000000000000000000000000000000000000000..a9f6cd93c849c8b1677bc54f8bb836c91b40d63d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tashkent differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tbilisi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tbilisi new file mode 100644 index 0000000000000000000000000000000000000000..3b131bb10e100bc2dd619d57367a4e43c86e5316 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tbilisi differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tehran b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tehran new file mode 100644 index 0000000000000000000000000000000000000000..cc2a2c219b0c893cfa8187e962028eb19ea3425d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tehran differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tel_Aviv b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tel_Aviv new file mode 100644 index 0000000000000000000000000000000000000000..1ebd0664aa29c0abd722661f761031ec0304631c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tel_Aviv differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Thimbu b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Thimbu new file mode 100644 index 0000000000000000000000000000000000000000..95a9de9657f5b8b15aacb6e05c085c7e11bb8f55 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Thimbu differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Thimphu b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Thimphu new file mode 100644 index 0000000000000000000000000000000000000000..95a9de9657f5b8b15aacb6e05c085c7e11bb8f55 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Thimphu differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tokyo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tokyo new file mode 100644 index 0000000000000000000000000000000000000000..26f4d34d67b46513491f26c2e661c6e653cc130d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tokyo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tomsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tomsk new file mode 100644 index 0000000000000000000000000000000000000000..a6e494a78cef4baaa30d06cea4186391788eb30b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Tomsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ujung_Pandang b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ujung_Pandang new file mode 100644 index 0000000000000000000000000000000000000000..556ba866933d37f3cfcf8042045d64e209bae30f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ujung_Pandang differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ulaanbaatar b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ulaanbaatar new file mode 100644 index 0000000000000000000000000000000000000000..2aa5cc4b84d369b03684c30cdb66b7abf087f467 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ulaanbaatar differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ulan_Bator b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ulan_Bator new file mode 100644 index 0000000000000000000000000000000000000000..2aa5cc4b84d369b03684c30cdb66b7abf087f467 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ulan_Bator differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Urumqi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Urumqi new file mode 100644 index 0000000000000000000000000000000000000000..62bdcac14db3f464ff561e32db2c6b55c0cb1866 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Urumqi differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ust-Nera b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ust-Nera new file mode 100644 index 0000000000000000000000000000000000000000..d05726aba9fd67bf230290b3e2d74b75e46ee214 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Ust-Nera differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Vientiane b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Vientiane new file mode 100644 index 0000000000000000000000000000000000000000..fa799db39e7625dd74bd9caa5c29b4819a7cbd3f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Vientiane differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Vladivostok b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Vladivostok new file mode 100644 index 0000000000000000000000000000000000000000..274a10b43d8089ed522daf9ded5b6aa3653075c9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Vladivostok differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Yakutsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Yakutsk new file mode 100644 index 0000000000000000000000000000000000000000..ae65a5f9b94d196b29b68ddec7862e098d829b59 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Yakutsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Yangon b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Yangon new file mode 100644 index 0000000000000000000000000000000000000000..eef37b42e8a0e7179f8113bea01f4a71d668e8ef Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Yangon differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Yekaterinburg b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Yekaterinburg new file mode 100644 index 0000000000000000000000000000000000000000..d4d19ccf1e91121589a7cabff444bc916f67f9ce Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Asia/Yekaterinburg differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Azores b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Azores new file mode 100644 index 0000000000000000000000000000000000000000..10232ab38ec595b889167a3f0f037a940ef2ac98 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Azores differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Bermuda b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Bermuda new file mode 100644 index 0000000000000000000000000000000000000000..527524ed295aba41b9a0448ffd7993c489a2cb99 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Bermuda differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Canary b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Canary new file mode 100644 index 0000000000000000000000000000000000000000..f3192156ff043a529461aa9004a8de9dda326f7d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Canary differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Cape_Verde b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Cape_Verde new file mode 100644 index 0000000000000000000000000000000000000000..0d0d31a2f092d03f8512ed9c34f36a3f3f21209b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Cape_Verde differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Faeroe b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Faeroe new file mode 100644 index 0000000000000000000000000000000000000000..4dab7ef0859c244b916d61b7489d7371881e0ca2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Faeroe differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Faroe b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Faroe new file mode 100644 index 0000000000000000000000000000000000000000..4dab7ef0859c244b916d61b7489d7371881e0ca2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Faroe differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Jan_Mayen b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Jan_Mayen new file mode 100644 index 0000000000000000000000000000000000000000..7f6d958f8630cba512d8e58ca8edfbd516291522 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Jan_Mayen differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Madeira b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Madeira new file mode 100644 index 0000000000000000000000000000000000000000..7ddcd883fedcb493b7ab527483c7d4a6d4fc5055 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Madeira differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Reykjavik b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Reykjavik new file mode 100644 index 0000000000000000000000000000000000000000..28b32ab2e0b9053f39a91d9f28b6072e41423954 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Reykjavik differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/South_Georgia b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/South_Georgia new file mode 100644 index 0000000000000000000000000000000000000000..a2b59a9d1088690cb2f9ad9011bfa59e6cb5c658 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/South_Georgia differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/St_Helena b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/St_Helena new file mode 100644 index 0000000000000000000000000000000000000000..28b32ab2e0b9053f39a91d9f28b6072e41423954 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/St_Helena differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Stanley b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Stanley new file mode 100644 index 0000000000000000000000000000000000000000..1527d0e1a762674748735a95b6c3034d162f4240 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Atlantic/Stanley differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/ACT b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/ACT new file mode 100644 index 0000000000000000000000000000000000000000..0aea4c3d43e504dafabc031d7ca9cbe8db46163c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/ACT differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Adelaide b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Adelaide new file mode 100644 index 0000000000000000000000000000000000000000..f5dedca59e2b220f7395c73f60ff26e610373e8b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Adelaide differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Brisbane b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Brisbane new file mode 100644 index 0000000000000000000000000000000000000000..7ff9949ffa93e44835ab133998b89e440094f909 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Brisbane differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Broken_Hill b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Broken_Hill new file mode 100644 index 0000000000000000000000000000000000000000..698c76e30e91f568a29daca12993cfacbfdbf83e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Broken_Hill differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Canberra b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Canberra new file mode 100644 index 0000000000000000000000000000000000000000..0aea4c3d43e504dafabc031d7ca9cbe8db46163c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Canberra differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Currie b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Currie new file mode 100644 index 0000000000000000000000000000000000000000..3adb8e1bf7c6ec51f1c100538799271d7d7a6e6f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Currie differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Darwin b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Darwin new file mode 100644 index 0000000000000000000000000000000000000000..74a30879bc6180d588a706451226cb4c95faf79d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Darwin differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Eucla b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Eucla new file mode 100644 index 0000000000000000000000000000000000000000..1551e96cbc3de5565356954b61aac3c4388e90db Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Eucla differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Hobart b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Hobart new file mode 100644 index 0000000000000000000000000000000000000000..3adb8e1bf7c6ec51f1c100538799271d7d7a6e6f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Hobart differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/LHI b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/LHI new file mode 100644 index 0000000000000000000000000000000000000000..069a95ad686c1139e2ff2b9ce94dc5ef5bc98c67 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/LHI differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Lindeman b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Lindeman new file mode 100644 index 0000000000000000000000000000000000000000..4ee1825abfe65887069dcbd10bcf786d50ba0702 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Lindeman differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Lord_Howe b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Lord_Howe new file mode 100644 index 0000000000000000000000000000000000000000..069a95ad686c1139e2ff2b9ce94dc5ef5bc98c67 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Lord_Howe differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Melbourne b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Melbourne new file mode 100644 index 0000000000000000000000000000000000000000..ee903f4b1fc292bc9cbec7b501a266030ef3510e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Melbourne differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/NSW b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/NSW new file mode 100644 index 0000000000000000000000000000000000000000..0aea4c3d43e504dafabc031d7ca9cbe8db46163c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/NSW differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/North b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/North new file mode 100644 index 0000000000000000000000000000000000000000..74a30879bc6180d588a706451226cb4c95faf79d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/North differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Perth b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Perth new file mode 100644 index 0000000000000000000000000000000000000000..f8ddbdf215d34b022af11c3d1930dd6ea4dca87e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Perth differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Queensland b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Queensland new file mode 100644 index 0000000000000000000000000000000000000000..7ff9949ffa93e44835ab133998b89e440094f909 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Queensland differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/South b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/South new file mode 100644 index 0000000000000000000000000000000000000000..f5dedca59e2b220f7395c73f60ff26e610373e8b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/South differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Sydney b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Sydney new file mode 100644 index 0000000000000000000000000000000000000000..0aea4c3d43e504dafabc031d7ca9cbe8db46163c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Sydney differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Tasmania b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Tasmania new file mode 100644 index 0000000000000000000000000000000000000000..3adb8e1bf7c6ec51f1c100538799271d7d7a6e6f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Tasmania differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Victoria b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Victoria new file mode 100644 index 0000000000000000000000000000000000000000..ee903f4b1fc292bc9cbec7b501a266030ef3510e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Victoria differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/West b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/West new file mode 100644 index 0000000000000000000000000000000000000000..f8ddbdf215d34b022af11c3d1930dd6ea4dca87e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/West differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Yancowinna b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Yancowinna new file mode 100644 index 0000000000000000000000000000000000000000..698c76e30e91f568a29daca12993cfacbfdbf83e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Australia/Yancowinna differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/CET b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/CET new file mode 100644 index 0000000000000000000000000000000000000000..122e934210cabf0b29a2dd7d11eb8220ed1cad43 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/CET differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/CST6CDT b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/CST6CDT new file mode 100644 index 0000000000000000000000000000000000000000..ca67929fbeb05083c63e8319dd9ebf65b3d75e4d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/CST6CDT differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Atlantic b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Atlantic new file mode 100644 index 0000000000000000000000000000000000000000..756099abe6cee44295a5566ad6cd0c352fb82e64 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Atlantic differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Central b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Central new file mode 100644 index 0000000000000000000000000000000000000000..ac40299f6b27043e8f2454ac594b0ec184c1a237 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Central differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Eastern b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Eastern new file mode 100644 index 0000000000000000000000000000000000000000..6752c5b05285678b86aea170f0921fc5f5e57738 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Eastern differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Mountain b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Mountain new file mode 100644 index 0000000000000000000000000000000000000000..cd78a6f8be1dd55ac5afd25bbae39bd5706e42d1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Mountain differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Newfoundland b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Newfoundland new file mode 100644 index 0000000000000000000000000000000000000000..65a5b0c720dad151ffdcba3dbe91c8bd638845c6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Newfoundland differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Pacific b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Pacific new file mode 100644 index 0000000000000000000000000000000000000000..bb60cbced30763c08b6cf73554c8d6651ff387d0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Pacific differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Saskatchewan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Saskatchewan new file mode 100644 index 0000000000000000000000000000000000000000..20c9c84df491e4072ec4c5d2c931a7433d9fd394 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Saskatchewan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Yukon b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Yukon new file mode 100644 index 0000000000000000000000000000000000000000..318c4a8e4003bcff00f9a21e294e7815f170235b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Canada/Yukon differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Chile/Continental b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Chile/Continental new file mode 100644 index 0000000000000000000000000000000000000000..010c6bd04cae79078540da560ce38400bfe0ade6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Chile/Continental differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Chile/EasterIsland b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Chile/EasterIsland new file mode 100644 index 0000000000000000000000000000000000000000..184cb6a83b3392d0492c42297531c85e7e38c4f5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Chile/EasterIsland differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Cuba b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Cuba new file mode 100644 index 0000000000000000000000000000000000000000..b69ac4510784f23ee794cd6d11e62315a7318e5e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Cuba differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/EET b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/EET new file mode 100644 index 0000000000000000000000000000000000000000..cbdb71ddd38be8f4a23e57bdb4b86e52195e9f89 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/EET differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/EST b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/EST new file mode 100644 index 0000000000000000000000000000000000000000..21ebc00b3fc096035b9810519d778d04a3562a44 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/EST differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/EST5EDT b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/EST5EDT new file mode 100644 index 0000000000000000000000000000000000000000..9bce5007d4dbb871974a69cb0f68151c1ee22556 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/EST5EDT differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Egypt b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Egypt new file mode 100644 index 0000000000000000000000000000000000000000..dd538c65db6ed0a0e47feb7b6001640516958e19 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Egypt differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Eire b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Eire new file mode 100644 index 0000000000000000000000000000000000000000..c729def42fc0822e6b24f7bf503c67cc7e6965f0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Eire differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT new file mode 100644 index 0000000000000000000000000000000000000000..c63474664a289aa3c3c0d8b2ce06d484679754c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+0 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+0 new file mode 100644 index 0000000000000000000000000000000000000000..c63474664a289aa3c3c0d8b2ce06d484679754c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+0 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+1 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+1 new file mode 100644 index 0000000000000000000000000000000000000000..4dab6f9005bea50a065c685ec8260b0da2bff921 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+1 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+10 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+10 new file mode 100644 index 0000000000000000000000000000000000000000..c749290af2f6b5fe22770c34eb1e8fc87cd85aff Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+10 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+11 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+11 new file mode 100644 index 0000000000000000000000000000000000000000..d969982309e5ca7d32979a7dad814ca307d2cd8d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+11 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+12 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+12 new file mode 100644 index 0000000000000000000000000000000000000000..cdeec90973be28ee4075eadd22b8b574db2d7a5f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+12 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+2 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+2 new file mode 100644 index 0000000000000000000000000000000000000000..fbd2a941fda996f4abc1f0e09cdf99c271f5a1e2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+2 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+3 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+3 new file mode 100644 index 0000000000000000000000000000000000000000..ee246ef56f18de61105af0c14d201fd090f74905 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+3 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+4 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+4 new file mode 100644 index 0000000000000000000000000000000000000000..5a25ff2a6afda2cb09b9e147ad20610bc1923444 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+4 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+5 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+5 new file mode 100644 index 0000000000000000000000000000000000000000..c0b745f1cc44d03a00f8bdf127c154392e3baf27 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+5 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+6 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+6 new file mode 100644 index 0000000000000000000000000000000000000000..06e777d57e0267a0635b6b284729fddcfe6221dd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+6 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+7 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+7 new file mode 100644 index 0000000000000000000000000000000000000000..4e0b53a082f11f9b9debf5e110b97b1b0473c9a6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+7 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+8 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+8 new file mode 100644 index 0000000000000000000000000000000000000000..714b0c562889a8a774d9aa27810d8400164d00e6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+8 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+9 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+9 new file mode 100644 index 0000000000000000000000000000000000000000..78b9daa373d2aa2856eafcc92ebc6d899cafde5c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT+9 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-0 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-0 new file mode 100644 index 0000000000000000000000000000000000000000..c63474664a289aa3c3c0d8b2ce06d484679754c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-0 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-1 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-1 new file mode 100644 index 0000000000000000000000000000000000000000..a838bebf5e7bac3e1257eeb0a61c1b83feb1324c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-1 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-10 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-10 new file mode 100644 index 0000000000000000000000000000000000000000..68ff77db0d95c7d054ef33c05e05ba71bcbbbdd8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-10 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-11 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-11 new file mode 100644 index 0000000000000000000000000000000000000000..66af5a42be440f1fb8fec3b915afb49b356f63a5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-11 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-12 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-12 new file mode 100644 index 0000000000000000000000000000000000000000..17ba5057727dd73bd5f6234cc5b239b71a861945 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-12 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-13 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-13 new file mode 100644 index 0000000000000000000000000000000000000000..5f3706ce64cadf081a6c56abd7ba423575a4abb2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-13 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-14 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-14 new file mode 100644 index 0000000000000000000000000000000000000000..7e9f9c465ce6211c65d617f60472c9b55b5052c5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-14 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-2 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-2 new file mode 100644 index 0000000000000000000000000000000000000000..fcef6d9acb247deb539fcc4b30149802572ea642 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-2 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-3 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-3 new file mode 100644 index 0000000000000000000000000000000000000000..27973bc857b4e618218ca2790acacb81f7c7bb82 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-3 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-4 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-4 new file mode 100644 index 0000000000000000000000000000000000000000..1efd841261a977ae218d408f9cc308c3e312a5e8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-4 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-5 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-5 new file mode 100644 index 0000000000000000000000000000000000000000..1f761844fc44f8228bb748235bfd30be6c389cd1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-5 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-6 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-6 new file mode 100644 index 0000000000000000000000000000000000000000..952681ed46cb60e59baf76a2c43b49d5f67255d1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-6 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-7 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-7 new file mode 100644 index 0000000000000000000000000000000000000000..cefc9126c691060225ff2eee1241b1e5e9825fcd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-7 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-8 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-8 new file mode 100644 index 0000000000000000000000000000000000000000..afb093da00685297cb11347c4840acf3a8e2e2bf Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-8 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-9 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-9 new file mode 100644 index 0000000000000000000000000000000000000000..9265fb7c2071ec0e66c657ad2ae42d5dd525fe97 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT-9 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT0 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT0 new file mode 100644 index 0000000000000000000000000000000000000000..c63474664a289aa3c3c0d8b2ce06d484679754c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/GMT0 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/Greenwich b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/Greenwich new file mode 100644 index 0000000000000000000000000000000000000000..c63474664a289aa3c3c0d8b2ce06d484679754c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/Greenwich differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/UCT b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/UCT new file mode 100644 index 0000000000000000000000000000000000000000..91558be0c2bf903b2364215ba26d5227d6126508 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/UCT differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/UTC b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/UTC new file mode 100644 index 0000000000000000000000000000000000000000..91558be0c2bf903b2364215ba26d5227d6126508 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/UTC differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/Universal b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/Universal new file mode 100644 index 0000000000000000000000000000000000000000..91558be0c2bf903b2364215ba26d5227d6126508 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/Universal differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/Zulu b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/Zulu new file mode 100644 index 0000000000000000000000000000000000000000..91558be0c2bf903b2364215ba26d5227d6126508 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Etc/Zulu differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Amsterdam b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Amsterdam new file mode 100644 index 0000000000000000000000000000000000000000..40d7124e5346af056c75e2f7012a51d94e8154b7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Amsterdam differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Astrakhan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Astrakhan new file mode 100644 index 0000000000000000000000000000000000000000..a41624f5df9698d78049008a2bd8a77395c0480a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Astrakhan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Belfast b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Belfast new file mode 100644 index 0000000000000000000000000000000000000000..5ad74220e83e6c30a0aeefda4a00271b8ebdfcad Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Belfast differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Bratislava b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Bratislava new file mode 100644 index 0000000000000000000000000000000000000000..ce8f433ece44f0b96b18d3b5780730e7f9cad9f5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Bratislava differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Brussels b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Brussels new file mode 100644 index 0000000000000000000000000000000000000000..40d7124e5346af056c75e2f7012a51d94e8154b7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Brussels differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Bucharest b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Bucharest new file mode 100644 index 0000000000000000000000000000000000000000..4303b903e5e007484c0d8e1eea43a35e9b53f38b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Bucharest differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Budapest b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Budapest new file mode 100644 index 0000000000000000000000000000000000000000..b76c873d9256e1d73c2ea672140b813f15657bc7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Budapest differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Busingen b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Busingen new file mode 100644 index 0000000000000000000000000000000000000000..ad6cf59281a1046d9dcd045fda521585e3e33e06 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Busingen differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Chisinau b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Chisinau new file mode 100644 index 0000000000000000000000000000000000000000..5ee23fe0e59f044598675db44d53c20590b88934 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Chisinau differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Copenhagen b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Copenhagen new file mode 100644 index 0000000000000000000000000000000000000000..7f6d958f8630cba512d8e58ca8edfbd516291522 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Copenhagen differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Dublin b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Dublin new file mode 100644 index 0000000000000000000000000000000000000000..c729def42fc0822e6b24f7bf503c67cc7e6965f0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Dublin differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Gibraltar b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Gibraltar new file mode 100644 index 0000000000000000000000000000000000000000..a38f11ffdf2a9e538695ea8cae20b1d2c04164af Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Gibraltar differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Helsinki b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Helsinki new file mode 100644 index 0000000000000000000000000000000000000000..b4f8f9cbb57450549933f83ac90dd56a2ca75344 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Helsinki differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Isle_of_Man b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Isle_of_Man new file mode 100644 index 0000000000000000000000000000000000000000..5ad74220e83e6c30a0aeefda4a00271b8ebdfcad Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Isle_of_Man differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Istanbul b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Istanbul new file mode 100644 index 0000000000000000000000000000000000000000..7c2336dd80c3c9cbf71cb53d2b2c1f89a65a8ba5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Istanbul differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Kaliningrad b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Kaliningrad new file mode 100644 index 0000000000000000000000000000000000000000..cc99beabe4ffc5107c4719d1201d6583b9ead03a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Kaliningrad differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Kiev b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Kiev new file mode 100644 index 0000000000000000000000000000000000000000..52efea88065b220e44fd876de3bf3090fe62cc79 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Kiev differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Kyiv b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Kyiv new file mode 100644 index 0000000000000000000000000000000000000000..52efea88065b220e44fd876de3bf3090fe62cc79 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Kyiv differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Lisbon b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Lisbon new file mode 100644 index 0000000000000000000000000000000000000000..55f01930ba92ff6852ae4745e78adb5f96c5b057 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Lisbon differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Ljubljana b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Ljubljana new file mode 100644 index 0000000000000000000000000000000000000000..27de456f16ab549627b284a39e2265cbdb4ad8e9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Ljubljana differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/London b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/London new file mode 100644 index 0000000000000000000000000000000000000000..5ad74220e83e6c30a0aeefda4a00271b8ebdfcad Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/London differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Luxembourg b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Luxembourg new file mode 100644 index 0000000000000000000000000000000000000000..40d7124e5346af056c75e2f7012a51d94e8154b7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Luxembourg differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Madrid b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Madrid new file mode 100644 index 0000000000000000000000000000000000000000..53f4cd101c18058a1ee4d4b9d1184ada11d74232 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Madrid differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Malta b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Malta new file mode 100644 index 0000000000000000000000000000000000000000..1d1a7bcfcbbf37ff1ad7025f9843d0d2d8cb06d4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Malta differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Mariehamn b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Mariehamn new file mode 100644 index 0000000000000000000000000000000000000000..b4f8f9cbb57450549933f83ac90dd56a2ca75344 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Mariehamn differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Minsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Minsk new file mode 100644 index 0000000000000000000000000000000000000000..3731e40d8634c4d58ddb3378d828c92948f06d67 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Minsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Moscow b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Moscow new file mode 100644 index 0000000000000000000000000000000000000000..ddb3f4e99a1030f33b56fad986c8d9c16e59eb32 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Moscow differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Nicosia b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Nicosia new file mode 100644 index 0000000000000000000000000000000000000000..f7f10ab7665e94ca44fd8cd98a362cd4b304eff1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Nicosia differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Oslo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Oslo new file mode 100644 index 0000000000000000000000000000000000000000..7f6d958f8630cba512d8e58ca8edfbd516291522 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Oslo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Paris b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Paris new file mode 100644 index 0000000000000000000000000000000000000000..7d366c6098c49ecd546e1cc1538919e1414a3aee Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Paris differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Prague b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Prague new file mode 100644 index 0000000000000000000000000000000000000000..ce8f433ece44f0b96b18d3b5780730e7f9cad9f5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Prague differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Riga b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Riga new file mode 100644 index 0000000000000000000000000000000000000000..8db477d01736445cafce8af7a7085d226d81f546 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Riga differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/San_Marino b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/San_Marino new file mode 100644 index 0000000000000000000000000000000000000000..32b2899a306dde401fa2e3952d06f5f4d9952bed Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/San_Marino differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Sarajevo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Sarajevo new file mode 100644 index 0000000000000000000000000000000000000000..27de456f16ab549627b284a39e2265cbdb4ad8e9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Sarajevo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Saratov b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Saratov new file mode 100644 index 0000000000000000000000000000000000000000..a863913358adb7a9118fcc48a6a5dcfba5f9914b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Saratov differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Simferopol b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Simferopol new file mode 100644 index 0000000000000000000000000000000000000000..4bf24de1d9f8ebc410f120aa83d98b7e41d1e6c4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Simferopol differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Skopje b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Skopje new file mode 100644 index 0000000000000000000000000000000000000000..27de456f16ab549627b284a39e2265cbdb4ad8e9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Skopje differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Sofia b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Sofia new file mode 100644 index 0000000000000000000000000000000000000000..0e4d879332d21c93c229fc25587205020eeb3127 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Sofia differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Stockholm b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Stockholm new file mode 100644 index 0000000000000000000000000000000000000000..7f6d958f8630cba512d8e58ca8edfbd516291522 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Stockholm differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Tallinn b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Tallinn new file mode 100644 index 0000000000000000000000000000000000000000..b5acca3cf51e7f7b3176965748688ff41720246f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Tallinn differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Tirane b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Tirane new file mode 100644 index 0000000000000000000000000000000000000000..0b86017d243f1b7bbb41d6b4feefcb2b7edfc7d8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Tirane differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Tiraspol b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Tiraspol new file mode 100644 index 0000000000000000000000000000000000000000..5ee23fe0e59f044598675db44d53c20590b88934 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Tiraspol differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Ulyanovsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Ulyanovsk new file mode 100644 index 0000000000000000000000000000000000000000..d668233b37f268a745e995177195b06ffab1e69b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Ulyanovsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Uzhgorod b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Uzhgorod new file mode 100644 index 0000000000000000000000000000000000000000..52efea88065b220e44fd876de3bf3090fe62cc79 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Uzhgorod differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Vaduz b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Vaduz new file mode 100644 index 0000000000000000000000000000000000000000..ad6cf59281a1046d9dcd045fda521585e3e33e06 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Vaduz differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Vienna b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Vienna new file mode 100644 index 0000000000000000000000000000000000000000..3582bb15cd7322088839b0134987ad10e717b6b5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Vienna differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Vilnius b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Vilnius new file mode 100644 index 0000000000000000000000000000000000000000..7abd63fa608e0186b9f154d9fcc32472c28f6759 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Vilnius differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Volgograd b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Volgograd new file mode 100644 index 0000000000000000000000000000000000000000..9d51a38c0ea719c5042837d47e0f427057b845f0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Volgograd differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Zaporozhye b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Zaporozhye new file mode 100644 index 0000000000000000000000000000000000000000..52efea88065b220e44fd876de3bf3090fe62cc79 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Europe/Zaporozhye differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Factory b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Factory new file mode 100644 index 0000000000000000000000000000000000000000..60aa2a0d695ba577ff87624d479f1eb25c8f1caf Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Factory differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GB b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GB new file mode 100644 index 0000000000000000000000000000000000000000..5ad74220e83e6c30a0aeefda4a00271b8ebdfcad Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GB differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GB-Eire b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GB-Eire new file mode 100644 index 0000000000000000000000000000000000000000..5ad74220e83e6c30a0aeefda4a00271b8ebdfcad Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GB-Eire differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT new file mode 100644 index 0000000000000000000000000000000000000000..c63474664a289aa3c3c0d8b2ce06d484679754c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT+0 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT+0 new file mode 100644 index 0000000000000000000000000000000000000000..c63474664a289aa3c3c0d8b2ce06d484679754c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT+0 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT-0 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT-0 new file mode 100644 index 0000000000000000000000000000000000000000..c63474664a289aa3c3c0d8b2ce06d484679754c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT-0 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT0 b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT0 new file mode 100644 index 0000000000000000000000000000000000000000..c63474664a289aa3c3c0d8b2ce06d484679754c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/GMT0 differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Greenwich b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Greenwich new file mode 100644 index 0000000000000000000000000000000000000000..c63474664a289aa3c3c0d8b2ce06d484679754c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Greenwich differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/HST b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/HST new file mode 100644 index 0000000000000000000000000000000000000000..cccd45eb8cb2f56b6a1b75e2d7b9530cb5abf2e1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/HST differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Hongkong b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Hongkong new file mode 100644 index 0000000000000000000000000000000000000000..f9f7b134dd5c35e4718c6fa3697024cb95442c53 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Hongkong differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Iceland b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Iceland new file mode 100644 index 0000000000000000000000000000000000000000..28b32ab2e0b9053f39a91d9f28b6072e41423954 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Iceland differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Iran b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Iran new file mode 100644 index 0000000000000000000000000000000000000000..cc2a2c219b0c893cfa8187e962028eb19ea3425d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Iran differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Israel b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Israel new file mode 100644 index 0000000000000000000000000000000000000000..1ebd0664aa29c0abd722661f761031ec0304631c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Israel differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Jamaica b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Jamaica new file mode 100644 index 0000000000000000000000000000000000000000..2a9b7fd52d37a1ffe9fc589daa04d88c6c71a6e0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Jamaica differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Japan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Japan new file mode 100644 index 0000000000000000000000000000000000000000..26f4d34d67b46513491f26c2e661c6e653cc130d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Japan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Kwajalein b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Kwajalein new file mode 100644 index 0000000000000000000000000000000000000000..1887a607422edd499fdf24afe91a04294f1caf6f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Kwajalein differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Libya b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Libya new file mode 100644 index 0000000000000000000000000000000000000000..07b393bb7db14cef1e906ebe63cfbbe8cddc79d5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Libya differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/MET b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/MET new file mode 100644 index 0000000000000000000000000000000000000000..4a826bb185531c34eb37959037c68fbf08c23f71 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/MET differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/MST b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/MST new file mode 100644 index 0000000000000000000000000000000000000000..c93a58eee8b32f672fd3a96ca3e6ada5b0a0e168 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/MST differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/MST7MDT b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/MST7MDT new file mode 100644 index 0000000000000000000000000000000000000000..4506a6e150dfd73884811c8c0f5a0e21dc76a756 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/MST7MDT differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/NZ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/NZ new file mode 100644 index 0000000000000000000000000000000000000000..6575fdce31183d8238b18f2f30ab5b9227c7071c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/NZ differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/NZ-CHAT b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/NZ-CHAT new file mode 100644 index 0000000000000000000000000000000000000000..bde46cf7e4b7909714b93cee39a5d953387d756c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/NZ-CHAT differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Navajo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Navajo new file mode 100644 index 0000000000000000000000000000000000000000..abb2b974a47eb3e5c8b4f5d4370baf4898b239ab Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Navajo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/PRC b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/PRC new file mode 100644 index 0000000000000000000000000000000000000000..91f6f8bc2e234bafd484146986bdb289082c3588 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/PRC differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/PST8PDT b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/PST8PDT new file mode 100644 index 0000000000000000000000000000000000000000..99d246baa35cb9c6f56d50adbec163452e2a47fa Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/PST8PDT differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Apia b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Apia new file mode 100644 index 0000000000000000000000000000000000000000..e592a68e53f6215de9e1d1ac61ce062a333283c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Apia differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Chuuk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Chuuk new file mode 100644 index 0000000000000000000000000000000000000000..7be2474dd91c8a7da181fcda09d838254b890d75 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Chuuk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Fakaofo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Fakaofo new file mode 100644 index 0000000000000000000000000000000000000000..4905ea72b1640ca67e35b06395e1c700dffa8d21 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Fakaofo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Fiji b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Fiji new file mode 100644 index 0000000000000000000000000000000000000000..acf8091ac85151a6c887e2b5049ee40754b7b0d3 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Fiji differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Galapagos b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Galapagos new file mode 100644 index 0000000000000000000000000000000000000000..40051ddf63a32d79e5233b916e3911d6dc3ef759 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Galapagos differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Gambier b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Gambier new file mode 100644 index 0000000000000000000000000000000000000000..84acaf41520d2d302f75e300e2b47c5527218df4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Gambier differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Honolulu b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Honolulu new file mode 100644 index 0000000000000000000000000000000000000000..c7cd060159bd22fc5e6f10ac5a2089afb2c19c6a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Honolulu differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Johnston b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Johnston new file mode 100644 index 0000000000000000000000000000000000000000..c7cd060159bd22fc5e6f10ac5a2089afb2c19c6a Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Johnston differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Kiritimati b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Kiritimati new file mode 100644 index 0000000000000000000000000000000000000000..b4c6037a2d2a8f89539c3df05c32b6f52b1b1e92 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Kiritimati differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Majuro b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Majuro new file mode 100644 index 0000000000000000000000000000000000000000..47661d40a4188eb39e8d52e5af8ab23ef7f23766 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Majuro differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Marquesas b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Marquesas new file mode 100644 index 0000000000000000000000000000000000000000..f546c03f96b24859521aab5b9997bfc5dd124ead Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Marquesas differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Midway b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Midway new file mode 100644 index 0000000000000000000000000000000000000000..cb56709a77dedb471150f4907771bf38f1879ba4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Midway differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Nauru b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Nauru new file mode 100644 index 0000000000000000000000000000000000000000..3339b6cf86d6e98ba70c9bd6cab3dbf50588acd2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Nauru differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Norfolk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Norfolk new file mode 100644 index 0000000000000000000000000000000000000000..3b4186d61152629b764efc4222e41647b65f7fbb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Norfolk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Noumea b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Noumea new file mode 100644 index 0000000000000000000000000000000000000000..959cc8cd26f8a7b10a70e0f93bf3b3c9bbc680d2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Noumea differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Pago_Pago b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Pago_Pago new file mode 100644 index 0000000000000000000000000000000000000000..cb56709a77dedb471150f4907771bf38f1879ba4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Pago_Pago differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Pitcairn b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Pitcairn new file mode 100644 index 0000000000000000000000000000000000000000..5ee90e70203d72484b8752475c86139671bcb102 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Pitcairn differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Saipan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Saipan new file mode 100644 index 0000000000000000000000000000000000000000..66490d25dff9bcc8f710b0141f1a02e64aeb32f3 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Saipan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Tahiti b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Tahiti new file mode 100644 index 0000000000000000000000000000000000000000..481edd30580f00eccf69de4f1c332fc048210011 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Tahiti differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Tarawa b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Tarawa new file mode 100644 index 0000000000000000000000000000000000000000..47661d40a4188eb39e8d52e5af8ab23ef7f23766 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Tarawa differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Yap b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Yap new file mode 100644 index 0000000000000000000000000000000000000000..7be2474dd91c8a7da181fcda09d838254b890d75 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Pacific/Yap differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Poland b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Poland new file mode 100644 index 0000000000000000000000000000000000000000..e33cf67171da78aa9e6eb02e50f9b9603da4c3f4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Poland differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Portugal b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Portugal new file mode 100644 index 0000000000000000000000000000000000000000..55f01930ba92ff6852ae4745e78adb5f96c5b057 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Portugal differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/ROC b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/ROC new file mode 100644 index 0000000000000000000000000000000000000000..24c43444b6751343d2915843d03e55753d4d7359 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/ROC differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/ROK b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/ROK new file mode 100644 index 0000000000000000000000000000000000000000..96199e73e73aafacd89e48cb2855a96d7a134e1d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/ROK differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Singapore b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Singapore new file mode 100644 index 0000000000000000000000000000000000000000..3d9f191e3acad56fb4f73ab44a74c50cdf91c12e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Singapore differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Turkey b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Turkey new file mode 100644 index 0000000000000000000000000000000000000000..7c2336dd80c3c9cbf71cb53d2b2c1f89a65a8ba5 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Turkey differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/UCT b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/UCT new file mode 100644 index 0000000000000000000000000000000000000000..91558be0c2bf903b2364215ba26d5227d6126508 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/UCT differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/UTC b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/UTC new file mode 100644 index 0000000000000000000000000000000000000000..91558be0c2bf903b2364215ba26d5227d6126508 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/UTC differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Universal b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Universal new file mode 100644 index 0000000000000000000000000000000000000000..91558be0c2bf903b2364215ba26d5227d6126508 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Universal differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/W-SU b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/W-SU new file mode 100644 index 0000000000000000000000000000000000000000..ddb3f4e99a1030f33b56fad986c8d9c16e59eb32 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/W-SU differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/WET b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/WET new file mode 100644 index 0000000000000000000000000000000000000000..c27390b5b638399057d5f5c6d09ef8c81d5f01c1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/WET differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Zulu b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Zulu new file mode 100644 index 0000000000000000000000000000000000000000..91558be0c2bf903b2364215ba26d5227d6126508 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/Zulu differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/iso3166.tab b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/iso3166.tab new file mode 100644 index 0000000000000000000000000000000000000000..402c015ec6b1071499155f7d28739db68be7763f --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/iso3166.tab @@ -0,0 +1,279 @@ +# ISO 3166 alpha-2 country codes +# +# This file is in the public domain, so clarified as of +# 2009-05-17 by Arthur David Olson. +# +# From Paul Eggert (2023-09-06): +# This file contains a table of two-letter country codes. Columns are +# separated by a single tab. Lines beginning with '#' are comments. +# All text uses UTF-8 encoding. The columns of the table are as follows: +# +# 1. ISO 3166-1 alpha-2 country code, current as of +# ISO/TC 46 N1108 (2023-04-05). See: ISO/TC 46 Documents +# https://www.iso.org/committee/48750.html?view=documents +# 2. The usual English name for the coded region. This sometimes +# departs from ISO-listed names, sometimes so that sorted subsets +# of names are useful (e.g., "Samoa (American)" and "Samoa +# (western)" rather than "American Samoa" and "Samoa"), +# sometimes to avoid confusion among non-experts (e.g., +# "Czech Republic" and "Turkey" rather than "Czechia" and "Türkiye"), +# and sometimes to omit needless detail or churn (e.g., "Netherlands" +# rather than "Netherlands (the)" or "Netherlands (Kingdom of the)"). +# +# The table is sorted by country code. +# +# This table is intended as an aid for users, to help them select time +# zone data appropriate for their practical needs. It is not intended +# to take or endorse any position on legal or territorial claims. +# +#country- +#code name of country, territory, area, or subdivision +AD Andorra +AE United Arab Emirates +AF Afghanistan +AG Antigua & Barbuda +AI Anguilla +AL Albania +AM Armenia +AO Angola +AQ Antarctica +AR Argentina +AS Samoa (American) +AT Austria +AU Australia +AW Aruba +AX Åland Islands +AZ Azerbaijan +BA Bosnia & Herzegovina +BB Barbados +BD Bangladesh +BE Belgium +BF Burkina Faso +BG Bulgaria +BH Bahrain +BI Burundi +BJ Benin +BL St Barthelemy +BM Bermuda +BN Brunei +BO Bolivia +BQ Caribbean NL +BR Brazil +BS Bahamas +BT Bhutan +BV Bouvet Island +BW Botswana +BY Belarus +BZ Belize +CA Canada +CC Cocos (Keeling) Islands +CD Congo (Dem. Rep.) +CF Central African Rep. +CG Congo (Rep.) +CH Switzerland +CI Côte d'Ivoire +CK Cook Islands +CL Chile +CM Cameroon +CN China +CO Colombia +CR Costa Rica +CU Cuba +CV Cape Verde +CW Curaçao +CX Christmas Island +CY Cyprus +CZ Czech Republic +DE Germany +DJ Djibouti +DK Denmark +DM Dominica +DO Dominican Republic +DZ Algeria +EC Ecuador +EE Estonia +EG Egypt +EH Western Sahara +ER Eritrea +ES Spain +ET Ethiopia +FI Finland +FJ Fiji +FK Falkland Islands +FM Micronesia +FO Faroe Islands +FR France +GA Gabon +GB Britain (UK) +GD Grenada +GE Georgia +GF French Guiana +GG Guernsey +GH Ghana +GI Gibraltar +GL Greenland +GM Gambia +GN Guinea +GP Guadeloupe +GQ Equatorial Guinea +GR Greece +GS South Georgia & the South Sandwich Islands +GT Guatemala +GU Guam +GW Guinea-Bissau +GY Guyana +HK Hong Kong +HM Heard Island & McDonald Islands +HN Honduras +HR Croatia +HT Haiti +HU Hungary +ID Indonesia +IE Ireland +IL Israel +IM Isle of Man +IN India +IO British Indian Ocean Territory +IQ Iraq +IR Iran +IS Iceland +IT Italy +JE Jersey +JM Jamaica +JO Jordan +JP Japan +KE Kenya +KG Kyrgyzstan +KH Cambodia +KI Kiribati +KM Comoros +KN St Kitts & Nevis +KP Korea (North) +KR Korea (South) +KW Kuwait +KY Cayman Islands +KZ Kazakhstan +LA Laos +LB Lebanon +LC St Lucia +LI Liechtenstein +LK Sri Lanka +LR Liberia +LS Lesotho +LT Lithuania +LU Luxembourg +LV Latvia +LY Libya +MA Morocco +MC Monaco +MD Moldova +ME Montenegro +MF St Martin (French) +MG Madagascar +MH Marshall Islands +MK North Macedonia +ML Mali +MM Myanmar (Burma) +MN Mongolia +MO Macau +MP Northern Mariana Islands +MQ Martinique +MR Mauritania +MS Montserrat +MT Malta +MU Mauritius +MV Maldives +MW Malawi +MX Mexico +MY Malaysia +MZ Mozambique +NA Namibia +NC New Caledonia +NE Niger +NF Norfolk Island +NG Nigeria +NI Nicaragua +NL Netherlands +NO Norway +NP Nepal +NR Nauru +NU Niue +NZ New Zealand +OM Oman +PA Panama +PE Peru +PF French Polynesia +PG Papua New Guinea +PH Philippines +PK Pakistan +PL Poland +PM St Pierre & Miquelon +PN Pitcairn +PR Puerto Rico +PS Palestine +PT Portugal +PW Palau +PY Paraguay +QA Qatar +RE Réunion +RO Romania +RS Serbia +RU Russia +RW Rwanda +SA Saudi Arabia +SB Solomon Islands +SC Seychelles +SD Sudan +SE Sweden +SG Singapore +SH St Helena +SI Slovenia +SJ Svalbard & Jan Mayen +SK Slovakia +SL Sierra Leone +SM San Marino +SN Senegal +SO Somalia +SR Suriname +SS South Sudan +ST Sao Tome & Principe +SV El Salvador +SX St Maarten (Dutch) +SY Syria +SZ Eswatini (Swaziland) +TC Turks & Caicos Is +TD Chad +TF French S. Terr. +TG Togo +TH Thailand +TJ Tajikistan +TK Tokelau +TL East Timor +TM Turkmenistan +TN Tunisia +TO Tonga +TR Turkey +TT Trinidad & Tobago +TV Tuvalu +TW Taiwan +TZ Tanzania +UA Ukraine +UG Uganda +UM US minor outlying islands +US United States +UY Uruguay +UZ Uzbekistan +VA Vatican City +VC St Vincent +VE Venezuela +VG Virgin Islands (UK) +VI Virgin Islands (US) +VN Vietnam +VU Vanuatu +WF Wallis & Futuna +WS Samoa (western) +YE Yemen +YT Mayotte +ZA South Africa +ZM Zambia +ZW Zimbabwe diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/leapseconds b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/leapseconds new file mode 100644 index 0000000000000000000000000000000000000000..8938c763e0ed719d607f06bc35dabcfcc0c5d72b --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/leapseconds @@ -0,0 +1,82 @@ +# Allowance for leap seconds added to each time zone file. + +# This file is in the public domain. + +# This file is generated automatically from the data in the public-domain +# NIST format leap-seconds.list file, which can be copied from +# +# or . +# The NIST file is used instead of its IERS upstream counterpart +# +# because under US law the NIST file is public domain +# whereas the IERS file's copyright and license status is unclear. +# For more about leap-seconds.list, please see +# The NTP Timescale and Leap Seconds +# . + +# The rules for leap seconds are specified in Annex 1 (Time scales) of: +# Standard-frequency and time-signal emissions. +# International Telecommunication Union - Radiocommunication Sector +# (ITU-R) Recommendation TF.460-6 (02/2002) +# . +# The International Earth Rotation and Reference Systems Service (IERS) +# periodically uses leap seconds to keep UTC to within 0.9 s of UT1 +# (a proxy for Earth's angle in space as measured by astronomers) +# and publishes leap second data in a copyrighted file +# . +# See: Levine J. Coordinated Universal Time and the leap second. +# URSI Radio Sci Bull. 2016;89(4):30-6. doi:10.23919/URSIRSB.2016.7909995 +# . + +# There were no leap seconds before 1972, as no official mechanism +# accounted for the discrepancy between atomic time (TAI) and the earth's +# rotation. The first ("1 Jan 1972") data line in leap-seconds.list +# does not denote a leap second; it denotes the start of the current definition +# of UTC. + +# All leap-seconds are Stationary (S) at the given UTC time. +# The correction (+ or -) is made at the given time, so in the unlikely +# event of a negative leap second, a line would look like this: +# Leap YEAR MON DAY 23:59:59 - S +# Typical lines look like this: +# Leap YEAR MON DAY 23:59:60 + S +Leap 1972 Jun 30 23:59:60 + S +Leap 1972 Dec 31 23:59:60 + S +Leap 1973 Dec 31 23:59:60 + S +Leap 1974 Dec 31 23:59:60 + S +Leap 1975 Dec 31 23:59:60 + S +Leap 1976 Dec 31 23:59:60 + S +Leap 1977 Dec 31 23:59:60 + S +Leap 1978 Dec 31 23:59:60 + S +Leap 1979 Dec 31 23:59:60 + S +Leap 1981 Jun 30 23:59:60 + S +Leap 1982 Jun 30 23:59:60 + S +Leap 1983 Jun 30 23:59:60 + S +Leap 1985 Jun 30 23:59:60 + S +Leap 1987 Dec 31 23:59:60 + S +Leap 1989 Dec 31 23:59:60 + S +Leap 1990 Dec 31 23:59:60 + S +Leap 1992 Jun 30 23:59:60 + S +Leap 1993 Jun 30 23:59:60 + S +Leap 1994 Jun 30 23:59:60 + S +Leap 1995 Dec 31 23:59:60 + S +Leap 1997 Jun 30 23:59:60 + S +Leap 1998 Dec 31 23:59:60 + S +Leap 2005 Dec 31 23:59:60 + S +Leap 2008 Dec 31 23:59:60 + S +Leap 2012 Jun 30 23:59:60 + S +Leap 2015 Jun 30 23:59:60 + S +Leap 2016 Dec 31 23:59:60 + S + +# UTC timestamp when this leap second list expires. +# Any additional leap seconds will come after this. +# This Expires line is commented out for now, +# so that pre-2020a zic implementations do not reject this file. +#Expires 2024 Jun 28 00:00:00 + +# POSIX timestamps for the data in this file: +#updated 1467936000 (2016-07-08 00:00:00 UTC) +#expires 1719532800 (2024-06-28 00:00:00 UTC) + +# Updated through IERS Bulletin C66 +# File expires on: 28 June 2024 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/tzdata.zi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/tzdata.zi new file mode 100644 index 0000000000000000000000000000000000000000..e4286bca774582d55c610b43b925aa924b42e414 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/tzdata.zi @@ -0,0 +1,4296 @@ +# version unknown +# This zic input file is in the public domain. +R d 1916 o - Jun 14 23s 1 S +R d 1916 1919 - O Su>=1 23s 0 - +R d 1917 o - Mar 24 23s 1 S +R d 1918 o - Mar 9 23s 1 S +R d 1919 o - Mar 1 23s 1 S +R d 1920 o - F 14 23s 1 S +R d 1920 o - O 23 23s 0 - +R d 1921 o - Mar 14 23s 1 S +R d 1921 o - Jun 21 23s 0 - +R d 1939 o - S 11 23s 1 S +R d 1939 o - N 19 1 0 - +R d 1944 1945 - Ap M>=1 2 1 S +R d 1944 o - O 8 2 0 - +R d 1945 o - S 16 1 0 - +R d 1971 o - Ap 25 23s 1 S +R d 1971 o - S 26 23s 0 - +R d 1977 o - May 6 0 1 S +R d 1977 o - O 21 0 0 - +R d 1978 o - Mar 24 1 1 S +R d 1978 o - S 22 3 0 - +R d 1980 o - Ap 25 0 1 S +R d 1980 o - O 31 2 0 - +Z Africa/Algiers 0:12:12 - LMT 1891 Mar 16 +0:9:21 - PMT 1911 Mar 11 +0 d WE%sT 1940 F 25 2 +1 d CE%sT 1946 O 7 +0 - WET 1956 Ja 29 +1 - CET 1963 Ap 14 +0 d WE%sT 1977 O 21 +1 d CE%sT 1979 O 26 +0 d WE%sT 1981 May +1 - CET +Z Atlantic/Cape_Verde -1:34:4 - LMT 1912 Ja 1 2u +-2 - -02 1942 S +-2 1 -01 1945 O 15 +-2 - -02 1975 N 25 2 +-1 - -01 +Z Africa/Ndjamena 1:0:12 - LMT 1912 +1 - WAT 1979 O 14 +1 1 WAST 1980 Mar 8 +1 - WAT +Z Africa/Abidjan -0:16:8 - LMT 1912 +0 - GMT +R K 1940 o - Jul 15 0 1 S +R K 1940 o - O 1 0 0 - +R K 1941 o - Ap 15 0 1 S +R K 1941 o - S 16 0 0 - +R K 1942 1944 - Ap 1 0 1 S +R K 1942 o - O 27 0 0 - +R K 1943 1945 - N 1 0 0 - +R K 1945 o - Ap 16 0 1 S +R K 1957 o - May 10 0 1 S +R K 1957 1958 - O 1 0 0 - +R K 1958 o - May 1 0 1 S +R K 1959 1981 - May 1 1 1 S +R K 1959 1965 - S 30 3 0 - +R K 1966 1994 - O 1 3 0 - +R K 1982 o - Jul 25 1 1 S +R K 1983 o - Jul 12 1 1 S +R K 1984 1988 - May 1 1 1 S +R K 1989 o - May 6 1 1 S +R K 1990 1994 - May 1 1 1 S +R K 1995 2010 - Ap lastF 0s 1 S +R K 1995 2005 - S lastTh 24 0 - +R K 2006 o - S 21 24 0 - +R K 2007 o - S Th>=1 24 0 - +R K 2008 o - Au lastTh 24 0 - +R K 2009 o - Au 20 24 0 - +R K 2010 o - Au 10 24 0 - +R K 2010 o - S 9 24 1 S +R K 2010 o - S lastTh 24 0 - +R K 2014 o - May 15 24 1 S +R K 2014 o - Jun 26 24 0 - +R K 2014 o - Jul 31 24 1 S +R K 2014 o - S lastTh 24 0 - +R K 2023 ma - Ap lastF 0 1 S +R K 2023 ma - O lastTh 24 0 - +Z Africa/Cairo 2:5:9 - LMT 1900 O +2 K EE%sT +Z Africa/Bissau -1:2:20 - LMT 1912 Ja 1 1u +-1 - -01 1975 +0 - GMT +Z Africa/Nairobi 2:27:16 - LMT 1908 May +2:30 - +0230 1928 Jun 30 24 +3 - EAT 1930 Ja 4 24 +2:30 - +0230 1936 D 31 24 +2:45 - +0245 1942 Jul 31 24 +3 - EAT +Z Africa/Monrovia -0:43:8 - LMT 1882 +-0:43:8 - MMT 1919 Mar +-0:44:30 - MMT 1972 Ja 7 +0 - GMT +R L 1951 o - O 14 2 1 S +R L 1952 o - Ja 1 0 0 - +R L 1953 o - O 9 2 1 S +R L 1954 o - Ja 1 0 0 - +R L 1955 o - S 30 0 1 S +R L 1956 o - Ja 1 0 0 - +R L 1982 1984 - Ap 1 0 1 S +R L 1982 1985 - O 1 0 0 - +R L 1985 o - Ap 6 0 1 S +R L 1986 o - Ap 4 0 1 S +R L 1986 o - O 3 0 0 - +R L 1987 1989 - Ap 1 0 1 S +R L 1987 1989 - O 1 0 0 - +R L 1997 o - Ap 4 0 1 S +R L 1997 o - O 4 0 0 - +R L 2013 o - Mar lastF 1 1 S +R L 2013 o - O lastF 2 0 - +Z Africa/Tripoli 0:52:44 - LMT 1920 +1 L CE%sT 1959 +2 - EET 1982 +1 L CE%sT 1990 May 4 +2 - EET 1996 S 30 +1 L CE%sT 1997 O 4 +2 - EET 2012 N 10 2 +1 L CE%sT 2013 O 25 2 +2 - EET +R MU 1982 o - O 10 0 1 - +R MU 1983 o - Mar 21 0 0 - +R MU 2008 o - O lastSu 2 1 - +R MU 2009 o - Mar lastSu 2 0 - +Z Indian/Mauritius 3:50 - LMT 1907 +4 MU +04/+05 +R M 1939 o - S 12 0 1 - +R M 1939 o - N 19 0 0 - +R M 1940 o - F 25 0 1 - +R M 1945 o - N 18 0 0 - +R M 1950 o - Jun 11 0 1 - +R M 1950 o - O 29 0 0 - +R M 1967 o - Jun 3 12 1 - +R M 1967 o - O 1 0 0 - +R M 1974 o - Jun 24 0 1 - +R M 1974 o - S 1 0 0 - +R M 1976 1977 - May 1 0 1 - +R M 1976 o - Au 1 0 0 - +R M 1977 o - S 28 0 0 - +R M 1978 o - Jun 1 0 1 - +R M 1978 o - Au 4 0 0 - +R M 2008 o - Jun 1 0 1 - +R M 2008 o - S 1 0 0 - +R M 2009 o - Jun 1 0 1 - +R M 2009 o - Au 21 0 0 - +R M 2010 o - May 2 0 1 - +R M 2010 o - Au 8 0 0 - +R M 2011 o - Ap 3 0 1 - +R M 2011 o - Jul 31 0 0 - +R M 2012 2013 - Ap lastSu 2 1 - +R M 2012 o - Jul 20 3 0 - +R M 2012 o - Au 20 2 1 - +R M 2012 o - S 30 3 0 - +R M 2013 o - Jul 7 3 0 - +R M 2013 o - Au 10 2 1 - +R M 2013 2018 - O lastSu 3 0 - +R M 2014 2018 - Mar lastSu 2 1 - +R M 2014 o - Jun 28 3 0 - +R M 2014 o - Au 2 2 1 - +R M 2015 o - Jun 14 3 0 - +R M 2015 o - Jul 19 2 1 - +R M 2016 o - Jun 5 3 0 - +R M 2016 o - Jul 10 2 1 - +R M 2017 o - May 21 3 0 - +R M 2017 o - Jul 2 2 1 - +R M 2018 o - May 13 3 0 - +R M 2018 o - Jun 17 2 1 - +R M 2019 o - May 5 3 -1 - +R M 2019 o - Jun 9 2 0 - +R M 2020 o - Ap 19 3 -1 - +R M 2020 o - May 31 2 0 - +R M 2021 o - Ap 11 3 -1 - +R M 2021 o - May 16 2 0 - +R M 2022 o - Mar 27 3 -1 - +R M 2022 o - May 8 2 0 - +R M 2023 o - Mar 19 3 -1 - +R M 2023 o - Ap 23 2 0 - +R M 2024 o - Mar 10 3 -1 - +R M 2024 o - Ap 14 2 0 - +R M 2025 o - F 23 3 -1 - +R M 2025 o - Ap 6 2 0 - +R M 2026 o - F 15 3 -1 - +R M 2026 o - Mar 22 2 0 - +R M 2027 o - F 7 3 -1 - +R M 2027 o - Mar 14 2 0 - +R M 2028 o - Ja 23 3 -1 - +R M 2028 o - Mar 5 2 0 - +R M 2029 o - Ja 14 3 -1 - +R M 2029 o - F 18 2 0 - +R M 2029 o - D 30 3 -1 - +R M 2030 o - F 10 2 0 - +R M 2030 o - D 22 3 -1 - +R M 2031 o - Ja 26 2 0 - +R M 2031 o - D 14 3 -1 - +R M 2032 o - Ja 18 2 0 - +R M 2032 o - N 28 3 -1 - +R M 2033 o - Ja 9 2 0 - +R M 2033 o - N 20 3 -1 - +R M 2033 o - D 25 2 0 - +R M 2034 o - N 5 3 -1 - +R M 2034 o - D 17 2 0 - +R M 2035 o - O 28 3 -1 - +R M 2035 o - D 9 2 0 - +R M 2036 o - O 19 3 -1 - +R M 2036 o - N 23 2 0 - +R M 2037 o - O 4 3 -1 - +R M 2037 o - N 15 2 0 - +R M 2038 o - S 26 3 -1 - +R M 2038 o - O 31 2 0 - +R M 2039 o - S 18 3 -1 - +R M 2039 o - O 23 2 0 - +R M 2040 o - S 2 3 -1 - +R M 2040 o - O 14 2 0 - +R M 2041 o - Au 25 3 -1 - +R M 2041 o - S 29 2 0 - +R M 2042 o - Au 10 3 -1 - +R M 2042 o - S 21 2 0 - +R M 2043 o - Au 2 3 -1 - +R M 2043 o - S 13 2 0 - +R M 2044 o - Jul 24 3 -1 - +R M 2044 o - Au 28 2 0 - +R M 2045 o - Jul 9 3 -1 - +R M 2045 o - Au 20 2 0 - +R M 2046 o - Jul 1 3 -1 - +R M 2046 o - Au 5 2 0 - +R M 2047 o - Jun 23 3 -1 - +R M 2047 o - Jul 28 2 0 - +R M 2048 o - Jun 7 3 -1 - +R M 2048 o - Jul 19 2 0 - +R M 2049 o - May 30 3 -1 - +R M 2049 o - Jul 4 2 0 - +R M 2050 o - May 15 3 -1 - +R M 2050 o - Jun 26 2 0 - +R M 2051 o - May 7 3 -1 - +R M 2051 o - Jun 18 2 0 - +R M 2052 o - Ap 28 3 -1 - +R M 2052 o - Jun 2 2 0 - +R M 2053 o - Ap 13 3 -1 - +R M 2053 o - May 25 2 0 - +R M 2054 o - Ap 5 3 -1 - +R M 2054 o - May 10 2 0 - +R M 2055 o - Mar 28 3 -1 - +R M 2055 o - May 2 2 0 - +R M 2056 o - Mar 12 3 -1 - +R M 2056 o - Ap 23 2 0 - +R M 2057 o - Mar 4 3 -1 - +R M 2057 o - Ap 8 2 0 - +R M 2058 o - F 17 3 -1 - +R M 2058 o - Mar 31 2 0 - +R M 2059 o - F 9 3 -1 - +R M 2059 o - Mar 23 2 0 - +R M 2060 o - F 1 3 -1 - +R M 2060 o - Mar 7 2 0 - +R M 2061 o - Ja 16 3 -1 - +R M 2061 o - F 27 2 0 - +R M 2062 o - Ja 8 3 -1 - +R M 2062 o - F 12 2 0 - +R M 2062 o - D 31 3 -1 - +R M 2063 o - F 4 2 0 - +R M 2063 o - D 16 3 -1 - +R M 2064 o - Ja 27 2 0 - +R M 2064 o - D 7 3 -1 - +R M 2065 o - Ja 11 2 0 - +R M 2065 o - N 22 3 -1 - +R M 2066 o - Ja 3 2 0 - +R M 2066 o - N 14 3 -1 - +R M 2066 o - D 26 2 0 - +R M 2067 o - N 6 3 -1 - +R M 2067 o - D 11 2 0 - +R M 2068 o - O 21 3 -1 - +R M 2068 o - D 2 2 0 - +R M 2069 o - O 13 3 -1 - +R M 2069 o - N 17 2 0 - +R M 2070 o - O 5 3 -1 - +R M 2070 o - N 9 2 0 - +R M 2071 o - S 20 3 -1 - +R M 2071 o - N 1 2 0 - +R M 2072 o - S 11 3 -1 - +R M 2072 o - O 16 2 0 - +R M 2073 o - Au 27 3 -1 - +R M 2073 o - O 8 2 0 - +R M 2074 o - Au 19 3 -1 - +R M 2074 o - S 30 2 0 - +R M 2075 o - Au 11 3 -1 - +R M 2075 o - S 15 2 0 - +R M 2076 o - Jul 26 3 -1 - +R M 2076 o - S 6 2 0 - +R M 2077 o - Jul 18 3 -1 - +R M 2077 o - Au 22 2 0 - +R M 2078 o - Jul 10 3 -1 - +R M 2078 o - Au 14 2 0 - +R M 2079 o - Jun 25 3 -1 - +R M 2079 o - Au 6 2 0 - +R M 2080 o - Jun 16 3 -1 - +R M 2080 o - Jul 21 2 0 - +R M 2081 o - Jun 1 3 -1 - +R M 2081 o - Jul 13 2 0 - +R M 2082 o - May 24 3 -1 - +R M 2082 o - Jun 28 2 0 - +R M 2083 o - May 16 3 -1 - +R M 2083 o - Jun 20 2 0 - +R M 2084 o - Ap 30 3 -1 - +R M 2084 o - Jun 11 2 0 - +R M 2085 o - Ap 22 3 -1 - +R M 2085 o - May 27 2 0 - +R M 2086 o - Ap 14 3 -1 - +R M 2086 o - May 19 2 0 - +R M 2087 o - Mar 30 3 -1 - +R M 2087 o - May 11 2 0 - +Z Africa/Casablanca -0:30:20 - LMT 1913 O 26 +0 M +00/+01 1984 Mar 16 +1 - +01 1986 +0 M +00/+01 2018 O 28 3 +1 M +01/+00 +Z Africa/El_Aaiun -0:52:48 - LMT 1934 +-1 - -01 1976 Ap 14 +0 M +00/+01 2018 O 28 3 +1 M +01/+00 +Z Africa/Maputo 2:10:20 - LMT 1903 Mar +2 - CAT +R NA 1994 o - Mar 21 0 -1 WAT +R NA 1994 2017 - S Su>=1 2 0 CAT +R NA 1995 2017 - Ap Su>=1 2 -1 WAT +Z Africa/Windhoek 1:8:24 - LMT 1892 F 8 +1:30 - +0130 1903 Mar +2 - SAST 1942 S 20 2 +2 1 SAST 1943 Mar 21 2 +2 - SAST 1990 Mar 21 +2 NA %s +Z Africa/Lagos 0:13:35 - LMT 1905 Jul +0 - GMT 1908 Jul +0:13:35 - LMT 1914 +0:30 - +0030 1919 S +1 - WAT +Z Africa/Sao_Tome 0:26:56 - LMT 1884 +-0:36:45 - LMT 1912 Ja 1 0u +0 - GMT 2018 Ja 1 1 +1 - WAT 2019 Ja 1 2 +0 - GMT +R SA 1942 1943 - S Su>=15 2 1 - +R SA 1943 1944 - Mar Su>=15 2 0 - +Z Africa/Johannesburg 1:52 - LMT 1892 F 8 +1:30 - SAST 1903 Mar +2 SA SAST +R SD 1970 o - May 1 0 1 S +R SD 1970 1985 - O 15 0 0 - +R SD 1971 o - Ap 30 0 1 S +R SD 1972 1985 - Ap lastSu 0 1 S +Z Africa/Khartoum 2:10:8 - LMT 1931 +2 SD CA%sT 2000 Ja 15 12 +3 - EAT 2017 N +2 - CAT +Z Africa/Juba 2:6:28 - LMT 1931 +2 SD CA%sT 2000 Ja 15 12 +3 - EAT 2021 F +2 - CAT +R n 1939 o - Ap 15 23s 1 S +R n 1939 o - N 18 23s 0 - +R n 1940 o - F 25 23s 1 S +R n 1941 o - O 6 0 0 - +R n 1942 o - Mar 9 0 1 S +R n 1942 o - N 2 3 0 - +R n 1943 o - Mar 29 2 1 S +R n 1943 o - Ap 17 2 0 - +R n 1943 o - Ap 25 2 1 S +R n 1943 o - O 4 2 0 - +R n 1944 1945 - Ap M>=1 2 1 S +R n 1944 o - O 8 0 0 - +R n 1945 o - S 16 0 0 - +R n 1977 o - Ap 30 0s 1 S +R n 1977 o - S 24 0s 0 - +R n 1978 o - May 1 0s 1 S +R n 1978 o - O 1 0s 0 - +R n 1988 o - Jun 1 0s 1 S +R n 1988 1990 - S lastSu 0s 0 - +R n 1989 o - Mar 26 0s 1 S +R n 1990 o - May 1 0s 1 S +R n 2005 o - May 1 0s 1 S +R n 2005 o - S 30 1s 0 - +R n 2006 2008 - Mar lastSu 2s 1 S +R n 2006 2008 - O lastSu 2s 0 - +Z Africa/Tunis 0:40:44 - LMT 1881 May 12 +0:9:21 - PMT 1911 Mar 11 +1 n CE%sT +Z Antarctica/Casey 0 - -00 1969 +8 - +08 2009 O 18 2 +11 - +11 2010 Mar 5 2 +8 - +08 2011 O 28 2 +11 - +11 2012 F 21 17u +8 - +08 2016 O 22 +11 - +11 2018 Mar 11 4 +8 - +08 2018 O 7 4 +11 - +11 2019 Mar 17 3 +8 - +08 2019 O 4 3 +11 - +11 2020 Mar 8 3 +8 - +08 2020 O 4 0:1 +11 - +11 2021 Mar 14 +8 - +08 2021 O 3 0:1 +11 - +11 2022 Mar 13 +8 - +08 2022 O 2 0:1 +11 - +11 2023 Mar 9 3 +8 - +08 +Z Antarctica/Davis 0 - -00 1957 Ja 13 +7 - +07 1964 N +0 - -00 1969 F +7 - +07 2009 O 18 2 +5 - +05 2010 Mar 10 20u +7 - +07 2011 O 28 2 +5 - +05 2012 F 21 20u +7 - +07 +Z Antarctica/Mawson 0 - -00 1954 F 13 +6 - +06 2009 O 18 2 +5 - +05 +R Tr 2005 ma - Mar lastSu 1u 2 +02 +R Tr 2004 ma - O lastSu 1u 0 +00 +Z Antarctica/Troll 0 - -00 2005 F 12 +0 Tr %s +Z Antarctica/Vostok 0 - -00 1957 D 16 +7 - +07 1994 F +0 - -00 1994 N +7 - +07 2023 D 18 2 +5 - +05 +Z Antarctica/Rothera 0 - -00 1976 D +-3 - -03 +Z Asia/Kabul 4:36:48 - LMT 1890 +4 - +04 1945 +4:30 - +0430 +R AM 2011 o - Mar lastSu 2s 1 - +R AM 2011 o - O lastSu 2s 0 - +Z Asia/Yerevan 2:58 - LMT 1924 May 2 +3 - +03 1957 Mar +4 R +04/+05 1991 Mar 31 2s +3 R +03/+04 1995 S 24 2s +4 - +04 1997 +4 R +04/+05 2011 +4 AM +04/+05 +R AZ 1997 2015 - Mar lastSu 4 1 - +R AZ 1997 2015 - O lastSu 5 0 - +Z Asia/Baku 3:19:24 - LMT 1924 May 2 +3 - +03 1957 Mar +4 R +04/+05 1991 Mar 31 2s +3 R +03/+04 1992 S lastSu 2s +4 - +04 1996 +4 E +04/+05 1997 +4 AZ +04/+05 +R BD 2009 o - Jun 19 23 1 - +R BD 2009 o - D 31 24 0 - +Z Asia/Dhaka 6:1:40 - LMT 1890 +5:53:20 - HMT 1941 O +6:30 - +0630 1942 May 15 +5:30 - +0530 1942 S +6:30 - +0630 1951 S 30 +6 - +06 2009 +6 BD +06/+07 +Z Asia/Thimphu 5:58:36 - LMT 1947 Au 15 +5:30 - +0530 1987 O +6 - +06 +Z Indian/Chagos 4:49:40 - LMT 1907 +5 - +05 1996 +6 - +06 +Z Asia/Yangon 6:24:47 - LMT 1880 +6:24:47 - RMT 1920 +6:30 - +0630 1942 May +9 - +09 1945 May 3 +6:30 - +0630 +R Sh 1919 o - Ap 12 24 1 D +R Sh 1919 o - S 30 24 0 S +R Sh 1940 o - Jun 1 0 1 D +R Sh 1940 o - O 12 24 0 S +R Sh 1941 o - Mar 15 0 1 D +R Sh 1941 o - N 1 24 0 S +R Sh 1942 o - Ja 31 0 1 D +R Sh 1945 o - S 1 24 0 S +R Sh 1946 o - May 15 0 1 D +R Sh 1946 o - S 30 24 0 S +R Sh 1947 o - Ap 15 0 1 D +R Sh 1947 o - O 31 24 0 S +R Sh 1948 1949 - May 1 0 1 D +R Sh 1948 1949 - S 30 24 0 S +R CN 1986 o - May 4 2 1 D +R CN 1986 1991 - S Su>=11 2 0 S +R CN 1987 1991 - Ap Su>=11 2 1 D +Z Asia/Shanghai 8:5:43 - LMT 1901 +8 Sh C%sT 1949 May 28 +8 CN C%sT +Z Asia/Urumqi 5:50:20 - LMT 1928 +6 - +06 +R HK 1946 o - Ap 21 0 1 S +R HK 1946 o - D 1 3:30s 0 - +R HK 1947 o - Ap 13 3:30s 1 S +R HK 1947 o - N 30 3:30s 0 - +R HK 1948 o - May 2 3:30s 1 S +R HK 1948 1952 - O Su>=28 3:30s 0 - +R HK 1949 1953 - Ap Su>=1 3:30 1 S +R HK 1953 1964 - O Su>=31 3:30 0 - +R HK 1954 1964 - Mar Su>=18 3:30 1 S +R HK 1965 1976 - Ap Su>=16 3:30 1 S +R HK 1965 1976 - O Su>=16 3:30 0 - +R HK 1973 o - D 30 3:30 1 S +R HK 1979 o - May 13 3:30 1 S +R HK 1979 o - O 21 3:30 0 - +Z Asia/Hong_Kong 7:36:42 - LMT 1904 O 29 17u +8 - HKT 1941 Jun 15 3 +8 1 HKST 1941 O 1 4 +8 0:30 HKWT 1941 D 25 +9 - JST 1945 N 18 2 +8 HK HK%sT +R f 1946 o - May 15 0 1 D +R f 1946 o - O 1 0 0 S +R f 1947 o - Ap 15 0 1 D +R f 1947 o - N 1 0 0 S +R f 1948 1951 - May 1 0 1 D +R f 1948 1951 - O 1 0 0 S +R f 1952 o - Mar 1 0 1 D +R f 1952 1954 - N 1 0 0 S +R f 1953 1959 - Ap 1 0 1 D +R f 1955 1961 - O 1 0 0 S +R f 1960 1961 - Jun 1 0 1 D +R f 1974 1975 - Ap 1 0 1 D +R f 1974 1975 - O 1 0 0 S +R f 1979 o - Jul 1 0 1 D +R f 1979 o - O 1 0 0 S +Z Asia/Taipei 8:6 - LMT 1896 +8 - CST 1937 O +9 - JST 1945 S 21 1 +8 f C%sT +R _ 1942 1943 - Ap 30 23 1 - +R _ 1942 o - N 17 23 0 - +R _ 1943 o - S 30 23 0 S +R _ 1946 o - Ap 30 23s 1 D +R _ 1946 o - S 30 23s 0 S +R _ 1947 o - Ap 19 23s 1 D +R _ 1947 o - N 30 23s 0 S +R _ 1948 o - May 2 23s 1 D +R _ 1948 o - O 31 23s 0 S +R _ 1949 1950 - Ap Sa>=1 23s 1 D +R _ 1949 1950 - O lastSa 23s 0 S +R _ 1951 o - Mar 31 23s 1 D +R _ 1951 o - O 28 23s 0 S +R _ 1952 1953 - Ap Sa>=1 23s 1 D +R _ 1952 o - N 1 23s 0 S +R _ 1953 1954 - O lastSa 23s 0 S +R _ 1954 1956 - Mar Sa>=17 23s 1 D +R _ 1955 o - N 5 23s 0 S +R _ 1956 1964 - N Su>=1 3:30 0 S +R _ 1957 1964 - Mar Su>=18 3:30 1 D +R _ 1965 1973 - Ap Su>=16 3:30 1 D +R _ 1965 1966 - O Su>=16 2:30 0 S +R _ 1967 1976 - O Su>=16 3:30 0 S +R _ 1973 o - D 30 3:30 1 D +R _ 1975 1976 - Ap Su>=16 3:30 1 D +R _ 1979 o - May 13 3:30 1 D +R _ 1979 o - O Su>=16 3:30 0 S +Z Asia/Macau 7:34:10 - LMT 1904 O 30 +8 - CST 1941 D 21 23 +9 _ +09/+10 1945 S 30 24 +8 _ C%sT +R CY 1975 o - Ap 13 0 1 S +R CY 1975 o - O 12 0 0 - +R CY 1976 o - May 15 0 1 S +R CY 1976 o - O 11 0 0 - +R CY 1977 1980 - Ap Su>=1 0 1 S +R CY 1977 o - S 25 0 0 - +R CY 1978 o - O 2 0 0 - +R CY 1979 1997 - S lastSu 0 0 - +R CY 1981 1998 - Mar lastSu 0 1 S +Z Asia/Nicosia 2:13:28 - LMT 1921 N 14 +2 CY EE%sT 1998 S +2 E EE%sT +Z Asia/Famagusta 2:15:48 - LMT 1921 N 14 +2 CY EE%sT 1998 S +2 E EE%sT 2016 S 8 +3 - +03 2017 O 29 1u +2 E EE%sT +Z Asia/Tbilisi 2:59:11 - LMT 1880 +2:59:11 - TBMT 1924 May 2 +3 - +03 1957 Mar +4 R +04/+05 1991 Mar 31 2s +3 R +03/+04 1992 +3 e +03/+04 1994 S lastSu +4 e +04/+05 1996 O lastSu +4 1 +05 1997 Mar lastSu +4 e +04/+05 2004 Jun 27 +3 R +03/+04 2005 Mar lastSu 2 +4 - +04 +Z Asia/Dili 8:22:20 - LMT 1912 +8 - +08 1942 F 21 23 +9 - +09 1976 May 3 +8 - +08 2000 S 17 +9 - +09 +Z Asia/Kolkata 5:53:28 - LMT 1854 Jun 28 +5:53:20 - HMT 1870 +5:21:10 - MMT 1906 +5:30 - IST 1941 O +5:30 1 +0630 1942 May 15 +5:30 - IST 1942 S +5:30 1 +0630 1945 O 15 +5:30 - IST +Z Asia/Jakarta 7:7:12 - LMT 1867 Au 10 +7:7:12 - BMT 1923 D 31 16:40u +7:20 - +0720 1932 N +7:30 - +0730 1942 Mar 23 +9 - +09 1945 S 23 +7:30 - +0730 1948 May +8 - +08 1950 May +7:30 - +0730 1964 +7 - WIB +Z Asia/Pontianak 7:17:20 - LMT 1908 May +7:17:20 - PMT 1932 N +7:30 - +0730 1942 Ja 29 +9 - +09 1945 S 23 +7:30 - +0730 1948 May +8 - +08 1950 May +7:30 - +0730 1964 +8 - WITA 1988 +7 - WIB +Z Asia/Makassar 7:57:36 - LMT 1920 +7:57:36 - MMT 1932 N +8 - +08 1942 F 9 +9 - +09 1945 S 23 +8 - WITA +Z Asia/Jayapura 9:22:48 - LMT 1932 N +9 - +09 1944 S +9:30 - +0930 1964 +9 - WIT +R i 1910 o - Ja 1 0 0 - +R i 1977 o - Mar 21 23 1 - +R i 1977 o - O 20 24 0 - +R i 1978 o - Mar 24 24 1 - +R i 1978 o - Au 5 1 0 - +R i 1979 o - May 26 24 1 - +R i 1979 o - S 18 24 0 - +R i 1980 o - Mar 20 24 1 - +R i 1980 o - S 22 24 0 - +R i 1991 o - May 2 24 1 - +R i 1992 1995 - Mar 21 24 1 - +R i 1991 1995 - S 21 24 0 - +R i 1996 o - Mar 20 24 1 - +R i 1996 o - S 20 24 0 - +R i 1997 1999 - Mar 21 24 1 - +R i 1997 1999 - S 21 24 0 - +R i 2000 o - Mar 20 24 1 - +R i 2000 o - S 20 24 0 - +R i 2001 2003 - Mar 21 24 1 - +R i 2001 2003 - S 21 24 0 - +R i 2004 o - Mar 20 24 1 - +R i 2004 o - S 20 24 0 - +R i 2005 o - Mar 21 24 1 - +R i 2005 o - S 21 24 0 - +R i 2008 o - Mar 20 24 1 - +R i 2008 o - S 20 24 0 - +R i 2009 2011 - Mar 21 24 1 - +R i 2009 2011 - S 21 24 0 - +R i 2012 o - Mar 20 24 1 - +R i 2012 o - S 20 24 0 - +R i 2013 2015 - Mar 21 24 1 - +R i 2013 2015 - S 21 24 0 - +R i 2016 o - Mar 20 24 1 - +R i 2016 o - S 20 24 0 - +R i 2017 2019 - Mar 21 24 1 - +R i 2017 2019 - S 21 24 0 - +R i 2020 o - Mar 20 24 1 - +R i 2020 o - S 20 24 0 - +R i 2021 2022 - Mar 21 24 1 - +R i 2021 2022 - S 21 24 0 - +Z Asia/Tehran 3:25:44 - LMT 1916 +3:25:44 - TMT 1935 Jun 13 +3:30 i +0330/+0430 1977 O 20 24 +4 i +04/+05 1979 +3:30 i +0330/+0430 +R IQ 1982 o - May 1 0 1 - +R IQ 1982 1984 - O 1 0 0 - +R IQ 1983 o - Mar 31 0 1 - +R IQ 1984 1985 - Ap 1 0 1 - +R IQ 1985 1990 - S lastSu 1s 0 - +R IQ 1986 1990 - Mar lastSu 1s 1 - +R IQ 1991 2007 - Ap 1 3s 1 - +R IQ 1991 2007 - O 1 3s 0 - +Z Asia/Baghdad 2:57:40 - LMT 1890 +2:57:36 - BMT 1918 +3 - +03 1982 May +3 IQ +03/+04 +R Z 1940 o - May 31 24u 1 D +R Z 1940 o - S 30 24u 0 S +R Z 1940 o - N 16 24u 1 D +R Z 1942 1946 - O 31 24u 0 S +R Z 1943 1944 - Mar 31 24u 1 D +R Z 1945 1946 - Ap 15 24u 1 D +R Z 1948 o - May 22 24u 2 DD +R Z 1948 o - Au 31 24u 1 D +R Z 1948 1949 - O 31 24u 0 S +R Z 1949 o - Ap 30 24u 1 D +R Z 1950 o - Ap 15 24u 1 D +R Z 1950 o - S 14 24u 0 S +R Z 1951 o - Mar 31 24u 1 D +R Z 1951 o - N 10 24u 0 S +R Z 1952 o - Ap 19 24u 1 D +R Z 1952 o - O 18 24u 0 S +R Z 1953 o - Ap 11 24u 1 D +R Z 1953 o - S 12 24u 0 S +R Z 1954 o - Jun 12 24u 1 D +R Z 1954 o - S 11 24u 0 S +R Z 1955 o - Jun 11 24u 1 D +R Z 1955 o - S 10 24u 0 S +R Z 1956 o - Jun 2 24u 1 D +R Z 1956 o - S 29 24u 0 S +R Z 1957 o - Ap 27 24u 1 D +R Z 1957 o - S 21 24u 0 S +R Z 1974 o - Jul 6 24 1 D +R Z 1974 o - O 12 24 0 S +R Z 1975 o - Ap 19 24 1 D +R Z 1975 o - Au 30 24 0 S +R Z 1980 o - Au 2 24s 1 D +R Z 1980 o - S 13 24s 0 S +R Z 1984 o - May 5 24s 1 D +R Z 1984 o - Au 25 24s 0 S +R Z 1985 o - Ap 13 24 1 D +R Z 1985 o - Au 31 24 0 S +R Z 1986 o - May 17 24 1 D +R Z 1986 o - S 6 24 0 S +R Z 1987 o - Ap 14 24 1 D +R Z 1987 o - S 12 24 0 S +R Z 1988 o - Ap 9 24 1 D +R Z 1988 o - S 3 24 0 S +R Z 1989 o - Ap 29 24 1 D +R Z 1989 o - S 2 24 0 S +R Z 1990 o - Mar 24 24 1 D +R Z 1990 o - Au 25 24 0 S +R Z 1991 o - Mar 23 24 1 D +R Z 1991 o - Au 31 24 0 S +R Z 1992 o - Mar 28 24 1 D +R Z 1992 o - S 5 24 0 S +R Z 1993 o - Ap 2 0 1 D +R Z 1993 o - S 5 0 0 S +R Z 1994 o - Ap 1 0 1 D +R Z 1994 o - Au 28 0 0 S +R Z 1995 o - Mar 31 0 1 D +R Z 1995 o - S 3 0 0 S +R Z 1996 o - Mar 14 24 1 D +R Z 1996 o - S 15 24 0 S +R Z 1997 o - Mar 20 24 1 D +R Z 1997 o - S 13 24 0 S +R Z 1998 o - Mar 20 0 1 D +R Z 1998 o - S 6 0 0 S +R Z 1999 o - Ap 2 2 1 D +R Z 1999 o - S 3 2 0 S +R Z 2000 o - Ap 14 2 1 D +R Z 2000 o - O 6 1 0 S +R Z 2001 o - Ap 9 1 1 D +R Z 2001 o - S 24 1 0 S +R Z 2002 o - Mar 29 1 1 D +R Z 2002 o - O 7 1 0 S +R Z 2003 o - Mar 28 1 1 D +R Z 2003 o - O 3 1 0 S +R Z 2004 o - Ap 7 1 1 D +R Z 2004 o - S 22 1 0 S +R Z 2005 2012 - Ap F<=1 2 1 D +R Z 2005 o - O 9 2 0 S +R Z 2006 o - O 1 2 0 S +R Z 2007 o - S 16 2 0 S +R Z 2008 o - O 5 2 0 S +R Z 2009 o - S 27 2 0 S +R Z 2010 o - S 12 2 0 S +R Z 2011 o - O 2 2 0 S +R Z 2012 o - S 23 2 0 S +R Z 2013 ma - Mar F>=23 2 1 D +R Z 2013 ma - O lastSu 2 0 S +Z Asia/Jerusalem 2:20:54 - LMT 1880 +2:20:40 - JMT 1918 +2 Z I%sT +R JP 1948 o - May Sa>=1 24 1 D +R JP 1948 1951 - S Sa>=8 25 0 S +R JP 1949 o - Ap Sa>=1 24 1 D +R JP 1950 1951 - May Sa>=1 24 1 D +Z Asia/Tokyo 9:18:59 - LMT 1887 D 31 15u +9 JP J%sT +R J 1973 o - Jun 6 0 1 S +R J 1973 1975 - O 1 0 0 - +R J 1974 1977 - May 1 0 1 S +R J 1976 o - N 1 0 0 - +R J 1977 o - O 1 0 0 - +R J 1978 o - Ap 30 0 1 S +R J 1978 o - S 30 0 0 - +R J 1985 o - Ap 1 0 1 S +R J 1985 o - O 1 0 0 - +R J 1986 1988 - Ap F>=1 0 1 S +R J 1986 1990 - O F>=1 0 0 - +R J 1989 o - May 8 0 1 S +R J 1990 o - Ap 27 0 1 S +R J 1991 o - Ap 17 0 1 S +R J 1991 o - S 27 0 0 - +R J 1992 o - Ap 10 0 1 S +R J 1992 1993 - O F>=1 0 0 - +R J 1993 1998 - Ap F>=1 0 1 S +R J 1994 o - S F>=15 0 0 - +R J 1995 1998 - S F>=15 0s 0 - +R J 1999 o - Jul 1 0s 1 S +R J 1999 2002 - S lastF 0s 0 - +R J 2000 2001 - Mar lastTh 0s 1 S +R J 2002 2012 - Mar lastTh 24 1 S +R J 2003 o - O 24 0s 0 - +R J 2004 o - O 15 0s 0 - +R J 2005 o - S lastF 0s 0 - +R J 2006 2011 - O lastF 0s 0 - +R J 2013 o - D 20 0 0 - +R J 2014 2021 - Mar lastTh 24 1 S +R J 2014 2022 - O lastF 0s 0 - +R J 2022 o - F lastTh 24 1 S +Z Asia/Amman 2:23:44 - LMT 1931 +2 J EE%sT 2022 O 28 0s +3 - +03 +Z Asia/Almaty 5:7:48 - LMT 1924 May 2 +5 - +05 1930 Jun 21 +6 R +06/+07 1991 Mar 31 2s +5 R +05/+06 1992 Ja 19 2s +6 R +06/+07 2004 O 31 2s +6 - +06 +Z Asia/Qyzylorda 4:21:52 - LMT 1924 May 2 +4 - +04 1930 Jun 21 +5 - +05 1981 Ap +5 1 +06 1981 O +6 - +06 1982 Ap +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1991 S 29 2s +5 R +05/+06 1992 Ja 19 2s +6 R +06/+07 1992 Mar 29 2s +5 R +05/+06 2004 O 31 2s +6 - +06 2018 D 21 +5 - +05 +Z Asia/Qostanay 4:14:28 - LMT 1924 May 2 +4 - +04 1930 Jun 21 +5 - +05 1981 Ap +5 1 +06 1981 O +6 - +06 1982 Ap +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 2004 O 31 2s +6 - +06 +Z Asia/Aqtobe 3:48:40 - LMT 1924 May 2 +4 - +04 1930 Jun 21 +5 - +05 1981 Ap +5 1 +06 1981 O +6 - +06 1982 Ap +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 2004 O 31 2s +5 - +05 +Z Asia/Aqtau 3:21:4 - LMT 1924 May 2 +4 - +04 1930 Jun 21 +5 - +05 1981 O +6 - +06 1982 Ap +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 1994 S 25 2s +4 R +04/+05 2004 O 31 2s +5 - +05 +Z Asia/Atyrau 3:27:44 - LMT 1924 May 2 +3 - +03 1930 Jun 21 +5 - +05 1981 O +6 - +06 1982 Ap +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 1999 Mar 28 2s +4 R +04/+05 2004 O 31 2s +5 - +05 +Z Asia/Oral 3:25:24 - LMT 1924 May 2 +3 - +03 1930 Jun 21 +5 - +05 1981 Ap +5 1 +06 1981 O +6 - +06 1982 Ap +5 R +05/+06 1989 Mar 26 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 1992 Mar 29 2s +4 R +04/+05 2004 O 31 2s +5 - +05 +R KG 1992 1996 - Ap Su>=7 0s 1 - +R KG 1992 1996 - S lastSu 0 0 - +R KG 1997 2005 - Mar lastSu 2:30 1 - +R KG 1997 2004 - O lastSu 2:30 0 - +Z Asia/Bishkek 4:58:24 - LMT 1924 May 2 +5 - +05 1930 Jun 21 +6 R +06/+07 1991 Mar 31 2s +5 R +05/+06 1991 Au 31 2 +5 KG +05/+06 2005 Au 12 +6 - +06 +R KR 1948 o - Jun 1 0 1 D +R KR 1948 o - S 12 24 0 S +R KR 1949 o - Ap 3 0 1 D +R KR 1949 1951 - S Sa>=7 24 0 S +R KR 1950 o - Ap 1 0 1 D +R KR 1951 o - May 6 0 1 D +R KR 1955 o - May 5 0 1 D +R KR 1955 o - S 8 24 0 S +R KR 1956 o - May 20 0 1 D +R KR 1956 o - S 29 24 0 S +R KR 1957 1960 - May Su>=1 0 1 D +R KR 1957 1960 - S Sa>=17 24 0 S +R KR 1987 1988 - May Su>=8 2 1 D +R KR 1987 1988 - O Su>=8 3 0 S +Z Asia/Seoul 8:27:52 - LMT 1908 Ap +8:30 - KST 1912 +9 - JST 1945 S 8 +9 KR K%sT 1954 Mar 21 +8:30 KR K%sT 1961 Au 10 +9 KR K%sT +Z Asia/Pyongyang 8:23 - LMT 1908 Ap +8:30 - KST 1912 +9 - JST 1945 Au 24 +9 - KST 2015 Au 15 +8:30 - KST 2018 May 4 23:30 +9 - KST +R l 1920 o - Mar 28 0 1 S +R l 1920 o - O 25 0 0 - +R l 1921 o - Ap 3 0 1 S +R l 1921 o - O 3 0 0 - +R l 1922 o - Mar 26 0 1 S +R l 1922 o - O 8 0 0 - +R l 1923 o - Ap 22 0 1 S +R l 1923 o - S 16 0 0 - +R l 1957 1961 - May 1 0 1 S +R l 1957 1961 - O 1 0 0 - +R l 1972 o - Jun 22 0 1 S +R l 1972 1977 - O 1 0 0 - +R l 1973 1977 - May 1 0 1 S +R l 1978 o - Ap 30 0 1 S +R l 1978 o - S 30 0 0 - +R l 1984 1987 - May 1 0 1 S +R l 1984 1991 - O 16 0 0 - +R l 1988 o - Jun 1 0 1 S +R l 1989 o - May 10 0 1 S +R l 1990 1992 - May 1 0 1 S +R l 1992 o - O 4 0 0 - +R l 1993 ma - Mar lastSu 0 1 S +R l 1993 1998 - S lastSu 0 0 - +R l 1999 ma - O lastSu 0 0 - +Z Asia/Beirut 2:22 - LMT 1880 +2 l EE%sT +R NB 1935 1941 - S 14 0 0:20 - +R NB 1935 1941 - D 14 0 0 - +Z Asia/Kuching 7:21:20 - LMT 1926 Mar +7:30 - +0730 1933 +8 NB +08/+0820 1942 F 16 +9 - +09 1945 S 12 +8 - +08 +Z Indian/Maldives 4:54 - LMT 1880 +4:54 - MMT 1960 +5 - +05 +R X 1983 1984 - Ap 1 0 1 - +R X 1983 o - O 1 0 0 - +R X 1985 1998 - Mar lastSu 0 1 - +R X 1984 1998 - S lastSu 0 0 - +R X 2001 o - Ap lastSa 2 1 - +R X 2001 2006 - S lastSa 2 0 - +R X 2002 2006 - Mar lastSa 2 1 - +R X 2015 2016 - Mar lastSa 2 1 - +R X 2015 2016 - S lastSa 0 0 - +Z Asia/Hovd 6:6:36 - LMT 1905 Au +6 - +06 1978 +7 X +07/+08 +Z Asia/Ulaanbaatar 7:7:32 - LMT 1905 Au +7 - +07 1978 +8 X +08/+09 +Z Asia/Choibalsan 7:38 - LMT 1905 Au +7 - +07 1978 +8 - +08 1983 Ap +9 X +09/+10 2008 Mar 31 +8 X +08/+09 +Z Asia/Kathmandu 5:41:16 - LMT 1920 +5:30 - +0530 1986 +5:45 - +0545 +R PK 2002 o - Ap Su>=2 0 1 S +R PK 2002 o - O Su>=2 0 0 - +R PK 2008 o - Jun 1 0 1 S +R PK 2008 2009 - N 1 0 0 - +R PK 2009 o - Ap 15 0 1 S +Z Asia/Karachi 4:28:12 - LMT 1907 +5:30 - +0530 1942 S +5:30 1 +0630 1945 O 15 +5:30 - +0530 1951 S 30 +5 - +05 1971 Mar 26 +5 PK PK%sT +R P 1999 2005 - Ap F>=15 0 1 S +R P 1999 2003 - O F>=15 0 0 - +R P 2004 o - O 1 1 0 - +R P 2005 o - O 4 2 0 - +R P 2006 2007 - Ap 1 0 1 S +R P 2006 o - S 22 0 0 - +R P 2007 o - S 13 2 0 - +R P 2008 2009 - Mar lastF 0 1 S +R P 2008 o - S 1 0 0 - +R P 2009 o - S 4 1 0 - +R P 2010 o - Mar 26 0 1 S +R P 2010 o - Au 11 0 0 - +R P 2011 o - Ap 1 0:1 1 S +R P 2011 o - Au 1 0 0 - +R P 2011 o - Au 30 0 1 S +R P 2011 o - S 30 0 0 - +R P 2012 2014 - Mar lastTh 24 1 S +R P 2012 o - S 21 1 0 - +R P 2013 o - S 27 0 0 - +R P 2014 o - O 24 0 0 - +R P 2015 o - Mar 28 0 1 S +R P 2015 o - O 23 1 0 - +R P 2016 2018 - Mar Sa<=30 1 1 S +R P 2016 2018 - O Sa<=30 1 0 - +R P 2019 o - Mar 29 0 1 S +R P 2019 o - O Sa<=30 0 0 - +R P 2020 2021 - Mar Sa<=30 0 1 S +R P 2020 o - O 24 1 0 - +R P 2021 o - O 29 1 0 - +R P 2022 o - Mar 27 0 1 S +R P 2022 2035 - O Sa<=30 2 0 - +R P 2023 o - Ap 29 2 1 S +R P 2024 o - Ap 13 2 1 S +R P 2025 o - Ap 5 2 1 S +R P 2026 2054 - Mar Sa<=30 2 1 S +R P 2036 o - O 18 2 0 - +R P 2037 o - O 10 2 0 - +R P 2038 o - S 25 2 0 - +R P 2039 o - S 17 2 0 - +R P 2039 o - O 22 2 1 S +R P 2039 2067 - O Sa<=30 2 0 - +R P 2040 o - S 1 2 0 - +R P 2040 o - O 13 2 1 S +R P 2041 o - Au 24 2 0 - +R P 2041 o - S 28 2 1 S +R P 2042 o - Au 16 2 0 - +R P 2042 o - S 20 2 1 S +R P 2043 o - Au 1 2 0 - +R P 2043 o - S 12 2 1 S +R P 2044 o - Jul 23 2 0 - +R P 2044 o - Au 27 2 1 S +R P 2045 o - Jul 15 2 0 - +R P 2045 o - Au 19 2 1 S +R P 2046 o - Jun 30 2 0 - +R P 2046 o - Au 11 2 1 S +R P 2047 o - Jun 22 2 0 - +R P 2047 o - Jul 27 2 1 S +R P 2048 o - Jun 6 2 0 - +R P 2048 o - Jul 18 2 1 S +R P 2049 o - May 29 2 0 - +R P 2049 o - Jul 3 2 1 S +R P 2050 o - May 21 2 0 - +R P 2050 o - Jun 25 2 1 S +R P 2051 o - May 6 2 0 - +R P 2051 o - Jun 17 2 1 S +R P 2052 o - Ap 27 2 0 - +R P 2052 o - Jun 1 2 1 S +R P 2053 o - Ap 12 2 0 - +R P 2053 o - May 24 2 1 S +R P 2054 o - Ap 4 2 0 - +R P 2054 o - May 16 2 1 S +R P 2055 o - May 1 2 1 S +R P 2056 o - Ap 22 2 1 S +R P 2057 o - Ap 7 2 1 S +R P 2058 ma - Mar Sa<=30 2 1 S +R P 2068 o - O 20 2 0 - +R P 2069 o - O 12 2 0 - +R P 2070 o - O 4 2 0 - +R P 2071 o - S 19 2 0 - +R P 2072 o - S 10 2 0 - +R P 2072 o - O 15 2 1 S +R P 2072 ma - O Sa<=30 2 0 - +R P 2073 o - S 2 2 0 - +R P 2073 o - O 7 2 1 S +R P 2074 o - Au 18 2 0 - +R P 2074 o - S 29 2 1 S +R P 2075 o - Au 10 2 0 - +R P 2075 o - S 14 2 1 S +R P 2076 o - Jul 25 2 0 - +R P 2076 o - S 5 2 1 S +R P 2077 o - Jul 17 2 0 - +R P 2077 o - Au 28 2 1 S +R P 2078 o - Jul 9 2 0 - +R P 2078 o - Au 13 2 1 S +R P 2079 o - Jun 24 2 0 - +R P 2079 o - Au 5 2 1 S +R P 2080 o - Jun 15 2 0 - +R P 2080 o - Jul 20 2 1 S +R P 2081 o - Jun 7 2 0 - +R P 2081 o - Jul 12 2 1 S +R P 2082 o - May 23 2 0 - +R P 2082 o - Jul 4 2 1 S +R P 2083 o - May 15 2 0 - +R P 2083 o - Jun 19 2 1 S +R P 2084 o - Ap 29 2 0 - +R P 2084 o - Jun 10 2 1 S +R P 2085 o - Ap 21 2 0 - +R P 2085 o - Jun 2 2 1 S +R P 2086 o - Ap 13 2 0 - +R P 2086 o - May 18 2 1 S +Z Asia/Gaza 2:17:52 - LMT 1900 O +2 Z EET/EEST 1948 May 15 +2 K EE%sT 1967 Jun 5 +2 Z I%sT 1996 +2 J EE%sT 1999 +2 P EE%sT 2008 Au 29 +2 - EET 2008 S +2 P EE%sT 2010 +2 - EET 2010 Mar 27 0:1 +2 P EE%sT 2011 Au +2 - EET 2012 +2 P EE%sT +Z Asia/Hebron 2:20:23 - LMT 1900 O +2 Z EET/EEST 1948 May 15 +2 K EE%sT 1967 Jun 5 +2 Z I%sT 1996 +2 J EE%sT 1999 +2 P EE%sT +R PH 1936 o - N 1 0 1 D +R PH 1937 o - F 1 0 0 S +R PH 1954 o - Ap 12 0 1 D +R PH 1954 o - Jul 1 0 0 S +R PH 1978 o - Mar 22 0 1 D +R PH 1978 o - S 21 0 0 S +Z Asia/Manila -15:56 - LMT 1844 D 31 +8:4 - LMT 1899 May 11 +8 PH P%sT 1942 May +9 - JST 1944 N +8 PH P%sT +Z Asia/Qatar 3:26:8 - LMT 1920 +4 - +04 1972 Jun +3 - +03 +Z Asia/Riyadh 3:6:52 - LMT 1947 Mar 14 +3 - +03 +Z Asia/Singapore 6:55:25 - LMT 1901 +6:55:25 - SMT 1905 Jun +7 - +07 1933 +7 0:20 +0720 1936 +7:20 - +0720 1941 S +7:30 - +0730 1942 F 16 +9 - +09 1945 S 12 +7:30 - +0730 1981 D 31 16u +8 - +08 +Z Asia/Colombo 5:19:24 - LMT 1880 +5:19:32 - MMT 1906 +5:30 - +0530 1942 Ja 5 +5:30 0:30 +06 1942 S +5:30 1 +0630 1945 O 16 2 +5:30 - +0530 1996 May 25 +6:30 - +0630 1996 O 26 0:30 +6 - +06 2006 Ap 15 0:30 +5:30 - +0530 +R S 1920 1923 - Ap Su>=15 2 1 S +R S 1920 1923 - O Su>=1 2 0 - +R S 1962 o - Ap 29 2 1 S +R S 1962 o - O 1 2 0 - +R S 1963 1965 - May 1 2 1 S +R S 1963 o - S 30 2 0 - +R S 1964 o - O 1 2 0 - +R S 1965 o - S 30 2 0 - +R S 1966 o - Ap 24 2 1 S +R S 1966 1976 - O 1 2 0 - +R S 1967 1978 - May 1 2 1 S +R S 1977 1978 - S 1 2 0 - +R S 1983 1984 - Ap 9 2 1 S +R S 1983 1984 - O 1 2 0 - +R S 1986 o - F 16 2 1 S +R S 1986 o - O 9 2 0 - +R S 1987 o - Mar 1 2 1 S +R S 1987 1988 - O 31 2 0 - +R S 1988 o - Mar 15 2 1 S +R S 1989 o - Mar 31 2 1 S +R S 1989 o - O 1 2 0 - +R S 1990 o - Ap 1 2 1 S +R S 1990 o - S 30 2 0 - +R S 1991 o - Ap 1 0 1 S +R S 1991 1992 - O 1 0 0 - +R S 1992 o - Ap 8 0 1 S +R S 1993 o - Mar 26 0 1 S +R S 1993 o - S 25 0 0 - +R S 1994 1996 - Ap 1 0 1 S +R S 1994 2005 - O 1 0 0 - +R S 1997 1998 - Mar lastM 0 1 S +R S 1999 2006 - Ap 1 0 1 S +R S 2006 o - S 22 0 0 - +R S 2007 o - Mar lastF 0 1 S +R S 2007 o - N F>=1 0 0 - +R S 2008 o - Ap F>=1 0 1 S +R S 2008 o - N 1 0 0 - +R S 2009 o - Mar lastF 0 1 S +R S 2010 2011 - Ap F>=1 0 1 S +R S 2012 2022 - Mar lastF 0 1 S +R S 2009 2022 - O lastF 0 0 - +Z Asia/Damascus 2:25:12 - LMT 1920 +2 S EE%sT 2022 O 28 +3 - +03 +Z Asia/Dushanbe 4:35:12 - LMT 1924 May 2 +5 - +05 1930 Jun 21 +6 R +06/+07 1991 Mar 31 2s +5 1 +06 1991 S 9 2s +5 - +05 +Z Asia/Bangkok 6:42:4 - LMT 1880 +6:42:4 - BMT 1920 Ap +7 - +07 +Z Asia/Ashgabat 3:53:32 - LMT 1924 May 2 +4 - +04 1930 Jun 21 +5 R +05/+06 1991 Mar 31 2 +4 R +04/+05 1992 Ja 19 2 +5 - +05 +Z Asia/Dubai 3:41:12 - LMT 1920 +4 - +04 +Z Asia/Samarkand 4:27:53 - LMT 1924 May 2 +4 - +04 1930 Jun 21 +5 - +05 1981 Ap +5 1 +06 1981 O +6 - +06 1982 Ap +5 R +05/+06 1992 +5 - +05 +Z Asia/Tashkent 4:37:11 - LMT 1924 May 2 +5 - +05 1930 Jun 21 +6 R +06/+07 1991 Mar 31 2 +5 R +05/+06 1992 +5 - +05 +Z Asia/Ho_Chi_Minh 7:6:30 - LMT 1906 Jul +7:6:30 - PLMT 1911 May +7 - +07 1942 D 31 23 +8 - +08 1945 Mar 14 23 +9 - +09 1945 S 2 +7 - +07 1947 Ap +8 - +08 1955 Jul +7 - +07 1959 D 31 23 +8 - +08 1975 Jun 13 +7 - +07 +R AU 1917 o - Ja 1 2s 1 D +R AU 1917 o - Mar lastSu 2s 0 S +R AU 1942 o - Ja 1 2s 1 D +R AU 1942 o - Mar lastSu 2s 0 S +R AU 1942 o - S 27 2s 1 D +R AU 1943 1944 - Mar lastSu 2s 0 S +R AU 1943 o - O 3 2s 1 D +Z Australia/Darwin 8:43:20 - LMT 1895 F +9 - ACST 1899 May +9:30 AU AC%sT +R AW 1974 o - O lastSu 2s 1 D +R AW 1975 o - Mar Su>=1 2s 0 S +R AW 1983 o - O lastSu 2s 1 D +R AW 1984 o - Mar Su>=1 2s 0 S +R AW 1991 o - N 17 2s 1 D +R AW 1992 o - Mar Su>=1 2s 0 S +R AW 2006 o - D 3 2s 1 D +R AW 2007 2009 - Mar lastSu 2s 0 S +R AW 2007 2008 - O lastSu 2s 1 D +Z Australia/Perth 7:43:24 - LMT 1895 D +8 AU AW%sT 1943 Jul +8 AW AW%sT +Z Australia/Eucla 8:35:28 - LMT 1895 D +8:45 AU +0845/+0945 1943 Jul +8:45 AW +0845/+0945 +R AQ 1971 o - O lastSu 2s 1 D +R AQ 1972 o - F lastSu 2s 0 S +R AQ 1989 1991 - O lastSu 2s 1 D +R AQ 1990 1992 - Mar Su>=1 2s 0 S +R Ho 1992 1993 - O lastSu 2s 1 D +R Ho 1993 1994 - Mar Su>=1 2s 0 S +Z Australia/Brisbane 10:12:8 - LMT 1895 +10 AU AE%sT 1971 +10 AQ AE%sT +Z Australia/Lindeman 9:55:56 - LMT 1895 +10 AU AE%sT 1971 +10 AQ AE%sT 1992 Jul +10 Ho AE%sT +R AS 1971 1985 - O lastSu 2s 1 D +R AS 1986 o - O 19 2s 1 D +R AS 1987 2007 - O lastSu 2s 1 D +R AS 1972 o - F 27 2s 0 S +R AS 1973 1985 - Mar Su>=1 2s 0 S +R AS 1986 1990 - Mar Su>=15 2s 0 S +R AS 1991 o - Mar 3 2s 0 S +R AS 1992 o - Mar 22 2s 0 S +R AS 1993 o - Mar 7 2s 0 S +R AS 1994 o - Mar 20 2s 0 S +R AS 1995 2005 - Mar lastSu 2s 0 S +R AS 2006 o - Ap 2 2s 0 S +R AS 2007 o - Mar lastSu 2s 0 S +R AS 2008 ma - Ap Su>=1 2s 0 S +R AS 2008 ma - O Su>=1 2s 1 D +Z Australia/Adelaide 9:14:20 - LMT 1895 F +9 - ACST 1899 May +9:30 AU AC%sT 1971 +9:30 AS AC%sT +R AT 1916 o - O Su>=1 2s 1 D +R AT 1917 o - Mar lastSu 2s 0 S +R AT 1917 1918 - O Su>=22 2s 1 D +R AT 1918 1919 - Mar Su>=1 2s 0 S +R AT 1967 o - O Su>=1 2s 1 D +R AT 1968 o - Mar Su>=29 2s 0 S +R AT 1968 1985 - O lastSu 2s 1 D +R AT 1969 1971 - Mar Su>=8 2s 0 S +R AT 1972 o - F lastSu 2s 0 S +R AT 1973 1981 - Mar Su>=1 2s 0 S +R AT 1982 1983 - Mar lastSu 2s 0 S +R AT 1984 1986 - Mar Su>=1 2s 0 S +R AT 1986 o - O Su>=15 2s 1 D +R AT 1987 1990 - Mar Su>=15 2s 0 S +R AT 1987 o - O Su>=22 2s 1 D +R AT 1988 1990 - O lastSu 2s 1 D +R AT 1991 1999 - O Su>=1 2s 1 D +R AT 1991 2005 - Mar lastSu 2s 0 S +R AT 2000 o - Au lastSu 2s 1 D +R AT 2001 ma - O Su>=1 2s 1 D +R AT 2006 o - Ap Su>=1 2s 0 S +R AT 2007 o - Mar lastSu 2s 0 S +R AT 2008 ma - Ap Su>=1 2s 0 S +Z Australia/Hobart 9:49:16 - LMT 1895 S +10 AT AE%sT 1919 O 24 +10 AU AE%sT 1967 +10 AT AE%sT +R AV 1971 1985 - O lastSu 2s 1 D +R AV 1972 o - F lastSu 2s 0 S +R AV 1973 1985 - Mar Su>=1 2s 0 S +R AV 1986 1990 - Mar Su>=15 2s 0 S +R AV 1986 1987 - O Su>=15 2s 1 D +R AV 1988 1999 - O lastSu 2s 1 D +R AV 1991 1994 - Mar Su>=1 2s 0 S +R AV 1995 2005 - Mar lastSu 2s 0 S +R AV 2000 o - Au lastSu 2s 1 D +R AV 2001 2007 - O lastSu 2s 1 D +R AV 2006 o - Ap Su>=1 2s 0 S +R AV 2007 o - Mar lastSu 2s 0 S +R AV 2008 ma - Ap Su>=1 2s 0 S +R AV 2008 ma - O Su>=1 2s 1 D +Z Australia/Melbourne 9:39:52 - LMT 1895 F +10 AU AE%sT 1971 +10 AV AE%sT +R AN 1971 1985 - O lastSu 2s 1 D +R AN 1972 o - F 27 2s 0 S +R AN 1973 1981 - Mar Su>=1 2s 0 S +R AN 1982 o - Ap Su>=1 2s 0 S +R AN 1983 1985 - Mar Su>=1 2s 0 S +R AN 1986 1989 - Mar Su>=15 2s 0 S +R AN 1986 o - O 19 2s 1 D +R AN 1987 1999 - O lastSu 2s 1 D +R AN 1990 1995 - Mar Su>=1 2s 0 S +R AN 1996 2005 - Mar lastSu 2s 0 S +R AN 2000 o - Au lastSu 2s 1 D +R AN 2001 2007 - O lastSu 2s 1 D +R AN 2006 o - Ap Su>=1 2s 0 S +R AN 2007 o - Mar lastSu 2s 0 S +R AN 2008 ma - Ap Su>=1 2s 0 S +R AN 2008 ma - O Su>=1 2s 1 D +Z Australia/Sydney 10:4:52 - LMT 1895 F +10 AU AE%sT 1971 +10 AN AE%sT +Z Australia/Broken_Hill 9:25:48 - LMT 1895 F +10 - AEST 1896 Au 23 +9 - ACST 1899 May +9:30 AU AC%sT 1971 +9:30 AN AC%sT 2000 +9:30 AS AC%sT +R LH 1981 1984 - O lastSu 2 1 - +R LH 1982 1985 - Mar Su>=1 2 0 - +R LH 1985 o - O lastSu 2 0:30 - +R LH 1986 1989 - Mar Su>=15 2 0 - +R LH 1986 o - O 19 2 0:30 - +R LH 1987 1999 - O lastSu 2 0:30 - +R LH 1990 1995 - Mar Su>=1 2 0 - +R LH 1996 2005 - Mar lastSu 2 0 - +R LH 2000 o - Au lastSu 2 0:30 - +R LH 2001 2007 - O lastSu 2 0:30 - +R LH 2006 o - Ap Su>=1 2 0 - +R LH 2007 o - Mar lastSu 2 0 - +R LH 2008 ma - Ap Su>=1 2 0 - +R LH 2008 ma - O Su>=1 2 0:30 - +Z Australia/Lord_Howe 10:36:20 - LMT 1895 F +10 - AEST 1981 Mar +10:30 LH +1030/+1130 1985 Jul +10:30 LH +1030/+11 +Z Antarctica/Macquarie 0 - -00 1899 N +10 - AEST 1916 O 1 2 +10 1 AEDT 1917 F +10 AU AE%sT 1919 Ap 1 0s +0 - -00 1948 Mar 25 +10 AU AE%sT 1967 +10 AT AE%sT 2010 +10 1 AEDT 2011 +10 AT AE%sT +R FJ 1998 1999 - N Su>=1 2 1 - +R FJ 1999 2000 - F lastSu 3 0 - +R FJ 2009 o - N 29 2 1 - +R FJ 2010 o - Mar lastSu 3 0 - +R FJ 2010 2013 - O Su>=21 2 1 - +R FJ 2011 o - Mar Su>=1 3 0 - +R FJ 2012 2013 - Ja Su>=18 3 0 - +R FJ 2014 o - Ja Su>=18 2 0 - +R FJ 2014 2018 - N Su>=1 2 1 - +R FJ 2015 2021 - Ja Su>=12 3 0 - +R FJ 2019 o - N Su>=8 2 1 - +R FJ 2020 o - D 20 2 1 - +Z Pacific/Fiji 11:55:44 - LMT 1915 O 26 +12 FJ +12/+13 +Z Pacific/Gambier -8:59:48 - LMT 1912 O +-9 - -09 +Z Pacific/Marquesas -9:18 - LMT 1912 O +-9:30 - -0930 +Z Pacific/Tahiti -9:58:16 - LMT 1912 O +-10 - -10 +R Gu 1959 o - Jun 27 2 1 D +R Gu 1961 o - Ja 29 2 0 S +R Gu 1967 o - S 1 2 1 D +R Gu 1969 o - Ja 26 0:1 0 S +R Gu 1969 o - Jun 22 2 1 D +R Gu 1969 o - Au 31 2 0 S +R Gu 1970 1971 - Ap lastSu 2 1 D +R Gu 1970 1971 - S Su>=1 2 0 S +R Gu 1973 o - D 16 2 1 D +R Gu 1974 o - F 24 2 0 S +R Gu 1976 o - May 26 2 1 D +R Gu 1976 o - Au 22 2:1 0 S +R Gu 1977 o - Ap 24 2 1 D +R Gu 1977 o - Au 28 2 0 S +Z Pacific/Guam -14:21 - LMT 1844 D 31 +9:39 - LMT 1901 +10 - GST 1941 D 10 +9 - +09 1944 Jul 31 +10 Gu G%sT 2000 D 23 +10 - ChST +Z Pacific/Tarawa 11:32:4 - LMT 1901 +12 - +12 +Z Pacific/Kanton 0 - -00 1937 Au 31 +-12 - -12 1979 O +-11 - -11 1994 D 31 +13 - +13 +Z Pacific/Kiritimati -10:29:20 - LMT 1901 +-10:40 - -1040 1979 O +-10 - -10 1994 D 31 +14 - +14 +Z Pacific/Kwajalein 11:9:20 - LMT 1901 +11 - +11 1937 +10 - +10 1941 Ap +9 - +09 1944 F 6 +11 - +11 1969 O +-12 - -12 1993 Au 20 24 +12 - +12 +Z Pacific/Kosrae -13:8:4 - LMT 1844 D 31 +10:51:56 - LMT 1901 +11 - +11 1914 O +9 - +09 1919 F +11 - +11 1937 +10 - +10 1941 Ap +9 - +09 1945 Au +11 - +11 1969 O +12 - +12 1999 +11 - +11 +Z Pacific/Nauru 11:7:40 - LMT 1921 Ja 15 +11:30 - +1130 1942 Au 29 +9 - +09 1945 S 8 +11:30 - +1130 1979 F 10 2 +12 - +12 +R NC 1977 1978 - D Su>=1 0 1 - +R NC 1978 1979 - F 27 0 0 - +R NC 1996 o - D 1 2s 1 - +R NC 1997 o - Mar 2 2s 0 - +Z Pacific/Noumea 11:5:48 - LMT 1912 Ja 13 +11 NC +11/+12 +R NZ 1927 o - N 6 2 1 S +R NZ 1928 o - Mar 4 2 0 M +R NZ 1928 1933 - O Su>=8 2 0:30 S +R NZ 1929 1933 - Mar Su>=15 2 0 M +R NZ 1934 1940 - Ap lastSu 2 0 M +R NZ 1934 1940 - S lastSu 2 0:30 S +R NZ 1946 o - Ja 1 0 0 S +R NZ 1974 o - N Su>=1 2s 1 D +R k 1974 o - N Su>=1 2:45s 1 - +R NZ 1975 o - F lastSu 2s 0 S +R k 1975 o - F lastSu 2:45s 0 - +R NZ 1975 1988 - O lastSu 2s 1 D +R k 1975 1988 - O lastSu 2:45s 1 - +R NZ 1976 1989 - Mar Su>=1 2s 0 S +R k 1976 1989 - Mar Su>=1 2:45s 0 - +R NZ 1989 o - O Su>=8 2s 1 D +R k 1989 o - O Su>=8 2:45s 1 - +R NZ 1990 2006 - O Su>=1 2s 1 D +R k 1990 2006 - O Su>=1 2:45s 1 - +R NZ 1990 2007 - Mar Su>=15 2s 0 S +R k 1990 2007 - Mar Su>=15 2:45s 0 - +R NZ 2007 ma - S lastSu 2s 1 D +R k 2007 ma - S lastSu 2:45s 1 - +R NZ 2008 ma - Ap Su>=1 2s 0 S +R k 2008 ma - Ap Su>=1 2:45s 0 - +Z Pacific/Auckland 11:39:4 - LMT 1868 N 2 +11:30 NZ NZ%sT 1946 +12 NZ NZ%sT +Z Pacific/Chatham 12:13:48 - LMT 1868 N 2 +12:15 - +1215 1946 +12:45 k +1245/+1345 +R CK 1978 o - N 12 0 0:30 - +R CK 1979 1991 - Mar Su>=1 0 0 - +R CK 1979 1990 - O lastSu 0 0:30 - +Z Pacific/Rarotonga 13:20:56 - LMT 1899 D 26 +-10:39:4 - LMT 1952 O 16 +-10:30 - -1030 1978 N 12 +-10 CK -10/-0930 +Z Pacific/Niue -11:19:40 - LMT 1952 O 16 +-11:20 - -1120 1964 Jul +-11 - -11 +Z Pacific/Norfolk 11:11:52 - LMT 1901 +11:12 - +1112 1951 +11:30 - +1130 1974 O 27 2s +11:30 1 +1230 1975 Mar 2 2s +11:30 - +1130 2015 O 4 2s +11 - +11 2019 Jul +11 AN +11/+12 +Z Pacific/Palau -15:2:4 - LMT 1844 D 31 +8:57:56 - LMT 1901 +9 - +09 +Z Pacific/Port_Moresby 9:48:40 - LMT 1880 +9:48:32 - PMMT 1895 +10 - +10 +Z Pacific/Bougainville 10:22:16 - LMT 1880 +9:48:32 - PMMT 1895 +10 - +10 1942 Jul +9 - +09 1945 Au 21 +10 - +10 2014 D 28 2 +11 - +11 +Z Pacific/Pitcairn -8:40:20 - LMT 1901 +-8:30 - -0830 1998 Ap 27 +-8 - -08 +Z Pacific/Pago_Pago 12:37:12 - LMT 1892 Jul 5 +-11:22:48 - LMT 1911 +-11 - SST +R WS 2010 o - S lastSu 0 1 - +R WS 2011 o - Ap Sa>=1 4 0 - +R WS 2011 o - S lastSa 3 1 - +R WS 2012 2021 - Ap Su>=1 4 0 - +R WS 2012 2020 - S lastSu 3 1 - +Z Pacific/Apia 12:33:4 - LMT 1892 Jul 5 +-11:26:56 - LMT 1911 +-11:30 - -1130 1950 +-11 WS -11/-10 2011 D 29 24 +13 WS +13/+14 +Z Pacific/Guadalcanal 10:39:48 - LMT 1912 O +11 - +11 +Z Pacific/Fakaofo -11:24:56 - LMT 1901 +-11 - -11 2011 D 30 +13 - +13 +R TO 1999 o - O 7 2s 1 - +R TO 2000 o - Mar 19 2s 0 - +R TO 2000 2001 - N Su>=1 2 1 - +R TO 2001 2002 - Ja lastSu 2 0 - +R TO 2016 o - N Su>=1 2 1 - +R TO 2017 o - Ja Su>=15 3 0 - +Z Pacific/Tongatapu 12:19:12 - LMT 1945 S 10 +12:20 - +1220 1961 +13 - +13 1999 +13 TO +13/+14 +R VU 1973 o - D 22 12u 1 - +R VU 1974 o - Mar 30 12u 0 - +R VU 1983 1991 - S Sa>=22 24 1 - +R VU 1984 1991 - Mar Sa>=22 24 0 - +R VU 1992 1993 - Ja Sa>=22 24 0 - +R VU 1992 o - O Sa>=22 24 1 - +Z Pacific/Efate 11:13:16 - LMT 1912 Ja 13 +11 VU +11/+12 +R G 1916 o - May 21 2s 1 BST +R G 1916 o - O 1 2s 0 GMT +R G 1917 o - Ap 8 2s 1 BST +R G 1917 o - S 17 2s 0 GMT +R G 1918 o - Mar 24 2s 1 BST +R G 1918 o - S 30 2s 0 GMT +R G 1919 o - Mar 30 2s 1 BST +R G 1919 o - S 29 2s 0 GMT +R G 1920 o - Mar 28 2s 1 BST +R G 1920 o - O 25 2s 0 GMT +R G 1921 o - Ap 3 2s 1 BST +R G 1921 o - O 3 2s 0 GMT +R G 1922 o - Mar 26 2s 1 BST +R G 1922 o - O 8 2s 0 GMT +R G 1923 o - Ap Su>=16 2s 1 BST +R G 1923 1924 - S Su>=16 2s 0 GMT +R G 1924 o - Ap Su>=9 2s 1 BST +R G 1925 1926 - Ap Su>=16 2s 1 BST +R G 1925 1938 - O Su>=2 2s 0 GMT +R G 1927 o - Ap Su>=9 2s 1 BST +R G 1928 1929 - Ap Su>=16 2s 1 BST +R G 1930 o - Ap Su>=9 2s 1 BST +R G 1931 1932 - Ap Su>=16 2s 1 BST +R G 1933 o - Ap Su>=9 2s 1 BST +R G 1934 o - Ap Su>=16 2s 1 BST +R G 1935 o - Ap Su>=9 2s 1 BST +R G 1936 1937 - Ap Su>=16 2s 1 BST +R G 1938 o - Ap Su>=9 2s 1 BST +R G 1939 o - Ap Su>=16 2s 1 BST +R G 1939 o - N Su>=16 2s 0 GMT +R G 1940 o - F Su>=23 2s 1 BST +R G 1941 o - May Su>=2 1s 2 BDST +R G 1941 1943 - Au Su>=9 1s 1 BST +R G 1942 1944 - Ap Su>=2 1s 2 BDST +R G 1944 o - S Su>=16 1s 1 BST +R G 1945 o - Ap M>=2 1s 2 BDST +R G 1945 o - Jul Su>=9 1s 1 BST +R G 1945 1946 - O Su>=2 2s 0 GMT +R G 1946 o - Ap Su>=9 2s 1 BST +R G 1947 o - Mar 16 2s 1 BST +R G 1947 o - Ap 13 1s 2 BDST +R G 1947 o - Au 10 1s 1 BST +R G 1947 o - N 2 2s 0 GMT +R G 1948 o - Mar 14 2s 1 BST +R G 1948 o - O 31 2s 0 GMT +R G 1949 o - Ap 3 2s 1 BST +R G 1949 o - O 30 2s 0 GMT +R G 1950 1952 - Ap Su>=14 2s 1 BST +R G 1950 1952 - O Su>=21 2s 0 GMT +R G 1953 o - Ap Su>=16 2s 1 BST +R G 1953 1960 - O Su>=2 2s 0 GMT +R G 1954 o - Ap Su>=9 2s 1 BST +R G 1955 1956 - Ap Su>=16 2s 1 BST +R G 1957 o - Ap Su>=9 2s 1 BST +R G 1958 1959 - Ap Su>=16 2s 1 BST +R G 1960 o - Ap Su>=9 2s 1 BST +R G 1961 1963 - Mar lastSu 2s 1 BST +R G 1961 1968 - O Su>=23 2s 0 GMT +R G 1964 1967 - Mar Su>=19 2s 1 BST +R G 1968 o - F 18 2s 1 BST +R G 1972 1980 - Mar Su>=16 2s 1 BST +R G 1972 1980 - O Su>=23 2s 0 GMT +R G 1981 1995 - Mar lastSu 1u 1 BST +R G 1981 1989 - O Su>=23 1u 0 GMT +R G 1990 1995 - O Su>=22 1u 0 GMT +Z Europe/London -0:1:15 - LMT 1847 D +0 G %s 1968 O 27 +1 - BST 1971 O 31 2u +0 G %s 1996 +0 E GMT/BST +R IE 1971 o - O 31 2u -1 - +R IE 1972 1980 - Mar Su>=16 2u 0 - +R IE 1972 1980 - O Su>=23 2u -1 - +R IE 1981 ma - Mar lastSu 1u 0 - +R IE 1981 1989 - O Su>=23 1u -1 - +R IE 1990 1995 - O Su>=22 1u -1 - +R IE 1996 ma - O lastSu 1u -1 - +Z Europe/Dublin -0:25:21 - LMT 1880 Au 2 +-0:25:21 - DMT 1916 May 21 2s +-0:25:21 1 IST 1916 O 1 2s +0 G %s 1921 D 6 +0 G GMT/IST 1940 F 25 2s +0 1 IST 1946 O 6 2s +0 - GMT 1947 Mar 16 2s +0 1 IST 1947 N 2 2s +0 - GMT 1948 Ap 18 2s +0 G GMT/IST 1968 O 27 +1 IE IST/GMT +R E 1977 1980 - Ap Su>=1 1u 1 S +R E 1977 o - S lastSu 1u 0 - +R E 1978 o - O 1 1u 0 - +R E 1979 1995 - S lastSu 1u 0 - +R E 1981 ma - Mar lastSu 1u 1 S +R E 1996 ma - O lastSu 1u 0 - +R W- 1977 1980 - Ap Su>=1 1s 1 S +R W- 1977 o - S lastSu 1s 0 - +R W- 1978 o - O 1 1s 0 - +R W- 1979 1995 - S lastSu 1s 0 - +R W- 1981 ma - Mar lastSu 1s 1 S +R W- 1996 ma - O lastSu 1s 0 - +R c 1916 o - Ap 30 23 1 S +R c 1916 o - O 1 1 0 - +R c 1917 1918 - Ap M>=15 2s 1 S +R c 1917 1918 - S M>=15 2s 0 - +R c 1940 o - Ap 1 2s 1 S +R c 1942 o - N 2 2s 0 - +R c 1943 o - Mar 29 2s 1 S +R c 1943 o - O 4 2s 0 - +R c 1944 1945 - Ap M>=1 2s 1 S +R c 1944 o - O 2 2s 0 - +R c 1945 o - S 16 2s 0 - +R c 1977 1980 - Ap Su>=1 2s 1 S +R c 1977 o - S lastSu 2s 0 - +R c 1978 o - O 1 2s 0 - +R c 1979 1995 - S lastSu 2s 0 - +R c 1981 ma - Mar lastSu 2s 1 S +R c 1996 ma - O lastSu 2s 0 - +R e 1977 1980 - Ap Su>=1 0 1 S +R e 1977 o - S lastSu 0 0 - +R e 1978 o - O 1 0 0 - +R e 1979 1995 - S lastSu 0 0 - +R e 1981 ma - Mar lastSu 0 1 S +R e 1996 ma - O lastSu 0 0 - +R R 1917 o - Jul 1 23 1 MST +R R 1917 o - D 28 0 0 MMT +R R 1918 o - May 31 22 2 MDST +R R 1918 o - S 16 1 1 MST +R R 1919 o - May 31 23 2 MDST +R R 1919 o - Jul 1 0u 1 MSD +R R 1919 o - Au 16 0 0 MSK +R R 1921 o - F 14 23 1 MSD +R R 1921 o - Mar 20 23 2 +05 +R R 1921 o - S 1 0 1 MSD +R R 1921 o - O 1 0 0 - +R R 1981 1984 - Ap 1 0 1 S +R R 1981 1983 - O 1 0 0 - +R R 1984 1995 - S lastSu 2s 0 - +R R 1985 2010 - Mar lastSu 2s 1 S +R R 1996 2010 - O lastSu 2s 0 - +Z WET 0 E WE%sT +Z CET 1 c CE%sT +Z MET 1 c ME%sT +Z EET 2 E EE%sT +R q 1940 o - Jun 16 0 1 S +R q 1942 o - N 2 3 0 - +R q 1943 o - Mar 29 2 1 S +R q 1943 o - Ap 10 3 0 - +R q 1974 o - May 4 0 1 S +R q 1974 o - O 2 0 0 - +R q 1975 o - May 1 0 1 S +R q 1975 o - O 2 0 0 - +R q 1976 o - May 2 0 1 S +R q 1976 o - O 3 0 0 - +R q 1977 o - May 8 0 1 S +R q 1977 o - O 2 0 0 - +R q 1978 o - May 6 0 1 S +R q 1978 o - O 1 0 0 - +R q 1979 o - May 5 0 1 S +R q 1979 o - S 30 0 0 - +R q 1980 o - May 3 0 1 S +R q 1980 o - O 4 0 0 - +R q 1981 o - Ap 26 0 1 S +R q 1981 o - S 27 0 0 - +R q 1982 o - May 2 0 1 S +R q 1982 o - O 3 0 0 - +R q 1983 o - Ap 18 0 1 S +R q 1983 o - O 1 0 0 - +R q 1984 o - Ap 1 0 1 S +Z Europe/Tirane 1:19:20 - LMT 1914 +1 - CET 1940 Jun 16 +1 q CE%sT 1984 Jul +1 E CE%sT +Z Europe/Andorra 0:6:4 - LMT 1901 +0 - WET 1946 S 30 +1 - CET 1985 Mar 31 2 +1 E CE%sT +R a 1920 o - Ap 5 2s 1 S +R a 1920 o - S 13 2s 0 - +R a 1946 o - Ap 14 2s 1 S +R a 1946 o - O 7 2s 0 - +R a 1947 1948 - O Su>=1 2s 0 - +R a 1947 o - Ap 6 2s 1 S +R a 1948 o - Ap 18 2s 1 S +R a 1980 o - Ap 6 0 1 S +R a 1980 o - S 28 0 0 - +Z Europe/Vienna 1:5:21 - LMT 1893 Ap +1 c CE%sT 1920 +1 a CE%sT 1940 Ap 1 2s +1 c CE%sT 1945 Ap 2 2s +1 1 CEST 1945 Ap 12 2s +1 - CET 1946 +1 a CE%sT 1981 +1 E CE%sT +Z Europe/Minsk 1:50:16 - LMT 1880 +1:50 - MMT 1924 May 2 +2 - EET 1930 Jun 21 +3 - MSK 1941 Jun 28 +1 c CE%sT 1944 Jul 3 +3 R MSK/MSD 1990 +3 - MSK 1991 Mar 31 2s +2 R EE%sT 2011 Mar 27 2s +3 - +03 +R b 1918 o - Mar 9 0s 1 S +R b 1918 1919 - O Sa>=1 23s 0 - +R b 1919 o - Mar 1 23s 1 S +R b 1920 o - F 14 23s 1 S +R b 1920 o - O 23 23s 0 - +R b 1921 o - Mar 14 23s 1 S +R b 1921 o - O 25 23s 0 - +R b 1922 o - Mar 25 23s 1 S +R b 1922 1927 - O Sa>=1 23s 0 - +R b 1923 o - Ap 21 23s 1 S +R b 1924 o - Mar 29 23s 1 S +R b 1925 o - Ap 4 23s 1 S +R b 1926 o - Ap 17 23s 1 S +R b 1927 o - Ap 9 23s 1 S +R b 1928 o - Ap 14 23s 1 S +R b 1928 1938 - O Su>=2 2s 0 - +R b 1929 o - Ap 21 2s 1 S +R b 1930 o - Ap 13 2s 1 S +R b 1931 o - Ap 19 2s 1 S +R b 1932 o - Ap 3 2s 1 S +R b 1933 o - Mar 26 2s 1 S +R b 1934 o - Ap 8 2s 1 S +R b 1935 o - Mar 31 2s 1 S +R b 1936 o - Ap 19 2s 1 S +R b 1937 o - Ap 4 2s 1 S +R b 1938 o - Mar 27 2s 1 S +R b 1939 o - Ap 16 2s 1 S +R b 1939 o - N 19 2s 0 - +R b 1940 o - F 25 2s 1 S +R b 1944 o - S 17 2s 0 - +R b 1945 o - Ap 2 2s 1 S +R b 1945 o - S 16 2s 0 - +R b 1946 o - May 19 2s 1 S +R b 1946 o - O 7 2s 0 - +Z Europe/Brussels 0:17:30 - LMT 1880 +0:17:30 - BMT 1892 May 1 0:17:30 +0 - WET 1914 N 8 +1 - CET 1916 May +1 c CE%sT 1918 N 11 11u +0 b WE%sT 1940 May 20 2s +1 c CE%sT 1944 S 3 +1 b CE%sT 1977 +1 E CE%sT +R BG 1979 o - Mar 31 23 1 S +R BG 1979 o - O 1 1 0 - +R BG 1980 1982 - Ap Sa>=1 23 1 S +R BG 1980 o - S 29 1 0 - +R BG 1981 o - S 27 2 0 - +Z Europe/Sofia 1:33:16 - LMT 1880 +1:56:56 - IMT 1894 N 30 +2 - EET 1942 N 2 3 +1 c CE%sT 1945 +1 - CET 1945 Ap 2 3 +2 - EET 1979 Mar 31 23 +2 BG EE%sT 1982 S 26 3 +2 c EE%sT 1991 +2 e EE%sT 1997 +2 E EE%sT +R CZ 1945 o - Ap M>=1 2s 1 S +R CZ 1945 o - O 1 2s 0 - +R CZ 1946 o - May 6 2s 1 S +R CZ 1946 1949 - O Su>=1 2s 0 - +R CZ 1947 1948 - Ap Su>=15 2s 1 S +R CZ 1949 o - Ap 9 2s 1 S +Z Europe/Prague 0:57:44 - LMT 1850 +0:57:44 - PMT 1891 O +1 c CE%sT 1945 May 9 +1 CZ CE%sT 1946 D 1 3 +1 -1 GMT 1947 F 23 2 +1 CZ CE%sT 1979 +1 E CE%sT +Z Atlantic/Faroe -0:27:4 - LMT 1908 Ja 11 +0 - WET 1981 +0 E WE%sT +R Th 1991 1992 - Mar lastSu 2 1 D +R Th 1991 1992 - S lastSu 2 0 S +R Th 1993 2006 - Ap Su>=1 2 1 D +R Th 1993 2006 - O lastSu 2 0 S +R Th 2007 ma - Mar Su>=8 2 1 D +R Th 2007 ma - N Su>=1 2 0 S +Z America/Danmarkshavn -1:14:40 - LMT 1916 Jul 28 +-3 - -03 1980 Ap 6 2 +-3 E -03/-02 1996 +0 - GMT +Z America/Scoresbysund -1:27:52 - LMT 1916 Jul 28 +-2 - -02 1980 Ap 6 2 +-2 c -02/-01 1981 Mar 29 +-1 E -01/+00 2024 Mar 31 +-2 E -02/-01 +Z America/Nuuk -3:26:56 - LMT 1916 Jul 28 +-3 - -03 1980 Ap 6 2 +-3 E -03/-02 2023 Mar 26 1u +-2 - -02 2023 O 29 1u +-2 E -02/-01 +Z America/Thule -4:35:8 - LMT 1916 Jul 28 +-4 Th A%sT +Z Europe/Tallinn 1:39 - LMT 1880 +1:39 - TMT 1918 F +1 c CE%sT 1919 Jul +1:39 - TMT 1921 May +2 - EET 1940 Au 6 +3 - MSK 1941 S 15 +1 c CE%sT 1944 S 22 +3 R MSK/MSD 1989 Mar 26 2s +2 1 EEST 1989 S 24 2s +2 c EE%sT 1998 S 22 +2 E EE%sT 1999 O 31 4 +2 - EET 2002 F 21 +2 E EE%sT +R FI 1942 o - Ap 2 24 1 S +R FI 1942 o - O 4 1 0 - +R FI 1981 1982 - Mar lastSu 2 1 S +R FI 1981 1982 - S lastSu 3 0 - +Z Europe/Helsinki 1:39:49 - LMT 1878 May 31 +1:39:49 - HMT 1921 May +2 FI EE%sT 1983 +2 E EE%sT +R F 1916 o - Jun 14 23s 1 S +R F 1916 1919 - O Su>=1 23s 0 - +R F 1917 o - Mar 24 23s 1 S +R F 1918 o - Mar 9 23s 1 S +R F 1919 o - Mar 1 23s 1 S +R F 1920 o - F 14 23s 1 S +R F 1920 o - O 23 23s 0 - +R F 1921 o - Mar 14 23s 1 S +R F 1921 o - O 25 23s 0 - +R F 1922 o - Mar 25 23s 1 S +R F 1922 1938 - O Sa>=1 23s 0 - +R F 1923 o - May 26 23s 1 S +R F 1924 o - Mar 29 23s 1 S +R F 1925 o - Ap 4 23s 1 S +R F 1926 o - Ap 17 23s 1 S +R F 1927 o - Ap 9 23s 1 S +R F 1928 o - Ap 14 23s 1 S +R F 1929 o - Ap 20 23s 1 S +R F 1930 o - Ap 12 23s 1 S +R F 1931 o - Ap 18 23s 1 S +R F 1932 o - Ap 2 23s 1 S +R F 1933 o - Mar 25 23s 1 S +R F 1934 o - Ap 7 23s 1 S +R F 1935 o - Mar 30 23s 1 S +R F 1936 o - Ap 18 23s 1 S +R F 1937 o - Ap 3 23s 1 S +R F 1938 o - Mar 26 23s 1 S +R F 1939 o - Ap 15 23s 1 S +R F 1939 o - N 18 23s 0 - +R F 1940 o - F 25 2 1 S +R F 1941 o - May 5 0 2 M +R F 1941 o - O 6 0 1 S +R F 1942 o - Mar 9 0 2 M +R F 1942 o - N 2 3 1 S +R F 1943 o - Mar 29 2 2 M +R F 1943 o - O 4 3 1 S +R F 1944 o - Ap 3 2 2 M +R F 1944 o - O 8 1 1 S +R F 1945 o - Ap 2 2 2 M +R F 1945 o - S 16 3 0 - +R F 1976 o - Mar 28 1 1 S +R F 1976 o - S 26 1 0 - +Z Europe/Paris 0:9:21 - LMT 1891 Mar 16 +0:9:21 - PMT 1911 Mar 11 +0 F WE%sT 1940 Jun 14 23 +1 c CE%sT 1944 Au 25 +0 F WE%sT 1945 S 16 3 +1 F CE%sT 1977 +1 E CE%sT +R DE 1946 o - Ap 14 2s 1 S +R DE 1946 o - O 7 2s 0 - +R DE 1947 1949 - O Su>=1 2s 0 - +R DE 1947 o - Ap 6 3s 1 S +R DE 1947 o - May 11 2s 2 M +R DE 1947 o - Jun 29 3 1 S +R DE 1948 o - Ap 18 2s 1 S +R DE 1949 o - Ap 10 2s 1 S +R So 1945 o - May 24 2 2 M +R So 1945 o - S 24 3 1 S +R So 1945 o - N 18 2s 0 - +Z Europe/Berlin 0:53:28 - LMT 1893 Ap +1 c CE%sT 1945 May 24 2 +1 So CE%sT 1946 +1 DE CE%sT 1980 +1 E CE%sT +Z Europe/Gibraltar -0:21:24 - LMT 1880 Au 2 +0 G %s 1957 Ap 14 2 +1 - CET 1982 +1 E CE%sT +R g 1932 o - Jul 7 0 1 S +R g 1932 o - S 1 0 0 - +R g 1941 o - Ap 7 0 1 S +R g 1942 o - N 2 3 0 - +R g 1943 o - Mar 30 0 1 S +R g 1943 o - O 4 0 0 - +R g 1952 o - Jul 1 0 1 S +R g 1952 o - N 2 0 0 - +R g 1975 o - Ap 12 0s 1 S +R g 1975 o - N 26 0s 0 - +R g 1976 o - Ap 11 2s 1 S +R g 1976 o - O 10 2s 0 - +R g 1977 1978 - Ap Su>=1 2s 1 S +R g 1977 o - S 26 2s 0 - +R g 1978 o - S 24 4 0 - +R g 1979 o - Ap 1 9 1 S +R g 1979 o - S 29 2 0 - +R g 1980 o - Ap 1 0 1 S +R g 1980 o - S 28 0 0 - +Z Europe/Athens 1:34:52 - LMT 1895 S 14 +1:34:52 - AMT 1916 Jul 28 0:1 +2 g EE%sT 1941 Ap 30 +1 g CE%sT 1944 Ap 4 +2 g EE%sT 1981 +2 E EE%sT +R h 1918 1919 - Ap 15 2 1 S +R h 1918 1920 - S M>=15 3 0 - +R h 1920 o - Ap 5 2 1 S +R h 1945 o - May 1 23 1 S +R h 1945 o - N 1 1 0 - +R h 1946 o - Mar 31 2s 1 S +R h 1946 o - O 7 2 0 - +R h 1947 1949 - Ap Su>=4 2s 1 S +R h 1947 1949 - O Su>=1 2s 0 - +R h 1954 o - May 23 0 1 S +R h 1954 o - O 3 0 0 - +R h 1955 o - May 22 2 1 S +R h 1955 o - O 2 3 0 - +R h 1956 1957 - Jun Su>=1 2 1 S +R h 1956 1957 - S lastSu 3 0 - +R h 1980 o - Ap 6 0 1 S +R h 1980 o - S 28 1 0 - +R h 1981 1983 - Mar lastSu 0 1 S +R h 1981 1983 - S lastSu 1 0 - +Z Europe/Budapest 1:16:20 - LMT 1890 N +1 c CE%sT 1918 +1 h CE%sT 1941 Ap 7 23 +1 c CE%sT 1945 +1 h CE%sT 1984 +1 E CE%sT +R I 1916 o - Jun 3 24 1 S +R I 1916 1917 - S 30 24 0 - +R I 1917 o - Mar 31 24 1 S +R I 1918 o - Mar 9 24 1 S +R I 1918 o - O 6 24 0 - +R I 1919 o - Mar 1 24 1 S +R I 1919 o - O 4 24 0 - +R I 1920 o - Mar 20 24 1 S +R I 1920 o - S 18 24 0 - +R I 1940 o - Jun 14 24 1 S +R I 1942 o - N 2 2s 0 - +R I 1943 o - Mar 29 2s 1 S +R I 1943 o - O 4 2s 0 - +R I 1944 o - Ap 2 2s 1 S +R I 1944 o - S 17 2s 0 - +R I 1945 o - Ap 2 2 1 S +R I 1945 o - S 15 1 0 - +R I 1946 o - Mar 17 2s 1 S +R I 1946 o - O 6 2s 0 - +R I 1947 o - Mar 16 0s 1 S +R I 1947 o - O 5 0s 0 - +R I 1948 o - F 29 2s 1 S +R I 1948 o - O 3 2s 0 - +R I 1966 1968 - May Su>=22 0s 1 S +R I 1966 o - S 24 24 0 - +R I 1967 1969 - S Su>=22 0s 0 - +R I 1969 o - Jun 1 0s 1 S +R I 1970 o - May 31 0s 1 S +R I 1970 o - S lastSu 0s 0 - +R I 1971 1972 - May Su>=22 0s 1 S +R I 1971 o - S lastSu 0s 0 - +R I 1972 o - O 1 0s 0 - +R I 1973 o - Jun 3 0s 1 S +R I 1973 1974 - S lastSu 0s 0 - +R I 1974 o - May 26 0s 1 S +R I 1975 o - Jun 1 0s 1 S +R I 1975 1977 - S lastSu 0s 0 - +R I 1976 o - May 30 0s 1 S +R I 1977 1979 - May Su>=22 0s 1 S +R I 1978 o - O 1 0s 0 - +R I 1979 o - S 30 0s 0 - +Z Europe/Rome 0:49:56 - LMT 1866 D 12 +0:49:56 - RMT 1893 O 31 23u +1 I CE%sT 1943 S 10 +1 c CE%sT 1944 Jun 4 +1 I CE%sT 1980 +1 E CE%sT +R LV 1989 1996 - Mar lastSu 2s 1 S +R LV 1989 1996 - S lastSu 2s 0 - +Z Europe/Riga 1:36:34 - LMT 1880 +1:36:34 - RMT 1918 Ap 15 2 +1:36:34 1 LST 1918 S 16 3 +1:36:34 - RMT 1919 Ap 1 2 +1:36:34 1 LST 1919 May 22 3 +1:36:34 - RMT 1926 May 11 +2 - EET 1940 Au 5 +3 - MSK 1941 Jul +1 c CE%sT 1944 O 13 +3 R MSK/MSD 1989 Mar lastSu 2s +2 1 EEST 1989 S lastSu 2s +2 LV EE%sT 1997 Ja 21 +2 E EE%sT 2000 F 29 +2 - EET 2001 Ja 2 +2 E EE%sT +Z Europe/Vilnius 1:41:16 - LMT 1880 +1:24 - WMT 1917 +1:35:36 - KMT 1919 O 10 +1 - CET 1920 Jul 12 +2 - EET 1920 O 9 +1 - CET 1940 Au 3 +3 - MSK 1941 Jun 24 +1 c CE%sT 1944 Au +3 R MSK/MSD 1989 Mar 26 2s +2 R EE%sT 1991 S 29 2s +2 c EE%sT 1998 +2 - EET 1998 Mar 29 1u +1 E CE%sT 1999 O 31 1u +2 - EET 2003 +2 E EE%sT +R MT 1973 o - Mar 31 0s 1 S +R MT 1973 o - S 29 0s 0 - +R MT 1974 o - Ap 21 0s 1 S +R MT 1974 o - S 16 0s 0 - +R MT 1975 1979 - Ap Su>=15 2 1 S +R MT 1975 1980 - S Su>=15 2 0 - +R MT 1980 o - Mar 31 2 1 S +Z Europe/Malta 0:58:4 - LMT 1893 N 2 +1 I CE%sT 1973 Mar 31 +1 MT CE%sT 1981 +1 E CE%sT +R MD 1997 ma - Mar lastSu 2 1 S +R MD 1997 ma - O lastSu 3 0 - +Z Europe/Chisinau 1:55:20 - LMT 1880 +1:55 - CMT 1918 F 15 +1:44:24 - BMT 1931 Jul 24 +2 z EE%sT 1940 Au 15 +2 1 EEST 1941 Jul 17 +1 c CE%sT 1944 Au 24 +3 R MSK/MSD 1990 May 6 2 +2 R EE%sT 1992 +2 e EE%sT 1997 +2 MD EE%sT +R O 1918 1919 - S 16 2s 0 - +R O 1919 o - Ap 15 2s 1 S +R O 1944 o - Ap 3 2s 1 S +R O 1944 o - O 4 2 0 - +R O 1945 o - Ap 29 0 1 S +R O 1945 o - N 1 0 0 - +R O 1946 o - Ap 14 0s 1 S +R O 1946 o - O 7 2s 0 - +R O 1947 o - May 4 2s 1 S +R O 1947 1949 - O Su>=1 2s 0 - +R O 1948 o - Ap 18 2s 1 S +R O 1949 o - Ap 10 2s 1 S +R O 1957 o - Jun 2 1s 1 S +R O 1957 1958 - S lastSu 1s 0 - +R O 1958 o - Mar 30 1s 1 S +R O 1959 o - May 31 1s 1 S +R O 1959 1961 - O Su>=1 1s 0 - +R O 1960 o - Ap 3 1s 1 S +R O 1961 1964 - May lastSu 1s 1 S +R O 1962 1964 - S lastSu 1s 0 - +Z Europe/Warsaw 1:24 - LMT 1880 +1:24 - WMT 1915 Au 5 +1 c CE%sT 1918 S 16 3 +2 O EE%sT 1922 Jun +1 O CE%sT 1940 Jun 23 2 +1 c CE%sT 1944 O +1 O CE%sT 1977 +1 W- CE%sT 1988 +1 E CE%sT +R p 1916 o - Jun 17 23 1 S +R p 1916 o - N 1 1 0 - +R p 1917 o - F 28 23s 1 S +R p 1917 1921 - O 14 23s 0 - +R p 1918 o - Mar 1 23s 1 S +R p 1919 o - F 28 23s 1 S +R p 1920 o - F 29 23s 1 S +R p 1921 o - F 28 23s 1 S +R p 1924 o - Ap 16 23s 1 S +R p 1924 o - O 14 23s 0 - +R p 1926 o - Ap 17 23s 1 S +R p 1926 1929 - O Sa>=1 23s 0 - +R p 1927 o - Ap 9 23s 1 S +R p 1928 o - Ap 14 23s 1 S +R p 1929 o - Ap 20 23s 1 S +R p 1931 o - Ap 18 23s 1 S +R p 1931 1932 - O Sa>=1 23s 0 - +R p 1932 o - Ap 2 23s 1 S +R p 1934 o - Ap 7 23s 1 S +R p 1934 1938 - O Sa>=1 23s 0 - +R p 1935 o - Mar 30 23s 1 S +R p 1936 o - Ap 18 23s 1 S +R p 1937 o - Ap 3 23s 1 S +R p 1938 o - Mar 26 23s 1 S +R p 1939 o - Ap 15 23s 1 S +R p 1939 o - N 18 23s 0 - +R p 1940 o - F 24 23s 1 S +R p 1940 1941 - O 5 23s 0 - +R p 1941 o - Ap 5 23s 1 S +R p 1942 1945 - Mar Sa>=8 23s 1 S +R p 1942 o - Ap 25 22s 2 M +R p 1942 o - Au 15 22s 1 S +R p 1942 1945 - O Sa>=24 23s 0 - +R p 1943 o - Ap 17 22s 2 M +R p 1943 1945 - Au Sa>=25 22s 1 S +R p 1944 1945 - Ap Sa>=21 22s 2 M +R p 1946 o - Ap Sa>=1 23s 1 S +R p 1946 o - O Sa>=1 23s 0 - +R p 1947 1965 - Ap Su>=1 2s 1 S +R p 1947 1965 - O Su>=1 2s 0 - +R p 1977 o - Mar 27 0s 1 S +R p 1977 o - S 25 0s 0 - +R p 1978 1979 - Ap Su>=1 0s 1 S +R p 1978 o - O 1 0s 0 - +R p 1979 1982 - S lastSu 1s 0 - +R p 1980 o - Mar lastSu 0s 1 S +R p 1981 1982 - Mar lastSu 1s 1 S +R p 1983 o - Mar lastSu 2s 1 S +Z Europe/Lisbon -0:36:45 - LMT 1884 +-0:36:45 - LMT 1912 Ja 1 0u +0 p WE%sT 1966 Ap 3 2 +1 - CET 1976 S 26 1 +0 p WE%sT 1983 S 25 1s +0 W- WE%sT 1992 S 27 1s +1 E CE%sT 1996 Mar 31 1u +0 E WE%sT +Z Atlantic/Azores -1:42:40 - LMT 1884 +-1:54:32 - HMT 1912 Ja 1 2u +-2 p -02/-01 1942 Ap 25 22s +-2 p +00 1942 Au 15 22s +-2 p -02/-01 1943 Ap 17 22s +-2 p +00 1943 Au 28 22s +-2 p -02/-01 1944 Ap 22 22s +-2 p +00 1944 Au 26 22s +-2 p -02/-01 1945 Ap 21 22s +-2 p +00 1945 Au 25 22s +-2 p -02/-01 1966 Ap 3 2 +-1 p -01/+00 1983 S 25 1s +-1 W- -01/+00 1992 S 27 1s +0 E WE%sT 1993 Mar 28 1u +-1 E -01/+00 +Z Atlantic/Madeira -1:7:36 - LMT 1884 +-1:7:36 - FMT 1912 Ja 1 1u +-1 p -01/+00 1942 Ap 25 22s +-1 p +01 1942 Au 15 22s +-1 p -01/+00 1943 Ap 17 22s +-1 p +01 1943 Au 28 22s +-1 p -01/+00 1944 Ap 22 22s +-1 p +01 1944 Au 26 22s +-1 p -01/+00 1945 Ap 21 22s +-1 p +01 1945 Au 25 22s +-1 p -01/+00 1966 Ap 3 2 +0 p WE%sT 1983 S 25 1s +0 E WE%sT +R z 1932 o - May 21 0s 1 S +R z 1932 1939 - O Su>=1 0s 0 - +R z 1933 1939 - Ap Su>=2 0s 1 S +R z 1979 o - May 27 0 1 S +R z 1979 o - S lastSu 0 0 - +R z 1980 o - Ap 5 23 1 S +R z 1980 o - S lastSu 1 0 - +R z 1991 1993 - Mar lastSu 0s 1 S +R z 1991 1993 - S lastSu 0s 0 - +Z Europe/Bucharest 1:44:24 - LMT 1891 O +1:44:24 - BMT 1931 Jul 24 +2 z EE%sT 1981 Mar 29 2s +2 c EE%sT 1991 +2 z EE%sT 1994 +2 e EE%sT 1997 +2 E EE%sT +Z Europe/Kaliningrad 1:22 - LMT 1893 Ap +1 c CE%sT 1945 Ap 10 +2 O EE%sT 1946 Ap 7 +3 R MSK/MSD 1989 Mar 26 2s +2 R EE%sT 2011 Mar 27 2s +3 - +03 2014 O 26 2s +2 - EET +Z Europe/Moscow 2:30:17 - LMT 1880 +2:30:17 - MMT 1916 Jul 3 +2:31:19 R %s 1919 Jul 1 0u +3 R %s 1921 O +3 R MSK/MSD 1922 O +2 - EET 1930 Jun 21 +3 R MSK/MSD 1991 Mar 31 2s +2 R EE%sT 1992 Ja 19 2s +3 R MSK/MSD 2011 Mar 27 2s +4 - MSK 2014 O 26 2s +3 - MSK +Z Europe/Simferopol 2:16:24 - LMT 1880 +2:16 - SMT 1924 May 2 +2 - EET 1930 Jun 21 +3 - MSK 1941 N +1 c CE%sT 1944 Ap 13 +3 R MSK/MSD 1990 +3 - MSK 1990 Jul 1 2 +2 - EET 1992 Mar 20 +2 c EE%sT 1994 May +3 c MSK/MSD 1996 Mar 31 0s +3 1 MSD 1996 O 27 3s +3 - MSK 1997 Mar lastSu 1u +2 E EE%sT 2014 Mar 30 2 +4 - MSK 2014 O 26 2s +3 - MSK +Z Europe/Astrakhan 3:12:12 - LMT 1924 May +3 - +03 1930 Jun 21 +4 R +04/+05 1989 Mar 26 2s +3 R +03/+04 1991 Mar 31 2s +4 - +04 1992 Mar 29 2s +3 R +03/+04 2011 Mar 27 2s +4 - +04 2014 O 26 2s +3 - +03 2016 Mar 27 2s +4 - +04 +Z Europe/Volgograd 2:57:40 - LMT 1920 Ja 3 +3 - +03 1930 Jun 21 +4 - +04 1961 N 11 +4 R +04/+05 1988 Mar 27 2s +3 R MSK/MSD 1991 Mar 31 2s +4 - +04 1992 Mar 29 2s +3 R MSK/MSD 2011 Mar 27 2s +4 - MSK 2014 O 26 2s +3 - MSK 2018 O 28 2s +4 - +04 2020 D 27 2s +3 - MSK +Z Europe/Saratov 3:4:18 - LMT 1919 Jul 1 0u +3 - +03 1930 Jun 21 +4 R +04/+05 1988 Mar 27 2s +3 R +03/+04 1991 Mar 31 2s +4 - +04 1992 Mar 29 2s +3 R +03/+04 2011 Mar 27 2s +4 - +04 2014 O 26 2s +3 - +03 2016 D 4 2s +4 - +04 +Z Europe/Kirov 3:18:48 - LMT 1919 Jul 1 0u +3 - +03 1930 Jun 21 +4 R +04/+05 1989 Mar 26 2s +3 R MSK/MSD 1991 Mar 31 2s +4 - +04 1992 Mar 29 2s +3 R MSK/MSD 2011 Mar 27 2s +4 - MSK 2014 O 26 2s +3 - MSK +Z Europe/Samara 3:20:20 - LMT 1919 Jul 1 0u +3 - +03 1930 Jun 21 +4 - +04 1935 Ja 27 +4 R +04/+05 1989 Mar 26 2s +3 R +03/+04 1991 Mar 31 2s +2 R +02/+03 1991 S 29 2s +3 - +03 1991 O 20 3 +4 R +04/+05 2010 Mar 28 2s +3 R +03/+04 2011 Mar 27 2s +4 - +04 +Z Europe/Ulyanovsk 3:13:36 - LMT 1919 Jul 1 0u +3 - +03 1930 Jun 21 +4 R +04/+05 1989 Mar 26 2s +3 R +03/+04 1991 Mar 31 2s +2 R +02/+03 1992 Ja 19 2s +3 R +03/+04 2011 Mar 27 2s +4 - +04 2014 O 26 2s +3 - +03 2016 Mar 27 2s +4 - +04 +Z Asia/Yekaterinburg 4:2:33 - LMT 1916 Jul 3 +3:45:5 - PMT 1919 Jul 15 4 +4 - +04 1930 Jun 21 +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 2011 Mar 27 2s +6 - +06 2014 O 26 2s +5 - +05 +Z Asia/Omsk 4:53:30 - LMT 1919 N 14 +5 - +05 1930 Jun 21 +6 R +06/+07 1991 Mar 31 2s +5 R +05/+06 1992 Ja 19 2s +6 R +06/+07 2011 Mar 27 2s +7 - +07 2014 O 26 2s +6 - +06 +Z Asia/Barnaul 5:35 - LMT 1919 D 10 +6 - +06 1930 Jun 21 +7 R +07/+08 1991 Mar 31 2s +6 R +06/+07 1992 Ja 19 2s +7 R +07/+08 1995 May 28 +6 R +06/+07 2011 Mar 27 2s +7 - +07 2014 O 26 2s +6 - +06 2016 Mar 27 2s +7 - +07 +Z Asia/Novosibirsk 5:31:40 - LMT 1919 D 14 6 +6 - +06 1930 Jun 21 +7 R +07/+08 1991 Mar 31 2s +6 R +06/+07 1992 Ja 19 2s +7 R +07/+08 1993 May 23 +6 R +06/+07 2011 Mar 27 2s +7 - +07 2014 O 26 2s +6 - +06 2016 Jul 24 2s +7 - +07 +Z Asia/Tomsk 5:39:51 - LMT 1919 D 22 +6 - +06 1930 Jun 21 +7 R +07/+08 1991 Mar 31 2s +6 R +06/+07 1992 Ja 19 2s +7 R +07/+08 2002 May 1 3 +6 R +06/+07 2011 Mar 27 2s +7 - +07 2014 O 26 2s +6 - +06 2016 May 29 2s +7 - +07 +Z Asia/Novokuznetsk 5:48:48 - LMT 1924 May +6 - +06 1930 Jun 21 +7 R +07/+08 1991 Mar 31 2s +6 R +06/+07 1992 Ja 19 2s +7 R +07/+08 2010 Mar 28 2s +6 R +06/+07 2011 Mar 27 2s +7 - +07 +Z Asia/Krasnoyarsk 6:11:26 - LMT 1920 Ja 6 +6 - +06 1930 Jun 21 +7 R +07/+08 1991 Mar 31 2s +6 R +06/+07 1992 Ja 19 2s +7 R +07/+08 2011 Mar 27 2s +8 - +08 2014 O 26 2s +7 - +07 +Z Asia/Irkutsk 6:57:5 - LMT 1880 +6:57:5 - IMT 1920 Ja 25 +7 - +07 1930 Jun 21 +8 R +08/+09 1991 Mar 31 2s +7 R +07/+08 1992 Ja 19 2s +8 R +08/+09 2011 Mar 27 2s +9 - +09 2014 O 26 2s +8 - +08 +Z Asia/Chita 7:33:52 - LMT 1919 D 15 +8 - +08 1930 Jun 21 +9 R +09/+10 1991 Mar 31 2s +8 R +08/+09 1992 Ja 19 2s +9 R +09/+10 2011 Mar 27 2s +10 - +10 2014 O 26 2s +8 - +08 2016 Mar 27 2 +9 - +09 +Z Asia/Yakutsk 8:38:58 - LMT 1919 D 15 +8 - +08 1930 Jun 21 +9 R +09/+10 1991 Mar 31 2s +8 R +08/+09 1992 Ja 19 2s +9 R +09/+10 2011 Mar 27 2s +10 - +10 2014 O 26 2s +9 - +09 +Z Asia/Vladivostok 8:47:31 - LMT 1922 N 15 +9 - +09 1930 Jun 21 +10 R +10/+11 1991 Mar 31 2s +9 R +09/+10 1992 Ja 19 2s +10 R +10/+11 2011 Mar 27 2s +11 - +11 2014 O 26 2s +10 - +10 +Z Asia/Khandyga 9:2:13 - LMT 1919 D 15 +8 - +08 1930 Jun 21 +9 R +09/+10 1991 Mar 31 2s +8 R +08/+09 1992 Ja 19 2s +9 R +09/+10 2004 +10 R +10/+11 2011 Mar 27 2s +11 - +11 2011 S 13 0s +10 - +10 2014 O 26 2s +9 - +09 +Z Asia/Sakhalin 9:30:48 - LMT 1905 Au 23 +9 - +09 1945 Au 25 +11 R +11/+12 1991 Mar 31 2s +10 R +10/+11 1992 Ja 19 2s +11 R +11/+12 1997 Mar lastSu 2s +10 R +10/+11 2011 Mar 27 2s +11 - +11 2014 O 26 2s +10 - +10 2016 Mar 27 2s +11 - +11 +Z Asia/Magadan 10:3:12 - LMT 1924 May 2 +10 - +10 1930 Jun 21 +11 R +11/+12 1991 Mar 31 2s +10 R +10/+11 1992 Ja 19 2s +11 R +11/+12 2011 Mar 27 2s +12 - +12 2014 O 26 2s +10 - +10 2016 Ap 24 2s +11 - +11 +Z Asia/Srednekolymsk 10:14:52 - LMT 1924 May 2 +10 - +10 1930 Jun 21 +11 R +11/+12 1991 Mar 31 2s +10 R +10/+11 1992 Ja 19 2s +11 R +11/+12 2011 Mar 27 2s +12 - +12 2014 O 26 2s +11 - +11 +Z Asia/Ust-Nera 9:32:54 - LMT 1919 D 15 +8 - +08 1930 Jun 21 +9 R +09/+10 1981 Ap +11 R +11/+12 1991 Mar 31 2s +10 R +10/+11 1992 Ja 19 2s +11 R +11/+12 2011 Mar 27 2s +12 - +12 2011 S 13 0s +11 - +11 2014 O 26 2s +10 - +10 +Z Asia/Kamchatka 10:34:36 - LMT 1922 N 10 +11 - +11 1930 Jun 21 +12 R +12/+13 1991 Mar 31 2s +11 R +11/+12 1992 Ja 19 2s +12 R +12/+13 2010 Mar 28 2s +11 R +11/+12 2011 Mar 27 2s +12 - +12 +Z Asia/Anadyr 11:49:56 - LMT 1924 May 2 +12 - +12 1930 Jun 21 +13 R +13/+14 1982 Ap 1 0s +12 R +12/+13 1991 Mar 31 2s +11 R +11/+12 1992 Ja 19 2s +12 R +12/+13 2010 Mar 28 2s +11 R +11/+12 2011 Mar 27 2s +12 - +12 +Z Europe/Belgrade 1:22 - LMT 1884 +1 - CET 1941 Ap 18 23 +1 c CE%sT 1945 +1 - CET 1945 May 8 2s +1 1 CEST 1945 S 16 2s +1 - CET 1982 N 27 +1 E CE%sT +R s 1918 o - Ap 15 23 1 S +R s 1918 1919 - O 6 24s 0 - +R s 1919 o - Ap 6 23 1 S +R s 1924 o - Ap 16 23 1 S +R s 1924 o - O 4 24s 0 - +R s 1926 o - Ap 17 23 1 S +R s 1926 1929 - O Sa>=1 24s 0 - +R s 1927 o - Ap 9 23 1 S +R s 1928 o - Ap 15 0 1 S +R s 1929 o - Ap 20 23 1 S +R s 1937 o - Jun 16 23 1 S +R s 1937 o - O 2 24s 0 - +R s 1938 o - Ap 2 23 1 S +R s 1938 o - Ap 30 23 2 M +R s 1938 o - O 2 24 1 S +R s 1939 o - O 7 24s 0 - +R s 1942 o - May 2 23 1 S +R s 1942 o - S 1 1 0 - +R s 1943 1946 - Ap Sa>=13 23 1 S +R s 1943 1944 - O Su>=1 1 0 - +R s 1945 1946 - S lastSu 1 0 - +R s 1949 o - Ap 30 23 1 S +R s 1949 o - O 2 1 0 - +R s 1974 1975 - Ap Sa>=12 23 1 S +R s 1974 1975 - O Su>=1 1 0 - +R s 1976 o - Mar 27 23 1 S +R s 1976 1977 - S lastSu 1 0 - +R s 1977 o - Ap 2 23 1 S +R s 1978 o - Ap 2 2s 1 S +R s 1978 o - O 1 2s 0 - +R Sp 1967 o - Jun 3 12 1 S +R Sp 1967 o - O 1 0 0 - +R Sp 1974 o - Jun 24 0 1 S +R Sp 1974 o - S 1 0 0 - +R Sp 1976 1977 - May 1 0 1 S +R Sp 1976 o - Au 1 0 0 - +R Sp 1977 o - S 28 0 0 - +R Sp 1978 o - Jun 1 0 1 S +R Sp 1978 o - Au 4 0 0 - +Z Europe/Madrid -0:14:44 - LMT 1901 Ja 1 0u +0 s WE%sT 1940 Mar 16 23 +1 s CE%sT 1979 +1 E CE%sT +Z Africa/Ceuta -0:21:16 - LMT 1901 Ja 1 0u +0 - WET 1918 May 6 23 +0 1 WEST 1918 O 7 23 +0 - WET 1924 +0 s WE%sT 1929 +0 - WET 1967 +0 Sp WE%sT 1984 Mar 16 +1 - CET 1986 +1 E CE%sT +Z Atlantic/Canary -1:1:36 - LMT 1922 Mar +-1 - -01 1946 S 30 1 +0 - WET 1980 Ap 6 0s +0 1 WEST 1980 S 28 1u +0 E WE%sT +R CH 1941 1942 - May M>=1 1 1 S +R CH 1941 1942 - O M>=1 2 0 - +Z Europe/Zurich 0:34:8 - LMT 1853 Jul 16 +0:29:46 - BMT 1894 Jun +1 CH CE%sT 1981 +1 E CE%sT +R T 1916 o - May 1 0 1 S +R T 1916 o - O 1 0 0 - +R T 1920 o - Mar 28 0 1 S +R T 1920 o - O 25 0 0 - +R T 1921 o - Ap 3 0 1 S +R T 1921 o - O 3 0 0 - +R T 1922 o - Mar 26 0 1 S +R T 1922 o - O 8 0 0 - +R T 1924 o - May 13 0 1 S +R T 1924 1925 - O 1 0 0 - +R T 1925 o - May 1 0 1 S +R T 1940 o - Jul 1 0 1 S +R T 1940 o - O 6 0 0 - +R T 1940 o - D 1 0 1 S +R T 1941 o - S 21 0 0 - +R T 1942 o - Ap 1 0 1 S +R T 1945 o - O 8 0 0 - +R T 1946 o - Jun 1 0 1 S +R T 1946 o - O 1 0 0 - +R T 1947 1948 - Ap Su>=16 0 1 S +R T 1947 1951 - O Su>=2 0 0 - +R T 1949 o - Ap 10 0 1 S +R T 1950 o - Ap 16 0 1 S +R T 1951 o - Ap 22 0 1 S +R T 1962 o - Jul 15 0 1 S +R T 1963 o - O 30 0 0 - +R T 1964 o - May 15 0 1 S +R T 1964 o - O 1 0 0 - +R T 1973 o - Jun 3 1 1 S +R T 1973 1976 - O Su>=31 2 0 - +R T 1974 o - Mar 31 2 1 S +R T 1975 o - Mar 22 2 1 S +R T 1976 o - Mar 21 2 1 S +R T 1977 1978 - Ap Su>=1 2 1 S +R T 1977 1978 - O Su>=15 2 0 - +R T 1978 o - Jun 29 0 0 - +R T 1983 o - Jul 31 2 1 S +R T 1983 o - O 2 2 0 - +R T 1985 o - Ap 20 1s 1 S +R T 1985 o - S 28 1s 0 - +R T 1986 1993 - Mar lastSu 1s 1 S +R T 1986 1995 - S lastSu 1s 0 - +R T 1994 o - Mar 20 1s 1 S +R T 1995 2006 - Mar lastSu 1s 1 S +R T 1996 2006 - O lastSu 1s 0 - +Z Europe/Istanbul 1:55:52 - LMT 1880 +1:56:56 - IMT 1910 O +2 T EE%sT 1978 Jun 29 +3 T +03/+04 1984 N 1 2 +2 T EE%sT 2007 +2 E EE%sT 2011 Mar 27 1u +2 - EET 2011 Mar 28 1u +2 E EE%sT 2014 Mar 30 1u +2 - EET 2014 Mar 31 1u +2 E EE%sT 2015 O 25 1u +2 1 EEST 2015 N 8 1u +2 E EE%sT 2016 S 7 +3 - +03 +Z Europe/Kyiv 2:2:4 - LMT 1880 +2:2:4 - KMT 1924 May 2 +2 - EET 1930 Jun 21 +3 - MSK 1941 S 20 +1 c CE%sT 1943 N 6 +3 R MSK/MSD 1990 Jul 1 2 +2 1 EEST 1991 S 29 3 +2 c EE%sT 1996 May 13 +2 E EE%sT +R u 1918 1919 - Mar lastSu 2 1 D +R u 1918 1919 - O lastSu 2 0 S +R u 1942 o - F 9 2 1 W +R u 1945 o - Au 14 23u 1 P +R u 1945 o - S 30 2 0 S +R u 1967 2006 - O lastSu 2 0 S +R u 1967 1973 - Ap lastSu 2 1 D +R u 1974 o - Ja 6 2 1 D +R u 1975 o - F lastSu 2 1 D +R u 1976 1986 - Ap lastSu 2 1 D +R u 1987 2006 - Ap Su>=1 2 1 D +R u 2007 ma - Mar Su>=8 2 1 D +R u 2007 ma - N Su>=1 2 0 S +Z EST -5 - EST +Z MST -7 - MST +Z HST -10 - HST +Z EST5EDT -5 u E%sT +Z CST6CDT -6 u C%sT +Z MST7MDT -7 u M%sT +Z PST8PDT -8 u P%sT +R NY 1920 o - Mar lastSu 2 1 D +R NY 1920 o - O lastSu 2 0 S +R NY 1921 1966 - Ap lastSu 2 1 D +R NY 1921 1954 - S lastSu 2 0 S +R NY 1955 1966 - O lastSu 2 0 S +Z America/New_York -4:56:2 - LMT 1883 N 18 17u +-5 u E%sT 1920 +-5 NY E%sT 1942 +-5 u E%sT 1946 +-5 NY E%sT 1967 +-5 u E%sT +R Ch 1920 o - Jun 13 2 1 D +R Ch 1920 1921 - O lastSu 2 0 S +R Ch 1921 o - Mar lastSu 2 1 D +R Ch 1922 1966 - Ap lastSu 2 1 D +R Ch 1922 1954 - S lastSu 2 0 S +R Ch 1955 1966 - O lastSu 2 0 S +Z America/Chicago -5:50:36 - LMT 1883 N 18 18u +-6 u C%sT 1920 +-6 Ch C%sT 1936 Mar 1 2 +-5 - EST 1936 N 15 2 +-6 Ch C%sT 1942 +-6 u C%sT 1946 +-6 Ch C%sT 1967 +-6 u C%sT +Z America/North_Dakota/Center -6:45:12 - LMT 1883 N 18 19u +-7 u M%sT 1992 O 25 2 +-6 u C%sT +Z America/North_Dakota/New_Salem -6:45:39 - LMT 1883 N 18 19u +-7 u M%sT 2003 O 26 2 +-6 u C%sT +Z America/North_Dakota/Beulah -6:47:7 - LMT 1883 N 18 19u +-7 u M%sT 2010 N 7 2 +-6 u C%sT +R De 1920 1921 - Mar lastSu 2 1 D +R De 1920 o - O lastSu 2 0 S +R De 1921 o - May 22 2 0 S +R De 1965 1966 - Ap lastSu 2 1 D +R De 1965 1966 - O lastSu 2 0 S +Z America/Denver -6:59:56 - LMT 1883 N 18 19u +-7 u M%sT 1920 +-7 De M%sT 1942 +-7 u M%sT 1946 +-7 De M%sT 1967 +-7 u M%sT +R CA 1948 o - Mar 14 2:1 1 D +R CA 1949 o - Ja 1 2 0 S +R CA 1950 1966 - Ap lastSu 1 1 D +R CA 1950 1961 - S lastSu 2 0 S +R CA 1962 1966 - O lastSu 2 0 S +Z America/Los_Angeles -7:52:58 - LMT 1883 N 18 20u +-8 u P%sT 1946 +-8 CA P%sT 1967 +-8 u P%sT +Z America/Juneau 15:2:19 - LMT 1867 O 19 15:33:32 +-8:57:41 - LMT 1900 Au 20 12 +-8 - PST 1942 +-8 u P%sT 1946 +-8 - PST 1969 +-8 u P%sT 1980 Ap 27 2 +-9 u Y%sT 1980 O 26 2 +-8 u P%sT 1983 O 30 2 +-9 u Y%sT 1983 N 30 +-9 u AK%sT +Z America/Sitka 14:58:47 - LMT 1867 O 19 15:30 +-9:1:13 - LMT 1900 Au 20 12 +-8 - PST 1942 +-8 u P%sT 1946 +-8 - PST 1969 +-8 u P%sT 1983 O 30 2 +-9 u Y%sT 1983 N 30 +-9 u AK%sT +Z America/Metlakatla 15:13:42 - LMT 1867 O 19 15:44:55 +-8:46:18 - LMT 1900 Au 20 12 +-8 - PST 1942 +-8 u P%sT 1946 +-8 - PST 1969 +-8 u P%sT 1983 O 30 2 +-8 - PST 2015 N 1 2 +-9 u AK%sT 2018 N 4 2 +-8 - PST 2019 Ja 20 2 +-9 u AK%sT +Z America/Yakutat 14:41:5 - LMT 1867 O 19 15:12:18 +-9:18:55 - LMT 1900 Au 20 12 +-9 - YST 1942 +-9 u Y%sT 1946 +-9 - YST 1969 +-9 u Y%sT 1983 N 30 +-9 u AK%sT +Z America/Anchorage 14:0:24 - LMT 1867 O 19 14:31:37 +-9:59:36 - LMT 1900 Au 20 12 +-10 - AST 1942 +-10 u A%sT 1967 Ap +-10 - AHST 1969 +-10 u AH%sT 1983 O 30 2 +-9 u Y%sT 1983 N 30 +-9 u AK%sT +Z America/Nome 12:58:22 - LMT 1867 O 19 13:29:35 +-11:1:38 - LMT 1900 Au 20 12 +-11 - NST 1942 +-11 u N%sT 1946 +-11 - NST 1967 Ap +-11 - BST 1969 +-11 u B%sT 1983 O 30 2 +-9 u Y%sT 1983 N 30 +-9 u AK%sT +Z America/Adak 12:13:22 - LMT 1867 O 19 12:44:35 +-11:46:38 - LMT 1900 Au 20 12 +-11 - NST 1942 +-11 u N%sT 1946 +-11 - NST 1967 Ap +-11 - BST 1969 +-11 u B%sT 1983 O 30 2 +-10 u AH%sT 1983 N 30 +-10 u H%sT +Z Pacific/Honolulu -10:31:26 - LMT 1896 Ja 13 12 +-10:30 - HST 1933 Ap 30 2 +-10:30 1 HDT 1933 May 21 12 +-10:30 u H%sT 1947 Jun 8 2 +-10 - HST +Z America/Phoenix -7:28:18 - LMT 1883 N 18 19u +-7 u M%sT 1944 Ja 1 0:1 +-7 - MST 1944 Ap 1 0:1 +-7 u M%sT 1944 O 1 0:1 +-7 - MST 1967 +-7 u M%sT 1968 Mar 21 +-7 - MST +Z America/Boise -7:44:49 - LMT 1883 N 18 20u +-8 u P%sT 1923 May 13 2 +-7 u M%sT 1974 +-7 - MST 1974 F 3 2 +-7 u M%sT +R In 1941 o - Jun 22 2 1 D +R In 1941 1954 - S lastSu 2 0 S +R In 1946 1954 - Ap lastSu 2 1 D +Z America/Indiana/Indianapolis -5:44:38 - LMT 1883 N 18 18u +-6 u C%sT 1920 +-6 In C%sT 1942 +-6 u C%sT 1946 +-6 In C%sT 1955 Ap 24 2 +-5 - EST 1957 S 29 2 +-6 - CST 1958 Ap 27 2 +-5 - EST 1969 +-5 u E%sT 1971 +-5 - EST 2006 +-5 u E%sT +R Ma 1951 o - Ap lastSu 2 1 D +R Ma 1951 o - S lastSu 2 0 S +R Ma 1954 1960 - Ap lastSu 2 1 D +R Ma 1954 1960 - S lastSu 2 0 S +Z America/Indiana/Marengo -5:45:23 - LMT 1883 N 18 18u +-6 u C%sT 1951 +-6 Ma C%sT 1961 Ap 30 2 +-5 - EST 1969 +-5 u E%sT 1974 Ja 6 2 +-6 1 CDT 1974 O 27 2 +-5 u E%sT 1976 +-5 - EST 2006 +-5 u E%sT +R V 1946 o - Ap lastSu 2 1 D +R V 1946 o - S lastSu 2 0 S +R V 1953 1954 - Ap lastSu 2 1 D +R V 1953 1959 - S lastSu 2 0 S +R V 1955 o - May 1 0 1 D +R V 1956 1963 - Ap lastSu 2 1 D +R V 1960 o - O lastSu 2 0 S +R V 1961 o - S lastSu 2 0 S +R V 1962 1963 - O lastSu 2 0 S +Z America/Indiana/Vincennes -5:50:7 - LMT 1883 N 18 18u +-6 u C%sT 1946 +-6 V C%sT 1964 Ap 26 2 +-5 - EST 1969 +-5 u E%sT 1971 +-5 - EST 2006 Ap 2 2 +-6 u C%sT 2007 N 4 2 +-5 u E%sT +R Pe 1955 o - May 1 0 1 D +R Pe 1955 1960 - S lastSu 2 0 S +R Pe 1956 1963 - Ap lastSu 2 1 D +R Pe 1961 1963 - O lastSu 2 0 S +Z America/Indiana/Tell_City -5:47:3 - LMT 1883 N 18 18u +-6 u C%sT 1946 +-6 Pe C%sT 1964 Ap 26 2 +-5 - EST 1967 O 29 2 +-6 u C%sT 1969 Ap 27 2 +-5 u E%sT 1971 +-5 - EST 2006 Ap 2 2 +-6 u C%sT +R Pi 1955 o - May 1 0 1 D +R Pi 1955 1960 - S lastSu 2 0 S +R Pi 1956 1964 - Ap lastSu 2 1 D +R Pi 1961 1964 - O lastSu 2 0 S +Z America/Indiana/Petersburg -5:49:7 - LMT 1883 N 18 18u +-6 u C%sT 1955 +-6 Pi C%sT 1965 Ap 25 2 +-5 - EST 1966 O 30 2 +-6 u C%sT 1977 O 30 2 +-5 - EST 2006 Ap 2 2 +-6 u C%sT 2007 N 4 2 +-5 u E%sT +R St 1947 1961 - Ap lastSu 2 1 D +R St 1947 1954 - S lastSu 2 0 S +R St 1955 1956 - O lastSu 2 0 S +R St 1957 1958 - S lastSu 2 0 S +R St 1959 1961 - O lastSu 2 0 S +Z America/Indiana/Knox -5:46:30 - LMT 1883 N 18 18u +-6 u C%sT 1947 +-6 St C%sT 1962 Ap 29 2 +-5 - EST 1963 O 27 2 +-6 u C%sT 1991 O 27 2 +-5 - EST 2006 Ap 2 2 +-6 u C%sT +R Pu 1946 1960 - Ap lastSu 2 1 D +R Pu 1946 1954 - S lastSu 2 0 S +R Pu 1955 1956 - O lastSu 2 0 S +R Pu 1957 1960 - S lastSu 2 0 S +Z America/Indiana/Winamac -5:46:25 - LMT 1883 N 18 18u +-6 u C%sT 1946 +-6 Pu C%sT 1961 Ap 30 2 +-5 - EST 1969 +-5 u E%sT 1971 +-5 - EST 2006 Ap 2 2 +-6 u C%sT 2007 Mar 11 2 +-5 u E%sT +Z America/Indiana/Vevay -5:40:16 - LMT 1883 N 18 18u +-6 u C%sT 1954 Ap 25 2 +-5 - EST 1969 +-5 u E%sT 1973 +-5 - EST 2006 +-5 u E%sT +R v 1921 o - May 1 2 1 D +R v 1921 o - S 1 2 0 S +R v 1941 o - Ap lastSu 2 1 D +R v 1941 o - S lastSu 2 0 S +R v 1946 o - Ap lastSu 0:1 1 D +R v 1946 o - Jun 2 2 0 S +R v 1950 1961 - Ap lastSu 2 1 D +R v 1950 1955 - S lastSu 2 0 S +R v 1956 1961 - O lastSu 2 0 S +Z America/Kentucky/Louisville -5:43:2 - LMT 1883 N 18 18u +-6 u C%sT 1921 +-6 v C%sT 1942 +-6 u C%sT 1946 +-6 v C%sT 1961 Jul 23 2 +-5 - EST 1968 +-5 u E%sT 1974 Ja 6 2 +-6 1 CDT 1974 O 27 2 +-5 u E%sT +Z America/Kentucky/Monticello -5:39:24 - LMT 1883 N 18 18u +-6 u C%sT 1946 +-6 - CST 1968 +-6 u C%sT 2000 O 29 2 +-5 u E%sT +R Dt 1948 o - Ap lastSu 2 1 D +R Dt 1948 o - S lastSu 2 0 S +Z America/Detroit -5:32:11 - LMT 1905 +-6 - CST 1915 May 15 2 +-5 - EST 1942 +-5 u E%sT 1946 +-5 Dt E%sT 1967 Jun 14 0:1 +-5 u E%sT 1969 +-5 - EST 1973 +-5 u E%sT 1975 +-5 - EST 1975 Ap 27 2 +-5 u E%sT +R Me 1946 o - Ap lastSu 2 1 D +R Me 1946 o - S lastSu 2 0 S +R Me 1966 o - Ap lastSu 2 1 D +R Me 1966 o - O lastSu 2 0 S +Z America/Menominee -5:50:27 - LMT 1885 S 18 12 +-6 u C%sT 1946 +-6 Me C%sT 1969 Ap 27 2 +-5 - EST 1973 Ap 29 2 +-6 u C%sT +R C 1918 o - Ap 14 2 1 D +R C 1918 o - O 27 2 0 S +R C 1942 o - F 9 2 1 W +R C 1945 o - Au 14 23u 1 P +R C 1945 o - S 30 2 0 S +R C 1974 1986 - Ap lastSu 2 1 D +R C 1974 2006 - O lastSu 2 0 S +R C 1987 2006 - Ap Su>=1 2 1 D +R C 2007 ma - Mar Su>=8 2 1 D +R C 2007 ma - N Su>=1 2 0 S +R j 1917 o - Ap 8 2 1 D +R j 1917 o - S 17 2 0 S +R j 1919 o - May 5 23 1 D +R j 1919 o - Au 12 23 0 S +R j 1920 1935 - May Su>=1 23 1 D +R j 1920 1935 - O lastSu 23 0 S +R j 1936 1941 - May M>=9 0 1 D +R j 1936 1941 - O M>=2 0 0 S +R j 1946 1950 - May Su>=8 2 1 D +R j 1946 1950 - O Su>=2 2 0 S +R j 1951 1986 - Ap lastSu 2 1 D +R j 1951 1959 - S lastSu 2 0 S +R j 1960 1986 - O lastSu 2 0 S +R j 1987 o - Ap Su>=1 0:1 1 D +R j 1987 2006 - O lastSu 0:1 0 S +R j 1988 o - Ap Su>=1 0:1 2 DD +R j 1989 2006 - Ap Su>=1 0:1 1 D +R j 2007 2011 - Mar Su>=8 0:1 1 D +R j 2007 2010 - N Su>=1 0:1 0 S +Z America/St_Johns -3:30:52 - LMT 1884 +-3:30:52 j N%sT 1918 +-3:30:52 C N%sT 1919 +-3:30:52 j N%sT 1935 Mar 30 +-3:30 j N%sT 1942 May 11 +-3:30 C N%sT 1946 +-3:30 j N%sT 2011 N +-3:30 C N%sT +Z America/Goose_Bay -4:1:40 - LMT 1884 +-3:30:52 - NST 1918 +-3:30:52 C N%sT 1919 +-3:30:52 - NST 1935 Mar 30 +-3:30 - NST 1936 +-3:30 j N%sT 1942 May 11 +-3:30 C N%sT 1946 +-3:30 j N%sT 1966 Mar 15 2 +-4 j A%sT 2011 N +-4 C A%sT +R H 1916 o - Ap 1 0 1 D +R H 1916 o - O 1 0 0 S +R H 1920 o - May 9 0 1 D +R H 1920 o - Au 29 0 0 S +R H 1921 o - May 6 0 1 D +R H 1921 1922 - S 5 0 0 S +R H 1922 o - Ap 30 0 1 D +R H 1923 1925 - May Su>=1 0 1 D +R H 1923 o - S 4 0 0 S +R H 1924 o - S 15 0 0 S +R H 1925 o - S 28 0 0 S +R H 1926 o - May 16 0 1 D +R H 1926 o - S 13 0 0 S +R H 1927 o - May 1 0 1 D +R H 1927 o - S 26 0 0 S +R H 1928 1931 - May Su>=8 0 1 D +R H 1928 o - S 9 0 0 S +R H 1929 o - S 3 0 0 S +R H 1930 o - S 15 0 0 S +R H 1931 1932 - S M>=24 0 0 S +R H 1932 o - May 1 0 1 D +R H 1933 o - Ap 30 0 1 D +R H 1933 o - O 2 0 0 S +R H 1934 o - May 20 0 1 D +R H 1934 o - S 16 0 0 S +R H 1935 o - Jun 2 0 1 D +R H 1935 o - S 30 0 0 S +R H 1936 o - Jun 1 0 1 D +R H 1936 o - S 14 0 0 S +R H 1937 1938 - May Su>=1 0 1 D +R H 1937 1941 - S M>=24 0 0 S +R H 1939 o - May 28 0 1 D +R H 1940 1941 - May Su>=1 0 1 D +R H 1946 1949 - Ap lastSu 2 1 D +R H 1946 1949 - S lastSu 2 0 S +R H 1951 1954 - Ap lastSu 2 1 D +R H 1951 1954 - S lastSu 2 0 S +R H 1956 1959 - Ap lastSu 2 1 D +R H 1956 1959 - S lastSu 2 0 S +R H 1962 1973 - Ap lastSu 2 1 D +R H 1962 1973 - O lastSu 2 0 S +Z America/Halifax -4:14:24 - LMT 1902 Jun 15 +-4 H A%sT 1918 +-4 C A%sT 1919 +-4 H A%sT 1942 F 9 2s +-4 C A%sT 1946 +-4 H A%sT 1974 +-4 C A%sT +Z America/Glace_Bay -3:59:48 - LMT 1902 Jun 15 +-4 C A%sT 1953 +-4 H A%sT 1954 +-4 - AST 1972 +-4 H A%sT 1974 +-4 C A%sT +R o 1933 1935 - Jun Su>=8 1 1 D +R o 1933 1935 - S Su>=8 1 0 S +R o 1936 1938 - Jun Su>=1 1 1 D +R o 1936 1938 - S Su>=1 1 0 S +R o 1939 o - May 27 1 1 D +R o 1939 1941 - S Sa>=21 1 0 S +R o 1940 o - May 19 1 1 D +R o 1941 o - May 4 1 1 D +R o 1946 1972 - Ap lastSu 2 1 D +R o 1946 1956 - S lastSu 2 0 S +R o 1957 1972 - O lastSu 2 0 S +R o 1993 2006 - Ap Su>=1 0:1 1 D +R o 1993 2006 - O lastSu 0:1 0 S +Z America/Moncton -4:19:8 - LMT 1883 D 9 +-5 - EST 1902 Jun 15 +-4 C A%sT 1933 +-4 o A%sT 1942 +-4 C A%sT 1946 +-4 o A%sT 1973 +-4 C A%sT 1993 +-4 o A%sT 2007 +-4 C A%sT +R t 1919 o - Mar 30 23:30 1 D +R t 1919 o - O 26 0 0 S +R t 1920 o - May 2 2 1 D +R t 1920 o - S 26 0 0 S +R t 1921 o - May 15 2 1 D +R t 1921 o - S 15 2 0 S +R t 1922 1923 - May Su>=8 2 1 D +R t 1922 1926 - S Su>=15 2 0 S +R t 1924 1927 - May Su>=1 2 1 D +R t 1927 1937 - S Su>=25 2 0 S +R t 1928 1937 - Ap Su>=25 2 1 D +R t 1938 1940 - Ap lastSu 2 1 D +R t 1938 1939 - S lastSu 2 0 S +R t 1945 1946 - S lastSu 2 0 S +R t 1946 o - Ap lastSu 2 1 D +R t 1947 1949 - Ap lastSu 0 1 D +R t 1947 1948 - S lastSu 0 0 S +R t 1949 o - N lastSu 0 0 S +R t 1950 1973 - Ap lastSu 2 1 D +R t 1950 o - N lastSu 2 0 S +R t 1951 1956 - S lastSu 2 0 S +R t 1957 1973 - O lastSu 2 0 S +Z America/Toronto -5:17:32 - LMT 1895 +-5 C E%sT 1919 +-5 t E%sT 1942 F 9 2s +-5 C E%sT 1946 +-5 t E%sT 1974 +-5 C E%sT +R W 1916 o - Ap 23 0 1 D +R W 1916 o - S 17 0 0 S +R W 1918 o - Ap 14 2 1 D +R W 1918 o - O 27 2 0 S +R W 1937 o - May 16 2 1 D +R W 1937 o - S 26 2 0 S +R W 1942 o - F 9 2 1 W +R W 1945 o - Au 14 23u 1 P +R W 1945 o - S lastSu 2 0 S +R W 1946 o - May 12 2 1 D +R W 1946 o - O 13 2 0 S +R W 1947 1949 - Ap lastSu 2 1 D +R W 1947 1949 - S lastSu 2 0 S +R W 1950 o - May 1 2 1 D +R W 1950 o - S 30 2 0 S +R W 1951 1960 - Ap lastSu 2 1 D +R W 1951 1958 - S lastSu 2 0 S +R W 1959 o - O lastSu 2 0 S +R W 1960 o - S lastSu 2 0 S +R W 1963 o - Ap lastSu 2 1 D +R W 1963 o - S 22 2 0 S +R W 1966 1986 - Ap lastSu 2s 1 D +R W 1966 2005 - O lastSu 2s 0 S +R W 1987 2005 - Ap Su>=1 2s 1 D +Z America/Winnipeg -6:28:36 - LMT 1887 Jul 16 +-6 W C%sT 2006 +-6 C C%sT +R r 1918 o - Ap 14 2 1 D +R r 1918 o - O 27 2 0 S +R r 1930 1934 - May Su>=1 0 1 D +R r 1930 1934 - O Su>=1 0 0 S +R r 1937 1941 - Ap Su>=8 0 1 D +R r 1937 o - O Su>=8 0 0 S +R r 1938 o - O Su>=1 0 0 S +R r 1939 1941 - O Su>=8 0 0 S +R r 1942 o - F 9 2 1 W +R r 1945 o - Au 14 23u 1 P +R r 1945 o - S lastSu 2 0 S +R r 1946 o - Ap Su>=8 2 1 D +R r 1946 o - O Su>=8 2 0 S +R r 1947 1957 - Ap lastSu 2 1 D +R r 1947 1957 - S lastSu 2 0 S +R r 1959 o - Ap lastSu 2 1 D +R r 1959 o - O lastSu 2 0 S +R Sw 1957 o - Ap lastSu 2 1 D +R Sw 1957 o - O lastSu 2 0 S +R Sw 1959 1961 - Ap lastSu 2 1 D +R Sw 1959 o - O lastSu 2 0 S +R Sw 1960 1961 - S lastSu 2 0 S +Z America/Regina -6:58:36 - LMT 1905 S +-7 r M%sT 1960 Ap lastSu 2 +-6 - CST +Z America/Swift_Current -7:11:20 - LMT 1905 S +-7 C M%sT 1946 Ap lastSu 2 +-7 r M%sT 1950 +-7 Sw M%sT 1972 Ap lastSu 2 +-6 - CST +R Ed 1918 1919 - Ap Su>=8 2 1 D +R Ed 1918 o - O 27 2 0 S +R Ed 1919 o - May 27 2 0 S +R Ed 1920 1923 - Ap lastSu 2 1 D +R Ed 1920 o - O lastSu 2 0 S +R Ed 1921 1923 - S lastSu 2 0 S +R Ed 1942 o - F 9 2 1 W +R Ed 1945 o - Au 14 23u 1 P +R Ed 1945 o - S lastSu 2 0 S +R Ed 1947 o - Ap lastSu 2 1 D +R Ed 1947 o - S lastSu 2 0 S +R Ed 1972 1986 - Ap lastSu 2 1 D +R Ed 1972 2006 - O lastSu 2 0 S +Z America/Edmonton -7:33:52 - LMT 1906 S +-7 Ed M%sT 1987 +-7 C M%sT +R Va 1918 o - Ap 14 2 1 D +R Va 1918 o - O 27 2 0 S +R Va 1942 o - F 9 2 1 W +R Va 1945 o - Au 14 23u 1 P +R Va 1945 o - S 30 2 0 S +R Va 1946 1986 - Ap lastSu 2 1 D +R Va 1946 o - S 29 2 0 S +R Va 1947 1961 - S lastSu 2 0 S +R Va 1962 2006 - O lastSu 2 0 S +Z America/Vancouver -8:12:28 - LMT 1884 +-8 Va P%sT 1987 +-8 C P%sT +Z America/Dawson_Creek -8:0:56 - LMT 1884 +-8 C P%sT 1947 +-8 Va P%sT 1972 Au 30 2 +-7 - MST +Z America/Fort_Nelson -8:10:47 - LMT 1884 +-8 Va P%sT 1946 +-8 - PST 1947 +-8 Va P%sT 1987 +-8 C P%sT 2015 Mar 8 2 +-7 - MST +R Y 1918 o - Ap 14 2 1 D +R Y 1918 o - O 27 2 0 S +R Y 1919 o - May 25 2 1 D +R Y 1919 o - N 1 0 0 S +R Y 1942 o - F 9 2 1 W +R Y 1945 o - Au 14 23u 1 P +R Y 1945 o - S 30 2 0 S +R Y 1972 1986 - Ap lastSu 2 1 D +R Y 1972 2006 - O lastSu 2 0 S +R Y 1987 2006 - Ap Su>=1 2 1 D +R Yu 1965 o - Ap lastSu 0 2 DD +R Yu 1965 o - O lastSu 2 0 S +Z America/Iqaluit 0 - -00 1942 Au +-5 Y E%sT 1999 O 31 2 +-6 C C%sT 2000 O 29 2 +-5 C E%sT +Z America/Resolute 0 - -00 1947 Au 31 +-6 Y C%sT 2000 O 29 2 +-5 - EST 2001 Ap 1 3 +-6 C C%sT 2006 O 29 2 +-5 - EST 2007 Mar 11 3 +-6 C C%sT +Z America/Rankin_Inlet 0 - -00 1957 +-6 Y C%sT 2000 O 29 2 +-5 - EST 2001 Ap 1 3 +-6 C C%sT +Z America/Cambridge_Bay 0 - -00 1920 +-7 Y M%sT 1999 O 31 2 +-6 C C%sT 2000 O 29 2 +-5 - EST 2000 N 5 +-6 - CST 2001 Ap 1 3 +-7 C M%sT +Z America/Inuvik 0 - -00 1953 +-8 Y P%sT 1979 Ap lastSu 2 +-7 Y M%sT 1980 +-7 C M%sT +Z America/Whitehorse -9:0:12 - LMT 1900 Au 20 +-9 Y Y%sT 1965 +-9 Yu Y%sT 1966 F 27 +-8 - PST 1980 +-8 C P%sT 2020 N +-7 - MST +Z America/Dawson -9:17:40 - LMT 1900 Au 20 +-9 Y Y%sT 1965 +-9 Yu Y%sT 1973 O 28 +-8 - PST 1980 +-8 C P%sT 2020 N +-7 - MST +R m 1931 o - May 1 23 1 D +R m 1931 o - O 1 0 0 S +R m 1939 o - F 5 0 1 D +R m 1939 o - Jun 25 0 0 S +R m 1940 o - D 9 0 1 D +R m 1941 o - Ap 1 0 0 S +R m 1943 o - D 16 0 1 W +R m 1944 o - May 1 0 0 S +R m 1950 o - F 12 0 1 D +R m 1950 o - Jul 30 0 0 S +R m 1996 2000 - Ap Su>=1 2 1 D +R m 1996 2000 - O lastSu 2 0 S +R m 2001 o - May Su>=1 2 1 D +R m 2001 o - S lastSu 2 0 S +R m 2002 2022 - Ap Su>=1 2 1 D +R m 2002 2022 - O lastSu 2 0 S +Z America/Cancun -5:47:4 - LMT 1922 Ja 1 6u +-6 - CST 1981 D 23 +-5 m E%sT 1998 Au 2 2 +-6 m C%sT 2015 F 1 2 +-5 - EST +Z America/Merida -5:58:28 - LMT 1922 Ja 1 6u +-6 - CST 1981 D 23 +-5 - EST 1982 D 2 +-6 m C%sT +Z America/Matamoros -6:30 - LMT 1922 Ja 1 6u +-6 - CST 1988 +-6 u C%sT 1989 +-6 m C%sT 2010 +-6 u C%sT +Z America/Monterrey -6:41:16 - LMT 1922 Ja 1 6u +-6 - CST 1988 +-6 u C%sT 1989 +-6 m C%sT +Z America/Mexico_City -6:36:36 - LMT 1922 Ja 1 7u +-7 - MST 1927 Jun 10 23 +-6 - CST 1930 N 15 +-7 m M%sT 1932 Ap +-6 m C%sT 2001 S 30 2 +-6 - CST 2002 F 20 +-6 m C%sT +Z America/Ciudad_Juarez -7:5:56 - LMT 1922 Ja 1 7u +-7 - MST 1927 Jun 10 23 +-6 - CST 1930 N 15 +-7 m M%sT 1932 Ap +-6 - CST 1996 +-6 m C%sT 1998 +-6 - CST 1998 Ap Su>=1 3 +-7 m M%sT 2010 +-7 u M%sT 2022 O 30 2 +-6 - CST 2022 N 30 +-7 u M%sT +Z America/Ojinaga -6:57:40 - LMT 1922 Ja 1 7u +-7 - MST 1927 Jun 10 23 +-6 - CST 1930 N 15 +-7 m M%sT 1932 Ap +-6 - CST 1996 +-6 m C%sT 1998 +-6 - CST 1998 Ap Su>=1 3 +-7 m M%sT 2010 +-7 u M%sT 2022 O 30 2 +-6 - CST 2022 N 30 +-6 u C%sT +Z America/Chihuahua -7:4:20 - LMT 1922 Ja 1 7u +-7 - MST 1927 Jun 10 23 +-6 - CST 1930 N 15 +-7 m M%sT 1932 Ap +-6 - CST 1996 +-6 m C%sT 1998 +-6 - CST 1998 Ap Su>=1 3 +-7 m M%sT 2022 O 30 2 +-6 - CST +Z America/Hermosillo -7:23:52 - LMT 1922 Ja 1 7u +-7 - MST 1927 Jun 10 23 +-6 - CST 1930 N 15 +-7 m M%sT 1932 Ap +-6 - CST 1942 Ap 24 +-7 - MST 1949 Ja 14 +-8 - PST 1970 +-7 m M%sT 1999 +-7 - MST +Z America/Mazatlan -7:5:40 - LMT 1922 Ja 1 7u +-7 - MST 1927 Jun 10 23 +-6 - CST 1930 N 15 +-7 m M%sT 1932 Ap +-6 - CST 1942 Ap 24 +-7 - MST 1949 Ja 14 +-8 - PST 1970 +-7 m M%sT +Z America/Bahia_Banderas -7:1 - LMT 1922 Ja 1 7u +-7 - MST 1927 Jun 10 23 +-6 - CST 1930 N 15 +-7 m M%sT 1932 Ap +-6 - CST 1942 Ap 24 +-7 - MST 1949 Ja 14 +-8 - PST 1970 +-7 m M%sT 2010 Ap 4 2 +-6 m C%sT +Z America/Tijuana -7:48:4 - LMT 1922 Ja 1 7u +-7 - MST 1924 +-8 - PST 1927 Jun 10 23 +-7 - MST 1930 N 15 +-8 - PST 1931 Ap +-8 1 PDT 1931 S 30 +-8 - PST 1942 Ap 24 +-8 1 PWT 1945 Au 14 23u +-8 1 PPT 1945 N 12 +-8 - PST 1948 Ap 5 +-8 1 PDT 1949 Ja 14 +-8 - PST 1954 +-8 CA P%sT 1961 +-8 - PST 1976 +-8 u P%sT 1996 +-8 m P%sT 2001 +-8 u P%sT 2002 F 20 +-8 m P%sT 2010 +-8 u P%sT +R BB 1942 o - Ap 19 5u 1 D +R BB 1942 o - Au 31 6u 0 S +R BB 1943 o - May 2 5u 1 D +R BB 1943 o - S 5 6u 0 S +R BB 1944 o - Ap 10 5u 0:30 - +R BB 1944 o - S 10 6u 0 S +R BB 1977 o - Jun 12 2 1 D +R BB 1977 1978 - O Su>=1 2 0 S +R BB 1978 1980 - Ap Su>=15 2 1 D +R BB 1979 o - S 30 2 0 S +R BB 1980 o - S 25 2 0 S +Z America/Barbados -3:58:29 - LMT 1911 Au 28 +-4 BB A%sT 1944 +-4 BB AST/-0330 1945 +-4 BB A%sT +R BZ 1918 1941 - O Sa>=1 24 0:30 -0530 +R BZ 1919 1942 - F Sa>=8 24 0 CST +R BZ 1942 o - Jun 27 24 1 CWT +R BZ 1945 o - Au 14 23u 1 CPT +R BZ 1945 o - D 15 24 0 CST +R BZ 1947 1967 - O Sa>=1 24 0:30 -0530 +R BZ 1948 1968 - F Sa>=8 24 0 CST +R BZ 1973 o - D 5 0 1 CDT +R BZ 1974 o - F 9 0 0 CST +R BZ 1982 o - D 18 0 1 CDT +R BZ 1983 o - F 12 0 0 CST +Z America/Belize -5:52:48 - LMT 1912 Ap +-6 BZ %s +R Be 1917 o - Ap 5 24 1 - +R Be 1917 o - S 30 24 0 - +R Be 1918 o - Ap 13 24 1 - +R Be 1918 o - S 15 24 0 S +R Be 1942 o - Ja 11 2 1 D +R Be 1942 o - O 18 2 0 S +R Be 1943 o - Mar 21 2 1 D +R Be 1943 o - O 31 2 0 S +R Be 1944 1945 - Mar Su>=8 2 1 D +R Be 1944 1945 - N Su>=1 2 0 S +R Be 1947 o - May Su>=15 2 1 D +R Be 1947 o - S Su>=8 2 0 S +R Be 1948 1952 - May Su>=22 2 1 D +R Be 1948 1952 - S Su>=1 2 0 S +R Be 1956 o - May Su>=22 2 1 D +R Be 1956 o - O lastSu 2 0 S +Z Atlantic/Bermuda -4:19:18 - LMT 1890 +-4:19:18 Be BMT/BST 1930 Ja 1 2 +-4 Be A%sT 1974 Ap 28 2 +-4 C A%sT 1976 +-4 u A%sT +R CR 1979 1980 - F lastSu 0 1 D +R CR 1979 1980 - Jun Su>=1 0 0 S +R CR 1991 1992 - Ja Sa>=15 0 1 D +R CR 1991 o - Jul 1 0 0 S +R CR 1992 o - Mar 15 0 0 S +Z America/Costa_Rica -5:36:13 - LMT 1890 +-5:36:13 - SJMT 1921 Ja 15 +-6 CR C%sT +R Q 1928 o - Jun 10 0 1 D +R Q 1928 o - O 10 0 0 S +R Q 1940 1942 - Jun Su>=1 0 1 D +R Q 1940 1942 - S Su>=1 0 0 S +R Q 1945 1946 - Jun Su>=1 0 1 D +R Q 1945 1946 - S Su>=1 0 0 S +R Q 1965 o - Jun 1 0 1 D +R Q 1965 o - S 30 0 0 S +R Q 1966 o - May 29 0 1 D +R Q 1966 o - O 2 0 0 S +R Q 1967 o - Ap 8 0 1 D +R Q 1967 1968 - S Su>=8 0 0 S +R Q 1968 o - Ap 14 0 1 D +R Q 1969 1977 - Ap lastSu 0 1 D +R Q 1969 1971 - O lastSu 0 0 S +R Q 1972 1974 - O 8 0 0 S +R Q 1975 1977 - O lastSu 0 0 S +R Q 1978 o - May 7 0 1 D +R Q 1978 1990 - O Su>=8 0 0 S +R Q 1979 1980 - Mar Su>=15 0 1 D +R Q 1981 1985 - May Su>=5 0 1 D +R Q 1986 1989 - Mar Su>=14 0 1 D +R Q 1990 1997 - Ap Su>=1 0 1 D +R Q 1991 1995 - O Su>=8 0s 0 S +R Q 1996 o - O 6 0s 0 S +R Q 1997 o - O 12 0s 0 S +R Q 1998 1999 - Mar lastSu 0s 1 D +R Q 1998 2003 - O lastSu 0s 0 S +R Q 2000 2003 - Ap Su>=1 0s 1 D +R Q 2004 o - Mar lastSu 0s 1 D +R Q 2006 2010 - O lastSu 0s 0 S +R Q 2007 o - Mar Su>=8 0s 1 D +R Q 2008 o - Mar Su>=15 0s 1 D +R Q 2009 2010 - Mar Su>=8 0s 1 D +R Q 2011 o - Mar Su>=15 0s 1 D +R Q 2011 o - N 13 0s 0 S +R Q 2012 o - Ap 1 0s 1 D +R Q 2012 ma - N Su>=1 0s 0 S +R Q 2013 ma - Mar Su>=8 0s 1 D +Z America/Havana -5:29:28 - LMT 1890 +-5:29:36 - HMT 1925 Jul 19 12 +-5 Q C%sT +R DO 1966 o - O 30 0 1 EDT +R DO 1967 o - F 28 0 0 EST +R DO 1969 1973 - O lastSu 0 0:30 -0430 +R DO 1970 o - F 21 0 0 EST +R DO 1971 o - Ja 20 0 0 EST +R DO 1972 1974 - Ja 21 0 0 EST +Z America/Santo_Domingo -4:39:36 - LMT 1890 +-4:40 - SDMT 1933 Ap 1 12 +-5 DO %s 1974 O 27 +-4 - AST 2000 O 29 2 +-5 u E%sT 2000 D 3 1 +-4 - AST +R SV 1987 1988 - May Su>=1 0 1 D +R SV 1987 1988 - S lastSu 0 0 S +Z America/El_Salvador -5:56:48 - LMT 1921 +-6 SV C%sT +R GT 1973 o - N 25 0 1 D +R GT 1974 o - F 24 0 0 S +R GT 1983 o - May 21 0 1 D +R GT 1983 o - S 22 0 0 S +R GT 1991 o - Mar 23 0 1 D +R GT 1991 o - S 7 0 0 S +R GT 2006 o - Ap 30 0 1 D +R GT 2006 o - O 1 0 0 S +Z America/Guatemala -6:2:4 - LMT 1918 O 5 +-6 GT C%sT +R HT 1983 o - May 8 0 1 D +R HT 1984 1987 - Ap lastSu 0 1 D +R HT 1983 1987 - O lastSu 0 0 S +R HT 1988 1997 - Ap Su>=1 1s 1 D +R HT 1988 1997 - O lastSu 1s 0 S +R HT 2005 2006 - Ap Su>=1 0 1 D +R HT 2005 2006 - O lastSu 0 0 S +R HT 2012 2015 - Mar Su>=8 2 1 D +R HT 2012 2015 - N Su>=1 2 0 S +R HT 2017 ma - Mar Su>=8 2 1 D +R HT 2017 ma - N Su>=1 2 0 S +Z America/Port-au-Prince -4:49:20 - LMT 1890 +-4:49 - PPMT 1917 Ja 24 12 +-5 HT E%sT +R HN 1987 1988 - May Su>=1 0 1 D +R HN 1987 1988 - S lastSu 0 0 S +R HN 2006 o - May Su>=1 0 1 D +R HN 2006 o - Au M>=1 0 0 S +Z America/Tegucigalpa -5:48:52 - LMT 1921 Ap +-6 HN C%sT +Z America/Jamaica -5:7:10 - LMT 1890 +-5:7:10 - KMT 1912 F +-5 - EST 1974 +-5 u E%sT 1984 +-5 - EST +Z America/Martinique -4:4:20 - LMT 1890 +-4:4:20 - FFMT 1911 May +-4 - AST 1980 Ap 6 +-4 1 ADT 1980 S 28 +-4 - AST +R NI 1979 1980 - Mar Su>=16 0 1 D +R NI 1979 1980 - Jun M>=23 0 0 S +R NI 2005 o - Ap 10 0 1 D +R NI 2005 o - O Su>=1 0 0 S +R NI 2006 o - Ap 30 2 1 D +R NI 2006 o - O Su>=1 1 0 S +Z America/Managua -5:45:8 - LMT 1890 +-5:45:12 - MMT 1934 Jun 23 +-6 - CST 1973 May +-5 - EST 1975 F 16 +-6 NI C%sT 1992 Ja 1 4 +-5 - EST 1992 S 24 +-6 - CST 1993 +-5 - EST 1997 +-6 NI C%sT +Z America/Panama -5:18:8 - LMT 1890 +-5:19:36 - CMT 1908 Ap 22 +-5 - EST +Z America/Puerto_Rico -4:24:25 - LMT 1899 Mar 28 12 +-4 - AST 1942 May 3 +-4 u A%sT 1946 +-4 - AST +Z America/Miquelon -3:44:40 - LMT 1911 May 15 +-4 - AST 1980 May +-3 - -03 1987 +-3 C -03/-02 +Z America/Grand_Turk -4:44:32 - LMT 1890 +-5:7:10 - KMT 1912 F +-5 - EST 1979 +-5 u E%sT 2015 Mar 8 2 +-4 - AST 2018 Mar 11 3 +-5 u E%sT +R A 1930 o - D 1 0 1 - +R A 1931 o - Ap 1 0 0 - +R A 1931 o - O 15 0 1 - +R A 1932 1940 - Mar 1 0 0 - +R A 1932 1939 - N 1 0 1 - +R A 1940 o - Jul 1 0 1 - +R A 1941 o - Jun 15 0 0 - +R A 1941 o - O 15 0 1 - +R A 1943 o - Au 1 0 0 - +R A 1943 o - O 15 0 1 - +R A 1946 o - Mar 1 0 0 - +R A 1946 o - O 1 0 1 - +R A 1963 o - O 1 0 0 - +R A 1963 o - D 15 0 1 - +R A 1964 1966 - Mar 1 0 0 - +R A 1964 1966 - O 15 0 1 - +R A 1967 o - Ap 2 0 0 - +R A 1967 1968 - O Su>=1 0 1 - +R A 1968 1969 - Ap Su>=1 0 0 - +R A 1974 o - Ja 23 0 1 - +R A 1974 o - May 1 0 0 - +R A 1988 o - D 1 0 1 - +R A 1989 1993 - Mar Su>=1 0 0 - +R A 1989 1992 - O Su>=15 0 1 - +R A 1999 o - O Su>=1 0 1 - +R A 2000 o - Mar 3 0 0 - +R A 2007 o - D 30 0 1 - +R A 2008 2009 - Mar Su>=15 0 0 - +R A 2008 o - O Su>=15 0 1 - +Z America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 A -03/-02 +Z America/Argentina/Cordoba -4:16:48 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar 3 +-4 - -04 1991 O 20 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 A -03/-02 +Z America/Argentina/Salta -4:21:40 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar 3 +-4 - -04 1991 O 20 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 A -03/-02 2008 O 18 +-3 - -03 +Z America/Argentina/Tucuman -4:20:52 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar 3 +-4 - -04 1991 O 20 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 - -03 2004 Jun +-4 - -04 2004 Jun 13 +-3 A -03/-02 +Z America/Argentina/La_Rioja -4:27:24 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar +-4 - -04 1991 May 7 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 - -03 2004 Jun +-4 - -04 2004 Jun 20 +-3 A -03/-02 2008 O 18 +-3 - -03 +Z America/Argentina/San_Juan -4:34:4 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar +-4 - -04 1991 May 7 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 - -03 2004 May 31 +-4 - -04 2004 Jul 25 +-3 A -03/-02 2008 O 18 +-3 - -03 +Z America/Argentina/Jujuy -4:21:12 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1990 Mar 4 +-4 - -04 1990 O 28 +-4 1 -03 1991 Mar 17 +-4 - -04 1991 O 6 +-3 1 -02 1992 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 A -03/-02 2008 O 18 +-3 - -03 +Z America/Argentina/Catamarca -4:23:8 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar 3 +-4 - -04 1991 O 20 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 - -03 2004 Jun +-4 - -04 2004 Jun 20 +-3 A -03/-02 2008 O 18 +-3 - -03 +Z America/Argentina/Mendoza -4:35:16 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1990 Mar 4 +-4 - -04 1990 O 15 +-4 1 -03 1991 Mar +-4 - -04 1991 O 15 +-4 1 -03 1992 Mar +-4 - -04 1992 O 18 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 - -03 2004 May 23 +-4 - -04 2004 S 26 +-3 A -03/-02 2008 O 18 +-3 - -03 +R Sa 2008 2009 - Mar Su>=8 0 0 - +R Sa 2007 2008 - O Su>=8 0 1 - +Z America/Argentina/San_Luis -4:25:24 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1990 +-3 1 -02 1990 Mar 14 +-4 - -04 1990 O 15 +-4 1 -03 1991 Mar +-4 - -04 1991 Jun +-3 - -03 1999 O 3 +-4 1 -03 2000 Mar 3 +-3 - -03 2004 May 31 +-4 - -04 2004 Jul 25 +-3 A -03/-02 2008 Ja 21 +-4 Sa -04/-03 2009 O 11 +-3 - -03 +Z America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 - -03 2004 Jun +-4 - -04 2004 Jun 20 +-3 A -03/-02 2008 O 18 +-3 - -03 +Z America/Argentina/Ushuaia -4:33:12 - LMT 1894 O 31 +-4:16:48 - CMT 1920 May +-4 - -04 1930 D +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 - -03 2004 May 30 +-4 - -04 2004 Jun 20 +-3 A -03/-02 2008 O 18 +-3 - -03 +Z America/La_Paz -4:32:36 - LMT 1890 +-4:32:36 - CMT 1931 O 15 +-4:32:36 1 BST 1932 Mar 21 +-4 - -04 +R B 1931 o - O 3 11 1 - +R B 1932 1933 - Ap 1 0 0 - +R B 1932 o - O 3 0 1 - +R B 1949 1952 - D 1 0 1 - +R B 1950 o - Ap 16 1 0 - +R B 1951 1952 - Ap 1 0 0 - +R B 1953 o - Mar 1 0 0 - +R B 1963 o - D 9 0 1 - +R B 1964 o - Mar 1 0 0 - +R B 1965 o - Ja 31 0 1 - +R B 1965 o - Mar 31 0 0 - +R B 1965 o - D 1 0 1 - +R B 1966 1968 - Mar 1 0 0 - +R B 1966 1967 - N 1 0 1 - +R B 1985 o - N 2 0 1 - +R B 1986 o - Mar 15 0 0 - +R B 1986 o - O 25 0 1 - +R B 1987 o - F 14 0 0 - +R B 1987 o - O 25 0 1 - +R B 1988 o - F 7 0 0 - +R B 1988 o - O 16 0 1 - +R B 1989 o - Ja 29 0 0 - +R B 1989 o - O 15 0 1 - +R B 1990 o - F 11 0 0 - +R B 1990 o - O 21 0 1 - +R B 1991 o - F 17 0 0 - +R B 1991 o - O 20 0 1 - +R B 1992 o - F 9 0 0 - +R B 1992 o - O 25 0 1 - +R B 1993 o - Ja 31 0 0 - +R B 1993 1995 - O Su>=11 0 1 - +R B 1994 1995 - F Su>=15 0 0 - +R B 1996 o - F 11 0 0 - +R B 1996 o - O 6 0 1 - +R B 1997 o - F 16 0 0 - +R B 1997 o - O 6 0 1 - +R B 1998 o - Mar 1 0 0 - +R B 1998 o - O 11 0 1 - +R B 1999 o - F 21 0 0 - +R B 1999 o - O 3 0 1 - +R B 2000 o - F 27 0 0 - +R B 2000 2001 - O Su>=8 0 1 - +R B 2001 2006 - F Su>=15 0 0 - +R B 2002 o - N 3 0 1 - +R B 2003 o - O 19 0 1 - +R B 2004 o - N 2 0 1 - +R B 2005 o - O 16 0 1 - +R B 2006 o - N 5 0 1 - +R B 2007 o - F 25 0 0 - +R B 2007 o - O Su>=8 0 1 - +R B 2008 2017 - O Su>=15 0 1 - +R B 2008 2011 - F Su>=15 0 0 - +R B 2012 o - F Su>=22 0 0 - +R B 2013 2014 - F Su>=15 0 0 - +R B 2015 o - F Su>=22 0 0 - +R B 2016 2019 - F Su>=15 0 0 - +R B 2018 o - N Su>=1 0 1 - +Z America/Noronha -2:9:40 - LMT 1914 +-2 B -02/-01 1990 S 17 +-2 - -02 1999 S 30 +-2 B -02/-01 2000 O 15 +-2 - -02 2001 S 13 +-2 B -02/-01 2002 O +-2 - -02 +Z America/Belem -3:13:56 - LMT 1914 +-3 B -03/-02 1988 S 12 +-3 - -03 +Z America/Santarem -3:38:48 - LMT 1914 +-4 B -04/-03 1988 S 12 +-4 - -04 2008 Jun 24 +-3 - -03 +Z America/Fortaleza -2:34 - LMT 1914 +-3 B -03/-02 1990 S 17 +-3 - -03 1999 S 30 +-3 B -03/-02 2000 O 22 +-3 - -03 2001 S 13 +-3 B -03/-02 2002 O +-3 - -03 +Z America/Recife -2:19:36 - LMT 1914 +-3 B -03/-02 1990 S 17 +-3 - -03 1999 S 30 +-3 B -03/-02 2000 O 15 +-3 - -03 2001 S 13 +-3 B -03/-02 2002 O +-3 - -03 +Z America/Araguaina -3:12:48 - LMT 1914 +-3 B -03/-02 1990 S 17 +-3 - -03 1995 S 14 +-3 B -03/-02 2003 S 24 +-3 - -03 2012 O 21 +-3 B -03/-02 2013 S +-3 - -03 +Z America/Maceio -2:22:52 - LMT 1914 +-3 B -03/-02 1990 S 17 +-3 - -03 1995 O 13 +-3 B -03/-02 1996 S 4 +-3 - -03 1999 S 30 +-3 B -03/-02 2000 O 22 +-3 - -03 2001 S 13 +-3 B -03/-02 2002 O +-3 - -03 +Z America/Bahia -2:34:4 - LMT 1914 +-3 B -03/-02 2003 S 24 +-3 - -03 2011 O 16 +-3 B -03/-02 2012 O 21 +-3 - -03 +Z America/Sao_Paulo -3:6:28 - LMT 1914 +-3 B -03/-02 1963 O 23 +-3 1 -02 1964 +-3 B -03/-02 +Z America/Campo_Grande -3:38:28 - LMT 1914 +-4 B -04/-03 +Z America/Cuiaba -3:44:20 - LMT 1914 +-4 B -04/-03 2003 S 24 +-4 - -04 2004 O +-4 B -04/-03 +Z America/Porto_Velho -4:15:36 - LMT 1914 +-4 B -04/-03 1988 S 12 +-4 - -04 +Z America/Boa_Vista -4:2:40 - LMT 1914 +-4 B -04/-03 1988 S 12 +-4 - -04 1999 S 30 +-4 B -04/-03 2000 O 15 +-4 - -04 +Z America/Manaus -4:0:4 - LMT 1914 +-4 B -04/-03 1988 S 12 +-4 - -04 1993 S 28 +-4 B -04/-03 1994 S 22 +-4 - -04 +Z America/Eirunepe -4:39:28 - LMT 1914 +-5 B -05/-04 1988 S 12 +-5 - -05 1993 S 28 +-5 B -05/-04 1994 S 22 +-5 - -05 2008 Jun 24 +-4 - -04 2013 N 10 +-5 - -05 +Z America/Rio_Branco -4:31:12 - LMT 1914 +-5 B -05/-04 1988 S 12 +-5 - -05 2008 Jun 24 +-4 - -04 2013 N 10 +-5 - -05 +R x 1927 1931 - S 1 0 1 - +R x 1928 1932 - Ap 1 0 0 - +R x 1968 o - N 3 4u 1 - +R x 1969 o - Mar 30 3u 0 - +R x 1969 o - N 23 4u 1 - +R x 1970 o - Mar 29 3u 0 - +R x 1971 o - Mar 14 3u 0 - +R x 1970 1972 - O Su>=9 4u 1 - +R x 1972 1986 - Mar Su>=9 3u 0 - +R x 1973 o - S 30 4u 1 - +R x 1974 1987 - O Su>=9 4u 1 - +R x 1987 o - Ap 12 3u 0 - +R x 1988 1990 - Mar Su>=9 3u 0 - +R x 1988 1989 - O Su>=9 4u 1 - +R x 1990 o - S 16 4u 1 - +R x 1991 1996 - Mar Su>=9 3u 0 - +R x 1991 1997 - O Su>=9 4u 1 - +R x 1997 o - Mar 30 3u 0 - +R x 1998 o - Mar Su>=9 3u 0 - +R x 1998 o - S 27 4u 1 - +R x 1999 o - Ap 4 3u 0 - +R x 1999 2010 - O Su>=9 4u 1 - +R x 2000 2007 - Mar Su>=9 3u 0 - +R x 2008 o - Mar 30 3u 0 - +R x 2009 o - Mar Su>=9 3u 0 - +R x 2010 o - Ap Su>=1 3u 0 - +R x 2011 o - May Su>=2 3u 0 - +R x 2011 o - Au Su>=16 4u 1 - +R x 2012 2014 - Ap Su>=23 3u 0 - +R x 2012 2014 - S Su>=2 4u 1 - +R x 2016 2018 - May Su>=9 3u 0 - +R x 2016 2018 - Au Su>=9 4u 1 - +R x 2019 ma - Ap Su>=2 3u 0 - +R x 2019 2021 - S Su>=2 4u 1 - +R x 2022 o - S Su>=9 4u 1 - +R x 2023 ma - S Su>=2 4u 1 - +Z America/Santiago -4:42:45 - LMT 1890 +-4:42:45 - SMT 1910 Ja 10 +-5 - -05 1916 Jul +-4:42:45 - SMT 1918 S 10 +-4 - -04 1919 Jul +-4:42:45 - SMT 1927 S +-5 x -05/-04 1932 S +-4 - -04 1942 Jun +-5 - -05 1942 Au +-4 - -04 1946 Jul 14 24 +-4 1 -03 1946 Au 28 24 +-5 1 -04 1947 Mar 31 24 +-5 - -05 1947 May 21 23 +-4 x -04/-03 +Z America/Punta_Arenas -4:43:40 - LMT 1890 +-4:42:45 - SMT 1910 Ja 10 +-5 - -05 1916 Jul +-4:42:45 - SMT 1918 S 10 +-4 - -04 1919 Jul +-4:42:45 - SMT 1927 S +-5 x -05/-04 1932 S +-4 - -04 1942 Jun +-5 - -05 1942 Au +-4 - -04 1946 Au 28 24 +-5 1 -04 1947 Mar 31 24 +-5 - -05 1947 May 21 23 +-4 x -04/-03 2016 D 4 +-3 - -03 +Z Pacific/Easter -7:17:28 - LMT 1890 +-7:17:28 - EMT 1932 S +-7 x -07/-06 1982 Mar 14 3u +-6 x -06/-05 +Z Antarctica/Palmer 0 - -00 1965 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1982 May +-4 x -04/-03 2016 D 4 +-3 - -03 +R CO 1992 o - May 3 0 1 - +R CO 1993 o - F 6 24 0 - +Z America/Bogota -4:56:16 - LMT 1884 Mar 13 +-4:56:16 - BMT 1914 N 23 +-5 CO -05/-04 +R EC 1992 o - N 28 0 1 - +R EC 1993 o - F 5 0 0 - +Z America/Guayaquil -5:19:20 - LMT 1890 +-5:14 - QMT 1931 +-5 EC -05/-04 +Z Pacific/Galapagos -5:58:24 - LMT 1931 +-5 - -05 1986 +-6 EC -06/-05 +R FK 1937 1938 - S lastSu 0 1 - +R FK 1938 1942 - Mar Su>=19 0 0 - +R FK 1939 o - O 1 0 1 - +R FK 1940 1942 - S lastSu 0 1 - +R FK 1943 o - Ja 1 0 0 - +R FK 1983 o - S lastSu 0 1 - +R FK 1984 1985 - Ap lastSu 0 0 - +R FK 1984 o - S 16 0 1 - +R FK 1985 2000 - S Su>=9 0 1 - +R FK 1986 2000 - Ap Su>=16 0 0 - +R FK 2001 2010 - Ap Su>=15 2 0 - +R FK 2001 2010 - S Su>=1 2 1 - +Z Atlantic/Stanley -3:51:24 - LMT 1890 +-3:51:24 - SMT 1912 Mar 12 +-4 FK -04/-03 1983 May +-3 FK -03/-02 1985 S 15 +-4 FK -04/-03 2010 S 5 2 +-3 - -03 +Z America/Cayenne -3:29:20 - LMT 1911 Jul +-4 - -04 1967 O +-3 - -03 +Z America/Guyana -3:52:39 - LMT 1911 Au +-4 - -04 1915 Mar +-3:45 - -0345 1975 Au +-3 - -03 1992 Mar 29 1 +-4 - -04 +R y 1975 1988 - O 1 0 1 - +R y 1975 1978 - Mar 1 0 0 - +R y 1979 1991 - Ap 1 0 0 - +R y 1989 o - O 22 0 1 - +R y 1990 o - O 1 0 1 - +R y 1991 o - O 6 0 1 - +R y 1992 o - Mar 1 0 0 - +R y 1992 o - O 5 0 1 - +R y 1993 o - Mar 31 0 0 - +R y 1993 1995 - O 1 0 1 - +R y 1994 1995 - F lastSu 0 0 - +R y 1996 o - Mar 1 0 0 - +R y 1996 2001 - O Su>=1 0 1 - +R y 1997 o - F lastSu 0 0 - +R y 1998 2001 - Mar Su>=1 0 0 - +R y 2002 2004 - Ap Su>=1 0 0 - +R y 2002 2003 - S Su>=1 0 1 - +R y 2004 2009 - O Su>=15 0 1 - +R y 2005 2009 - Mar Su>=8 0 0 - +R y 2010 ma - O Su>=1 0 1 - +R y 2010 2012 - Ap Su>=8 0 0 - +R y 2013 ma - Mar Su>=22 0 0 - +Z America/Asuncion -3:50:40 - LMT 1890 +-3:50:40 - AMT 1931 O 10 +-4 - -04 1972 O +-3 - -03 1974 Ap +-4 y -04/-03 +R PE 1938 o - Ja 1 0 1 - +R PE 1938 o - Ap 1 0 0 - +R PE 1938 1939 - S lastSu 0 1 - +R PE 1939 1940 - Mar Su>=24 0 0 - +R PE 1986 1987 - Ja 1 0 1 - +R PE 1986 1987 - Ap 1 0 0 - +R PE 1990 o - Ja 1 0 1 - +R PE 1990 o - Ap 1 0 0 - +R PE 1994 o - Ja 1 0 1 - +R PE 1994 o - Ap 1 0 0 - +Z America/Lima -5:8:12 - LMT 1890 +-5:8:36 - LMT 1908 Jul 28 +-5 PE -05/-04 +Z Atlantic/South_Georgia -2:26:8 - LMT 1890 +-2 - -02 +Z America/Paramaribo -3:40:40 - LMT 1911 +-3:40:52 - PMT 1935 +-3:40:36 - PMT 1945 O +-3:30 - -0330 1984 O +-3 - -03 +R U 1923 1925 - O 1 0 0:30 - +R U 1924 1926 - Ap 1 0 0 - +R U 1933 1938 - O lastSu 0 0:30 - +R U 1934 1941 - Mar lastSa 24 0 - +R U 1939 o - O 1 0 0:30 - +R U 1940 o - O 27 0 0:30 - +R U 1941 o - Au 1 0 0:30 - +R U 1942 o - D 14 0 0:30 - +R U 1943 o - Mar 14 0 0 - +R U 1959 o - May 24 0 0:30 - +R U 1959 o - N 15 0 0 - +R U 1960 o - Ja 17 0 1 - +R U 1960 o - Mar 6 0 0 - +R U 1965 o - Ap 4 0 1 - +R U 1965 o - S 26 0 0 - +R U 1968 o - May 27 0 0:30 - +R U 1968 o - D 1 0 0 - +R U 1970 o - Ap 25 0 1 - +R U 1970 o - Jun 14 0 0 - +R U 1972 o - Ap 23 0 1 - +R U 1972 o - Jul 16 0 0 - +R U 1974 o - Ja 13 0 1:30 - +R U 1974 o - Mar 10 0 0:30 - +R U 1974 o - S 1 0 0 - +R U 1974 o - D 22 0 1 - +R U 1975 o - Mar 30 0 0 - +R U 1976 o - D 19 0 1 - +R U 1977 o - Mar 6 0 0 - +R U 1977 o - D 4 0 1 - +R U 1978 1979 - Mar Su>=1 0 0 - +R U 1978 o - D 17 0 1 - +R U 1979 o - Ap 29 0 1 - +R U 1980 o - Mar 16 0 0 - +R U 1987 o - D 14 0 1 - +R U 1988 o - F 28 0 0 - +R U 1988 o - D 11 0 1 - +R U 1989 o - Mar 5 0 0 - +R U 1989 o - O 29 0 1 - +R U 1990 o - F 25 0 0 - +R U 1990 1991 - O Su>=21 0 1 - +R U 1991 1992 - Mar Su>=1 0 0 - +R U 1992 o - O 18 0 1 - +R U 1993 o - F 28 0 0 - +R U 2004 o - S 19 0 1 - +R U 2005 o - Mar 27 2 0 - +R U 2005 o - O 9 2 1 - +R U 2006 2015 - Mar Su>=8 2 0 - +R U 2006 2014 - O Su>=1 2 1 - +Z America/Montevideo -3:44:51 - LMT 1908 Jun 10 +-3:44:51 - MMT 1920 May +-4 - -04 1923 O +-3:30 U -0330/-03 1942 D 14 +-3 U -03/-0230 1960 +-3 U -03/-02 1968 +-3 U -03/-0230 1970 +-3 U -03/-02 1974 +-3 U -03/-0130 1974 Mar 10 +-3 U -03/-0230 1974 D 22 +-3 U -03/-02 +Z America/Caracas -4:27:44 - LMT 1890 +-4:27:40 - CMT 1912 F 12 +-4:30 - -0430 1965 +-4 - -04 2007 D 9 3 +-4:30 - -0430 2016 May 1 2:30 +-4 - -04 +Z Etc/UTC 0 - UTC +Z Etc/GMT 0 - GMT +L Etc/GMT GMT +Z Etc/GMT-14 14 - +14 +Z Etc/GMT-13 13 - +13 +Z Etc/GMT-12 12 - +12 +Z Etc/GMT-11 11 - +11 +Z Etc/GMT-10 10 - +10 +Z Etc/GMT-9 9 - +09 +Z Etc/GMT-8 8 - +08 +Z Etc/GMT-7 7 - +07 +Z Etc/GMT-6 6 - +06 +Z Etc/GMT-5 5 - +05 +Z Etc/GMT-4 4 - +04 +Z Etc/GMT-3 3 - +03 +Z Etc/GMT-2 2 - +02 +Z Etc/GMT-1 1 - +01 +Z Etc/GMT+1 -1 - -01 +Z Etc/GMT+2 -2 - -02 +Z Etc/GMT+3 -3 - -03 +Z Etc/GMT+4 -4 - -04 +Z Etc/GMT+5 -5 - -05 +Z Etc/GMT+6 -6 - -06 +Z Etc/GMT+7 -7 - -07 +Z Etc/GMT+8 -8 - -08 +Z Etc/GMT+9 -9 - -09 +Z Etc/GMT+10 -10 - -10 +Z Etc/GMT+11 -11 - -11 +Z Etc/GMT+12 -12 - -12 +Z Factory 0 - -00 +L Australia/Sydney Australia/ACT +L Australia/Lord_Howe Australia/LHI +L Australia/Sydney Australia/NSW +L Australia/Darwin Australia/North +L Australia/Brisbane Australia/Queensland +L Australia/Adelaide Australia/South +L Australia/Hobart Australia/Tasmania +L Australia/Melbourne Australia/Victoria +L Australia/Perth Australia/West +L Australia/Broken_Hill Australia/Yancowinna +L America/Rio_Branco Brazil/Acre +L America/Noronha Brazil/DeNoronha +L America/Sao_Paulo Brazil/East +L America/Manaus Brazil/West +L America/Halifax Canada/Atlantic +L America/Winnipeg Canada/Central +L America/Toronto Canada/Eastern +L America/Edmonton Canada/Mountain +L America/St_Johns Canada/Newfoundland +L America/Vancouver Canada/Pacific +L America/Regina Canada/Saskatchewan +L America/Whitehorse Canada/Yukon +L America/Santiago Chile/Continental +L Pacific/Easter Chile/EasterIsland +L America/Havana Cuba +L Africa/Cairo Egypt +L Europe/Dublin Eire +L Etc/GMT Etc/GMT+0 +L Etc/GMT Etc/GMT-0 +L Etc/GMT Etc/GMT0 +L Etc/GMT Etc/Greenwich +L Etc/UTC Etc/UCT +L Etc/UTC Etc/Universal +L Etc/UTC Etc/Zulu +L Europe/London GB +L Europe/London GB-Eire +L Etc/GMT GMT+0 +L Etc/GMT GMT-0 +L Etc/GMT GMT0 +L Etc/GMT Greenwich +L Asia/Hong_Kong Hongkong +L Africa/Abidjan Iceland +L Asia/Tehran Iran +L Asia/Jerusalem Israel +L America/Jamaica Jamaica +L Asia/Tokyo Japan +L Pacific/Kwajalein Kwajalein +L Africa/Tripoli Libya +L America/Tijuana Mexico/BajaNorte +L America/Mazatlan Mexico/BajaSur +L America/Mexico_City Mexico/General +L Pacific/Auckland NZ +L Pacific/Chatham NZ-CHAT +L America/Denver Navajo +L Asia/Shanghai PRC +L Europe/Warsaw Poland +L Europe/Lisbon Portugal +L Asia/Taipei ROC +L Asia/Seoul ROK +L Asia/Singapore Singapore +L Europe/Istanbul Turkey +L Etc/UTC UCT +L America/Anchorage US/Alaska +L America/Adak US/Aleutian +L America/Phoenix US/Arizona +L America/Chicago US/Central +L America/Indiana/Indianapolis US/East-Indiana +L America/New_York US/Eastern +L Pacific/Honolulu US/Hawaii +L America/Indiana/Knox US/Indiana-Starke +L America/Detroit US/Michigan +L America/Denver US/Mountain +L America/Los_Angeles US/Pacific +L Pacific/Pago_Pago US/Samoa +L Etc/UTC UTC +L Etc/UTC Universal +L Europe/Moscow W-SU +L Etc/UTC Zulu +L America/Argentina/Buenos_Aires America/Buenos_Aires +L America/Argentina/Catamarca America/Catamarca +L America/Argentina/Cordoba America/Cordoba +L America/Indiana/Indianapolis America/Indianapolis +L America/Argentina/Jujuy America/Jujuy +L America/Indiana/Knox America/Knox_IN +L America/Kentucky/Louisville America/Louisville +L America/Argentina/Mendoza America/Mendoza +L America/Puerto_Rico America/Virgin +L Pacific/Pago_Pago Pacific/Samoa +L Africa/Abidjan Africa/Accra +L Africa/Nairobi Africa/Addis_Ababa +L Africa/Nairobi Africa/Asmara +L Africa/Abidjan Africa/Bamako +L Africa/Lagos Africa/Bangui +L Africa/Abidjan Africa/Banjul +L Africa/Maputo Africa/Blantyre +L Africa/Lagos Africa/Brazzaville +L Africa/Maputo Africa/Bujumbura +L Africa/Abidjan Africa/Conakry +L Africa/Abidjan Africa/Dakar +L Africa/Nairobi Africa/Dar_es_Salaam +L Africa/Nairobi Africa/Djibouti +L Africa/Lagos Africa/Douala +L Africa/Abidjan Africa/Freetown +L Africa/Maputo Africa/Gaborone +L Africa/Maputo Africa/Harare +L Africa/Nairobi Africa/Kampala +L Africa/Maputo Africa/Kigali +L Africa/Lagos Africa/Kinshasa +L Africa/Lagos Africa/Libreville +L Africa/Abidjan Africa/Lome +L Africa/Lagos Africa/Luanda +L Africa/Maputo Africa/Lubumbashi +L Africa/Maputo Africa/Lusaka +L Africa/Lagos Africa/Malabo +L Africa/Johannesburg Africa/Maseru +L Africa/Johannesburg Africa/Mbabane +L Africa/Nairobi Africa/Mogadishu +L Africa/Lagos Africa/Niamey +L Africa/Abidjan Africa/Nouakchott +L Africa/Abidjan Africa/Ouagadougou +L Africa/Lagos Africa/Porto-Novo +L America/Puerto_Rico America/Anguilla +L America/Puerto_Rico America/Antigua +L America/Puerto_Rico America/Aruba +L America/Panama America/Atikokan +L America/Puerto_Rico America/Blanc-Sablon +L America/Panama America/Cayman +L America/Phoenix America/Creston +L America/Puerto_Rico America/Curacao +L America/Puerto_Rico America/Dominica +L America/Puerto_Rico America/Grenada +L America/Puerto_Rico America/Guadeloupe +L America/Puerto_Rico America/Kralendijk +L America/Puerto_Rico America/Lower_Princes +L America/Puerto_Rico America/Marigot +L America/Puerto_Rico America/Montserrat +L America/Toronto America/Nassau +L America/Puerto_Rico America/Port_of_Spain +L America/Puerto_Rico America/St_Barthelemy +L America/Puerto_Rico America/St_Kitts +L America/Puerto_Rico America/St_Lucia +L America/Puerto_Rico America/St_Thomas +L America/Puerto_Rico America/St_Vincent +L America/Puerto_Rico America/Tortola +L Pacific/Port_Moresby Antarctica/DumontDUrville +L Pacific/Auckland Antarctica/McMurdo +L Asia/Riyadh Antarctica/Syowa +L Europe/Berlin Arctic/Longyearbyen +L Asia/Riyadh Asia/Aden +L Asia/Qatar Asia/Bahrain +L Asia/Kuching Asia/Brunei +L Asia/Singapore Asia/Kuala_Lumpur +L Asia/Riyadh Asia/Kuwait +L Asia/Dubai Asia/Muscat +L Asia/Bangkok Asia/Phnom_Penh +L Asia/Bangkok Asia/Vientiane +L Africa/Abidjan Atlantic/Reykjavik +L Africa/Abidjan Atlantic/St_Helena +L Europe/Brussels Europe/Amsterdam +L Europe/Prague Europe/Bratislava +L Europe/Zurich Europe/Busingen +L Europe/Berlin Europe/Copenhagen +L Europe/London Europe/Guernsey +L Europe/London Europe/Isle_of_Man +L Europe/London Europe/Jersey +L Europe/Belgrade Europe/Ljubljana +L Europe/Brussels Europe/Luxembourg +L Europe/Helsinki Europe/Mariehamn +L Europe/Paris Europe/Monaco +L Europe/Berlin Europe/Oslo +L Europe/Belgrade Europe/Podgorica +L Europe/Rome Europe/San_Marino +L Europe/Belgrade Europe/Sarajevo +L Europe/Belgrade Europe/Skopje +L Europe/Berlin Europe/Stockholm +L Europe/Zurich Europe/Vaduz +L Europe/Rome Europe/Vatican +L Europe/Belgrade Europe/Zagreb +L Africa/Nairobi Indian/Antananarivo +L Asia/Bangkok Indian/Christmas +L Asia/Yangon Indian/Cocos +L Africa/Nairobi Indian/Comoro +L Indian/Maldives Indian/Kerguelen +L Asia/Dubai Indian/Mahe +L Africa/Nairobi Indian/Mayotte +L Asia/Dubai Indian/Reunion +L Pacific/Port_Moresby Pacific/Chuuk +L Pacific/Tarawa Pacific/Funafuti +L Pacific/Tarawa Pacific/Majuro +L Pacific/Pago_Pago Pacific/Midway +L Pacific/Guadalcanal Pacific/Pohnpei +L Pacific/Guam Pacific/Saipan +L Pacific/Tarawa Pacific/Wake +L Pacific/Tarawa Pacific/Wallis +L Africa/Abidjan Africa/Timbuktu +L America/Argentina/Catamarca America/Argentina/ComodRivadavia +L America/Adak America/Atka +L America/Panama America/Coral_Harbour +L America/Tijuana America/Ensenada +L America/Indiana/Indianapolis America/Fort_Wayne +L America/Toronto America/Montreal +L America/Toronto America/Nipigon +L America/Iqaluit America/Pangnirtung +L America/Rio_Branco America/Porto_Acre +L America/Winnipeg America/Rainy_River +L America/Argentina/Cordoba America/Rosario +L America/Tijuana America/Santa_Isabel +L America/Denver America/Shiprock +L America/Toronto America/Thunder_Bay +L America/Edmonton America/Yellowknife +L Pacific/Auckland Antarctica/South_Pole +L Asia/Shanghai Asia/Chongqing +L Asia/Shanghai Asia/Harbin +L Asia/Urumqi Asia/Kashgar +L Asia/Jerusalem Asia/Tel_Aviv +L Europe/Berlin Atlantic/Jan_Mayen +L Australia/Sydney Australia/Canberra +L Australia/Hobart Australia/Currie +L Europe/London Europe/Belfast +L Europe/Chisinau Europe/Tiraspol +L Europe/Kyiv Europe/Uzhgorod +L Europe/Kyiv Europe/Zaporozhye +L Pacific/Kanton Pacific/Enderbury +L Pacific/Honolulu Pacific/Johnston +L Pacific/Port_Moresby Pacific/Yap +L Africa/Nairobi Africa/Asmera +L America/Nuuk America/Godthab +L Asia/Ashgabat Asia/Ashkhabad +L Asia/Kolkata Asia/Calcutta +L Asia/Shanghai Asia/Chungking +L Asia/Dhaka Asia/Dacca +L Europe/Istanbul Asia/Istanbul +L Asia/Kathmandu Asia/Katmandu +L Asia/Macau Asia/Macao +L Asia/Yangon Asia/Rangoon +L Asia/Ho_Chi_Minh Asia/Saigon +L Asia/Thimphu Asia/Thimbu +L Asia/Makassar Asia/Ujung_Pandang +L Asia/Ulaanbaatar Asia/Ulan_Bator +L Atlantic/Faroe Atlantic/Faeroe +L Europe/Kyiv Europe/Kiev +L Asia/Nicosia Europe/Nicosia +L Pacific/Guadalcanal Pacific/Ponape +L Pacific/Port_Moresby Pacific/Truk diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/zone.tab b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/zone.tab new file mode 100644 index 0000000000000000000000000000000000000000..3fa9306afbad786fb8a6ba0bd54a1d38975dce8d --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/zone.tab @@ -0,0 +1,448 @@ +# tzdb timezone descriptions (deprecated version) +# +# This file is in the public domain, so clarified as of +# 2009-05-17 by Arthur David Olson. +# +# From Paul Eggert (2021-09-20): +# This file is intended as a backward-compatibility aid for older programs. +# New programs should use zone1970.tab. This file is like zone1970.tab (see +# zone1970.tab's comments), but with the following additional restrictions: +# +# 1. This file contains only ASCII characters. +# 2. The first data column contains exactly one country code. +# +# Because of (2), each row stands for an area that is the intersection +# of a region identified by a country code and of a timezone where civil +# clocks have agreed since 1970; this is a narrower definition than +# that of zone1970.tab. +# +# Unlike zone1970.tab, a row's third column can be a Link from +# 'backward' instead of a Zone. +# +# This table is intended as an aid for users, to help them select timezones +# appropriate for their practical needs. It is not intended to take or +# endorse any position on legal or territorial claims. +# +#country- +#code coordinates TZ comments +AD +4230+00131 Europe/Andorra +AE +2518+05518 Asia/Dubai +AF +3431+06912 Asia/Kabul +AG +1703-06148 America/Antigua +AI +1812-06304 America/Anguilla +AL +4120+01950 Europe/Tirane +AM +4011+04430 Asia/Yerevan +AO -0848+01314 Africa/Luanda +AQ -7750+16636 Antarctica/McMurdo New Zealand time - McMurdo, South Pole +AQ -6617+11031 Antarctica/Casey Casey +AQ -6835+07758 Antarctica/Davis Davis +AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville +AQ -6736+06253 Antarctica/Mawson Mawson +AQ -6448-06406 Antarctica/Palmer Palmer +AQ -6734-06808 Antarctica/Rothera Rothera +AQ -690022+0393524 Antarctica/Syowa Syowa +AQ -720041+0023206 Antarctica/Troll Troll +AQ -7824+10654 Antarctica/Vostok Vostok +AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF) +AR -3124-06411 America/Argentina/Cordoba Argentina (most areas: CB, CC, CN, ER, FM, MN, SE, SF) +AR -2447-06525 America/Argentina/Salta Salta (SA, LP, NQ, RN) +AR -2411-06518 America/Argentina/Jujuy Jujuy (JY) +AR -2649-06513 America/Argentina/Tucuman Tucuman (TM) +AR -2828-06547 America/Argentina/Catamarca Catamarca (CT), Chubut (CH) +AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR) +AR -3132-06831 America/Argentina/San_Juan San Juan (SJ) +AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ) +AR -3319-06621 America/Argentina/San_Luis San Luis (SL) +AR -5138-06913 America/Argentina/Rio_Gallegos Santa Cruz (SC) +AR -5448-06818 America/Argentina/Ushuaia Tierra del Fuego (TF) +AS -1416-17042 Pacific/Pago_Pago +AT +4813+01620 Europe/Vienna +AU -3133+15905 Australia/Lord_Howe Lord Howe Island +AU -5430+15857 Antarctica/Macquarie Macquarie Island +AU -4253+14719 Australia/Hobart Tasmania +AU -3749+14458 Australia/Melbourne Victoria +AU -3352+15113 Australia/Sydney New South Wales (most areas) +AU -3157+14127 Australia/Broken_Hill New South Wales (Yancowinna) +AU -2728+15302 Australia/Brisbane Queensland (most areas) +AU -2016+14900 Australia/Lindeman Queensland (Whitsunday Islands) +AU -3455+13835 Australia/Adelaide South Australia +AU -1228+13050 Australia/Darwin Northern Territory +AU -3157+11551 Australia/Perth Western Australia (most areas) +AU -3143+12852 Australia/Eucla Western Australia (Eucla) +AW +1230-06958 America/Aruba +AX +6006+01957 Europe/Mariehamn +AZ +4023+04951 Asia/Baku +BA +4352+01825 Europe/Sarajevo +BB +1306-05937 America/Barbados +BD +2343+09025 Asia/Dhaka +BE +5050+00420 Europe/Brussels +BF +1222-00131 Africa/Ouagadougou +BG +4241+02319 Europe/Sofia +BH +2623+05035 Asia/Bahrain +BI -0323+02922 Africa/Bujumbura +BJ +0629+00237 Africa/Porto-Novo +BL +1753-06251 America/St_Barthelemy +BM +3217-06446 Atlantic/Bermuda +BN +0456+11455 Asia/Brunei +BO -1630-06809 America/La_Paz +BQ +120903-0681636 America/Kralendijk +BR -0351-03225 America/Noronha Atlantic islands +BR -0127-04829 America/Belem Para (east), Amapa +BR -0343-03830 America/Fortaleza Brazil (northeast: MA, PI, CE, RN, PB) +BR -0803-03454 America/Recife Pernambuco +BR -0712-04812 America/Araguaina Tocantins +BR -0940-03543 America/Maceio Alagoas, Sergipe +BR -1259-03831 America/Bahia Bahia +BR -2332-04637 America/Sao_Paulo Brazil (southeast: GO, DF, MG, ES, RJ, SP, PR, SC, RS) +BR -2027-05437 America/Campo_Grande Mato Grosso do Sul +BR -1535-05605 America/Cuiaba Mato Grosso +BR -0226-05452 America/Santarem Para (west) +BR -0846-06354 America/Porto_Velho Rondonia +BR +0249-06040 America/Boa_Vista Roraima +BR -0308-06001 America/Manaus Amazonas (east) +BR -0640-06952 America/Eirunepe Amazonas (west) +BR -0958-06748 America/Rio_Branco Acre +BS +2505-07721 America/Nassau +BT +2728+08939 Asia/Thimphu +BW -2439+02555 Africa/Gaborone +BY +5354+02734 Europe/Minsk +BZ +1730-08812 America/Belize +CA +4734-05243 America/St_Johns Newfoundland, Labrador (SE) +CA +4439-06336 America/Halifax Atlantic - NS (most areas), PE +CA +4612-05957 America/Glace_Bay Atlantic - NS (Cape Breton) +CA +4606-06447 America/Moncton Atlantic - New Brunswick +CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas) +CA +5125-05707 America/Blanc-Sablon AST - QC (Lower North Shore) +CA +4339-07923 America/Toronto Eastern - ON & QC (most areas) +CA +6344-06828 America/Iqaluit Eastern - NU (most areas) +CA +484531-0913718 America/Atikokan EST - ON (Atikokan), NU (Coral H) +CA +4953-09709 America/Winnipeg Central - ON (west), Manitoba +CA +744144-0944945 America/Resolute Central - NU (Resolute) +CA +624900-0920459 America/Rankin_Inlet Central - NU (central) +CA +5024-10439 America/Regina CST - SK (most areas) +CA +5017-10750 America/Swift_Current CST - SK (midwest) +CA +5333-11328 America/Edmonton Mountain - AB, BC(E), NT(E), SK(W) +CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west) +CA +682059-1334300 America/Inuvik Mountain - NT (west) +CA +4906-11631 America/Creston MST - BC (Creston) +CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John) +CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson) +CA +6043-13503 America/Whitehorse MST - Yukon (east) +CA +6404-13925 America/Dawson MST - Yukon (west) +CA +4916-12307 America/Vancouver Pacific - BC (most areas) +CC -1210+09655 Indian/Cocos +CD -0418+01518 Africa/Kinshasa Dem. Rep. of Congo (west) +CD -1140+02728 Africa/Lubumbashi Dem. Rep. of Congo (east) +CF +0422+01835 Africa/Bangui +CG -0416+01517 Africa/Brazzaville +CH +4723+00832 Europe/Zurich +CI +0519-00402 Africa/Abidjan +CK -2114-15946 Pacific/Rarotonga +CL -3327-07040 America/Santiago most of Chile +CL -5309-07055 America/Punta_Arenas Region of Magallanes +CL -2709-10926 Pacific/Easter Easter Island +CM +0403+00942 Africa/Douala +CN +3114+12128 Asia/Shanghai Beijing Time +CN +4348+08735 Asia/Urumqi Xinjiang Time +CO +0436-07405 America/Bogota +CR +0956-08405 America/Costa_Rica +CU +2308-08222 America/Havana +CV +1455-02331 Atlantic/Cape_Verde +CW +1211-06900 America/Curacao +CX -1025+10543 Indian/Christmas +CY +3510+03322 Asia/Nicosia most of Cyprus +CY +3507+03357 Asia/Famagusta Northern Cyprus +CZ +5005+01426 Europe/Prague +DE +5230+01322 Europe/Berlin most of Germany +DE +4742+00841 Europe/Busingen Busingen +DJ +1136+04309 Africa/Djibouti +DK +5540+01235 Europe/Copenhagen +DM +1518-06124 America/Dominica +DO +1828-06954 America/Santo_Domingo +DZ +3647+00303 Africa/Algiers +EC -0210-07950 America/Guayaquil Ecuador (mainland) +EC -0054-08936 Pacific/Galapagos Galapagos Islands +EE +5925+02445 Europe/Tallinn +EG +3003+03115 Africa/Cairo +EH +2709-01312 Africa/El_Aaiun +ER +1520+03853 Africa/Asmara +ES +4024-00341 Europe/Madrid Spain (mainland) +ES +3553-00519 Africa/Ceuta Ceuta, Melilla +ES +2806-01524 Atlantic/Canary Canary Islands +ET +0902+03842 Africa/Addis_Ababa +FI +6010+02458 Europe/Helsinki +FJ -1808+17825 Pacific/Fiji +FK -5142-05751 Atlantic/Stanley +FM +0725+15147 Pacific/Chuuk Chuuk/Truk, Yap +FM +0658+15813 Pacific/Pohnpei Pohnpei/Ponape +FM +0519+16259 Pacific/Kosrae Kosrae +FO +6201-00646 Atlantic/Faroe +FR +4852+00220 Europe/Paris +GA +0023+00927 Africa/Libreville +GB +513030-0000731 Europe/London +GD +1203-06145 America/Grenada +GE +4143+04449 Asia/Tbilisi +GF +0456-05220 America/Cayenne +GG +492717-0023210 Europe/Guernsey +GH +0533-00013 Africa/Accra +GI +3608-00521 Europe/Gibraltar +GL +6411-05144 America/Nuuk most of Greenland +GL +7646-01840 America/Danmarkshavn National Park (east coast) +GL +7029-02158 America/Scoresbysund Scoresbysund/Ittoqqortoormiit +GL +7634-06847 America/Thule Thule/Pituffik +GM +1328-01639 Africa/Banjul +GN +0931-01343 Africa/Conakry +GP +1614-06132 America/Guadeloupe +GQ +0345+00847 Africa/Malabo +GR +3758+02343 Europe/Athens +GS -5416-03632 Atlantic/South_Georgia +GT +1438-09031 America/Guatemala +GU +1328+14445 Pacific/Guam +GW +1151-01535 Africa/Bissau +GY +0648-05810 America/Guyana +HK +2217+11409 Asia/Hong_Kong +HN +1406-08713 America/Tegucigalpa +HR +4548+01558 Europe/Zagreb +HT +1832-07220 America/Port-au-Prince +HU +4730+01905 Europe/Budapest +ID -0610+10648 Asia/Jakarta Java, Sumatra +ID -0002+10920 Asia/Pontianak Borneo (west, central) +ID -0507+11924 Asia/Makassar Borneo (east, south), Sulawesi/Celebes, Bali, Nusa Tengarra, Timor (west) +ID -0232+14042 Asia/Jayapura New Guinea (West Papua / Irian Jaya), Malukus/Moluccas +IE +5320-00615 Europe/Dublin +IL +314650+0351326 Asia/Jerusalem +IM +5409-00428 Europe/Isle_of_Man +IN +2232+08822 Asia/Kolkata +IO -0720+07225 Indian/Chagos +IQ +3321+04425 Asia/Baghdad +IR +3540+05126 Asia/Tehran +IS +6409-02151 Atlantic/Reykjavik +IT +4154+01229 Europe/Rome +JE +491101-0020624 Europe/Jersey +JM +175805-0764736 America/Jamaica +JO +3157+03556 Asia/Amman +JP +353916+1394441 Asia/Tokyo +KE -0117+03649 Africa/Nairobi +KG +4254+07436 Asia/Bishkek +KH +1133+10455 Asia/Phnom_Penh +KI +0125+17300 Pacific/Tarawa Gilbert Islands +KI -0247-17143 Pacific/Kanton Phoenix Islands +KI +0152-15720 Pacific/Kiritimati Line Islands +KM -1141+04316 Indian/Comoro +KN +1718-06243 America/St_Kitts +KP +3901+12545 Asia/Pyongyang +KR +3733+12658 Asia/Seoul +KW +2920+04759 Asia/Kuwait +KY +1918-08123 America/Cayman +KZ +4315+07657 Asia/Almaty most of Kazakhstan +KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda +KZ +5312+06337 Asia/Qostanay Qostanay/Kostanay/Kustanay +KZ +5017+05710 Asia/Aqtobe Aqtobe/Aktobe +KZ +4431+05016 Asia/Aqtau Mangghystau/Mankistau +KZ +4707+05156 Asia/Atyrau Atyrau/Atirau/Gur'yev +KZ +5113+05121 Asia/Oral West Kazakhstan +LA +1758+10236 Asia/Vientiane +LB +3353+03530 Asia/Beirut +LC +1401-06100 America/St_Lucia +LI +4709+00931 Europe/Vaduz +LK +0656+07951 Asia/Colombo +LR +0618-01047 Africa/Monrovia +LS -2928+02730 Africa/Maseru +LT +5441+02519 Europe/Vilnius +LU +4936+00609 Europe/Luxembourg +LV +5657+02406 Europe/Riga +LY +3254+01311 Africa/Tripoli +MA +3339-00735 Africa/Casablanca +MC +4342+00723 Europe/Monaco +MD +4700+02850 Europe/Chisinau +ME +4226+01916 Europe/Podgorica +MF +1804-06305 America/Marigot +MG -1855+04731 Indian/Antananarivo +MH +0709+17112 Pacific/Majuro most of Marshall Islands +MH +0905+16720 Pacific/Kwajalein Kwajalein +MK +4159+02126 Europe/Skopje +ML +1239-00800 Africa/Bamako +MM +1647+09610 Asia/Yangon +MN +4755+10653 Asia/Ulaanbaatar most of Mongolia +MN +4801+09139 Asia/Hovd Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan +MN +4804+11430 Asia/Choibalsan Dornod, Sukhbaatar +MO +221150+1133230 Asia/Macau +MP +1512+14545 Pacific/Saipan +MQ +1436-06105 America/Martinique +MR +1806-01557 Africa/Nouakchott +MS +1643-06213 America/Montserrat +MT +3554+01431 Europe/Malta +MU -2010+05730 Indian/Mauritius +MV +0410+07330 Indian/Maldives +MW -1547+03500 Africa/Blantyre +MX +1924-09909 America/Mexico_City Central Mexico +MX +2105-08646 America/Cancun Quintana Roo +MX +2058-08937 America/Merida Campeche, Yucatan +MX +2540-10019 America/Monterrey Durango; Coahuila, Nuevo Leon, Tamaulipas (most areas) +MX +2550-09730 America/Matamoros Coahuila, Nuevo Leon, Tamaulipas (US border) +MX +2838-10605 America/Chihuahua Chihuahua (most areas) +MX +3144-10629 America/Ciudad_Juarez Chihuahua (US border - west) +MX +2934-10425 America/Ojinaga Chihuahua (US border - east) +MX +2313-10625 America/Mazatlan Baja California Sur, Nayarit (most areas), Sinaloa +MX +2048-10515 America/Bahia_Banderas Bahia de Banderas +MX +2904-11058 America/Hermosillo Sonora +MX +3232-11701 America/Tijuana Baja California +MY +0310+10142 Asia/Kuala_Lumpur Malaysia (peninsula) +MY +0133+11020 Asia/Kuching Sabah, Sarawak +MZ -2558+03235 Africa/Maputo +NA -2234+01706 Africa/Windhoek +NC -2216+16627 Pacific/Noumea +NE +1331+00207 Africa/Niamey +NF -2903+16758 Pacific/Norfolk +NG +0627+00324 Africa/Lagos +NI +1209-08617 America/Managua +NL +5222+00454 Europe/Amsterdam +NO +5955+01045 Europe/Oslo +NP +2743+08519 Asia/Kathmandu +NR -0031+16655 Pacific/Nauru +NU -1901-16955 Pacific/Niue +NZ -3652+17446 Pacific/Auckland most of New Zealand +NZ -4357-17633 Pacific/Chatham Chatham Islands +OM +2336+05835 Asia/Muscat +PA +0858-07932 America/Panama +PE -1203-07703 America/Lima +PF -1732-14934 Pacific/Tahiti Society Islands +PF -0900-13930 Pacific/Marquesas Marquesas Islands +PF -2308-13457 Pacific/Gambier Gambier Islands +PG -0930+14710 Pacific/Port_Moresby most of Papua New Guinea +PG -0613+15534 Pacific/Bougainville Bougainville +PH +1435+12100 Asia/Manila +PK +2452+06703 Asia/Karachi +PL +5215+02100 Europe/Warsaw +PM +4703-05620 America/Miquelon +PN -2504-13005 Pacific/Pitcairn +PR +182806-0660622 America/Puerto_Rico +PS +3130+03428 Asia/Gaza Gaza Strip +PS +313200+0350542 Asia/Hebron West Bank +PT +3843-00908 Europe/Lisbon Portugal (mainland) +PT +3238-01654 Atlantic/Madeira Madeira Islands +PT +3744-02540 Atlantic/Azores Azores +PW +0720+13429 Pacific/Palau +PY -2516-05740 America/Asuncion +QA +2517+05132 Asia/Qatar +RE -2052+05528 Indian/Reunion +RO +4426+02606 Europe/Bucharest +RS +4450+02030 Europe/Belgrade +RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad +RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area +# The obsolescent zone.tab format cannot represent Europe/Simferopol well. +# Put it in RU section and list as UA. See "territorial claims" above. +# Programs should use zone1970.tab instead; see above. +UA +4457+03406 Europe/Simferopol Crimea +RU +5836+04939 Europe/Kirov MSK+00 - Kirov +RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd +RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan +RU +5134+04602 Europe/Saratov MSK+01 - Saratov +RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk +RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia +RU +5651+06036 Asia/Yekaterinburg MSK+02 - Urals +RU +5500+07324 Asia/Omsk MSK+03 - Omsk +RU +5502+08255 Asia/Novosibirsk MSK+04 - Novosibirsk +RU +5322+08345 Asia/Barnaul MSK+04 - Altai +RU +5630+08458 Asia/Tomsk MSK+04 - Tomsk +RU +5345+08707 Asia/Novokuznetsk MSK+04 - Kemerovo +RU +5601+09250 Asia/Krasnoyarsk MSK+04 - Krasnoyarsk area +RU +5216+10420 Asia/Irkutsk MSK+05 - Irkutsk, Buryatia +RU +5203+11328 Asia/Chita MSK+06 - Zabaykalsky +RU +6200+12940 Asia/Yakutsk MSK+06 - Lena River +RU +623923+1353314 Asia/Khandyga MSK+06 - Tomponsky, Ust-Maysky +RU +4310+13156 Asia/Vladivostok MSK+07 - Amur River +RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky +RU +5934+15048 Asia/Magadan MSK+08 - Magadan +RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island +RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E), N Kuril Is +RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka +RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea +RW -0157+03004 Africa/Kigali +SA +2438+04643 Asia/Riyadh +SB -0932+16012 Pacific/Guadalcanal +SC -0440+05528 Indian/Mahe +SD +1536+03232 Africa/Khartoum +SE +5920+01803 Europe/Stockholm +SG +0117+10351 Asia/Singapore +SH -1555-00542 Atlantic/St_Helena +SI +4603+01431 Europe/Ljubljana +SJ +7800+01600 Arctic/Longyearbyen +SK +4809+01707 Europe/Bratislava +SL +0830-01315 Africa/Freetown +SM +4355+01228 Europe/San_Marino +SN +1440-01726 Africa/Dakar +SO +0204+04522 Africa/Mogadishu +SR +0550-05510 America/Paramaribo +SS +0451+03137 Africa/Juba +ST +0020+00644 Africa/Sao_Tome +SV +1342-08912 America/El_Salvador +SX +180305-0630250 America/Lower_Princes +SY +3330+03618 Asia/Damascus +SZ -2618+03106 Africa/Mbabane +TC +2128-07108 America/Grand_Turk +TD +1207+01503 Africa/Ndjamena +TF -492110+0701303 Indian/Kerguelen +TG +0608+00113 Africa/Lome +TH +1345+10031 Asia/Bangkok +TJ +3835+06848 Asia/Dushanbe +TK -0922-17114 Pacific/Fakaofo +TL -0833+12535 Asia/Dili +TM +3757+05823 Asia/Ashgabat +TN +3648+01011 Africa/Tunis +TO -210800-1751200 Pacific/Tongatapu +TR +4101+02858 Europe/Istanbul +TT +1039-06131 America/Port_of_Spain +TV -0831+17913 Pacific/Funafuti +TW +2503+12130 Asia/Taipei +TZ -0648+03917 Africa/Dar_es_Salaam +UA +5026+03031 Europe/Kyiv most of Ukraine +UG +0019+03225 Africa/Kampala +UM +2813-17722 Pacific/Midway Midway Islands +UM +1917+16637 Pacific/Wake Wake Island +US +404251-0740023 America/New_York Eastern (most areas) +US +421953-0830245 America/Detroit Eastern - MI (most areas) +US +381515-0854534 America/Kentucky/Louisville Eastern - KY (Louisville area) +US +364947-0845057 America/Kentucky/Monticello Eastern - KY (Wayne) +US +394606-0860929 America/Indiana/Indianapolis Eastern - IN (most areas) +US +384038-0873143 America/Indiana/Vincennes Eastern - IN (Da, Du, K, Mn) +US +410305-0863611 America/Indiana/Winamac Eastern - IN (Pulaski) +US +382232-0862041 America/Indiana/Marengo Eastern - IN (Crawford) +US +382931-0871643 America/Indiana/Petersburg Eastern - IN (Pike) +US +384452-0850402 America/Indiana/Vevay Eastern - IN (Switzerland) +US +415100-0873900 America/Chicago Central (most areas) +US +375711-0864541 America/Indiana/Tell_City Central - IN (Perry) +US +411745-0863730 America/Indiana/Knox Central - IN (Starke) +US +450628-0873651 America/Menominee Central - MI (Wisconsin border) +US +470659-1011757 America/North_Dakota/Center Central - ND (Oliver) +US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural) +US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer) +US +394421-1045903 America/Denver Mountain (most areas) +US +433649-1161209 America/Boise Mountain - ID (south), OR (east) +US +332654-1120424 America/Phoenix MST - AZ (except Navajo) +US +340308-1181434 America/Los_Angeles Pacific +US +611305-1495401 America/Anchorage Alaska (most areas) +US +581807-1342511 America/Juneau Alaska - Juneau area +US +571035-1351807 America/Sitka Alaska - Sitka area +US +550737-1313435 America/Metlakatla Alaska - Annette Island +US +593249-1394338 America/Yakutat Alaska - Yakutat +US +643004-1652423 America/Nome Alaska (west) +US +515248-1763929 America/Adak Alaska - western Aleutians +US +211825-1575130 Pacific/Honolulu Hawaii +UY -345433-0561245 America/Montevideo +UZ +3940+06648 Asia/Samarkand Uzbekistan (west) +UZ +4120+06918 Asia/Tashkent Uzbekistan (east) +VA +415408+0122711 Europe/Vatican +VC +1309-06114 America/St_Vincent +VE +1030-06656 America/Caracas +VG +1827-06437 America/Tortola +VI +1821-06456 America/St_Thomas +VN +1045+10640 Asia/Ho_Chi_Minh +VU -1740+16825 Pacific/Efate +WF -1318-17610 Pacific/Wallis +WS -1350-17144 Pacific/Apia +YE +1245+04512 Asia/Aden +YT -1247+04514 Indian/Mayotte +ZA -2615+02800 Africa/Johannesburg +ZM -1525+02817 Africa/Lusaka +ZW -1750+03103 Africa/Harare diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/zone1970.tab b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/zone1970.tab new file mode 100644 index 0000000000000000000000000000000000000000..abd9489753f1aab2e8120506041d537d86f75206 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/zone1970.tab @@ -0,0 +1,375 @@ +# tzdb timezone descriptions +# +# This file is in the public domain. +# +# From Paul Eggert (2018-06-27): +# This file contains a table where each row stands for a timezone where +# civil timestamps have agreed since 1970. Columns are separated by +# a single tab. Lines beginning with '#' are comments. All text uses +# UTF-8 encoding. The columns of the table are as follows: +# +# 1. The countries that overlap the timezone, as a comma-separated list +# of ISO 3166 2-character country codes. See the file 'iso3166.tab'. +# 2. Latitude and longitude of the timezone's principal location +# in ISO 6709 sign-degrees-minutes-seconds format, +# either ±DDMM±DDDMM or ±DDMMSS±DDDMMSS, +# first latitude (+ is north), then longitude (+ is east). +# 3. Timezone name used in value of TZ environment variable. +# Please see the theory.html file for how these names are chosen. +# If multiple timezones overlap a country, each has a row in the +# table, with each column 1 containing the country code. +# 4. Comments; present if and only if countries have multiple timezones, +# and useful only for those countries. For example, the comments +# for the row with countries CH,DE,LI and name Europe/Zurich +# are useful only for DE, since CH and LI have no other timezones. +# +# If a timezone covers multiple countries, the most-populous city is used, +# and that country is listed first in column 1; any other countries +# are listed alphabetically by country code. The table is sorted +# first by country code, then (if possible) by an order within the +# country that (1) makes some geographical sense, and (2) puts the +# most populous timezones first, where that does not contradict (1). +# +# This table is intended as an aid for users, to help them select timezones +# appropriate for their practical needs. It is not intended to take or +# endorse any position on legal or territorial claims. +# +#country- +#codes coordinates TZ comments +AD +4230+00131 Europe/Andorra +AE,OM,RE,SC,TF +2518+05518 Asia/Dubai Crozet +AF +3431+06912 Asia/Kabul +AL +4120+01950 Europe/Tirane +AM +4011+04430 Asia/Yerevan +AQ -6617+11031 Antarctica/Casey Casey +AQ -6835+07758 Antarctica/Davis Davis +AQ -6736+06253 Antarctica/Mawson Mawson +AQ -6448-06406 Antarctica/Palmer Palmer +AQ -6734-06808 Antarctica/Rothera Rothera +AQ -720041+0023206 Antarctica/Troll Troll +AQ -7824+10654 Antarctica/Vostok Vostok +AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF) +AR -3124-06411 America/Argentina/Cordoba most areas: CB, CC, CN, ER, FM, MN, SE, SF +AR -2447-06525 America/Argentina/Salta Salta (SA, LP, NQ, RN) +AR -2411-06518 America/Argentina/Jujuy Jujuy (JY) +AR -2649-06513 America/Argentina/Tucuman Tucumán (TM) +AR -2828-06547 America/Argentina/Catamarca Catamarca (CT), Chubut (CH) +AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR) +AR -3132-06831 America/Argentina/San_Juan San Juan (SJ) +AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ) +AR -3319-06621 America/Argentina/San_Luis San Luis (SL) +AR -5138-06913 America/Argentina/Rio_Gallegos Santa Cruz (SC) +AR -5448-06818 America/Argentina/Ushuaia Tierra del Fuego (TF) +AS,UM -1416-17042 Pacific/Pago_Pago Midway +AT +4813+01620 Europe/Vienna +AU -3133+15905 Australia/Lord_Howe Lord Howe Island +AU -5430+15857 Antarctica/Macquarie Macquarie Island +AU -4253+14719 Australia/Hobart Tasmania +AU -3749+14458 Australia/Melbourne Victoria +AU -3352+15113 Australia/Sydney New South Wales (most areas) +AU -3157+14127 Australia/Broken_Hill New South Wales (Yancowinna) +AU -2728+15302 Australia/Brisbane Queensland (most areas) +AU -2016+14900 Australia/Lindeman Queensland (Whitsunday Islands) +AU -3455+13835 Australia/Adelaide South Australia +AU -1228+13050 Australia/Darwin Northern Territory +AU -3157+11551 Australia/Perth Western Australia (most areas) +AU -3143+12852 Australia/Eucla Western Australia (Eucla) +AZ +4023+04951 Asia/Baku +BB +1306-05937 America/Barbados +BD +2343+09025 Asia/Dhaka +BE,LU,NL +5050+00420 Europe/Brussels +BG +4241+02319 Europe/Sofia +BM +3217-06446 Atlantic/Bermuda +BO -1630-06809 America/La_Paz +BR -0351-03225 America/Noronha Atlantic islands +BR -0127-04829 America/Belem Pará (east), Amapá +BR -0343-03830 America/Fortaleza Brazil (northeast: MA, PI, CE, RN, PB) +BR -0803-03454 America/Recife Pernambuco +BR -0712-04812 America/Araguaina Tocantins +BR -0940-03543 America/Maceio Alagoas, Sergipe +BR -1259-03831 America/Bahia Bahia +BR -2332-04637 America/Sao_Paulo Brazil (southeast: GO, DF, MG, ES, RJ, SP, PR, SC, RS) +BR -2027-05437 America/Campo_Grande Mato Grosso do Sul +BR -1535-05605 America/Cuiaba Mato Grosso +BR -0226-05452 America/Santarem Pará (west) +BR -0846-06354 America/Porto_Velho Rondônia +BR +0249-06040 America/Boa_Vista Roraima +BR -0308-06001 America/Manaus Amazonas (east) +BR -0640-06952 America/Eirunepe Amazonas (west) +BR -0958-06748 America/Rio_Branco Acre +BT +2728+08939 Asia/Thimphu +BY +5354+02734 Europe/Minsk +BZ +1730-08812 America/Belize +CA +4734-05243 America/St_Johns Newfoundland, Labrador (SE) +CA +4439-06336 America/Halifax Atlantic - NS (most areas), PE +CA +4612-05957 America/Glace_Bay Atlantic - NS (Cape Breton) +CA +4606-06447 America/Moncton Atlantic - New Brunswick +CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas) +CA,BS +4339-07923 America/Toronto Eastern - ON & QC (most areas) +CA +6344-06828 America/Iqaluit Eastern - NU (most areas) +CA +4953-09709 America/Winnipeg Central - ON (west), Manitoba +CA +744144-0944945 America/Resolute Central - NU (Resolute) +CA +624900-0920459 America/Rankin_Inlet Central - NU (central) +CA +5024-10439 America/Regina CST - SK (most areas) +CA +5017-10750 America/Swift_Current CST - SK (midwest) +CA +5333-11328 America/Edmonton Mountain - AB, BC(E), NT(E), SK(W) +CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west) +CA +682059-1334300 America/Inuvik Mountain - NT (west) +CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John) +CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson) +CA +6043-13503 America/Whitehorse MST - Yukon (east) +CA +6404-13925 America/Dawson MST - Yukon (west) +CA +4916-12307 America/Vancouver Pacific - BC (most areas) +CH,DE,LI +4723+00832 Europe/Zurich Büsingen +CI,BF,GH,GM,GN,IS,ML,MR,SH,SL,SN,TG +0519-00402 Africa/Abidjan +CK -2114-15946 Pacific/Rarotonga +CL -3327-07040 America/Santiago most of Chile +CL -5309-07055 America/Punta_Arenas Region of Magallanes +CL -2709-10926 Pacific/Easter Easter Island +CN +3114+12128 Asia/Shanghai Beijing Time +CN +4348+08735 Asia/Urumqi Xinjiang Time +CO +0436-07405 America/Bogota +CR +0956-08405 America/Costa_Rica +CU +2308-08222 America/Havana +CV +1455-02331 Atlantic/Cape_Verde +CY +3510+03322 Asia/Nicosia most of Cyprus +CY +3507+03357 Asia/Famagusta Northern Cyprus +CZ,SK +5005+01426 Europe/Prague +DE,DK,NO,SE,SJ +5230+01322 Europe/Berlin most of Germany +DO +1828-06954 America/Santo_Domingo +DZ +3647+00303 Africa/Algiers +EC -0210-07950 America/Guayaquil Ecuador (mainland) +EC -0054-08936 Pacific/Galapagos Galápagos Islands +EE +5925+02445 Europe/Tallinn +EG +3003+03115 Africa/Cairo +EH +2709-01312 Africa/El_Aaiun +ES +4024-00341 Europe/Madrid Spain (mainland) +ES +3553-00519 Africa/Ceuta Ceuta, Melilla +ES +2806-01524 Atlantic/Canary Canary Islands +FI,AX +6010+02458 Europe/Helsinki +FJ -1808+17825 Pacific/Fiji +FK -5142-05751 Atlantic/Stanley +FM +0519+16259 Pacific/Kosrae Kosrae +FO +6201-00646 Atlantic/Faroe +FR,MC +4852+00220 Europe/Paris +GB,GG,IM,JE +513030-0000731 Europe/London +GE +4143+04449 Asia/Tbilisi +GF +0456-05220 America/Cayenne +GI +3608-00521 Europe/Gibraltar +GL +6411-05144 America/Nuuk most of Greenland +GL +7646-01840 America/Danmarkshavn National Park (east coast) +GL +7029-02158 America/Scoresbysund Scoresbysund/Ittoqqortoormiit +GL +7634-06847 America/Thule Thule/Pituffik +GR +3758+02343 Europe/Athens +GS -5416-03632 Atlantic/South_Georgia +GT +1438-09031 America/Guatemala +GU,MP +1328+14445 Pacific/Guam +GW +1151-01535 Africa/Bissau +GY +0648-05810 America/Guyana +HK +2217+11409 Asia/Hong_Kong +HN +1406-08713 America/Tegucigalpa +HT +1832-07220 America/Port-au-Prince +HU +4730+01905 Europe/Budapest +ID -0610+10648 Asia/Jakarta Java, Sumatra +ID -0002+10920 Asia/Pontianak Borneo (west, central) +ID -0507+11924 Asia/Makassar Borneo (east, south), Sulawesi/Celebes, Bali, Nusa Tengarra, Timor (west) +ID -0232+14042 Asia/Jayapura New Guinea (West Papua / Irian Jaya), Malukus/Moluccas +IE +5320-00615 Europe/Dublin +IL +314650+0351326 Asia/Jerusalem +IN +2232+08822 Asia/Kolkata +IO -0720+07225 Indian/Chagos +IQ +3321+04425 Asia/Baghdad +IR +3540+05126 Asia/Tehran +IT,SM,VA +4154+01229 Europe/Rome +JM +175805-0764736 America/Jamaica +JO +3157+03556 Asia/Amman +JP +353916+1394441 Asia/Tokyo +KE,DJ,ER,ET,KM,MG,SO,TZ,UG,YT -0117+03649 Africa/Nairobi +KG +4254+07436 Asia/Bishkek +KI,MH,TV,UM,WF +0125+17300 Pacific/Tarawa Gilberts, Marshalls, Wake +KI -0247-17143 Pacific/Kanton Phoenix Islands +KI +0152-15720 Pacific/Kiritimati Line Islands +KP +3901+12545 Asia/Pyongyang +KR +3733+12658 Asia/Seoul +KZ +4315+07657 Asia/Almaty most of Kazakhstan +KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda +KZ +5312+06337 Asia/Qostanay Qostanay/Kostanay/Kustanay +KZ +5017+05710 Asia/Aqtobe Aqtöbe/Aktobe +KZ +4431+05016 Asia/Aqtau Mangghystaū/Mankistau +KZ +4707+05156 Asia/Atyrau Atyraū/Atirau/Gur'yev +KZ +5113+05121 Asia/Oral West Kazakhstan +LB +3353+03530 Asia/Beirut +LK +0656+07951 Asia/Colombo +LR +0618-01047 Africa/Monrovia +LT +5441+02519 Europe/Vilnius +LV +5657+02406 Europe/Riga +LY +3254+01311 Africa/Tripoli +MA +3339-00735 Africa/Casablanca +MD +4700+02850 Europe/Chisinau +MH +0905+16720 Pacific/Kwajalein Kwajalein +MM,CC +1647+09610 Asia/Yangon +MN +4755+10653 Asia/Ulaanbaatar most of Mongolia +MN +4801+09139 Asia/Hovd Bayan-Ölgii, Govi-Altai, Hovd, Uvs, Zavkhan +MN +4804+11430 Asia/Choibalsan Dornod, Sükhbaatar +MO +221150+1133230 Asia/Macau +MQ +1436-06105 America/Martinique +MT +3554+01431 Europe/Malta +MU -2010+05730 Indian/Mauritius +MV,TF +0410+07330 Indian/Maldives Kerguelen, St Paul I, Amsterdam I +MX +1924-09909 America/Mexico_City Central Mexico +MX +2105-08646 America/Cancun Quintana Roo +MX +2058-08937 America/Merida Campeche, Yucatán +MX +2540-10019 America/Monterrey Durango; Coahuila, Nuevo León, Tamaulipas (most areas) +MX +2550-09730 America/Matamoros Coahuila, Nuevo León, Tamaulipas (US border) +MX +2838-10605 America/Chihuahua Chihuahua (most areas) +MX +3144-10629 America/Ciudad_Juarez Chihuahua (US border - west) +MX +2934-10425 America/Ojinaga Chihuahua (US border - east) +MX +2313-10625 America/Mazatlan Baja California Sur, Nayarit (most areas), Sinaloa +MX +2048-10515 America/Bahia_Banderas Bahía de Banderas +MX +2904-11058 America/Hermosillo Sonora +MX +3232-11701 America/Tijuana Baja California +MY,BN +0133+11020 Asia/Kuching Sabah, Sarawak +MZ,BI,BW,CD,MW,RW,ZM,ZW -2558+03235 Africa/Maputo Central Africa Time +NA -2234+01706 Africa/Windhoek +NC -2216+16627 Pacific/Noumea +NF -2903+16758 Pacific/Norfolk +NG,AO,BJ,CD,CF,CG,CM,GA,GQ,NE +0627+00324 Africa/Lagos West Africa Time +NI +1209-08617 America/Managua +NP +2743+08519 Asia/Kathmandu +NR -0031+16655 Pacific/Nauru +NU -1901-16955 Pacific/Niue +NZ,AQ -3652+17446 Pacific/Auckland New Zealand time +NZ -4357-17633 Pacific/Chatham Chatham Islands +PA,CA,KY +0858-07932 America/Panama EST - ON (Atikokan), NU (Coral H) +PE -1203-07703 America/Lima +PF -1732-14934 Pacific/Tahiti Society Islands +PF -0900-13930 Pacific/Marquesas Marquesas Islands +PF -2308-13457 Pacific/Gambier Gambier Islands +PG,AQ,FM -0930+14710 Pacific/Port_Moresby Papua New Guinea (most areas), Chuuk, Yap, Dumont d'Urville +PG -0613+15534 Pacific/Bougainville Bougainville +PH +1435+12100 Asia/Manila +PK +2452+06703 Asia/Karachi +PL +5215+02100 Europe/Warsaw +PM +4703-05620 America/Miquelon +PN -2504-13005 Pacific/Pitcairn +PR,AG,CA,AI,AW,BL,BQ,CW,DM,GD,GP,KN,LC,MF,MS,SX,TT,VC,VG,VI +182806-0660622 America/Puerto_Rico AST - QC (Lower North Shore) +PS +3130+03428 Asia/Gaza Gaza Strip +PS +313200+0350542 Asia/Hebron West Bank +PT +3843-00908 Europe/Lisbon Portugal (mainland) +PT +3238-01654 Atlantic/Madeira Madeira Islands +PT +3744-02540 Atlantic/Azores Azores +PW +0720+13429 Pacific/Palau +PY -2516-05740 America/Asuncion +QA,BH +2517+05132 Asia/Qatar +RO +4426+02606 Europe/Bucharest +RS,BA,HR,ME,MK,SI +4450+02030 Europe/Belgrade +RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad +RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area +# Mention RU and UA alphabetically. See "territorial claims" above. +RU,UA +4457+03406 Europe/Simferopol Crimea +RU +5836+04939 Europe/Kirov MSK+00 - Kirov +RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd +RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan +RU +5134+04602 Europe/Saratov MSK+01 - Saratov +RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk +RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia +RU +5651+06036 Asia/Yekaterinburg MSK+02 - Urals +RU +5500+07324 Asia/Omsk MSK+03 - Omsk +RU +5502+08255 Asia/Novosibirsk MSK+04 - Novosibirsk +RU +5322+08345 Asia/Barnaul MSK+04 - Altai +RU +5630+08458 Asia/Tomsk MSK+04 - Tomsk +RU +5345+08707 Asia/Novokuznetsk MSK+04 - Kemerovo +RU +5601+09250 Asia/Krasnoyarsk MSK+04 - Krasnoyarsk area +RU +5216+10420 Asia/Irkutsk MSK+05 - Irkutsk, Buryatia +RU +5203+11328 Asia/Chita MSK+06 - Zabaykalsky +RU +6200+12940 Asia/Yakutsk MSK+06 - Lena River +RU +623923+1353314 Asia/Khandyga MSK+06 - Tomponsky, Ust-Maysky +RU +4310+13156 Asia/Vladivostok MSK+07 - Amur River +RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky +RU +5934+15048 Asia/Magadan MSK+08 - Magadan +RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island +RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E), N Kuril Is +RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka +RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea +SA,AQ,KW,YE +2438+04643 Asia/Riyadh Syowa +SB,FM -0932+16012 Pacific/Guadalcanal Pohnpei +SD +1536+03232 Africa/Khartoum +SG,MY +0117+10351 Asia/Singapore peninsular Malaysia +SR +0550-05510 America/Paramaribo +SS +0451+03137 Africa/Juba +ST +0020+00644 Africa/Sao_Tome +SV +1342-08912 America/El_Salvador +SY +3330+03618 Asia/Damascus +TC +2128-07108 America/Grand_Turk +TD +1207+01503 Africa/Ndjamena +TH,CX,KH,LA,VN +1345+10031 Asia/Bangkok north Vietnam +TJ +3835+06848 Asia/Dushanbe +TK -0922-17114 Pacific/Fakaofo +TL -0833+12535 Asia/Dili +TM +3757+05823 Asia/Ashgabat +TN +3648+01011 Africa/Tunis +TO -210800-1751200 Pacific/Tongatapu +TR +4101+02858 Europe/Istanbul +TW +2503+12130 Asia/Taipei +UA +5026+03031 Europe/Kyiv most of Ukraine +US +404251-0740023 America/New_York Eastern (most areas) +US +421953-0830245 America/Detroit Eastern - MI (most areas) +US +381515-0854534 America/Kentucky/Louisville Eastern - KY (Louisville area) +US +364947-0845057 America/Kentucky/Monticello Eastern - KY (Wayne) +US +394606-0860929 America/Indiana/Indianapolis Eastern - IN (most areas) +US +384038-0873143 America/Indiana/Vincennes Eastern - IN (Da, Du, K, Mn) +US +410305-0863611 America/Indiana/Winamac Eastern - IN (Pulaski) +US +382232-0862041 America/Indiana/Marengo Eastern - IN (Crawford) +US +382931-0871643 America/Indiana/Petersburg Eastern - IN (Pike) +US +384452-0850402 America/Indiana/Vevay Eastern - IN (Switzerland) +US +415100-0873900 America/Chicago Central (most areas) +US +375711-0864541 America/Indiana/Tell_City Central - IN (Perry) +US +411745-0863730 America/Indiana/Knox Central - IN (Starke) +US +450628-0873651 America/Menominee Central - MI (Wisconsin border) +US +470659-1011757 America/North_Dakota/Center Central - ND (Oliver) +US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural) +US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer) +US +394421-1045903 America/Denver Mountain (most areas) +US +433649-1161209 America/Boise Mountain - ID (south), OR (east) +US,CA +332654-1120424 America/Phoenix MST - AZ (most areas), Creston BC +US +340308-1181434 America/Los_Angeles Pacific +US +611305-1495401 America/Anchorage Alaska (most areas) +US +581807-1342511 America/Juneau Alaska - Juneau area +US +571035-1351807 America/Sitka Alaska - Sitka area +US +550737-1313435 America/Metlakatla Alaska - Annette Island +US +593249-1394338 America/Yakutat Alaska - Yakutat +US +643004-1652423 America/Nome Alaska (west) +US +515248-1763929 America/Adak Alaska - western Aleutians +US +211825-1575130 Pacific/Honolulu Hawaii +UY -345433-0561245 America/Montevideo +UZ +3940+06648 Asia/Samarkand Uzbekistan (west) +UZ +4120+06918 Asia/Tashkent Uzbekistan (east) +VE +1030-06656 America/Caracas +VN +1045+10640 Asia/Ho_Chi_Minh south Vietnam +VU -1740+16825 Pacific/Efate +WS -1350-17144 Pacific/Apia +ZA,LS,SZ -2615+02800 Africa/Johannesburg +# +# The next section contains experimental tab-separated comments for +# use by user agents like tzselect that identify continents and oceans. +# +# For example, the comment "#@AQAntarctica/" means the country code +# AQ is in the continent Antarctica regardless of the Zone name, +# so Pacific/Auckland should be listed under Antarctica as well as +# under the Pacific because its line's country codes include AQ. +# +# If more than one country code is affected each is listed separated +# by commas, e.g., #@IS,SHAtlantic/". If a country code is in +# more than one continent or ocean, each is listed separated by +# commas, e.g., the second column of "#@CY,TRAsia/,Europe/". +# +# These experimental comments are present only for country codes where +# the continent or ocean is not already obvious from the Zone name. +# For example, there is no such comment for RU since it already +# corresponds to Zone names starting with both "Europe/" and "Asia/". +# +#@AQ Antarctica/ +#@IS,SH Atlantic/ +#@CY,TR Asia/,Europe/ +#@SJ Arctic/ +#@CC,CX,KM,MG,YT Indian/ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/zonenow.tab b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/zonenow.tab new file mode 100644 index 0000000000000000000000000000000000000000..2dbe8f00d1b83d28e22cffc3589133b232bf893d --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/pytz/zoneinfo/zonenow.tab @@ -0,0 +1,301 @@ +# tzdb timezone descriptions, for users who do not care about old timestamps +# +# This file is in the public domain. +# +# From Paul Eggert (2023-12-18): +# This file contains a table where each row stands for a timezone +# where civil timestamps are predicted to agree from now on. +# This file is like zone1970.tab (see zone1970.tab's coments), +# but with the following changes: +# +# 1. Each timezone corresponds to a set of clocks that are planned +# to agree from now on. This is a larger set of clocks than in +# zone1970.tab, where each timezone's clocks must agree from 1970 on. +# 2. The first column is irrelevant and ignored. +# 3. The table is sorted in a different way: +# first by standard time UTC offset; +# then, if DST is used, by daylight saving UTC offset; +# then by time zone abbreviation. +# 4. Every timezone has a nonempty comments column, with wording +# distinguishing the timezone only from other timezones with the +# same UTC offset at some point during the year. +# +# The format of this table is experimental, and may change in future versions. +# +# This table is intended as an aid for users, to help them select timezones +# appropriate for their practical needs. It is not intended to take or +# endorse any position on legal or territorial claims. +# +#XX coordinates TZ comments +# +# -11 - SST +XX -1416-17042 Pacific/Pago_Pago Midway; Samoa ("SST") +# +# -11 +XX -1901-16955 Pacific/Niue Niue +# +# -10 - HST +XX +211825-1575130 Pacific/Honolulu Hawaii ("HST") +# +# -10 +XX -1732-14934 Pacific/Tahiti Tahiti; Cook Islands +# +# -10/-09 - HST / HDT (North America DST) +XX +515248-1763929 America/Adak western Aleutians in Alaska ("HST/HDT") +# +# -09:30 +XX -0900-13930 Pacific/Marquesas Marquesas +# +# -09 +XX -2308-13457 Pacific/Gambier Gambier +# +# -09/-08 - AKST/AKDT (North America DST) +XX +611305-1495401 America/Anchorage most of Alaska ("AKST/AKDT") +# +# -08 +XX -2504-13005 Pacific/Pitcairn Pitcairn +# +# -08/-07 - PST/PDT (North America DST) +XX +340308-1181434 America/Los_Angeles Pacific ("PST/PDT") - US & Canada; Mexico near US border +# +# -07 - MST +XX +332654-1120424 America/Phoenix Mountain Standard ("MST") - Arizona; western Mexico; Yukon +# +# -07/-06 - MST/MDT (North America DST) +XX +394421-1045903 America/Denver Mountain ("MST/MDT") - US & Canada; Mexico near US border +# +# -06 +XX -0054-08936 Pacific/Galapagos Galápagos +# +# -06 - CST +XX +1924-09909 America/Mexico_City Central Standard ("CST") - Saskatchewan; central Mexico; Central America +# +# -06/-05 (Chile DST) +XX -2709-10926 Pacific/Easter Easter Island +# +# -06/-05 - CST/CDT (North America DST) +XX +415100-0873900 America/Chicago Central ("CST/CDT") - US & Canada; Mexico near US border +# +# -05 +XX -1203-07703 America/Lima eastern South America +# +# -05 - EST +XX +175805-0764736 America/Jamaica Eastern Standard ("EST") - Caymans; Jamaica; eastern Mexico; Panama +# +# -05/-04 - CST/CDT (Cuba DST) +XX +2308-08222 America/Havana Cuba +# +# -05/-04 - EST/EDT (North America DST) +XX +404251-0740023 America/New_York Eastern ("EST/EDT") - US & Canada +# +# -04 +XX +1030-06656 America/Caracas western South America +# +# -04 - AST +XX +1828-06954 America/Santo_Domingo Atlantic Standard ("AST") - eastern Caribbean +# +# -04/-03 (Chile DST) +XX -3327-07040 America/Santiago most of Chile +# +# -04/-03 (Paraguay DST) +XX -2516-05740 America/Asuncion Paraguay +# +# -04/-03 - AST/ADT (North America DST) +XX +4439-06336 America/Halifax Atlantic ("AST/ADT") - Canada; Bermuda +# +# -03:30/-02:30 - NST/NDT (North America DST) +XX +4734-05243 America/St_Johns Newfoundland ("NST/NDT") +# +# -03 +XX -2332-04637 America/Sao_Paulo eastern South America +# +# -03/-02 (North America DST) +XX +4703-05620 America/Miquelon St Pierre & Miquelon +# +# -02 +XX -0351-03225 America/Noronha Fernando de Noronha; South Georgia +# +# -02/-01 (EU DST) +XX +6411-05144 America/Nuuk most of Greenland +# +# -01 +XX +1455-02331 Atlantic/Cape_Verde Cape Verde +# +# -01/+00 (EU DST) +XX +3744-02540 Atlantic/Azores Azores +# -01/+00 (EU DST) until 2024-03-31; then -02/-01 (EU DST) +XX +7029-02158 America/Scoresbysund Ittoqqortoormiit +# +# +00 - GMT +XX +0519-00402 Africa/Abidjan far western Africa; Iceland ("GMT") +# +# +00/+01 - GMT/BST (EU DST) +XX +513030-0000731 Europe/London United Kingdom ("GMT/BST") +# +# +00/+01 - WET/WEST (EU DST) +XX +3843-00908 Europe/Lisbon western Europe ("WET/WEST") +# +# +00/+02 - Troll DST +XX -720041+0023206 Antarctica/Troll Troll Station in Antarctica +# +# +01 - CET +XX +3647+00303 Africa/Algiers Algeria, Tunisia ("CET") +# +# +01 - WAT +XX +0627+00324 Africa/Lagos western Africa ("WAT") +# +# +01/+00 - IST/GMT (EU DST in reverse) +XX +5320-00615 Europe/Dublin Ireland ("IST/GMT") +# +# +01/+00 - (Morocco DST) +XX +3339-00735 Africa/Casablanca Morocco +# +# +01/+02 - CET/CEST (EU DST) +XX +4852+00220 Europe/Paris central Europe ("CET/CEST") +# +# +02 - CAT +XX -2558+03235 Africa/Maputo central Africa ("CAT") +# +# +02 - EET +XX +3254+01311 Africa/Tripoli Libya; Kaliningrad ("EET") +# +# +02 - SAST +XX -2615+02800 Africa/Johannesburg southern Africa ("SAST") +# +# +02/+03 - EET/EEST (EU DST) +XX +3758+02343 Europe/Athens eastern Europe ("EET/EEST") +# +# +02/+03 - EET/EEST (Egypt DST) +XX +3003+03115 Africa/Cairo Egypt +# +# +02/+03 - EET/EEST (Lebanon DST) +XX +3353+03530 Asia/Beirut Lebanon +# +# +02/+03 - EET/EEST (Moldova DST) +XX +4700+02850 Europe/Chisinau Moldova +# +# +02/+03 - EET/EEST (Palestine DST) +XX +3130+03428 Asia/Gaza Palestine +# +# +02/+03 - IST/IDT (Israel DST) +XX +314650+0351326 Asia/Jerusalem Israel +# +# +03 +XX +4101+02858 Europe/Istanbul Near East; Belarus +# +# +03 - EAT +XX -0117+03649 Africa/Nairobi eastern Africa ("EAT") +# +# +03 - MSK +XX +554521+0373704 Europe/Moscow Moscow ("MSK") +# +# +03:30 +XX +3540+05126 Asia/Tehran Iran +# +# +04 +XX +2518+05518 Asia/Dubai Russia; Caucasus; Persian Gulf; Seychelles; Réunion +# +# +04:30 +XX +3431+06912 Asia/Kabul Afghanistan +# +# +05 +XX +4120+06918 Asia/Tashkent Russia; Tajikistan; Turkmenistan; Uzbekistan; Maldives +# +# +05 - PKT +XX +2452+06703 Asia/Karachi Pakistan ("PKT") +# +# +05:30 +XX +0656+07951 Asia/Colombo Sri Lanka +# +# +05:30 - IST +XX +2232+08822 Asia/Kolkata India ("IST") +# +# +05:45 +XX +2743+08519 Asia/Kathmandu Nepal +# +# +06 +XX +2343+09025 Asia/Dhaka Russia; Kyrgyzstan; Bhutan; Bangladesh; Chagos +# +# +06:30 +XX +1647+09610 Asia/Yangon Myanmar; Cocos +# +# +07 +XX +1345+10031 Asia/Bangkok Russia; Indochina; Christmas Island +# +# +07 - WIB +XX -0610+10648 Asia/Jakarta Indonesia ("WIB") +# +# +08 +XX +0117+10351 Asia/Singapore Russia; Brunei; Malaysia; Singapore +# +# +08 - AWST +XX -3157+11551 Australia/Perth Western Australia ("AWST") +# +# +08 - CST +XX +3114+12128 Asia/Shanghai China ("CST") +# +# +08 - HKT +XX +2217+11409 Asia/Hong_Kong Hong Kong ("HKT") +# +# +08 - PHT +XX +1435+12100 Asia/Manila Philippines ("PHT") +# +# +08 - WITA +XX -0507+11924 Asia/Makassar Indonesia ("WITA") +# +# +08:45 +XX -3143+12852 Australia/Eucla Eucla +# +# +09 +XX +5203+11328 Asia/Chita Russia; Palau; East Timor +# +# +09 - JST +XX +353916+1394441 Asia/Tokyo Japan ("JST") +# +# +09 - KST +XX +3733+12658 Asia/Seoul Korea ("KST") +# +# +09 - WIT +XX -0232+14042 Asia/Jayapura Indonesia ("WIT") +# +# +09:30 - ACST +XX -1228+13050 Australia/Darwin Northern Territory ("ACST") +# +# +09:30/+10:30 - ACST/ACDT (Australia DST) +XX -3455+13835 Australia/Adelaide South Australia ("ACST/ACDT") +# +# +10 +XX +4310+13156 Asia/Vladivostok Russia; Yap; Chuuk; Papua New Guinea; Dumont d'Urville +# +# +10 - AEST +XX -2728+15302 Australia/Brisbane Queensland ("AEST") +# +# +10 - ChST +XX +1328+14445 Pacific/Guam Mariana Islands ("ChST") +# +# +10/+11 - AEST/AEDT (Australia DST) +XX -3352+15113 Australia/Sydney southeast Australia ("AEST/AEDT") +# +# +10:30/+11 +XX -3133+15905 Australia/Lord_Howe Lord Howe Island +# +# +11 +XX -0613+15534 Pacific/Bougainville Russia; Kosrae; Bougainville; Solomons +# +# +11/+12 (Australia DST) +XX -2903+16758 Pacific/Norfolk Norfolk Island +# +# +12 +XX +5301+15839 Asia/Kamchatka Russia; Tuvalu; Fiji; etc. +# +# +12/+13 (New Zealand DST) +XX -3652+17446 Pacific/Auckland New Zealand ("NZST/NZDT") +# +# +12:45/+13:45 (Chatham DST) +XX -4357-17633 Pacific/Chatham Chatham Islands +# +# +13 +XX -210800-1751200 Pacific/Tongatapu Kanton; Tokelau; Samoa (western); Tonga +# +# +14 +XX +0152-15720 Pacific/Kiritimati Kiritimati diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/_cell_widths.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/_cell_widths.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c21102392aab193f86335cbc7bf7f78a8956a9a6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/_cell_widths.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/_export_format.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/_export_format.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c501fc611943378e975cd0493e6282adc3e9dba Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/_export_format.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/abc.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/abc.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fde3f34c870b81933ffe292226c37db8ba97dd85 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/abc.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/ansi.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/ansi.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f772b23c3a89acb548d5252605e976b6ca2abbcd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/ansi.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/errors.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/errors.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfe56dcbf72c280f1b0e56a9ac4ea24967afc845 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/errors.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/highlighter.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/highlighter.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4491f2d10fb5104c9c21e6f80f627924715d14e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/highlighter.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/syntax.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/syntax.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9fc762e4d1ab19515a23c5eea51d31e7e174f059 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/syntax.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/traceback.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/traceback.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0726ea5ec9c9c08756ccc2cde2f45002e2240a09 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/rich/__pycache__/traceback.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..058f4cf20e00da6e724a48e25a1142c1f7bd823d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/decoders/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/decoders/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..12ada5dbda08f28a2ffc863cb502bd3f25455ded --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/decoders/__init__.py @@ -0,0 +1,15 @@ +from .. import decoders + + +Decoder = decoders.Decoder +ByteLevel = decoders.ByteLevel +Replace = decoders.Replace +WordPiece = decoders.WordPiece +ByteFallback = decoders.ByteFallback +Fuse = decoders.Fuse +Strip = decoders.Strip +Metaspace = decoders.Metaspace +BPEDecoder = decoders.BPEDecoder +CTC = decoders.CTC +Sequence = decoders.Sequence +DecodeStream = decoders.DecodeStream diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/decoders/__init__.pyi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/decoders/__init__.pyi new file mode 100644 index 0000000000000000000000000000000000000000..29fb501c994fccb325192bdfcaf98d3e81d35cd7 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/decoders/__init__.pyi @@ -0,0 +1,569 @@ +# Generated content DO NOT EDIT +class DecodeStream: + """ + Class needed for streaming decode + + """ + def __init__(self, ids=None, skip_special_tokens=False): + pass + + def __getstate__(self, /): + """ + Helper for pickle. + """ + pass + + def step(self, tokenizer, id): + """ + Streaming decode step + + Args: + tokenizer (:class:`~tokenizers.Tokenizer`): + The tokenizer to use for decoding + id (:obj:`int` or `List[int]`): + The next token id or list of token ids to add to the stream + + + Returns: + :obj:`Optional[str]`: The next decoded string chunk, or None if not enough + tokens have been provided yet. + """ + pass + +class Decoder: + """ + Base class for all decoders + + This class is not supposed to be instantiated directly. Instead, any implementation of + a Decoder will return an instance of this class when instantiated. + """ + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(decoder): + """ """ + pass + + def decode(self, tokens): + """ + Decode the given list of tokens to a final string + + Args: + tokens (:obj:`List[str]`): + The list of tokens to decode + + Returns: + :obj:`str`: The decoded string + """ + pass + +class BPEDecoder(Decoder): + """ + BPEDecoder Decoder + + Args: + suffix (:obj:`str`, `optional`, defaults to :obj:``): + The suffix that was used to characterize an end-of-word. This suffix will + be replaced by whitespaces during the decoding + """ + def __init__(self, suffix=""): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(decoder): + """ """ + pass + + def decode(self, tokens): + """ + Decode the given list of tokens to a final string + + Args: + tokens (:obj:`List[str]`): + The list of tokens to decode + + Returns: + :obj:`str`: The decoded string + """ + pass + + @property + def suffix(self): + """ """ + pass + + @suffix.setter + def suffix(self, value): + """ """ + pass + +class ByteFallback(Decoder): + """ + ByteFallback Decoder + ByteFallback is a simple trick which converts tokens looking like `<0x61>` + to pure bytes, and attempts to make them into a string. If the tokens + cannot be decoded you will get � instead for each inconvertible byte token + + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(decoder): + """ """ + pass + + def decode(self, tokens): + """ + Decode the given list of tokens to a final string + + Args: + tokens (:obj:`List[str]`): + The list of tokens to decode + + Returns: + :obj:`str`: The decoded string + """ + pass + +class ByteLevel(Decoder): + """ + ByteLevel Decoder + + This decoder is to be used in tandem with the :class:`~tokenizers.pre_tokenizers.ByteLevel` + :class:`~tokenizers.pre_tokenizers.PreTokenizer`. + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(decoder): + """ """ + pass + + def decode(self, tokens): + """ + Decode the given list of tokens to a final string + + Args: + tokens (:obj:`List[str]`): + The list of tokens to decode + + Returns: + :obj:`str`: The decoded string + """ + pass + +class CTC(Decoder): + """ + CTC Decoder + + Args: + pad_token (:obj:`str`, `optional`, defaults to :obj:``): + The pad token used by CTC to delimit a new token. + word_delimiter_token (:obj:`str`, `optional`, defaults to :obj:`|`): + The word delimiter token. It will be replaced by a + cleanup (:obj:`bool`, `optional`, defaults to :obj:`True`): + Whether to cleanup some tokenization artifacts. + Mainly spaces before punctuation, and some abbreviated english forms. + """ + def __init__(self, pad_token="", word_delimiter_token="|", cleanup=True): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def cleanup(self): + """ """ + pass + + @cleanup.setter + def cleanup(self, value): + """ """ + pass + + @staticmethod + def custom(decoder): + """ """ + pass + + def decode(self, tokens): + """ + Decode the given list of tokens to a final string + + Args: + tokens (:obj:`List[str]`): + The list of tokens to decode + + Returns: + :obj:`str`: The decoded string + """ + pass + + @property + def pad_token(self): + """ """ + pass + + @pad_token.setter + def pad_token(self, value): + """ """ + pass + + @property + def word_delimiter_token(self): + """ """ + pass + + @word_delimiter_token.setter + def word_delimiter_token(self, value): + """ """ + pass + +class Fuse(Decoder): + """ + Fuse Decoder + Fuse simply fuses every token into a single string. + This is the last step of decoding, this decoder exists only if + there is need to add other decoders *after* the fusion + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(decoder): + """ """ + pass + + def decode(self, tokens): + """ + Decode the given list of tokens to a final string + + Args: + tokens (:obj:`List[str]`): + The list of tokens to decode + + Returns: + :obj:`str`: The decoded string + """ + pass + +class Metaspace(Decoder): + """ + Metaspace Decoder + + Args: + replacement (:obj:`str`, `optional`, defaults to :obj:`▁`): + The replacement character. Must be exactly one character. By default we + use the `▁` (U+2581) meta symbol (Same as in SentencePiece). + + prepend_scheme (:obj:`str`, `optional`, defaults to :obj:`"always"`): + Whether to add a space to the first word if there isn't already one. This + lets us treat `hello` exactly like `say hello`. + Choices: "always", "never", "first". First means the space is only added on the first + token (relevant when special tokens are used or other pre_tokenizer are used). + """ + def __init__(self, replacement="▁", prepend_scheme="always", split=True): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(decoder): + """ """ + pass + + def decode(self, tokens): + """ + Decode the given list of tokens to a final string + + Args: + tokens (:obj:`List[str]`): + The list of tokens to decode + + Returns: + :obj:`str`: The decoded string + """ + pass + + @property + def prepend_scheme(self): + """ """ + pass + + @prepend_scheme.setter + def prepend_scheme(self, value): + """ """ + pass + + @property + def replacement(self): + """ """ + pass + + @replacement.setter + def replacement(self, value): + """ """ + pass + + @property + def split(self): + """ """ + pass + + @split.setter + def split(self, value): + """ """ + pass + +class Replace(Decoder): + """ + Replace Decoder + + This decoder is to be used in tandem with the :class:`~tokenizers.pre_tokenizers.Replace` + :class:`~tokenizers.pre_tokenizers.PreTokenizer`. + """ + def __init__(self, pattern, content): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(decoder): + """ """ + pass + + def decode(self, tokens): + """ + Decode the given list of tokens to a final string + + Args: + tokens (:obj:`List[str]`): + The list of tokens to decode + + Returns: + :obj:`str`: The decoded string + """ + pass + +class Sequence(Decoder): + """ + Sequence Decoder + + Args: + decoders (:obj:`List[Decoder]`) + The decoders that need to be chained + """ + def __init__(self, decoders): + pass + + def __getnewargs__(self): + """ """ + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(decoder): + """ """ + pass + + def decode(self, tokens): + """ + Decode the given list of tokens to a final string + + Args: + tokens (:obj:`List[str]`): + The list of tokens to decode + + Returns: + :obj:`str`: The decoded string + """ + pass + +class Strip(Decoder): + """ + Strip normalizer + Strips n left characters of each token, or n right characters of each token + """ + def __init__(self, content=" ", left=0, right=0): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def content(self): + """ """ + pass + + @content.setter + def content(self, value): + """ """ + pass + + @staticmethod + def custom(decoder): + """ """ + pass + + def decode(self, tokens): + """ + Decode the given list of tokens to a final string + + Args: + tokens (:obj:`List[str]`): + The list of tokens to decode + + Returns: + :obj:`str`: The decoded string + """ + pass + + @property + def start(self): + """ """ + pass + + @start.setter + def start(self, value): + """ """ + pass + + @property + def stop(self): + """ """ + pass + + @stop.setter + def stop(self, value): + """ """ + pass + +class WordPiece(Decoder): + """ + WordPiece Decoder + + Args: + prefix (:obj:`str`, `optional`, defaults to :obj:`##`): + The prefix to use for subwords that are not a beginning-of-word + + cleanup (:obj:`bool`, `optional`, defaults to :obj:`True`): + Whether to cleanup some tokenization artifacts. Mainly spaces before punctuation, + and some abbreviated english forms. + """ + def __init__(self, prefix="##", cleanup=True): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def cleanup(self): + """ """ + pass + + @cleanup.setter + def cleanup(self, value): + """ """ + pass + + @staticmethod + def custom(decoder): + """ """ + pass + + def decode(self, tokens): + """ + Decode the given list of tokens to a final string + + Args: + tokens (:obj:`List[str]`): + The list of tokens to decode + + Returns: + :obj:`str`: The decoded string + """ + pass + + @property + def prefix(self): + """ """ + pass + + @prefix.setter + def prefix(self, value): + """ """ + pass diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/decoders/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/decoders/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34746d1bf49d0643b28ec63e49c3a3cf37809635 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/decoders/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7e775892d04a91d645653ea9015954b7985d3147 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__init__.py @@ -0,0 +1,6 @@ +from .base_tokenizer import BaseTokenizer +from .bert_wordpiece import BertWordPieceTokenizer +from .byte_level_bpe import ByteLevelBPETokenizer +from .char_level_bpe import CharBPETokenizer +from .sentencepiece_bpe import SentencePieceBPETokenizer +from .sentencepiece_unigram import SentencePieceUnigramTokenizer diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf4701d4185aa88034845980aa45230963e98e14 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/base_tokenizer.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/base_tokenizer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6cec99edb7601378dcf3737156a5370ef6fccb85 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/base_tokenizer.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/bert_wordpiece.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/bert_wordpiece.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5b4c1a5c99ec8e926416cd869062f65c72bd0ab Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/bert_wordpiece.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/byte_level_bpe.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/byte_level_bpe.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07a2f0d2c86618324b6edfb8dc40d932d02d1487 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/byte_level_bpe.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/char_level_bpe.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/char_level_bpe.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48961f7647a8c22791d1d7a5142337c559737e11 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/char_level_bpe.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/sentencepiece_bpe.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/sentencepiece_bpe.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..42dd11bec6e2dd94321dd5afdccb08f3853f6673 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/sentencepiece_bpe.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/sentencepiece_unigram.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/sentencepiece_unigram.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..085b63c7d6fe048465deef621736a3f290bf1cf4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/__pycache__/sentencepiece_unigram.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/base_tokenizer.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/base_tokenizer.py new file mode 100644 index 0000000000000000000000000000000000000000..c2e7effb4cfeeef4a4cf060ebcfdd4a4c420a7a4 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/base_tokenizer.py @@ -0,0 +1,459 @@ +from typing import Dict, List, Optional, Tuple, Union + +from tokenizers import AddedToken, EncodeInput, Encoding, InputSequence, Tokenizer +from tokenizers.decoders import Decoder +from tokenizers.models import Model +from tokenizers.normalizers import Normalizer +from tokenizers.pre_tokenizers import PreTokenizer +from tokenizers.processors import PostProcessor + + +Offsets = Tuple[int, int] + + +class BaseTokenizer: + def __init__(self, tokenizer: Tokenizer, parameters=None): + self._tokenizer = tokenizer + self._parameters = parameters if parameters is not None else {} + + def __repr__(self): + return "Tokenizer(vocabulary_size={}, {})".format( + self._tokenizer.get_vocab_size(), + ", ".join(k + "=" + str(v) for k, v in self._parameters.items()), + ) + + def num_special_tokens_to_add(self, is_pair: bool) -> int: + """ + Return the number of special tokens that would be added for single/pair sentences. + :param is_pair: Boolean indicating if the input would be a single sentence or a pair + :return: + """ + return self._tokenizer.num_special_tokens_to_add(is_pair) + + def get_vocab(self, with_added_tokens: bool = True) -> Dict[str, int]: + """Returns the vocabulary + + Args: + with_added_tokens: boolean: + Whether to include the added tokens in the vocabulary + + Returns: + The vocabulary + """ + return self._tokenizer.get_vocab(with_added_tokens=with_added_tokens) + + def get_added_tokens_decoder(self) -> Dict[int, AddedToken]: + """Returns the added reverse vocabulary + + Returns: + The added vocabulary mapping ints to AddedTokens + """ + return self._tokenizer.get_added_tokens_decoder() + + def get_vocab_size(self, with_added_tokens: bool = True) -> int: + """Return the size of vocabulary, with or without added tokens. + + Args: + with_added_tokens: (`optional`) bool: + Whether to count in added special tokens or not + + Returns: + Size of vocabulary + """ + return self._tokenizer.get_vocab_size(with_added_tokens=with_added_tokens) + + def enable_padding( + self, + direction: Optional[str] = "right", + pad_to_multiple_of: Optional[int] = None, + pad_id: Optional[int] = 0, + pad_type_id: Optional[int] = 0, + pad_token: Optional[str] = "[PAD]", + length: Optional[int] = None, + ): + """Change the padding strategy + + Args: + direction: (`optional`) str: + Can be one of: `right` or `left` + + pad_to_multiple_of: (`optional`) unsigned int: + If specified, the padding length should always snap to the next multiple of + the given value. For example if we were going to pad with a length of 250 but + `pad_to_multiple_of=8` then we will pad to 256. + + pad_id: (`optional`) unsigned int: + The indice to be used when padding + + pad_type_id: (`optional`) unsigned int: + The type indice to be used when padding + + pad_token: (`optional`) str: + The pad token to be used when padding + + length: (`optional`) unsigned int: + If specified, the length at which to pad. If not specified + we pad using the size of the longest sequence in a batch + """ + return self._tokenizer.enable_padding( + direction=direction, + pad_to_multiple_of=pad_to_multiple_of, + pad_id=pad_id, + pad_type_id=pad_type_id, + pad_token=pad_token, + length=length, + ) + + def no_padding(self): + """Disable padding""" + return self._tokenizer.no_padding() + + @property + def padding(self) -> Optional[dict]: + """Get the current padding parameters + + Returns: + None if padding is disabled, a dict with the currently set parameters + if the padding is enabled. + """ + return self._tokenizer.padding + + def enable_truncation(self, max_length: int, stride: Optional[int] = 0, strategy: Optional[str] = "longest_first"): + """Change the truncation options + + Args: + max_length: unsigned int: + The maximum length at which to truncate + + stride: (`optional`) unsigned int: + The length of the previous first sequence to be included + in the overflowing sequence + + strategy: (`optional`) str: + Can be one of `longest_first`, `only_first` or `only_second` + """ + return self._tokenizer.enable_truncation(max_length, stride=stride, strategy=strategy) + + def no_truncation(self): + """Disable truncation""" + return self._tokenizer.no_truncation() + + @property + def truncation(self) -> Optional[dict]: + """Get the current truncation parameters + + Returns: + None if truncation is disabled, a dict with the current truncation parameters if + truncation is enabled + """ + return self._tokenizer.truncation + + def add_tokens(self, tokens: List[Union[str, AddedToken]]) -> int: + """Add the given tokens to the vocabulary + + Args: + tokens: List[Union[str, AddedToken]]: + A list of tokens to add to the vocabulary. Each token can either be + a string, or an instance of AddedToken + + Returns: + The number of tokens that were added to the vocabulary + """ + return self._tokenizer.add_tokens(tokens) + + def add_special_tokens(self, special_tokens: List[Union[str, AddedToken]]) -> int: + """Add the given special tokens to the vocabulary, and treat them as special tokens. + + The special tokens will never be processed by the model, and will be + removed while decoding. + + Args: + tokens: List[Union[str, AddedToken]]: + A list of special tokens to add to the vocabulary. Each token can either be + a string, or an instance of AddedToken + + Returns: + The number of tokens that were added to the vocabulary + """ + return self._tokenizer.add_special_tokens(special_tokens) + + def normalize(self, sequence: str) -> str: + """Normalize the given sequence + + Args: + sequence: str: + The sequence to normalize + + Returns: + The normalized string + """ + return self._tokenizer.normalizer.normalize_str(sequence) + + def encode( + self, + sequence: InputSequence, + pair: Optional[InputSequence] = None, + is_pretokenized: bool = False, + add_special_tokens: bool = True, + ) -> Encoding: + """Encode the given sequence and pair. This method can process raw text sequences as well + as already pre-tokenized sequences. + + Args: + sequence: InputSequence: + The sequence we want to encode. This sequence can be either raw text or + pre-tokenized, according to the `is_pretokenized` argument: + + - If `is_pretokenized=False`: `InputSequence` is expected to be `str` + - If `is_pretokenized=True`: `InputSequence` is expected to be + `Union[List[str], Tuple[str]]` + + is_pretokenized: bool: + Whether the input is already pre-tokenized. + + add_special_tokens: bool: + Whether to add the special tokens while encoding. + + Returns: + An Encoding + """ + if sequence is None: + raise ValueError("encode: `sequence` can't be `None`") + + return self._tokenizer.encode(sequence, pair, is_pretokenized, add_special_tokens) + + def encode_batch( + self, + inputs: List[EncodeInput], + is_pretokenized: bool = False, + add_special_tokens: bool = True, + ) -> List[Encoding]: + """Encode the given inputs. This method accept both raw text sequences as well as already + pre-tokenized sequences. + + Args: + inputs: List[EncodeInput]: + A list of single sequences or pair sequences to encode. Each `EncodeInput` is + expected to be of the following form: + `Union[InputSequence, Tuple[InputSequence, InputSequence]]` + + Each `InputSequence` can either be raw text or pre-tokenized, + according to the `is_pretokenized` argument: + + - If `is_pretokenized=False`: `InputSequence` is expected to be `str` + - If `is_pretokenized=True`: `InputSequence` is expected to be + `Union[List[str], Tuple[str]]` + + is_pretokenized: bool: + Whether the input is already pre-tokenized. + + add_special_tokens: bool: + Whether to add the special tokens while encoding. + + Returns: + A list of Encoding + """ + + if inputs is None: + raise ValueError("encode_batch: `inputs` can't be `None`") + + return self._tokenizer.encode_batch(inputs, is_pretokenized, add_special_tokens) + + async def async_encode_batch( + self, + inputs: List[EncodeInput], + is_pretokenized: bool = False, + add_special_tokens: bool = True, + ) -> List[Encoding]: + """Asynchronously encode a batch (tracks character offsets). + + Args: + inputs: A list of single or pair sequences to encode. + is_pretokenized: Whether inputs are already pre-tokenized. + add_special_tokens: Whether to add special tokens. + + Returns: + A list of Encoding. + """ + if inputs is None: + raise ValueError("async_encode_batch: `inputs` can't be `None`") + # Exposed by the Rust bindings via pyo3_async_runtimes::tokio::future_into_py + return await self._tokenizer.async_encode_batch(inputs, is_pretokenized, add_special_tokens) + + async def async_encode_batch_fast( + self, + inputs: List[EncodeInput], + is_pretokenized: bool = False, + add_special_tokens: bool = True, + ) -> List[Encoding]: + """Asynchronously encode a batch (no character offsets, faster). + + Args: + inputs: A list of single or pair sequences to encode. + is_pretokenized: Whether inputs are already pre-tokenized. + add_special_tokens: Whether to add special tokens. + + Returns: + A list of Encoding. + """ + if inputs is None: + raise ValueError("async_encode_batch_fast: `inputs` can't be `None`") + return await self._tokenizer.async_encode_batch_fast(inputs, is_pretokenized, add_special_tokens) + + def decode(self, ids: List[int], skip_special_tokens: Optional[bool] = True) -> str: + """Decode the given list of ids to a string sequence + + Args: + ids: List[unsigned int]: + A list of ids to be decoded + + skip_special_tokens: (`optional`) boolean: + Whether to remove all the special tokens from the output string + + Returns: + The decoded string + """ + if ids is None: + raise ValueError("None input is not valid. Should be a list of integers.") + + return self._tokenizer.decode(ids, skip_special_tokens=skip_special_tokens) + + def decode_batch(self, sequences: List[List[int]], skip_special_tokens: Optional[bool] = True) -> str: + """Decode the list of sequences to a list of string sequences + + Args: + sequences: List[List[unsigned int]]: + A list of sequence of ids to be decoded + + skip_special_tokens: (`optional`) boolean: + Whether to remove all the special tokens from the output strings + + Returns: + A list of decoded strings + """ + if sequences is None: + raise ValueError("None input is not valid. Should be list of list of integers.") + + return self._tokenizer.decode_batch(sequences, skip_special_tokens=skip_special_tokens) + + def token_to_id(self, token: str) -> Optional[int]: + """Convert the given token to its corresponding id + + Args: + token: str: + The token to convert + + Returns: + The corresponding id if it exists, None otherwise + """ + return self._tokenizer.token_to_id(token) + + def id_to_token(self, id: int) -> Optional[str]: + """Convert the given token id to its corresponding string + + Args: + token: id: + The token id to convert + + Returns: + The corresponding string if it exists, None otherwise + """ + return self._tokenizer.id_to_token(id) + + def save_model(self, directory: str, prefix: Optional[str] = None): + """Save the current model to the given directory + + Args: + directory: str: + A path to the destination directory + + prefix: (Optional) str: + An optional prefix, used to prefix each file name + """ + return self._tokenizer.model.save(directory, prefix=prefix) + + def save(self, path: str, pretty: bool = True): + """Save the current Tokenizer at the given path + + Args: + path: str: + A path to the destination Tokenizer file + """ + return self._tokenizer.save(path, pretty) + + def to_str(self, pretty: bool = False): + """Get a serialized JSON version of the Tokenizer as a str + + Args: + pretty: bool: + Whether the JSON string should be prettified + + Returns: + str + """ + return self._tokenizer.to_str(pretty) + + def post_process( + self, encoding: Encoding, pair: Optional[Encoding] = None, add_special_tokens: bool = True + ) -> Encoding: + """Apply all the post-processing steps to the given encodings. + + The various steps are: + 1. Truncate according to global params (provided to `enable_truncation`) + 2. Apply the PostProcessor + 3. Pad according to global params. (provided to `enable_padding`) + + Args: + encoding: Encoding: + The main Encoding to post process + + pair: Optional[Encoding]: + An optional pair Encoding + + add_special_tokens: bool: + Whether to add special tokens + + Returns: + The resulting Encoding + """ + return self._tokenizer.post_process(encoding, pair, add_special_tokens) + + @property + def model(self) -> Model: + return self._tokenizer.model + + @model.setter + def model(self, model: Model): + self._tokenizer.model = model + + @property + def normalizer(self) -> Normalizer: + return self._tokenizer.normalizer + + @normalizer.setter + def normalizer(self, normalizer: Normalizer): + self._tokenizer.normalizer = normalizer + + @property + def pre_tokenizer(self) -> PreTokenizer: + return self._tokenizer.pre_tokenizer + + @pre_tokenizer.setter + def pre_tokenizer(self, pre_tokenizer: PreTokenizer): + self._tokenizer.pre_tokenizer = pre_tokenizer + + @property + def post_processor(self) -> PostProcessor: + return self._tokenizer.post_processor + + @post_processor.setter + def post_processor(self, post_processor: PostProcessor): + self._tokenizer.post_processor = post_processor + + @property + def decoder(self) -> Decoder: + return self._tokenizer.decoder + + @decoder.setter + def decoder(self, decoder: Decoder): + self._tokenizer.decoder = decoder diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/bert_wordpiece.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/bert_wordpiece.py new file mode 100644 index 0000000000000000000000000000000000000000..1f34e3ca8a4f8b3ed454e09d828918881232ef90 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/bert_wordpiece.py @@ -0,0 +1,151 @@ +from typing import Dict, Iterator, List, Optional, Union + +from tokenizers import AddedToken, Tokenizer, decoders, trainers +from tokenizers.models import WordPiece +from tokenizers.normalizers import BertNormalizer +from tokenizers.pre_tokenizers import BertPreTokenizer +from tokenizers.processors import BertProcessing + +from .base_tokenizer import BaseTokenizer + + +class BertWordPieceTokenizer(BaseTokenizer): + """Bert WordPiece Tokenizer""" + + def __init__( + self, + vocab: Optional[Union[str, Dict[str, int]]] = None, + unk_token: Union[str, AddedToken] = "[UNK]", + sep_token: Union[str, AddedToken] = "[SEP]", + cls_token: Union[str, AddedToken] = "[CLS]", + pad_token: Union[str, AddedToken] = "[PAD]", + mask_token: Union[str, AddedToken] = "[MASK]", + clean_text: bool = True, + handle_chinese_chars: bool = True, + strip_accents: Optional[bool] = None, + lowercase: bool = True, + wordpieces_prefix: str = "##", + ): + if vocab is not None: + tokenizer = Tokenizer(WordPiece(vocab, unk_token=str(unk_token))) + else: + tokenizer = Tokenizer(WordPiece(unk_token=str(unk_token))) + + # Let the tokenizer know about special tokens if they are part of the vocab + if tokenizer.token_to_id(str(unk_token)) is not None: + tokenizer.add_special_tokens([str(unk_token)]) + if tokenizer.token_to_id(str(sep_token)) is not None: + tokenizer.add_special_tokens([str(sep_token)]) + if tokenizer.token_to_id(str(cls_token)) is not None: + tokenizer.add_special_tokens([str(cls_token)]) + if tokenizer.token_to_id(str(pad_token)) is not None: + tokenizer.add_special_tokens([str(pad_token)]) + if tokenizer.token_to_id(str(mask_token)) is not None: + tokenizer.add_special_tokens([str(mask_token)]) + + tokenizer.normalizer = BertNormalizer( + clean_text=clean_text, + handle_chinese_chars=handle_chinese_chars, + strip_accents=strip_accents, + lowercase=lowercase, + ) + tokenizer.pre_tokenizer = BertPreTokenizer() + + if vocab is not None: + sep_token_id = tokenizer.token_to_id(str(sep_token)) + if sep_token_id is None: + raise TypeError("sep_token not found in the vocabulary") + cls_token_id = tokenizer.token_to_id(str(cls_token)) + if cls_token_id is None: + raise TypeError("cls_token not found in the vocabulary") + + tokenizer.post_processor = BertProcessing((str(sep_token), sep_token_id), (str(cls_token), cls_token_id)) + tokenizer.decoder = decoders.WordPiece(prefix=wordpieces_prefix) + + parameters = { + "model": "BertWordPiece", + "unk_token": unk_token, + "sep_token": sep_token, + "cls_token": cls_token, + "pad_token": pad_token, + "mask_token": mask_token, + "clean_text": clean_text, + "handle_chinese_chars": handle_chinese_chars, + "strip_accents": strip_accents, + "lowercase": lowercase, + "wordpieces_prefix": wordpieces_prefix, + } + + super().__init__(tokenizer, parameters) + + @staticmethod + def from_file(vocab: str, **kwargs): + vocab = WordPiece.read_file(vocab) + return BertWordPieceTokenizer(vocab, **kwargs) + + def train( + self, + files: Union[str, List[str]], + vocab_size: int = 30000, + min_frequency: int = 2, + limit_alphabet: int = 1000, + initial_alphabet: List[str] = [], + special_tokens: List[Union[str, AddedToken]] = [ + "[PAD]", + "[UNK]", + "[CLS]", + "[SEP]", + "[MASK]", + ], + show_progress: bool = True, + wordpieces_prefix: str = "##", + ): + """Train the model using the given files""" + + trainer = trainers.WordPieceTrainer( + vocab_size=vocab_size, + min_frequency=min_frequency, + limit_alphabet=limit_alphabet, + initial_alphabet=initial_alphabet, + special_tokens=special_tokens, + show_progress=show_progress, + continuing_subword_prefix=wordpieces_prefix, + ) + if isinstance(files, str): + files = [files] + self._tokenizer.train(files, trainer=trainer) + + def train_from_iterator( + self, + iterator: Union[Iterator[str], Iterator[Iterator[str]]], + vocab_size: int = 30000, + min_frequency: int = 2, + limit_alphabet: int = 1000, + initial_alphabet: List[str] = [], + special_tokens: List[Union[str, AddedToken]] = [ + "[PAD]", + "[UNK]", + "[CLS]", + "[SEP]", + "[MASK]", + ], + show_progress: bool = True, + wordpieces_prefix: str = "##", + length: Optional[int] = None, + ): + """Train the model using the given iterator""" + + trainer = trainers.WordPieceTrainer( + vocab_size=vocab_size, + min_frequency=min_frequency, + limit_alphabet=limit_alphabet, + initial_alphabet=initial_alphabet, + special_tokens=special_tokens, + show_progress=show_progress, + continuing_subword_prefix=wordpieces_prefix, + ) + self._tokenizer.train_from_iterator( + iterator, + trainer=trainer, + length=length, + ) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/byte_level_bpe.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/byte_level_bpe.py new file mode 100644 index 0000000000000000000000000000000000000000..f65f05e1ddd4c8ec6b3791aa3045762cc06523e3 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/byte_level_bpe.py @@ -0,0 +1,122 @@ +from typing import Dict, Iterator, List, Optional, Tuple, Union + +from tokenizers import AddedToken, Tokenizer, decoders, pre_tokenizers, processors, trainers +from tokenizers.models import BPE +from tokenizers.normalizers import Lowercase, Sequence, unicode_normalizer_from_str + +from .base_tokenizer import BaseTokenizer + + +class ByteLevelBPETokenizer(BaseTokenizer): + """ByteLevelBPETokenizer + + Represents a Byte-level BPE as introduced by OpenAI with their GPT-2 model + """ + + def __init__( + self, + vocab: Optional[Union[str, Dict[str, int]]] = None, + merges: Optional[Union[str, List[Tuple[str, str]]]] = None, + add_prefix_space: bool = False, + lowercase: bool = False, + dropout: Optional[float] = None, + unicode_normalizer: Optional[str] = None, + continuing_subword_prefix: Optional[str] = None, + end_of_word_suffix: Optional[str] = None, + trim_offsets: bool = False, + ): + if vocab is not None and merges is not None: + tokenizer = Tokenizer( + BPE( + vocab, + merges, + dropout=dropout, + continuing_subword_prefix=continuing_subword_prefix or "", + end_of_word_suffix=end_of_word_suffix or "", + ) + ) + else: + tokenizer = Tokenizer(BPE()) + + # Check for Unicode normalization first (before everything else) + normalizers = [] + + if unicode_normalizer: + normalizers += [unicode_normalizer_from_str(unicode_normalizer)] + + if lowercase: + normalizers += [Lowercase()] + + # Create the normalizer structure + if len(normalizers) > 0: + if len(normalizers) > 1: + tokenizer.normalizer = Sequence(normalizers) + else: + tokenizer.normalizer = normalizers[0] + + tokenizer.pre_tokenizer = pre_tokenizers.ByteLevel(add_prefix_space=add_prefix_space) + tokenizer.decoder = decoders.ByteLevel() + tokenizer.post_processor = processors.ByteLevel(trim_offsets=trim_offsets) + + parameters = { + "model": "ByteLevelBPE", + "add_prefix_space": add_prefix_space, + "lowercase": lowercase, + "dropout": dropout, + "unicode_normalizer": unicode_normalizer, + "continuing_subword_prefix": continuing_subword_prefix, + "end_of_word_suffix": end_of_word_suffix, + "trim_offsets": trim_offsets, + } + + super().__init__(tokenizer, parameters) + + @staticmethod + def from_file(vocab_filename: str, merges_filename: str, **kwargs): + vocab, merges = BPE.read_file(vocab_filename, merges_filename) + return ByteLevelBPETokenizer(vocab, merges, **kwargs) + + def train( + self, + files: Union[str, List[str]], + vocab_size: int = 30000, + min_frequency: int = 2, + show_progress: bool = True, + special_tokens: List[Union[str, AddedToken]] = [], + ): + """Train the model using the given files""" + + trainer = trainers.BpeTrainer( + vocab_size=vocab_size, + min_frequency=min_frequency, + show_progress=show_progress, + special_tokens=special_tokens, + initial_alphabet=pre_tokenizers.ByteLevel.alphabet(), + ) + if isinstance(files, str): + files = [files] + self._tokenizer.train(files, trainer=trainer) + + def train_from_iterator( + self, + iterator: Union[Iterator[str], Iterator[Iterator[str]]], + vocab_size: int = 30000, + min_frequency: int = 2, + show_progress: bool = True, + special_tokens: List[Union[str, AddedToken]] = [], + length: Optional[int] = None, + ): + """Train the model using the given iterator""" + + trainer = trainers.BpeTrainer( + vocab_size=vocab_size, + min_frequency=min_frequency, + show_progress=show_progress, + special_tokens=special_tokens, + initial_alphabet=pre_tokenizers.ByteLevel.alphabet(), + ) + self._tokenizer.train_from_iterator( + iterator, + trainer=trainer, + length=length, + ) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/char_level_bpe.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/char_level_bpe.py new file mode 100644 index 0000000000000000000000000000000000000000..62b5bcdf06b4026ce48620ee4d681f0c7399b520 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/char_level_bpe.py @@ -0,0 +1,150 @@ +from typing import Dict, Iterator, List, Optional, Tuple, Union + +from .. import AddedToken, Tokenizer, decoders, pre_tokenizers, trainers +from ..models import BPE +from ..normalizers import BertNormalizer, Lowercase, Sequence, unicode_normalizer_from_str +from .base_tokenizer import BaseTokenizer + + +class CharBPETokenizer(BaseTokenizer): + """Original BPE Tokenizer + + Represents the BPE algorithm, as introduced by Rico Sennrich + (https://arxiv.org/abs/1508.07909) + + The defaults settings corresponds to OpenAI GPT BPE tokenizers and differs from the original + Sennrich subword-nmt implementation by the following options that you can deactivate: + - adding a normalizer to clean up the text (deactivate with `bert_normalizer=False`) by: + * removing any control characters and replacing all whitespaces by the classic one. + * handle chinese chars by putting spaces around them. + * strip all accents. + - spitting on punctuation in addition to whitespaces (deactivate it with + `split_on_whitespace_only=True`) + """ + + def __init__( + self, + vocab: Optional[Union[str, Dict[str, int]]] = None, + merges: Optional[Union[str, List[Tuple[str, str]]]] = None, + unk_token: Union[str, AddedToken] = "", + suffix: str = "", + dropout: Optional[float] = None, + lowercase: bool = False, + unicode_normalizer: Optional[str] = None, + bert_normalizer: bool = True, + split_on_whitespace_only: bool = False, + ): + if vocab is not None and merges is not None: + tokenizer = Tokenizer( + BPE( + vocab, + merges, + dropout=dropout, + unk_token=str(unk_token), + end_of_word_suffix=suffix, + ) + ) + else: + tokenizer = Tokenizer(BPE(unk_token=str(unk_token), dropout=dropout, end_of_word_suffix=suffix)) + + if tokenizer.token_to_id(str(unk_token)) is not None: + tokenizer.add_special_tokens([str(unk_token)]) + + # Check for Unicode normalization first (before everything else) + normalizers = [] + + if unicode_normalizer: + normalizers += [unicode_normalizer_from_str(unicode_normalizer)] + + if bert_normalizer: + normalizers += [BertNormalizer(lowercase=False)] + + if lowercase: + normalizers += [Lowercase()] + + # Create the normalizer structure + if len(normalizers) > 0: + if len(normalizers) > 1: + tokenizer.normalizer = Sequence(normalizers) + else: + tokenizer.normalizer = normalizers[0] + + if split_on_whitespace_only: + tokenizer.pre_tokenizer = pre_tokenizers.WhitespaceSplit() + else: + tokenizer.pre_tokenizer = pre_tokenizers.BertPreTokenizer() + + tokenizer.decoder = decoders.BPEDecoder(suffix=suffix) + + parameters = { + "model": "BPE", + "unk_token": unk_token, + "suffix": suffix, + "dropout": dropout, + "lowercase": lowercase, + "unicode_normalizer": unicode_normalizer, + "bert_normalizer": bert_normalizer, + "split_on_whitespace_only": split_on_whitespace_only, + } + + super().__init__(tokenizer, parameters) + + @staticmethod + def from_file(vocab_filename: str, merges_filename: str, **kwargs): + vocab, merges = BPE.read_file(vocab_filename, merges_filename) + return CharBPETokenizer(vocab, merges, **kwargs) + + def train( + self, + files: Union[str, List[str]], + vocab_size: int = 30000, + min_frequency: int = 2, + special_tokens: List[Union[str, AddedToken]] = [""], + limit_alphabet: int = 1000, + initial_alphabet: List[str] = [], + suffix: Optional[str] = "", + show_progress: bool = True, + ): + """Train the model using the given files""" + + trainer = trainers.BpeTrainer( + vocab_size=vocab_size, + min_frequency=min_frequency, + special_tokens=special_tokens, + limit_alphabet=limit_alphabet, + initial_alphabet=initial_alphabet, + end_of_word_suffix=suffix, + show_progress=show_progress, + ) + if isinstance(files, str): + files = [files] + self._tokenizer.train(files, trainer=trainer) + + def train_from_iterator( + self, + iterator: Union[Iterator[str], Iterator[Iterator[str]]], + vocab_size: int = 30000, + min_frequency: int = 2, + special_tokens: List[Union[str, AddedToken]] = [""], + limit_alphabet: int = 1000, + initial_alphabet: List[str] = [], + suffix: Optional[str] = "", + show_progress: bool = True, + length: Optional[int] = None, + ): + """Train the model using the given iterator""" + + trainer = trainers.BpeTrainer( + vocab_size=vocab_size, + min_frequency=min_frequency, + special_tokens=special_tokens, + limit_alphabet=limit_alphabet, + initial_alphabet=initial_alphabet, + end_of_word_suffix=suffix, + show_progress=show_progress, + ) + self._tokenizer.train_from_iterator( + iterator, + trainer=trainer, + length=length, + ) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/sentencepiece_bpe.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/sentencepiece_bpe.py new file mode 100644 index 0000000000000000000000000000000000000000..26200489a60dfc6420b43f5dda21ad18ebfe7484 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/sentencepiece_bpe.py @@ -0,0 +1,103 @@ +from typing import Dict, Iterator, List, Optional, Tuple, Union + +from tokenizers import AddedToken, Tokenizer, decoders, pre_tokenizers, trainers +from tokenizers.models import BPE +from tokenizers.normalizers import NFKC + +from .base_tokenizer import BaseTokenizer + + +class SentencePieceBPETokenizer(BaseTokenizer): + """SentencePiece BPE Tokenizer + + Represents the BPE algorithm, with the pretokenization used by SentencePiece + """ + + def __init__( + self, + vocab: Optional[Union[str, Dict[str, int]]] = None, + merges: Optional[Union[str, List[Tuple[str, str]]]] = None, + unk_token: Union[str, AddedToken] = "", + replacement: str = "▁", + add_prefix_space: bool = True, + dropout: Optional[float] = None, + fuse_unk: Optional[bool] = False, + ): + if vocab is not None and merges is not None: + tokenizer = Tokenizer(BPE(vocab, merges, dropout=dropout, unk_token=unk_token, fuse_unk=fuse_unk)) + else: + tokenizer = Tokenizer(BPE(dropout=dropout, unk_token=unk_token, fuse_unk=fuse_unk)) + + if tokenizer.token_to_id(str(unk_token)) is not None: + tokenizer.add_special_tokens([str(unk_token)]) + + tokenizer.normalizer = NFKC() + prepend_scheme = "always" if add_prefix_space else "never" + tokenizer.pre_tokenizer = pre_tokenizers.Metaspace(replacement=replacement, prepend_scheme=prepend_scheme) + tokenizer.decoder = decoders.Metaspace(replacement=replacement, prepend_scheme=prepend_scheme) + + parameters = { + "model": "SentencePieceBPE", + "unk_token": unk_token, + "replacement": replacement, + "add_prefix_space": add_prefix_space, + "dropout": dropout, + } + + super().__init__(tokenizer, parameters) + + @staticmethod + def from_file(vocab_filename: str, merges_filename: str, **kwargs): + vocab, merges = BPE.read_file(vocab_filename, merges_filename) + return SentencePieceBPETokenizer(vocab, merges, **kwargs) + + def train( + self, + files: Union[str, List[str]], + vocab_size: int = 30000, + min_frequency: int = 2, + special_tokens: List[Union[str, AddedToken]] = [""], + limit_alphabet: int = 1000, + initial_alphabet: List[str] = [], + show_progress: bool = True, + ): + """Train the model using the given files""" + + trainer = trainers.BpeTrainer( + vocab_size=vocab_size, + min_frequency=min_frequency, + special_tokens=special_tokens, + limit_alphabet=limit_alphabet, + initial_alphabet=initial_alphabet, + show_progress=show_progress, + ) + if isinstance(files, str): + files = [files] + self._tokenizer.train(files, trainer=trainer) + + def train_from_iterator( + self, + iterator: Union[Iterator[str], Iterator[Iterator[str]]], + vocab_size: int = 30000, + min_frequency: int = 2, + special_tokens: List[Union[str, AddedToken]] = [""], + limit_alphabet: int = 1000, + initial_alphabet: List[str] = [], + show_progress: bool = True, + length: Optional[int] = None, + ): + """Train the model using the given iterator""" + + trainer = trainers.BpeTrainer( + vocab_size=vocab_size, + min_frequency=min_frequency, + special_tokens=special_tokens, + limit_alphabet=limit_alphabet, + initial_alphabet=initial_alphabet, + show_progress=show_progress, + ) + self._tokenizer.train_from_iterator( + iterator, + trainer=trainer, + length=length, + ) diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/sentencepiece_unigram.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/sentencepiece_unigram.py new file mode 100644 index 0000000000000000000000000000000000000000..5e945a433686be6643363a140b17dd56e64013f9 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/implementations/sentencepiece_unigram.py @@ -0,0 +1,196 @@ +import json +import os +from typing import Iterator, List, Optional, Union, Tuple + +from tokenizers import AddedToken, Regex, Tokenizer, decoders, normalizers, pre_tokenizers, trainers +from tokenizers.models import Unigram + +from .base_tokenizer import BaseTokenizer + + +class SentencePieceUnigramTokenizer(BaseTokenizer): + """SentencePiece Unigram Tokenizer + + Represents the Unigram algorithm, with the pretokenization used by SentencePiece + """ + + def __init__( + self, + vocab: Optional[List[Tuple[str, float]]] = None, + replacement: str = "▁", + add_prefix_space: bool = True, + ): + if vocab is not None: + # Let Unigram(..) fail if only one of them is None + tokenizer = Tokenizer(Unigram(vocab)) + else: + tokenizer = Tokenizer(Unigram()) + + tokenizer.normalizer = normalizers.Sequence( + [normalizers.Nmt(), normalizers.NFKC(), normalizers.Replace(Regex(" {2,}"), " ")] + ) + prepend_scheme = "always" if add_prefix_space else "never" + tokenizer.pre_tokenizer = pre_tokenizers.Metaspace(replacement=replacement, prepend_scheme=prepend_scheme) + tokenizer.decoder = decoders.Metaspace(replacement=replacement, prepend_scheme=prepend_scheme) + + parameters = { + "model": "SentencePieceUnigram", + "replacement": replacement, + "add_prefix_space": add_prefix_space, + } + + super().__init__(tokenizer, parameters) + + def train( + self, + files: Union[str, List[str]], + vocab_size: int = 8000, + show_progress: bool = True, + special_tokens: Optional[List[Union[str, AddedToken]]] = None, + initial_alphabet: Optional[List[str]] = None, + unk_token: Optional[str] = None, + ): + """ + Train the model using the given files + + Args: + files (:obj:`List[str]`): + A list of path to the files that we should use for training + vocab_size (:obj:`int`): + The size of the final vocabulary, including all tokens and alphabet. + show_progress (:obj:`bool`): + Whether to show progress bars while training. + special_tokens (:obj:`List[Union[str, AddedToken]]`, `optional`): + A list of special tokens the model should know of. + initial_alphabet (:obj:`List[str]`, `optional`): + A list of characters to include in the initial alphabet, even + if not seen in the training dataset. + If the strings contain more than one character, only the first one + is kept. + unk_token (:obj:`str`, `optional`): + The unknown token to be used by the model. + """ + + if special_tokens is None: + special_tokens = [] + + if initial_alphabet is None: + initial_alphabet = [] + + trainer = trainers.UnigramTrainer( + vocab_size=vocab_size, + special_tokens=special_tokens, + show_progress=show_progress, + initial_alphabet=initial_alphabet, + unk_token=unk_token, + ) + + if isinstance(files, str): + files = [files] + self._tokenizer.train(files, trainer=trainer) + + def train_from_iterator( + self, + iterator: Union[Iterator[str], Iterator[Iterator[str]]], + vocab_size: int = 8000, + show_progress: bool = True, + special_tokens: Optional[List[Union[str, AddedToken]]] = None, + initial_alphabet: Optional[List[str]] = None, + unk_token: Optional[str] = None, + length: Optional[int] = None, + ): + """ + Train the model using the given iterator + + Args: + iterator (:obj:`Union[Iterator[str], Iterator[Iterator[str]]]`): + Any iterator over strings or list of strings + vocab_size (:obj:`int`): + The size of the final vocabulary, including all tokens and alphabet. + show_progress (:obj:`bool`): + Whether to show progress bars while training. + special_tokens (:obj:`List[Union[str, AddedToken]]`, `optional`): + A list of special tokens the model should know of. + initial_alphabet (:obj:`List[str]`, `optional`): + A list of characters to include in the initial alphabet, even + if not seen in the training dataset. + If the strings contain more than one character, only the first one + is kept. + unk_token (:obj:`str`, `optional`): + The unknown token to be used by the model. + length (:obj:`int`, `optional`): + The total number of sequences in the iterator. This is used to + provide meaningful progress tracking + """ + + if special_tokens is None: + special_tokens = [] + + if initial_alphabet is None: + initial_alphabet = [] + + trainer = trainers.UnigramTrainer( + vocab_size=vocab_size, + special_tokens=special_tokens, + show_progress=show_progress, + initial_alphabet=initial_alphabet, + unk_token=unk_token, + ) + + self._tokenizer.train_from_iterator( + iterator, + trainer=trainer, + length=length, + ) + + @staticmethod + def from_spm(filename: str): + try: + import sys + + sys.path.append(".") + + import sentencepiece_model_pb2 as model # type: ignore[import] + except Exception: + raise Exception( + "You don't seem to have the required protobuf file, in order to use this function you need to run `pip install protobuf` and `wget https://raw.githubusercontent.com/google/sentencepiece/master/python/src/sentencepiece/sentencepiece_model_pb2.py` for us to be able to read the intrinsics of your spm_file. `pip install sentencepiece` is not required." + ) + + m = model.ModelProto() + m.ParseFromString(open(filename, "rb").read()) + + precompiled_charsmap = m.normalizer_spec.precompiled_charsmap + vocab = [(piece.piece, piece.score) for piece in m.pieces] + unk_id = m.trainer_spec.unk_id + model_type = m.trainer_spec.model_type + byte_fallback = m.trainer_spec.byte_fallback + if model_type != 1: + raise Exception( + "You're trying to run a `Unigram` model but you're file was trained with a different algorithm" + ) + + replacement = "▁" + add_prefix_space = True + + tokenizer = Tokenizer(Unigram(vocab, unk_id, byte_fallback)) + + if precompiled_charsmap: + tokenizer.normalizer = normalizers.Sequence( + [ + normalizers.Precompiled(precompiled_charsmap), + normalizers.Replace(Regex(" {2,}"), " "), + ] + ) + else: + tokenizer.normalizer = normalizers.Sequence([normalizers.Replace(Regex(" {2,}"), " ")]) + prepend_scheme = "always" if add_prefix_space else "never" + tokenizer.pre_tokenizer = pre_tokenizers.Metaspace(replacement=replacement, prepend_scheme=prepend_scheme) + tokenizer.decoder = decoders.Metaspace(replacement=replacement, prepend_scheme=prepend_scheme) + + parameters = { + "model": "SentencePieceUnigram", + } + + obj = BaseTokenizer.__new__(SentencePieceUnigramTokenizer, tokenizer, parameters) # type: ignore[arg-type] + BaseTokenizer.__init__(obj, tokenizer, parameters) + return obj diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/models/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..68ac211aa8032249db6b929ca64f9130c358d40b --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/models/__init__.py @@ -0,0 +1,8 @@ +# Generated content DO NOT EDIT +from .. import models + +Model = models.Model +BPE = models.BPE +Unigram = models.Unigram +WordLevel = models.WordLevel +WordPiece = models.WordPiece diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/models/__init__.pyi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/models/__init__.pyi new file mode 100644 index 0000000000000000000000000000000000000000..2548697410ffb5d0143c2d26df36fcf4fc0de242 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/models/__init__.pyi @@ -0,0 +1,744 @@ +# Generated content DO NOT EDIT +class Model: + """ + Base class for all models + + The model represents the actual tokenization algorithm. This is the part that + will contain and manage the learned vocabulary. + + This class cannot be constructed directly. Please use one of the concrete models. + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + def get_trainer(self): + """ + Get the associated :class:`~tokenizers.trainers.Trainer` + + Retrieve the :class:`~tokenizers.trainers.Trainer` associated to this + :class:`~tokenizers.models.Model`. + + Returns: + :class:`~tokenizers.trainers.Trainer`: The Trainer used to train this model + """ + pass + + def id_to_token(self, id): + """ + Get the token associated to an ID + + Args: + id (:obj:`int`): + An ID to convert to a token + + Returns: + :obj:`str`: The token associated to the ID + """ + pass + + def save(self, folder, prefix): + """ + Save the current model + + Save the current model in the given folder, using the given prefix for the various + files that will get created. + Any file with the same name that already exists in this folder will be overwritten. + + Args: + folder (:obj:`str`): + The path to the target folder in which to save the various files + + prefix (:obj:`str`, `optional`): + An optional prefix, used to prefix each file name + + Returns: + :obj:`List[str]`: The list of saved files + """ + pass + + def token_to_id(self, tokens): + """ + Get the ID associated to a token + + Args: + token (:obj:`str`): + A token to convert to an ID + + Returns: + :obj:`int`: The ID associated to the token + """ + pass + + def tokenize(self, sequence): + """ + Tokenize a sequence + + Args: + sequence (:obj:`str`): + A sequence to tokenize + + Returns: + A :obj:`List` of :class:`~tokenizers.Token`: The generated tokens + """ + pass + +class BPE(Model): + """ + An implementation of the BPE (Byte-Pair Encoding) algorithm + + Args: + vocab (:obj:`Dict[str, int]`, `optional`): + A dictionary of string keys and their ids :obj:`{"am": 0,...}` + + merges (:obj:`List[Tuple[str, str]]`, `optional`): + A list of pairs of tokens (:obj:`Tuple[str, str]`) :obj:`[("a", "b"),...]` + + cache_capacity (:obj:`int`, `optional`): + The number of words that the BPE cache can contain. The cache allows + to speed-up the process by keeping the result of the merge operations + for a number of words. + + dropout (:obj:`float`, `optional`): + A float between 0 and 1 that represents the BPE dropout to use. + + unk_token (:obj:`str`, `optional`): + The unknown token to be used by the model. + + continuing_subword_prefix (:obj:`str`, `optional`): + The prefix to attach to subword units that don't represent a beginning of word. + + end_of_word_suffix (:obj:`str`, `optional`): + The suffix to attach to subword units that represent an end of word. + + fuse_unk (:obj:`bool`, `optional`): + Whether to fuse any subsequent unknown tokens into a single one + + byte_fallback (:obj:`bool`, `optional`): + Whether to use spm byte-fallback trick (defaults to False) + + ignore_merges (:obj:`bool`, `optional`): + Whether or not to match tokens with the vocab before using merges. + """ + def __init__( + self, + vocab=None, + merges=None, + cache_capacity=None, + dropout=None, + unk_token=None, + continuing_subword_prefix=None, + end_of_word_suffix=None, + fuse_unk=None, + byte_fallback=False, + ignore_merges=False, + ): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def byte_fallback(self): + """ """ + pass + + @byte_fallback.setter + def byte_fallback(self, value): + """ """ + pass + + @property + def continuing_subword_prefix(self): + """ """ + pass + + @continuing_subword_prefix.setter + def continuing_subword_prefix(self, value): + """ """ + pass + + @property + def dropout(self): + """ """ + pass + + @dropout.setter + def dropout(self, value): + """ """ + pass + + @property + def end_of_word_suffix(self): + """ """ + pass + + @end_of_word_suffix.setter + def end_of_word_suffix(self, value): + """ """ + pass + + @staticmethod + def from_file(vocab, merges, **kwargs): + """ + Instantiate a BPE model from the given files. + + This method is roughly equivalent to doing:: + + vocab, merges = BPE.read_file(vocab_filename, merges_filename) + bpe = BPE(vocab, merges) + + If you don't need to keep the :obj:`vocab, merges` values lying around, + this method is more optimized than manually calling + :meth:`~tokenizers.models.BPE.read_file` to initialize a :class:`~tokenizers.models.BPE` + + Args: + vocab (:obj:`str`): + The path to a :obj:`vocab.json` file + + merges (:obj:`str`): + The path to a :obj:`merges.txt` file + + Returns: + :class:`~tokenizers.models.BPE`: An instance of BPE loaded from these files + """ + pass + + @property + def fuse_unk(self): + """ """ + pass + + @fuse_unk.setter + def fuse_unk(self, value): + """ """ + pass + + def get_trainer(self): + """ + Get the associated :class:`~tokenizers.trainers.Trainer` + + Retrieve the :class:`~tokenizers.trainers.Trainer` associated to this + :class:`~tokenizers.models.Model`. + + Returns: + :class:`~tokenizers.trainers.Trainer`: The Trainer used to train this model + """ + pass + + def id_to_token(self, id): + """ + Get the token associated to an ID + + Args: + id (:obj:`int`): + An ID to convert to a token + + Returns: + :obj:`str`: The token associated to the ID + """ + pass + + @property + def ignore_merges(self): + """ """ + pass + + @ignore_merges.setter + def ignore_merges(self, value): + """ """ + pass + + @staticmethod + def read_file(vocab, merges): + """ + Read a :obj:`vocab.json` and a :obj:`merges.txt` files + + This method provides a way to read and parse the content of these files, + returning the relevant data structures. If you want to instantiate some BPE models + from memory, this method gives you the expected input from the standard files. + + Args: + vocab (:obj:`str`): + The path to a :obj:`vocab.json` file + + merges (:obj:`str`): + The path to a :obj:`merges.txt` file + + Returns: + A :obj:`Tuple` with the vocab and the merges: + The vocabulary and merges loaded into memory + """ + pass + + def save(self, folder, prefix): + """ + Save the current model + + Save the current model in the given folder, using the given prefix for the various + files that will get created. + Any file with the same name that already exists in this folder will be overwritten. + + Args: + folder (:obj:`str`): + The path to the target folder in which to save the various files + + prefix (:obj:`str`, `optional`): + An optional prefix, used to prefix each file name + + Returns: + :obj:`List[str]`: The list of saved files + """ + pass + + def token_to_id(self, tokens): + """ + Get the ID associated to a token + + Args: + token (:obj:`str`): + A token to convert to an ID + + Returns: + :obj:`int`: The ID associated to the token + """ + pass + + def tokenize(self, sequence): + """ + Tokenize a sequence + + Args: + sequence (:obj:`str`): + A sequence to tokenize + + Returns: + A :obj:`List` of :class:`~tokenizers.Token`: The generated tokens + """ + pass + + @property + def unk_token(self): + """ """ + pass + + @unk_token.setter + def unk_token(self, value): + """ """ + pass + +class Unigram(Model): + """ + An implementation of the Unigram algorithm + + Args: + vocab (:obj:`List[Tuple[str, float]]`, `optional`, `optional`): + A list of vocabulary items and their relative score [("am", -0.2442),...] + """ + def __init__(self, vocab=None, unk_id=None, byte_fallback=None): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + def get_trainer(self): + """ + Get the associated :class:`~tokenizers.trainers.Trainer` + + Retrieve the :class:`~tokenizers.trainers.Trainer` associated to this + :class:`~tokenizers.models.Model`. + + Returns: + :class:`~tokenizers.trainers.Trainer`: The Trainer used to train this model + """ + pass + + def id_to_token(self, id): + """ + Get the token associated to an ID + + Args: + id (:obj:`int`): + An ID to convert to a token + + Returns: + :obj:`str`: The token associated to the ID + """ + pass + + def save(self, folder, prefix): + """ + Save the current model + + Save the current model in the given folder, using the given prefix for the various + files that will get created. + Any file with the same name that already exists in this folder will be overwritten. + + Args: + folder (:obj:`str`): + The path to the target folder in which to save the various files + + prefix (:obj:`str`, `optional`): + An optional prefix, used to prefix each file name + + Returns: + :obj:`List[str]`: The list of saved files + """ + pass + + def token_to_id(self, tokens): + """ + Get the ID associated to a token + + Args: + token (:obj:`str`): + A token to convert to an ID + + Returns: + :obj:`int`: The ID associated to the token + """ + pass + + def tokenize(self, sequence): + """ + Tokenize a sequence + + Args: + sequence (:obj:`str`): + A sequence to tokenize + + Returns: + A :obj:`List` of :class:`~tokenizers.Token`: The generated tokens + """ + pass + +class WordLevel(Model): + """ + An implementation of the WordLevel algorithm + + Most simple tokenizer model based on mapping tokens to their corresponding id. + + Args: + vocab (:obj:`str`, `optional`): + A dictionary of string keys and their ids :obj:`{"am": 0,...}` + + unk_token (:obj:`str`, `optional`): + The unknown token to be used by the model. + """ + def __init__(self, vocab=None, unk_token=None): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def from_file(vocab, unk_token=None): + """ + Instantiate a WordLevel model from the given file + + This method is roughly equivalent to doing:: + + vocab = WordLevel.read_file(vocab_filename) + wordlevel = WordLevel(vocab) + + If you don't need to keep the :obj:`vocab` values lying around, this method is + more optimized than manually calling :meth:`~tokenizers.models.WordLevel.read_file` to + initialize a :class:`~tokenizers.models.WordLevel` + + Args: + vocab (:obj:`str`): + The path to a :obj:`vocab.json` file + + Returns: + :class:`~tokenizers.models.WordLevel`: An instance of WordLevel loaded from file + """ + pass + + def get_trainer(self): + """ + Get the associated :class:`~tokenizers.trainers.Trainer` + + Retrieve the :class:`~tokenizers.trainers.Trainer` associated to this + :class:`~tokenizers.models.Model`. + + Returns: + :class:`~tokenizers.trainers.Trainer`: The Trainer used to train this model + """ + pass + + def id_to_token(self, id): + """ + Get the token associated to an ID + + Args: + id (:obj:`int`): + An ID to convert to a token + + Returns: + :obj:`str`: The token associated to the ID + """ + pass + + @staticmethod + def read_file(vocab): + """ + Read a :obj:`vocab.json` + + This method provides a way to read and parse the content of a vocabulary file, + returning the relevant data structures. If you want to instantiate some WordLevel models + from memory, this method gives you the expected input from the standard files. + + Args: + vocab (:obj:`str`): + The path to a :obj:`vocab.json` file + + Returns: + :obj:`Dict[str, int]`: The vocabulary as a :obj:`dict` + """ + pass + + def save(self, folder, prefix): + """ + Save the current model + + Save the current model in the given folder, using the given prefix for the various + files that will get created. + Any file with the same name that already exists in this folder will be overwritten. + + Args: + folder (:obj:`str`): + The path to the target folder in which to save the various files + + prefix (:obj:`str`, `optional`): + An optional prefix, used to prefix each file name + + Returns: + :obj:`List[str]`: The list of saved files + """ + pass + + def token_to_id(self, tokens): + """ + Get the ID associated to a token + + Args: + token (:obj:`str`): + A token to convert to an ID + + Returns: + :obj:`int`: The ID associated to the token + """ + pass + + def tokenize(self, sequence): + """ + Tokenize a sequence + + Args: + sequence (:obj:`str`): + A sequence to tokenize + + Returns: + A :obj:`List` of :class:`~tokenizers.Token`: The generated tokens + """ + pass + + @property + def unk_token(self): + """ """ + pass + + @unk_token.setter + def unk_token(self, value): + """ """ + pass + +class WordPiece(Model): + """ + An implementation of the WordPiece algorithm + + Args: + vocab (:obj:`Dict[str, int]`, `optional`): + A dictionary of string keys and their ids :obj:`{"am": 0,...}` + + unk_token (:obj:`str`, `optional`): + The unknown token to be used by the model. + + max_input_chars_per_word (:obj:`int`, `optional`): + The maximum number of characters to authorize in a single word. + """ + def __init__(self, vocab=None, unk_token="[UNK]", max_input_chars_per_word=100, continuing_subword_prefix="##"): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def continuing_subword_prefix(self): + """ """ + pass + + @continuing_subword_prefix.setter + def continuing_subword_prefix(self, value): + """ """ + pass + + @staticmethod + def from_file(vocab, **kwargs): + """ + Instantiate a WordPiece model from the given file + + This method is roughly equivalent to doing:: + + vocab = WordPiece.read_file(vocab_filename) + wordpiece = WordPiece(vocab) + + If you don't need to keep the :obj:`vocab` values lying around, this method is + more optimized than manually calling :meth:`~tokenizers.models.WordPiece.read_file` to + initialize a :class:`~tokenizers.models.WordPiece` + + Args: + vocab (:obj:`str`): + The path to a :obj:`vocab.txt` file + + Returns: + :class:`~tokenizers.models.WordPiece`: An instance of WordPiece loaded from file + """ + pass + + def get_trainer(self): + """ + Get the associated :class:`~tokenizers.trainers.Trainer` + + Retrieve the :class:`~tokenizers.trainers.Trainer` associated to this + :class:`~tokenizers.models.Model`. + + Returns: + :class:`~tokenizers.trainers.Trainer`: The Trainer used to train this model + """ + pass + + def id_to_token(self, id): + """ + Get the token associated to an ID + + Args: + id (:obj:`int`): + An ID to convert to a token + + Returns: + :obj:`str`: The token associated to the ID + """ + pass + + @property + def max_input_chars_per_word(self): + """ """ + pass + + @max_input_chars_per_word.setter + def max_input_chars_per_word(self, value): + """ """ + pass + + @staticmethod + def read_file(vocab): + """ + Read a :obj:`vocab.txt` file + + This method provides a way to read and parse the content of a standard `vocab.txt` + file as used by the WordPiece Model, returning the relevant data structures. If you + want to instantiate some WordPiece models from memory, this method gives you the + expected input from the standard files. + + Args: + vocab (:obj:`str`): + The path to a :obj:`vocab.txt` file + + Returns: + :obj:`Dict[str, int]`: The vocabulary as a :obj:`dict` + """ + pass + + def save(self, folder, prefix): + """ + Save the current model + + Save the current model in the given folder, using the given prefix for the various + files that will get created. + Any file with the same name that already exists in this folder will be overwritten. + + Args: + folder (:obj:`str`): + The path to the target folder in which to save the various files + + prefix (:obj:`str`, `optional`): + An optional prefix, used to prefix each file name + + Returns: + :obj:`List[str]`: The list of saved files + """ + pass + + def token_to_id(self, tokens): + """ + Get the ID associated to a token + + Args: + token (:obj:`str`): + A token to convert to an ID + + Returns: + :obj:`int`: The ID associated to the token + """ + pass + + def tokenize(self, sequence): + """ + Tokenize a sequence + + Args: + sequence (:obj:`str`): + A sequence to tokenize + + Returns: + A :obj:`List` of :class:`~tokenizers.Token`: The generated tokens + """ + pass + + @property + def unk_token(self): + """ """ + pass + + @unk_token.setter + def unk_token(self, value): + """ """ + pass diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/models/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/models/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8198aaff12d6b0ba7e3c14af1bce9e6abd2b3518 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/normalizers/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/normalizers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..86d233bd216821d77f5ccf88f874b6f530cedbf5 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/normalizers/__init__.py @@ -0,0 +1,29 @@ +from .. import normalizers + + +Normalizer = normalizers.Normalizer +BertNormalizer = normalizers.BertNormalizer +NFD = normalizers.NFD +NFKD = normalizers.NFKD +NFC = normalizers.NFC +NFKC = normalizers.NFKC +Sequence = normalizers.Sequence +Lowercase = normalizers.Lowercase +Prepend = normalizers.Prepend +Strip = normalizers.Strip +StripAccents = normalizers.StripAccents +Nmt = normalizers.Nmt +Precompiled = normalizers.Precompiled +Replace = normalizers.Replace +ByteLevel = normalizers.ByteLevel + +NORMALIZERS = {"nfc": NFC, "nfd": NFD, "nfkc": NFKC, "nfkd": NFKD} + + +def unicode_normalizer_from_str(normalizer: str) -> Normalizer: + if normalizer not in NORMALIZERS: + raise ValueError( + "{} is not a known unicode normalizer. Available are {}".format(normalizer, NORMALIZERS.keys()) + ) + + return NORMALIZERS[normalizer]() diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/normalizers/__init__.pyi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/normalizers/__init__.pyi new file mode 100644 index 0000000000000000000000000000000000000000..8d920e0ed73ae051f2135aa250d2426562b73a43 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/normalizers/__init__.pyi @@ -0,0 +1,946 @@ +# Generated content DO NOT EDIT +class Normalizer: + """ + Base class for all normalizers + + This class is not supposed to be instantiated directly. Instead, any implementation of a + Normalizer will return an instance of this class when instantiated. + """ + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + +class BertNormalizer(Normalizer): + """ + BertNormalizer + + Takes care of normalizing raw text before giving it to a Bert model. + This includes cleaning the text, handling accents, chinese chars and lowercasing + + Args: + clean_text (:obj:`bool`, `optional`, defaults to :obj:`True`): + Whether to clean the text, by removing any control characters + and replacing all whitespaces by the classic one. + + handle_chinese_chars (:obj:`bool`, `optional`, defaults to :obj:`True`): + Whether to handle chinese chars by putting spaces around them. + + strip_accents (:obj:`bool`, `optional`): + Whether to strip all accents. If this option is not specified (ie == None), + then it will be determined by the value for `lowercase` (as in the original Bert). + + lowercase (:obj:`bool`, `optional`, defaults to :obj:`True`): + Whether to lowercase. + """ + def __init__(self, clean_text=True, handle_chinese_chars=True, strip_accents=None, lowercase=True): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def clean_text(self): + """ """ + pass + + @clean_text.setter + def clean_text(self, value): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + @property + def handle_chinese_chars(self): + """ """ + pass + + @handle_chinese_chars.setter + def handle_chinese_chars(self, value): + """ """ + pass + + @property + def lowercase(self): + """ """ + pass + + @lowercase.setter + def lowercase(self, value): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + + @property + def strip_accents(self): + """ """ + pass + + @strip_accents.setter + def strip_accents(self, value): + """ """ + pass + +class ByteLevel(Normalizer): + """ + Bytelevel Normalizer + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + +class Lowercase(Normalizer): + """ + Lowercase Normalizer + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + +class NFC(Normalizer): + """ + NFC Unicode Normalizer + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + +class NFD(Normalizer): + """ + NFD Unicode Normalizer + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + +class NFKC(Normalizer): + """ + NFKC Unicode Normalizer + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + +class NFKD(Normalizer): + """ + NFKD Unicode Normalizer + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + +class Nmt(Normalizer): + """ + Nmt normalizer + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + +class Precompiled(Normalizer): + """ + Precompiled normalizer + Don't use manually it is used for compatibility for SentencePiece. + """ + def __init__(self, precompiled_charsmap): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + +class Prepend(Normalizer): + """ + Prepend normalizer + """ + def __init__(self, prepend): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + + @property + def prepend(self): + """ """ + pass + + @prepend.setter + def prepend(self, value): + """ """ + pass + +class Replace(Normalizer): + """ + Replace normalizer + """ + def __init__(self, pattern, content): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def content(self): + """ """ + pass + + @content.setter + def content(self, value): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + + @property + def pattern(self): + """ """ + pass + + @pattern.setter + def pattern(self, value): + """ """ + pass + +class Sequence(Normalizer): + """ + Allows concatenating multiple other Normalizer as a Sequence. + All the normalizers run in sequence in the given order + + Args: + normalizers (:obj:`List[Normalizer]`): + A list of Normalizer to be run as a sequence + """ + def __init__(self, normalizers): + pass + + def __getitem__(self, key): + """ + Return self[key]. + """ + pass + + def __getnewargs__(self): + """ """ + pass + + def __getstate__(self): + """ """ + pass + + def __setitem__(self, key, value): + """ + Set self[key] to value. + """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + +class Strip(Normalizer): + """ + Strip normalizer + """ + def __init__(self, left=True, right=True): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + @property + def left(self): + """ """ + pass + + @left.setter + def left(self, value): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + + @property + def right(self): + """ """ + pass + + @right.setter + def right(self, value): + """ """ + pass + +class StripAccents(Normalizer): + """ + StripAccents normalizer + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(normalizer): + """ """ + pass + + def normalize(self, normalized): + """ + Normalize a :class:`~tokenizers.NormalizedString` in-place + + This method allows to modify a :class:`~tokenizers.NormalizedString` to + keep track of the alignment information. If you just want to see the result + of the normalization on a raw string, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize_str` + + Args: + normalized (:class:`~tokenizers.NormalizedString`): + The normalized string on which to apply this + :class:`~tokenizers.normalizers.Normalizer` + """ + pass + + def normalize_str(self, sequence): + """ + Normalize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.normalizers.Normalizer` but it does not keep track of the alignment + information. If you need to get/convert offsets, you can use + :meth:`~tokenizers.normalizers.Normalizer.normalize` + + Args: + sequence (:obj:`str`): + A string to normalize + + Returns: + :obj:`str`: A string after normalization + """ + pass + +from typing import Dict + +NORMALIZERS: Dict[str, Normalizer] + +def unicode_normalizer_from_str(normalizer: str) -> Normalizer: ... diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/normalizers/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/normalizers/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc95a0728839a16ae5037781d6380049bc933fd7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/normalizers/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/pre_tokenizers/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/pre_tokenizers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..db8ddc20805b1c525be405134f8fa722ace89667 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/pre_tokenizers/__init__.py @@ -0,0 +1,16 @@ +# Generated content DO NOT EDIT +from .. import pre_tokenizers + +PreTokenizer = pre_tokenizers.PreTokenizer +BertPreTokenizer = pre_tokenizers.BertPreTokenizer +ByteLevel = pre_tokenizers.ByteLevel +CharDelimiterSplit = pre_tokenizers.CharDelimiterSplit +Digits = pre_tokenizers.Digits +FixedLength = pre_tokenizers.FixedLength +Metaspace = pre_tokenizers.Metaspace +Punctuation = pre_tokenizers.Punctuation +Sequence = pre_tokenizers.Sequence +Split = pre_tokenizers.Split +UnicodeScripts = pre_tokenizers.UnicodeScripts +Whitespace = pre_tokenizers.Whitespace +WhitespaceSplit = pre_tokenizers.WhitespaceSplit diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/pre_tokenizers/__init__.pyi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/pre_tokenizers/__init__.pyi new file mode 100644 index 0000000000000000000000000000000000000000..1e58d5d040816761987935facee50666221a94bd --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/pre_tokenizers/__init__.pyi @@ -0,0 +1,1015 @@ +# Generated content DO NOT EDIT +class PreTokenizer: + """ + Base class for all pre-tokenizers + + This class is not supposed to be instantiated directly. Instead, any implementation of a + PreTokenizer will return an instance of this class when instantiated. + """ + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + +class BertPreTokenizer(PreTokenizer): + """ + BertPreTokenizer + + This pre-tokenizer splits tokens on spaces, and also on punctuation. + Each occurrence of a punctuation character will be treated separately. + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + +class ByteLevel(PreTokenizer): + """ + ByteLevel PreTokenizer + + This pre-tokenizer takes care of replacing all bytes of the given string + with a corresponding representation, as well as splitting into words. + + Args: + add_prefix_space (:obj:`bool`, `optional`, defaults to :obj:`True`): + Whether to add a space to the first word if there isn't already one. This + lets us treat `hello` exactly like `say hello`. + use_regex (:obj:`bool`, `optional`, defaults to :obj:`True`): + Set this to :obj:`False` to prevent this `pre_tokenizer` from using + the GPT2 specific regexp for spliting on whitespace. + """ + def __init__(self, add_prefix_space=True, trim_offsets=True, use_regex=True): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def add_prefix_space(self): + """ """ + pass + + @add_prefix_space.setter + def add_prefix_space(self, value): + """ """ + pass + + @staticmethod + def alphabet(): + """ + Returns the alphabet used by this PreTokenizer. + + Since the ByteLevel works as its name suggests, at the byte level, it + encodes each byte value to a unique visible character. This means that there is a + total of 256 different characters composing this alphabet. + + Returns: + :obj:`List[str]`: A list of characters that compose the alphabet + """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + + @property + def trim_offsets(self): + """ """ + pass + + @trim_offsets.setter + def trim_offsets(self, value): + """ """ + pass + + @property + def use_regex(self): + """ """ + pass + + @use_regex.setter + def use_regex(self, value): + """ """ + pass + +class CharDelimiterSplit(PreTokenizer): + """ + This pre-tokenizer simply splits on the provided char. Works like `.split(delimiter)` + + Args: + delimiter: str: + The delimiter char that will be used to split input + """ + def __init__(self, delimiter): + pass + + def __getnewargs__(self): + """ """ + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + @property + def delimiter(self): + """ """ + pass + + @delimiter.setter + def delimiter(self, value): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + +class Digits(PreTokenizer): + """ + This pre-tokenizer simply splits using the digits in separate tokens + + Args: + individual_digits (:obj:`bool`, `optional`, defaults to :obj:`False`): + If set to True, digits will each be separated as follows:: + + "Call 123 please" -> "Call ", "1", "2", "3", " please" + + If set to False, digits will grouped as follows:: + + "Call 123 please" -> "Call ", "123", " please" + """ + def __init__(self, individual_digits=False): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + @property + def individual_digits(self): + """ """ + pass + + @individual_digits.setter + def individual_digits(self, value): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + +class FixedLength(PreTokenizer): + """ + This pre-tokenizer splits the text into fixed length chunks as used + [here](https://www.biorxiv.org/content/10.1101/2023.01.11.523679v1.full) + + Args: + length (:obj:`int`, `optional`, defaults to :obj:`5`): + The length of the chunks to split the text into. + + Strings are split on the character level rather than the byte level to avoid + splitting unicode characters consisting of multiple bytes. + """ + def __init__(self, length=5): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + @property + def length(self): + """ """ + pass + + @length.setter + def length(self, value): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + +class Metaspace(PreTokenizer): + """ + Metaspace pre-tokenizer + + This pre-tokenizer replaces any whitespace by the provided replacement character. + It then tries to split on these spaces. + + Args: + replacement (:obj:`str`, `optional`, defaults to :obj:`▁`): + The replacement character. Must be exactly one character. By default we + use the `▁` (U+2581) meta symbol (Same as in SentencePiece). + + prepend_scheme (:obj:`str`, `optional`, defaults to :obj:`"always"`): + Whether to add a space to the first word if there isn't already one. This + lets us treat `hello` exactly like `say hello`. + Choices: "always", "never", "first". First means the space is only added on the first + token (relevant when special tokens are used or other pre_tokenizer are used). + + """ + def __init__(self, replacement="_", prepend_scheme="always", split=True): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + + @property + def prepend_scheme(self): + """ """ + pass + + @prepend_scheme.setter + def prepend_scheme(self, value): + """ """ + pass + + @property + def replacement(self): + """ """ + pass + + @replacement.setter + def replacement(self, value): + """ """ + pass + + @property + def split(self): + """ """ + pass + + @split.setter + def split(self, value): + """ """ + pass + +class Punctuation(PreTokenizer): + """ + This pre-tokenizer simply splits on punctuation as individual characters. + + Args: + behavior (:class:`~tokenizers.SplitDelimiterBehavior`): + The behavior to use when splitting. + Choices: "removed", "isolated" (default), "merged_with_previous", "merged_with_next", + "contiguous" + """ + def __init__(self, behavior="isolated"): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def behavior(self): + """ """ + pass + + @behavior.setter + def behavior(self, value): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + +class Sequence(PreTokenizer): + """ + This pre-tokenizer composes other pre_tokenizers and applies them in sequence + """ + def __init__(self, pretokenizers): + pass + + def __getitem__(self, key): + """ + Return self[key]. + """ + pass + + def __getnewargs__(self): + """ """ + pass + + def __getstate__(self): + """ """ + pass + + def __setitem__(self, key, value): + """ + Set self[key] to value. + """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + +class Split(PreTokenizer): + """ + Split PreTokenizer + + This versatile pre-tokenizer splits using the provided pattern and + according to the provided behavior. The pattern can be inverted by + making use of the invert flag. + + Args: + pattern (:obj:`str` or :class:`~tokenizers.Regex`): + A pattern used to split the string. Usually a string or a regex built with `tokenizers.Regex`. + If you want to use a regex pattern, it has to be wrapped around a `tokenizers.Regex`, + otherwise we consider is as a string pattern. For example `pattern="|"` + means you want to split on `|` (imagine a csv file for example), while + `pattern=tokenizers.Regex("1|2")` means you split on either '1' or '2'. + behavior (:class:`~tokenizers.SplitDelimiterBehavior`): + The behavior to use when splitting. + Choices: "removed", "isolated", "merged_with_previous", "merged_with_next", + "contiguous" + + invert (:obj:`bool`, `optional`, defaults to :obj:`False`): + Whether to invert the pattern. + """ + def __init__(self, pattern, behavior, invert=False): + pass + + def __getnewargs__(self): + """ """ + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def behavior(self): + """ """ + pass + + @behavior.setter + def behavior(self, value): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + @property + def invert(self): + """ """ + pass + + @invert.setter + def invert(self, value): + """ """ + pass + + @property + def pattern(self): + """ """ + pass + + @pattern.setter + def pattern(self, value): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + +class UnicodeScripts(PreTokenizer): + """ + This pre-tokenizer splits on characters that belong to different language family + It roughly follows https://github.com/google/sentencepiece/blob/master/data/Scripts.txt + Actually Hiragana and Katakana are fused with Han, and 0x30FC is Han too. + This mimicks SentencePiece Unigram implementation. + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + +class Whitespace(PreTokenizer): + """ + This pre-tokenizer splits on word boundaries according to the `\w+|[^\w\s]+` + regex pattern. It splits on word characters or characters that aren't words or + whitespaces (punctuation such as hyphens, apostrophes, commas, etc.). + + Example: + Use the `Whitespace` function as shown below:: + + ```python + from tokenizers.pre_tokenizers import Whitespace + + pre_tokenizer = Whitespace() + text = "Hello, world! Let's try the Whitespace pre-tokenizer." + pre_tokenizer.pre_tokenize_str(text) + [('Hello', (0, 5)), + (',', (5, 6)), + ('world', (7, 12)), + ('!', (12, 13)), + ('Let', (14, 17)), + ("'", (17, 18)), + ('s', (18, 19)), + ('try', (20, 23)), + ('the', (24, 27)), + ('Whitespace', (28, 38)), + ('pre', (39, 42)), + ('-', (42, 43)), + ('tokenizer', (43, 52)), + ('.', (52, 53))] + ``` + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass + +class WhitespaceSplit(PreTokenizer): + """ + This pre-tokenizer simply splits on the whitespace. Works like `.split()` + """ + def __init__(self): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @staticmethod + def custom(pretok): + """ """ + pass + + def pre_tokenize(self, pretok): + """ + Pre-tokenize a :class:`~tokenizers.PyPreTokenizedString` in-place + + This method allows to modify a :class:`~tokenizers.PreTokenizedString` to + keep track of the pre-tokenization, and leverage the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you just want to see the result of + the pre-tokenization of a raw string, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize_str` + + Args: + pretok (:class:`~tokenizers.PreTokenizedString): + The pre-tokenized string on which to apply this + :class:`~tokenizers.pre_tokenizers.PreTokenizer` + """ + pass + + def pre_tokenize_str(self, sequence): + """ + Pre tokenize the given string + + This method provides a way to visualize the effect of a + :class:`~tokenizers.pre_tokenizers.PreTokenizer` but it does not keep track of the + alignment, nor does it provide all the capabilities of the + :class:`~tokenizers.PreTokenizedString`. If you need some of these, you can use + :meth:`~tokenizers.pre_tokenizers.PreTokenizer.pre_tokenize` + + Args: + sequence (:obj:`str`): + A string to pre-tokeize + + Returns: + :obj:`List[Tuple[str, Offsets]]`: + A list of tuple with the pre-tokenized parts and their offsets + """ + pass diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/pre_tokenizers/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/pre_tokenizers/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b6c32409c03b1ff1182c966d4b0e4bce4c5428c Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/pre_tokenizers/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/processors/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/processors/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..06d124037b6d932615fa0d31b02f8ac82ac0b5fc --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/processors/__init__.py @@ -0,0 +1,9 @@ +# Generated content DO NOT EDIT +from .. import processors + +PostProcessor = processors.PostProcessor +BertProcessing = processors.BertProcessing +ByteLevel = processors.ByteLevel +RobertaProcessing = processors.RobertaProcessing +Sequence = processors.Sequence +TemplateProcessing = processors.TemplateProcessing diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/processors/__init__.pyi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/processors/__init__.pyi new file mode 100644 index 0000000000000000000000000000000000000000..0d49520c63e56c90b45c4a24604938daebbaeb07 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/processors/__init__.pyi @@ -0,0 +1,519 @@ +# Generated content DO NOT EDIT +class PostProcessor: + """ + Base class for all post-processors + + This class is not supposed to be instantiated directly. Instead, any implementation of + a PostProcessor will return an instance of this class when instantiated. + """ + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + def num_special_tokens_to_add(self, is_pair): + """ + Return the number of special tokens that would be added for single/pair sentences. + + Args: + is_pair (:obj:`bool`): + Whether the input would be a pair of sequences + + Returns: + :obj:`int`: The number of tokens to add + """ + pass + + def process(self, encoding, pair=None, add_special_tokens=True): + """ + Post-process the given encodings, generating the final one + + Args: + encoding (:class:`~tokenizers.Encoding`): + The encoding for the first sequence + + pair (:class:`~tokenizers.Encoding`, `optional`): + The encoding for the pair sequence + + add_special_tokens (:obj:`bool`): + Whether to add the special tokens + + Return: + :class:`~tokenizers.Encoding`: The final encoding + """ + pass + +class BertProcessing(PostProcessor): + """ + This post-processor takes care of adding the special tokens needed by + a Bert model: + + - a SEP token + - a CLS token + + Args: + sep (:obj:`Tuple[str, int]`): + A tuple with the string representation of the SEP token, and its id + + cls (:obj:`Tuple[str, int]`): + A tuple with the string representation of the CLS token, and its id + """ + def __init__(self, sep, cls): + pass + + def __getnewargs__(self): + """ """ + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def cls(self): + """ """ + pass + + @cls.setter + def cls(self, value): + """ """ + pass + + def num_special_tokens_to_add(self, is_pair): + """ + Return the number of special tokens that would be added for single/pair sentences. + + Args: + is_pair (:obj:`bool`): + Whether the input would be a pair of sequences + + Returns: + :obj:`int`: The number of tokens to add + """ + pass + + def process(self, encoding, pair=None, add_special_tokens=True): + """ + Post-process the given encodings, generating the final one + + Args: + encoding (:class:`~tokenizers.Encoding`): + The encoding for the first sequence + + pair (:class:`~tokenizers.Encoding`, `optional`): + The encoding for the pair sequence + + add_special_tokens (:obj:`bool`): + Whether to add the special tokens + + Return: + :class:`~tokenizers.Encoding`: The final encoding + """ + pass + + @property + def sep(self): + """ """ + pass + + @sep.setter + def sep(self, value): + """ """ + pass + +class ByteLevel(PostProcessor): + """ + This post-processor takes care of trimming the offsets. + + By default, the ByteLevel BPE might include whitespaces in the produced tokens. If you don't + want the offsets to include these whitespaces, then this PostProcessor must be used. + + Args: + trim_offsets (:obj:`bool`): + Whether to trim the whitespaces from the produced offsets. + + add_prefix_space (:obj:`bool`, `optional`, defaults to :obj:`True`): + If :obj:`True`, keeps the first token's offset as is. If :obj:`False`, increments + the start of the first token's offset by 1. Only has an effect if :obj:`trim_offsets` + is set to :obj:`True`. + """ + def __init__(self, add_prefix_space=None, trim_offsets=None, use_regex=None): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def add_prefix_space(self): + """ """ + pass + + @add_prefix_space.setter + def add_prefix_space(self, value): + """ """ + pass + + def num_special_tokens_to_add(self, is_pair): + """ + Return the number of special tokens that would be added for single/pair sentences. + + Args: + is_pair (:obj:`bool`): + Whether the input would be a pair of sequences + + Returns: + :obj:`int`: The number of tokens to add + """ + pass + + def process(self, encoding, pair=None, add_special_tokens=True): + """ + Post-process the given encodings, generating the final one + + Args: + encoding (:class:`~tokenizers.Encoding`): + The encoding for the first sequence + + pair (:class:`~tokenizers.Encoding`, `optional`): + The encoding for the pair sequence + + add_special_tokens (:obj:`bool`): + Whether to add the special tokens + + Return: + :class:`~tokenizers.Encoding`: The final encoding + """ + pass + + @property + def trim_offsets(self): + """ """ + pass + + @trim_offsets.setter + def trim_offsets(self, value): + """ """ + pass + + @property + def use_regex(self): + """ """ + pass + + @use_regex.setter + def use_regex(self, value): + """ """ + pass + +class RobertaProcessing(PostProcessor): + """ + This post-processor takes care of adding the special tokens needed by + a Roberta model: + + - a SEP token + - a CLS token + + It also takes care of trimming the offsets. + By default, the ByteLevel BPE might include whitespaces in the produced tokens. If you don't + want the offsets to include these whitespaces, then this PostProcessor should be initialized + with :obj:`trim_offsets=True` + + Args: + sep (:obj:`Tuple[str, int]`): + A tuple with the string representation of the SEP token, and its id + + cls (:obj:`Tuple[str, int]`): + A tuple with the string representation of the CLS token, and its id + + trim_offsets (:obj:`bool`, `optional`, defaults to :obj:`True`): + Whether to trim the whitespaces from the produced offsets. + + add_prefix_space (:obj:`bool`, `optional`, defaults to :obj:`True`): + Whether the add_prefix_space option was enabled during pre-tokenization. This + is relevant because it defines the way the offsets are trimmed out. + """ + def __init__(self, sep, cls, trim_offsets=True, add_prefix_space=True): + pass + + def __getnewargs__(self): + """ """ + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def add_prefix_space(self): + """ """ + pass + + @add_prefix_space.setter + def add_prefix_space(self, value): + """ """ + pass + + @property + def cls(self): + """ """ + pass + + @cls.setter + def cls(self, value): + """ """ + pass + + def num_special_tokens_to_add(self, is_pair): + """ + Return the number of special tokens that would be added for single/pair sentences. + + Args: + is_pair (:obj:`bool`): + Whether the input would be a pair of sequences + + Returns: + :obj:`int`: The number of tokens to add + """ + pass + + def process(self, encoding, pair=None, add_special_tokens=True): + """ + Post-process the given encodings, generating the final one + + Args: + encoding (:class:`~tokenizers.Encoding`): + The encoding for the first sequence + + pair (:class:`~tokenizers.Encoding`, `optional`): + The encoding for the pair sequence + + add_special_tokens (:obj:`bool`): + Whether to add the special tokens + + Return: + :class:`~tokenizers.Encoding`: The final encoding + """ + pass + + @property + def sep(self): + """ """ + pass + + @sep.setter + def sep(self, value): + """ """ + pass + + @property + def trim_offsets(self): + """ """ + pass + + @trim_offsets.setter + def trim_offsets(self, value): + """ """ + pass + +class Sequence(PostProcessor): + """ + Sequence Processor + + Args: + processors (:obj:`List[PostProcessor]`) + The processors that need to be chained + """ + def __init__(self, processors): + pass + + def __getitem__(self, key): + """ + Return self[key]. + """ + pass + + def __getnewargs__(self): + """ """ + pass + + def __getstate__(self): + """ """ + pass + + def __setitem__(self, key, value): + """ + Set self[key] to value. + """ + pass + + def __setstate__(self, state): + """ """ + pass + + def num_special_tokens_to_add(self, is_pair): + """ + Return the number of special tokens that would be added for single/pair sentences. + + Args: + is_pair (:obj:`bool`): + Whether the input would be a pair of sequences + + Returns: + :obj:`int`: The number of tokens to add + """ + pass + + def process(self, encoding, pair=None, add_special_tokens=True): + """ + Post-process the given encodings, generating the final one + + Args: + encoding (:class:`~tokenizers.Encoding`): + The encoding for the first sequence + + pair (:class:`~tokenizers.Encoding`, `optional`): + The encoding for the pair sequence + + add_special_tokens (:obj:`bool`): + Whether to add the special tokens + + Return: + :class:`~tokenizers.Encoding`: The final encoding + """ + pass + +class TemplateProcessing(PostProcessor): + """ + Provides a way to specify templates in order to add the special tokens to each + input sequence as relevant. + + Let's take :obj:`BERT` tokenizer as an example. It uses two special tokens, used to + delimitate each sequence. :obj:`[CLS]` is always used at the beginning of the first + sequence, and :obj:`[SEP]` is added at the end of both the first, and the pair + sequences. The final result looks like this: + + - Single sequence: :obj:`[CLS] Hello there [SEP]` + - Pair sequences: :obj:`[CLS] My name is Anthony [SEP] What is my name? [SEP]` + + With the type ids as following:: + + [CLS] ... [SEP] ... [SEP] + 0 0 0 1 1 + + You can achieve such behavior using a TemplateProcessing:: + + TemplateProcessing( + single="[CLS] $0 [SEP]", + pair="[CLS] $A [SEP] $B:1 [SEP]:1", + special_tokens=[("[CLS]", 1), ("[SEP]", 0)], + ) + + In this example, each input sequence is identified using a ``$`` construct. This identifier + lets us specify each input sequence, and the type_id to use. When nothing is specified, + it uses the default values. Here are the different ways to specify it: + + - Specifying the sequence, with default ``type_id == 0``: ``$A`` or ``$B`` + - Specifying the `type_id` with default ``sequence == A``: ``$0``, ``$1``, ``$2``, ... + - Specifying both: ``$A:0``, ``$B:1``, ... + + The same construct is used for special tokens: ``(:)?``. + + **Warning**: You must ensure that you are giving the correct tokens/ids as these + will be added to the Encoding without any further check. If the given ids correspond + to something totally different in a `Tokenizer` using this `PostProcessor`, it + might lead to unexpected results. + + Args: + single (:obj:`Template`): + The template used for single sequences + + pair (:obj:`Template`): + The template used when both sequences are specified + + special_tokens (:obj:`Tokens`): + The list of special tokens used in each sequences + + Types: + + Template (:obj:`str` or :obj:`List`): + - If a :obj:`str` is provided, the whitespace is used as delimiter between tokens + - If a :obj:`List[str]` is provided, a list of tokens + + Tokens (:obj:`List[Union[Tuple[int, str], Tuple[str, int], dict]]`): + - A :obj:`Tuple` with both a token and its associated ID, in any order + - A :obj:`dict` with the following keys: + - "id": :obj:`str` => The special token id, as specified in the Template + - "ids": :obj:`List[int]` => The associated IDs + - "tokens": :obj:`List[str]` => The associated tokens + + The given dict expects the provided :obj:`ids` and :obj:`tokens` lists to have + the same length. + """ + def __init__(self, single=None, pair=None, special_tokens=None): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + def num_special_tokens_to_add(self, is_pair): + """ + Return the number of special tokens that would be added for single/pair sentences. + + Args: + is_pair (:obj:`bool`): + Whether the input would be a pair of sequences + + Returns: + :obj:`int`: The number of tokens to add + """ + pass + + def process(self, encoding, pair=None, add_special_tokens=True): + """ + Post-process the given encodings, generating the final one + + Args: + encoding (:class:`~tokenizers.Encoding`): + The encoding for the first sequence + + pair (:class:`~tokenizers.Encoding`, `optional`): + The encoding for the pair sequence + + add_special_tokens (:obj:`bool`): + Whether to add the special tokens + + Return: + :class:`~tokenizers.Encoding`: The final encoding + """ + pass + + @property + def single(self): + """ """ + pass + + @single.setter + def single(self, value): + """ """ + pass diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/processors/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/processors/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ca38082a3d747fc1caae8ee79a64797b5794124 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/processors/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f941e2ed39c7d69fa14abff7dcf973d93843ea06 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/__init__.py @@ -0,0 +1 @@ +from .visualizer import Annotation, EncodingVisualizer diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d237fca553743b6e9dadc5a183903812eb3d4c3 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/__pycache__/visualizer.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/__pycache__/visualizer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d157e430a4e10ae80f7cdda3624b27acb138532 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/__pycache__/visualizer.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/visualizer-styles.css b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/visualizer-styles.css new file mode 100644 index 0000000000000000000000000000000000000000..f54fde45ada66c902c0b41969d0f40d51c9717da --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/visualizer-styles.css @@ -0,0 +1,170 @@ +.tokenized-text { + width:100%; + padding:2rem; + max-height: 400px; + overflow-y: auto; + box-sizing:border-box; + line-height:4rem; /* Lots of space between lines */ + font-family: "Roboto Light", "Ubuntu Light", "Ubuntu", monospace; + box-shadow: 2px 2px 2px rgba(0,0,0,0.2); + background-color: rgba(0,0,0,0.01); + letter-spacing:2px; /* Give some extra separation between chars */ +} +.non-token{ + /* White space and other things the tokenizer ignores*/ + white-space: pre; + letter-spacing:4px; + border-top:1px solid #A0A0A0; /* A gentle border on top and bottom makes tabs more ovious*/ + border-bottom:1px solid #A0A0A0; + line-height: 1rem; + height: calc(100% - 2px); +} + +.token { + white-space: pre; + position:relative; + color:black; + letter-spacing:2px; +} + +.annotation{ + white-space:nowrap; /* Important - ensures that annotations appears even if the annotated text wraps a line */ + border-radius:4px; + position:relative; + width:fit-content; +} +.annotation:before { + /*The before holds the text and the after holds the background*/ + z-index:1000; /* Make sure this is above the background */ + content:attr(data-label); /* The annotations label is on a data attribute */ + color:white; + position:absolute; + font-size:1rem; + text-align:center; + font-weight:bold; + + top:1.75rem; + line-height:0; + left:0; + width:100%; + padding:0.5rem 0; + /* These make it so an annotation doesn't stretch beyond the annotated text if the label is longer*/ + overflow: hidden; + white-space: nowrap; + text-overflow:ellipsis; +} + +.annotation:after { + content:attr(data-label); /* The content defines the width of the annotation*/ + position:absolute; + font-size:0.75rem; + text-align:center; + font-weight:bold; + text-overflow:ellipsis; + top:1.75rem; + line-height:0; + overflow: hidden; + white-space: nowrap; + + left:0; + width:100%; /* 100% of the parent, which is the annotation whose width is the tokens inside it*/ + + padding:0.5rem 0; + /* Nast hack below: + We set the annotations color in code because we don't know the colors at css time. + But you can't pass a color as a data attribute to get it into the pseudo element (this thing) + So to get around that, annotations have the color set on them with a style attribute and then we + can get the color with currentColor. + Annotations wrap tokens and tokens set the color back to black + */ + background-color: currentColor; +} +.annotation:hover::after, .annotation:hover::before{ + /* When the user hovers over an annotation expand the label to display in full + */ + min-width: fit-content; +} + +.annotation:hover{ + /* Emphasize the annotation start end with a border on hover*/ + border-color: currentColor; + border: 2px solid; +} +.special-token:not(:empty){ + /* + A none empty special token is like UNK (as opposed to CLS which has no representation in the text ) + */ + position:relative; +} +.special-token:empty::before{ + /* Special tokens that don't have text are displayed as pseudo elements so we dont select them with the mouse*/ + content:attr(data-stok); + background:#202020; + font-size:0.75rem; + color:white; + margin: 0 0.25rem; + padding: 0.25rem; + border-radius:4px +} + +.special-token:not(:empty):before { + /* Special tokens that have text (UNK) are displayed above the actual text*/ + content:attr(data-stok); + position:absolute; + bottom:1.75rem; + min-width:100%; + width:100%; + height:1rem; + line-height:1rem; + font-size:1rem; + text-align:center; + color:white; + font-weight:bold; + background:#202020; + border-radius:10%; +} +/* +We want to alternate the color of tokens, but we can't use nth child because tokens might be broken up by annotations +instead we apply even and odd class at generation time and color them that way + */ +.even-token{ + background:#DCDCDC ; + border: 1px solid #DCDCDC; +} +.odd-token{ + background:#A0A0A0; + border: 1px solid #A0A0A0; +} +.even-token.multi-token,.odd-token.multi-token{ + background: repeating-linear-gradient( + 45deg, + transparent, + transparent 1px, + #ccc 1px, + #ccc 1px + ), + /* on "bottom" */ + linear-gradient( + to bottom, + #FFB6C1, + #999 + ); +} + +.multi-token:hover::after { + content:"This char has more than 1 token"; /* The content defines the width of the annotation*/ + color:white; + background-color: black; + position:absolute; + font-size:0.75rem; + text-align:center; + font-weight:bold; + text-overflow:ellipsis; + top:1.75rem; + line-height:0; + overflow: hidden; + white-space: nowrap; + left:0; + width:fit-content; /* 100% of the parent, which is the annotation whose width is the tokens inside it*/ + padding:0.5rem 0; +} diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/visualizer.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/visualizer.py new file mode 100644 index 0000000000000000000000000000000000000000..9e85f13e05baea5cec69136eb3c951cf28a84207 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/tools/visualizer.py @@ -0,0 +1,407 @@ +import itertools +import os +import re +from string import Template +from typing import Any, Callable, Dict, List, NamedTuple, Optional, Tuple + +from tokenizers import Encoding, Tokenizer + + +dirname = os.path.dirname(__file__) +css_filename = os.path.join(dirname, "visualizer-styles.css") +with open(css_filename) as f: + css = f.read() + + +class Annotation: + start: int + end: int + label: str + + def __init__(self, start: int, end: int, label: str): + self.start = start + self.end = end + self.label = label + + +AnnotationList = List[Annotation] +PartialIntList = List[Optional[int]] + + +class CharStateKey(NamedTuple): + token_ix: Optional[int] + anno_ix: Optional[int] + + +class CharState: + char_ix: Optional[int] + + def __init__(self, char_ix): + self.char_ix = char_ix + + self.anno_ix: Optional[int] = None + self.tokens: List[int] = [] + + @property + def token_ix(self): + return self.tokens[0] if len(self.tokens) > 0 else None + + @property + def is_multitoken(self): + """ + BPE tokenizers can output more than one token for a char + """ + return len(self.tokens) > 1 + + def partition_key(self) -> CharStateKey: + return CharStateKey( + token_ix=self.token_ix, + anno_ix=self.anno_ix, + ) + + +class Aligned: + pass + + +class EncodingVisualizer: + """ + Build an EncodingVisualizer + + Args: + + tokenizer (:class:`~tokenizers.Tokenizer`): + A tokenizer instance + + default_to_notebook (:obj:`bool`): + Whether to render html output in a notebook by default + + annotation_converter (:obj:`Callable`, `optional`): + An optional (lambda) function that takes an annotation in any format and returns + an Annotation object + """ + + unk_token_regex = re.compile("(.{1}\b)?(unk|oov)(\b.{1})?", flags=re.IGNORECASE) + + def __init__( + self, + tokenizer: Tokenizer, + default_to_notebook: bool = True, + annotation_converter: Optional[Callable[[Any], Annotation]] = None, + ): + if default_to_notebook: + try: + from IPython.core.display import HTML, display # type: ignore[attr-defined] + except ImportError: + raise Exception( + """We couldn't import IPython utils for html display. + Are you running in a notebook? + You can also pass `default_to_notebook=False` to get back raw HTML + """ + ) + + self.tokenizer = tokenizer + self.default_to_notebook = default_to_notebook + self.annotation_coverter = annotation_converter + pass + + def __call__( + self, + text: str, + annotations: Optional[List[Any]] = None, + default_to_notebook: Optional[bool] = None, + ) -> Optional[str]: + """ + Build a visualization of the given text + + Args: + text (:obj:`str`): + The text to tokenize + + annotations (:obj:`List[Annotation]`, `optional`): + An optional list of annotations of the text. The can either be an annotation class + or anything else if you instantiated the visualizer with a converter function + + default_to_notebook (:obj:`bool`, `optional`, defaults to `False`): + If True, will render the html in a notebook. Otherwise returns an html string. + + Returns: + The HTML string if default_to_notebook is False, otherwise (default) returns None and + renders the HTML in the notebook + + """ + final_default_to_notebook = self.default_to_notebook + if default_to_notebook is not None: + final_default_to_notebook = default_to_notebook + if final_default_to_notebook: + try: + from IPython.core.display import HTML, display # type: ignore[attr-defined] + except ImportError: + raise Exception( + """We couldn't import IPython utils for html display. + Are you running in a notebook?""" + ) + if annotations is None: + annotations = [] + if self.annotation_coverter is not None: + annotations = list(map(self.annotation_coverter, annotations)) + encoding = self.tokenizer.encode(text) + html = EncodingVisualizer.__make_html(text, encoding, annotations) + if final_default_to_notebook: + display(HTML(html)) + else: + return html + + @staticmethod + def calculate_label_colors(annotations: AnnotationList) -> Dict[str, str]: + """ + Generates a color palette for all the labels in a given set of annotations + + Args: + annotations (:obj:`Annotation`): + A list of annotations + + Returns: + :obj:`dict`: A dictionary mapping labels to colors in HSL format + """ + if len(annotations) == 0: + return {} + labels = set(map(lambda x: x.label, annotations)) + num_labels = len(labels) + h_step = int(255 / num_labels) + if h_step < 20: + h_step = 20 + s = 32 + l = 64 # noqa: E741 + h = 10 + colors = {} + + for label in sorted(labels): # sort so we always get the same colors for a given set of labels + colors[label] = f"hsl({h},{s}%,{l}%)" + h += h_step + return colors + + @staticmethod + def consecutive_chars_to_html( + consecutive_chars_list: List[CharState], + text: str, + encoding: Encoding, + ): + """ + Converts a list of "consecutive chars" into a single HTML element. + Chars are consecutive if they fall under the same word, token and annotation. + The CharState class is a named tuple with a "partition_key" method that makes it easy to + compare if two chars are consecutive. + + Args: + consecutive_chars_list (:obj:`List[CharState]`): + A list of CharStates that have been grouped together + + text (:obj:`str`): + The original text being processed + + encoding (:class:`~tokenizers.Encoding`): + The encoding returned from the tokenizer + + Returns: + :obj:`str`: The HTML span for a set of consecutive chars + """ + first = consecutive_chars_list[0] + if first.char_ix is None: + # its a special token + stoken = encoding.tokens[first.token_ix] + # special tokens are represented as empty spans. We use the data attribute and css + # magic to display it + return f'' + # We're not in a special token so this group has a start and end. + last = consecutive_chars_list[-1] + assert first.char_ix is not None + assert last.char_ix is not None + start = first.char_ix + end = last.char_ix + 1 + span_text = text[start:end] + css_classes = [] # What css classes will we apply on the resulting span + data_items = {} # What data attributes will we apply on the result span + if first.token_ix is not None: + # We can either be in a token or not (e.g. in white space) + css_classes.append("token") + if first.is_multitoken: + css_classes.append("multi-token") + if first.token_ix % 2: + # We use this to color alternating tokens. + # A token might be split by an annotation that ends in the middle of it, so this + # lets us visually indicate a consecutive token despite its possible splitting in + # the html markup + css_classes.append("odd-token") + else: + # Like above, but a different color so we can see the tokens alternate + css_classes.append("even-token") + if EncodingVisualizer.unk_token_regex.search(encoding.tokens[first.token_ix]) is not None: + # This is a special token that is in the text. probably UNK + css_classes.append("special-token") + # TODO is this the right name for the data attribute ? + data_items["stok"] = encoding.tokens[first.token_ix] + else: + # In this case we are looking at a group/single char that is not tokenized. + # e.g. white space + css_classes.append("non-token") + css = f'''class="{" ".join(css_classes)}"''' + data = "" + for key, val in data_items.items(): + data += f' data-{key}="{val}"' + return f"{span_text}" + + @staticmethod + def __make_html(text: str, encoding: Encoding, annotations: AnnotationList) -> str: + char_states = EncodingVisualizer.__make_char_states(text, encoding, annotations) + current_consecutive_chars = [char_states[0]] + prev_anno_ix = char_states[0].anno_ix + spans = [] + label_colors_dict = EncodingVisualizer.calculate_label_colors(annotations) + cur_anno_ix = char_states[0].anno_ix + if cur_anno_ix is not None: + # If we started in an annotation make a span for it + anno = annotations[cur_anno_ix] + label = anno.label + color = label_colors_dict[label] + spans.append(f'') + + for cs in char_states[1:]: + cur_anno_ix = cs.anno_ix + if cur_anno_ix != prev_anno_ix: + # If we've transitioned in or out of an annotation + spans.append( + # Create a span from the current consecutive characters + EncodingVisualizer.consecutive_chars_to_html( + current_consecutive_chars, + text=text, + encoding=encoding, + ) + ) + current_consecutive_chars = [cs] + + if prev_anno_ix is not None: + # if we transitioned out of an annotation close it's span + spans.append("") + if cur_anno_ix is not None: + # If we entered a new annotation make a span for it + anno = annotations[cur_anno_ix] + label = anno.label + color = label_colors_dict[label] + spans.append(f'') + prev_anno_ix = cur_anno_ix + + if cs.partition_key() == current_consecutive_chars[0].partition_key(): + # If the current charchter is in the same "group" as the previous one + current_consecutive_chars.append(cs) + else: + # Otherwise we make a span for the previous group + spans.append( + EncodingVisualizer.consecutive_chars_to_html( + current_consecutive_chars, + text=text, + encoding=encoding, + ) + ) + # An reset the consecutive_char_list to form a new group + current_consecutive_chars = [cs] + # All that's left is to fill out the final span + # TODO I think there is an edge case here where an annotation's span might not close + spans.append( + EncodingVisualizer.consecutive_chars_to_html( + current_consecutive_chars, + text=text, + encoding=encoding, + ) + ) + res = HTMLBody(spans) # Send the list of spans to the body of our html + return res + + @staticmethod + def __make_anno_map(text: str, annotations: AnnotationList) -> PartialIntList: + """ + Args: + text (:obj:`str`): + The raw text we want to align to + + annotations (:obj:`AnnotationList`): + A (possibly empty) list of annotations + + Returns: + A list of length len(text) whose entry at index i is None if there is no annotation on + character i or k, the index of the annotation that covers index i where k is with + respect to the list of annotations + """ + annotation_map = [None] * len(text) + for anno_ix, a in enumerate(annotations): + for i in range(a.start, a.end): + annotation_map[i] = anno_ix + return annotation_map + + @staticmethod + def __make_char_states(text: str, encoding: Encoding, annotations: AnnotationList) -> List[CharState]: + """ + For each character in the original text, we emit a tuple representing it's "state": + + * which token_ix it corresponds to + * which word_ix it corresponds to + * which annotation_ix it corresponds to + + Args: + text (:obj:`str`): + The raw text we want to align to + + annotations (:obj:`List[Annotation]`): + A (possibly empty) list of annotations + + encoding: (:class:`~tokenizers.Encoding`): + The encoding returned from the tokenizer + + Returns: + :obj:`List[CharState]`: A list of CharStates, indicating for each char in the text what + it's state is + """ + annotation_map = EncodingVisualizer.__make_anno_map(text, annotations) + # Todo make this a dataclass or named tuple + char_states: List[CharState] = [CharState(char_ix) for char_ix in range(len(text))] + for token_ix, token in enumerate(encoding.tokens): + offsets = encoding.token_to_chars(token_ix) + if offsets is not None: + start, end = offsets + for i in range(start, end): + char_states[i].tokens.append(token_ix) + for char_ix, anno_ix in enumerate(annotation_map): + char_states[char_ix].anno_ix = anno_ix + + return char_states + + +def HTMLBody(children: List[str], css_styles=css) -> str: + """ + Generates the full html with css from a list of html spans + + Args: + children (:obj:`List[str]`): + A list of strings, assumed to be html elements + + css_styles (:obj:`str`, `optional`): + Optional alternative implementation of the css + + Returns: + :obj:`str`: An HTML string with style markup + """ + children_text = "".join(children) + return f""" + + + + + +
+ {children_text} +
+ + + """ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/trainers/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/trainers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..22f94c50b7cf63f0b38231ab1ecec88141a678fd --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/trainers/__init__.py @@ -0,0 +1,8 @@ +# Generated content DO NOT EDIT +from .. import trainers + +Trainer = trainers.Trainer +BpeTrainer = trainers.BpeTrainer +UnigramTrainer = trainers.UnigramTrainer +WordLevelTrainer = trainers.WordLevelTrainer +WordPieceTrainer = trainers.WordPieceTrainer diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/trainers/__init__.pyi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/trainers/__init__.pyi new file mode 100644 index 0000000000000000000000000000000000000000..d7bf6c5283afb0d9fa046ffa93bb5501fafe06aa --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/trainers/__init__.pyi @@ -0,0 +1,462 @@ +# Generated content DO NOT EDIT +class Trainer: + """ + Base class for all trainers + + This class is not supposed to be instantiated directly. Instead, any implementation of a + Trainer will return an instance of this class when instantiated. + """ + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + +class BpeTrainer(Trainer): + """ + Trainer capable of training a BPE model + + Args: + vocab_size (:obj:`int`, `optional`): + The size of the final vocabulary, including all tokens and alphabet. + + min_frequency (:obj:`int`, `optional`): + The minimum frequency a pair should have in order to be merged. + + show_progress (:obj:`bool`, `optional`): + Whether to show progress bars while training. + + special_tokens (:obj:`List[Union[str, AddedToken]]`, `optional`): + A list of special tokens the model should know of. + + limit_alphabet (:obj:`int`, `optional`): + The maximum different characters to keep in the alphabet. + + initial_alphabet (:obj:`List[str]`, `optional`): + A list of characters to include in the initial alphabet, even + if not seen in the training dataset. + If the strings contain more than one character, only the first one + is kept. + + continuing_subword_prefix (:obj:`str`, `optional`): + A prefix to be used for every subword that is not a beginning-of-word. + + end_of_word_suffix (:obj:`str`, `optional`): + A suffix to be used for every subword that is a end-of-word. + + max_token_length (:obj:`int`, `optional`): + Prevents creating tokens longer than the specified size. + This can help with reducing polluting your vocabulary with + highly repetitive tokens like `======` for wikipedia + + """ + def __init__( + self, + vocab_size=30000, + min_frequency=0, + show_progress=True, + special_tokens=[], + limit_alphabet=None, + initial_alphabet=[], + continuing_subword_prefix=None, + end_of_word_suffix=None, + max_token_length=None, + words={}, + ): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def continuing_subword_prefix(self): + """ """ + pass + + @continuing_subword_prefix.setter + def continuing_subword_prefix(self, value): + """ """ + pass + + @property + def end_of_word_suffix(self): + """ """ + pass + + @end_of_word_suffix.setter + def end_of_word_suffix(self, value): + """ """ + pass + + @property + def initial_alphabet(self): + """ """ + pass + + @initial_alphabet.setter + def initial_alphabet(self, value): + """ """ + pass + + @property + def limit_alphabet(self): + """ """ + pass + + @limit_alphabet.setter + def limit_alphabet(self, value): + """ """ + pass + + @property + def max_token_length(self): + """ """ + pass + + @max_token_length.setter + def max_token_length(self, value): + """ """ + pass + + @property + def min_frequency(self): + """ """ + pass + + @min_frequency.setter + def min_frequency(self, value): + """ """ + pass + + @property + def show_progress(self): + """ """ + pass + + @show_progress.setter + def show_progress(self, value): + """ """ + pass + + @property + def special_tokens(self): + """ """ + pass + + @special_tokens.setter + def special_tokens(self, value): + """ """ + pass + + @property + def vocab_size(self): + """ """ + pass + + @vocab_size.setter + def vocab_size(self, value): + """ """ + pass + +class UnigramTrainer(Trainer): + """ + Trainer capable of training a Unigram model + + Args: + vocab_size (:obj:`int`): + The size of the final vocabulary, including all tokens and alphabet. + + show_progress (:obj:`bool`): + Whether to show progress bars while training. + + special_tokens (:obj:`List[Union[str, AddedToken]]`): + A list of special tokens the model should know of. + + initial_alphabet (:obj:`List[str]`): + A list of characters to include in the initial alphabet, even + if not seen in the training dataset. + If the strings contain more than one character, only the first one + is kept. + + shrinking_factor (:obj:`float`): + The shrinking factor used at each step of the training to prune the + vocabulary. + + unk_token (:obj:`str`): + The token used for out-of-vocabulary tokens. + + max_piece_length (:obj:`int`): + The maximum length of a given token. + + n_sub_iterations (:obj:`int`): + The number of iterations of the EM algorithm to perform before + pruning the vocabulary. + """ + def __init__( + self, + vocab_size=8000, + show_progress=True, + special_tokens=[], + initial_alphabet=[], + shrinking_factor=0.75, + unk_token=None, + max_piece_length=16, + n_sub_iterations=2, + ): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def initial_alphabet(self): + """ """ + pass + + @initial_alphabet.setter + def initial_alphabet(self, value): + """ """ + pass + + @property + def show_progress(self): + """ """ + pass + + @show_progress.setter + def show_progress(self, value): + """ """ + pass + + @property + def special_tokens(self): + """ """ + pass + + @special_tokens.setter + def special_tokens(self, value): + """ """ + pass + + @property + def vocab_size(self): + """ """ + pass + + @vocab_size.setter + def vocab_size(self, value): + """ """ + pass + +class WordLevelTrainer(Trainer): + """ + Trainer capable of training a WorldLevel model + + Args: + vocab_size (:obj:`int`, `optional`): + The size of the final vocabulary, including all tokens and alphabet. + + min_frequency (:obj:`int`, `optional`): + The minimum frequency a pair should have in order to be merged. + + show_progress (:obj:`bool`, `optional`): + Whether to show progress bars while training. + + special_tokens (:obj:`List[Union[str, AddedToken]]`): + A list of special tokens the model should know of. + """ + def __init__(self, vocab_size=30000, min_frequency=0, show_progress=True, special_tokens=[]): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def min_frequency(self): + """ """ + pass + + @min_frequency.setter + def min_frequency(self, value): + """ """ + pass + + @property + def show_progress(self): + """ """ + pass + + @show_progress.setter + def show_progress(self, value): + """ """ + pass + + @property + def special_tokens(self): + """ """ + pass + + @special_tokens.setter + def special_tokens(self, value): + """ """ + pass + + @property + def vocab_size(self): + """ """ + pass + + @vocab_size.setter + def vocab_size(self, value): + """ """ + pass + +class WordPieceTrainer(Trainer): + """ + Trainer capable of training a WordPiece model + + Args: + vocab_size (:obj:`int`, `optional`): + The size of the final vocabulary, including all tokens and alphabet. + + min_frequency (:obj:`int`, `optional`): + The minimum frequency a pair should have in order to be merged. + + show_progress (:obj:`bool`, `optional`): + Whether to show progress bars while training. + + special_tokens (:obj:`List[Union[str, AddedToken]]`, `optional`): + A list of special tokens the model should know of. + + limit_alphabet (:obj:`int`, `optional`): + The maximum different characters to keep in the alphabet. + + initial_alphabet (:obj:`List[str]`, `optional`): + A list of characters to include in the initial alphabet, even + if not seen in the training dataset. + If the strings contain more than one character, only the first one + is kept. + + continuing_subword_prefix (:obj:`str`, `optional`): + A prefix to be used for every subword that is not a beginning-of-word. + + end_of_word_suffix (:obj:`str`, `optional`): + A suffix to be used for every subword that is a end-of-word. + """ + def __init__( + self, + vocab_size=30000, + min_frequency=0, + show_progress=True, + special_tokens=[], + limit_alphabet=None, + initial_alphabet=[], + continuing_subword_prefix="##", + end_of_word_suffix=None, + ): + pass + + def __getstate__(self): + """ """ + pass + + def __setstate__(self, state): + """ """ + pass + + @property + def continuing_subword_prefix(self): + """ """ + pass + + @continuing_subword_prefix.setter + def continuing_subword_prefix(self, value): + """ """ + pass + + @property + def end_of_word_suffix(self): + """ """ + pass + + @end_of_word_suffix.setter + def end_of_word_suffix(self, value): + """ """ + pass + + @property + def initial_alphabet(self): + """ """ + pass + + @initial_alphabet.setter + def initial_alphabet(self, value): + """ """ + pass + + @property + def limit_alphabet(self): + """ """ + pass + + @limit_alphabet.setter + def limit_alphabet(self, value): + """ """ + pass + + @property + def min_frequency(self): + """ """ + pass + + @min_frequency.setter + def min_frequency(self, value): + """ """ + pass + + @property + def show_progress(self): + """ """ + pass + + @show_progress.setter + def show_progress(self, value): + """ """ + pass + + @property + def special_tokens(self): + """ """ + pass + + @special_tokens.setter + def special_tokens(self, value): + """ """ + pass + + @property + def vocab_size(self): + """ """ + pass + + @vocab_size.setter + def vocab_size(self, value): + """ """ + pass diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/trainers/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/trainers/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e46d75e07b289d610cdcd10bd40d6585f3a746a9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tokenizers/trainers/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/commands/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/commands/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d4ec5a1c80eabe241c8f001fd597557601733c0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/commands/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/commands/__pycache__/add_new_model_like.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/commands/__pycache__/add_new_model_like.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da740fb9ba02629038a997afb06460b42692f65e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/commands/__pycache__/add_new_model_like.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f83c145c7f980e6781b6636cc6e27353665bdb3f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/configuration_aya_vision.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/configuration_aya_vision.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a531c804a3bfd6ab940bacf3349054bddfe618f8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/configuration_aya_vision.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/modeling_aya_vision.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/modeling_aya_vision.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55cfff69bdb4001718c36e64932df84ea77a4e08 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/modeling_aya_vision.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/modular_aya_vision.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/modular_aya_vision.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5841639afe8b54ad2779ecf6a176be77ea9743ef Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/modular_aya_vision.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/processing_aya_vision.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/processing_aya_vision.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ffd1e9d2a895fc790c9e750779f91b9bca668599 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/aya_vision/__pycache__/processing_aya_vision.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/blip/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/blip/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24e60be588d43e8aaed9ab74bbb638491294bdb9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/blip/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/blip/__pycache__/image_processing_blip.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/blip/__pycache__/image_processing_blip.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1fe1788a149211be4a65f3fec37d0a858c4a0045 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/blip/__pycache__/image_processing_blip.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/blip/__pycache__/modeling_tf_blip_text.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/blip/__pycache__/modeling_tf_blip_text.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e337341af3c56a3c36309d85a6bd975b5d500df Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/blip/__pycache__/modeling_tf_blip_text.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa66e7e0facf46837a67d037591909f8bd494a70 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/configuration_canine.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/configuration_canine.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f23ee617fc8fffb58725fc64367dc6765f38929b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/configuration_canine.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/modeling_canine.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/modeling_canine.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c060eccc5f18d5be9967292c87550187593319f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/modeling_canine.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/tokenization_canine.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/tokenization_canine.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5b74930232baba4a0cb63500705f591f27aa2f0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/canine/__pycache__/tokenization_canine.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/decision_transformer/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/decision_transformer/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cabec075abe3d48e0d6ab0de1d49df0cc6e540a2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/decision_transformer/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/decision_transformer/__pycache__/configuration_decision_transformer.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/decision_transformer/__pycache__/configuration_decision_transformer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71eb53a22820db2834ed67e39cbbf183185330fb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/decision_transformer/__pycache__/configuration_decision_transformer.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/decision_transformer/__pycache__/modeling_decision_transformer.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/decision_transformer/__pycache__/modeling_decision_transformer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb8c84243e818afdd68245c441db73cab5e6324d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/decision_transformer/__pycache__/modeling_decision_transformer.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a3b13b6553e4f4227e69bbfbc0d30bd3ed3f736 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/configuration_deepseek_vl_hybrid.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/configuration_deepseek_vl_hybrid.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5689e5dda6b5453a528e5009c1c514c7af38e829 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/configuration_deepseek_vl_hybrid.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/image_processing_deepseek_vl_hybrid_fast.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/image_processing_deepseek_vl_hybrid_fast.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..204742938dd49fe8823d48bc4b35e0a6a49c0718 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/image_processing_deepseek_vl_hybrid_fast.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/modeling_deepseek_vl_hybrid.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/modeling_deepseek_vl_hybrid.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..477dbecbc9b86f5c8a09d9b8b5a06da2e176cfda Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/modeling_deepseek_vl_hybrid.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/processing_deepseek_vl_hybrid.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/processing_deepseek_vl_hybrid.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a63f0051c5fc4dba67772e20c15ab7dec39db2f7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/deepseek_vl_hybrid/__pycache__/processing_deepseek_vl_hybrid.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a34ea646ae8e996cd5bb48249d57795b5f893a4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/configuration_janus.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/configuration_janus.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7b40981c8a1709eda5d72bf8f6f75381f595537 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/configuration_janus.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/image_processing_janus.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/image_processing_janus.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7da58e24690c5b48b435f8c2d2a6b258cf4168db Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/image_processing_janus.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/image_processing_janus_fast.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/image_processing_janus_fast.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94a85a0032ae7b21c70027f7884c2a5bc369222e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/image_processing_janus_fast.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/modeling_janus.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/modeling_janus.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..85f063245a28f402fa2ac69c1b8976244ef854fe Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/modeling_janus.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/modular_janus.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/modular_janus.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b83502a1605423e4ddea19a4e19be1d0c3eb7db Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/modular_janus.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/processing_janus.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/processing_janus.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d4004482a25a811dc8a88cf95b7d4180a170637 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/janus/__pycache__/processing_janus.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..732a2caebb977c263924b02707f5b394a32266bb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/configuration_mbart.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/configuration_mbart.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4bef52ec93aa2e74ed8449cb74069693eee0d927 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/configuration_mbart.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/modeling_flax_mbart.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/modeling_flax_mbart.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23dfd4d81a385dd665ae87c9437a366882de3682 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/modeling_flax_mbart.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/modeling_mbart.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/modeling_mbart.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..533011e20e64919e9deeb418b1e3ddca2816ba7f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/modeling_mbart.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/modeling_tf_mbart.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/modeling_tf_mbart.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..319bcb89184e9f4739aa5b1ea43f24debe2e508d Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/modeling_tf_mbart.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/tokenization_mbart.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/tokenization_mbart.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d866b2661539bf761b240b409bf09a2ea9f3612 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/tokenization_mbart.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/tokenization_mbart_fast.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/tokenization_mbart_fast.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3cbb7b764b62c95c04dad00beaae2b5272d2e47b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mbart/__pycache__/tokenization_mbart_fast.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d1c52abc14d4cdbe4c2c18440c50e5a6195ab69 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/configuration_mistral3.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/configuration_mistral3.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad99939ad124e3348ee9a651fa90bb3ce3f10ef8 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/configuration_mistral3.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/modeling_mistral3.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/modeling_mistral3.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7eb204bdc16815de36be9d057f6ce5e585ded9ec Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/modeling_mistral3.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/modular_mistral3.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/modular_mistral3.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83f29f73ecb5c2ff2b811013daf6a153689e66df Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mistral3/__pycache__/modular_mistral3.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mluke/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mluke/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..128439726a9350f508f3ab58b26d79f170df13c6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mluke/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mluke/__pycache__/tokenization_mluke.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mluke/__pycache__/tokenization_mluke.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90a83c6b35376ef10247218fb9ef1b67d2c78f5b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/mluke/__pycache__/tokenization_mluke.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..170d2599d2ae1b6382ff7b1db9905acdd8169beb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/configuration_starcoder2.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/configuration_starcoder2.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..768499cf9f45e201ddc53d57146f3a03fa4022af Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/configuration_starcoder2.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/modeling_starcoder2.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/modeling_starcoder2.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..506585da31c10eecaed8fa2a4fb8d85774e32862 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/modeling_starcoder2.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/modular_starcoder2.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/modular_starcoder2.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..281ac6970e00f6c00e850fcf3278e038ea993f73 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/starcoder2/__pycache__/modular_starcoder2.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/vitpose_backbone/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/vitpose_backbone/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d332c3623b8f999b69e43e15a4c1a46e80a27295 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/vitpose_backbone/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/vitpose_backbone/__pycache__/configuration_vitpose_backbone.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/vitpose_backbone/__pycache__/configuration_vitpose_backbone.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40ed03e27ab4157b8a69f11b7a2c95eb12f8bc21 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/vitpose_backbone/__pycache__/configuration_vitpose_backbone.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/vitpose_backbone/__pycache__/modeling_vitpose_backbone.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/vitpose_backbone/__pycache__/modeling_vitpose_backbone.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4c2833cc9c01ebe8675735f1e9c8570ba6caeaf Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/transformers/models/vitpose_backbone/__pycache__/modeling_vitpose_backbone.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d3a7fc60fc1b7e18d321c975341c34d821882f1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/compiler.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/compiler.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3f8da0e2883a87cff6341bfccadf7ae91d2ac547 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/compiler.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/errors.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/errors.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..185f8e46f30d94237c251eb9f6dec69642704536 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/errors.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/make_launcher.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/make_launcher.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7656d910958475c03d739897053c0f58b72d6eea Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/compiler/__pycache__/make_launcher.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/experimental/gluon/amd/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/experimental/gluon/amd/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a69eb0a32943d182348d3368307c31946f3eebf Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/experimental/gluon/amd/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/experimental/gluon/amd/__pycache__/gfx1250.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/experimental/gluon/amd/__pycache__/gfx1250.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20206f3cd7f3aa343a76b69844245353f3e37d8b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/experimental/gluon/amd/__pycache__/gfx1250.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/experimental/gluon/language/amd/rdna3/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/experimental/gluon/language/amd/rdna3/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9528751a85b9c63ae937ed605c02fc890b36db0e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/triton/experimental/gluon/language/amd/rdna3/__pycache__/__init__.cpython-312.pyc differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Aden b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Aden new file mode 100644 index 0000000000000000000000000000000000000000..01c47ccb86ccbde2bf9ad0803298e8df87178a34 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Aden differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Almaty b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Almaty new file mode 100644 index 0000000000000000000000000000000000000000..02f047d70fc811f8cc17f2c08ddc1f328576fb94 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Almaty differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Amman b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Amman new file mode 100644 index 0000000000000000000000000000000000000000..a3f9dff57148554c4207d71df64851aee2b28b19 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Amman differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Anadyr b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Anadyr new file mode 100644 index 0000000000000000000000000000000000000000..551884d322bcd2201b4b9898ec765141277e6eee Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Anadyr differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Aqtau b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Aqtau new file mode 100644 index 0000000000000000000000000000000000000000..3a40d1175a7d81d8a307d0e546a1fe9a40888b29 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Aqtau differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Aqtobe b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Aqtobe new file mode 100644 index 0000000000000000000000000000000000000000..62c5840a83e29b4fcedba95e438581cec96b3cf6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Aqtobe differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ashgabat b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ashgabat new file mode 100644 index 0000000000000000000000000000000000000000..8482167269080ead3a6046ae5e64b56d48dac1dd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ashgabat differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ashkhabad b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ashkhabad new file mode 100644 index 0000000000000000000000000000000000000000..8482167269080ead3a6046ae5e64b56d48dac1dd Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ashkhabad differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Atyrau b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Atyrau new file mode 100644 index 0000000000000000000000000000000000000000..cb2c82f657c7380462b3ea38d5e58cc3d692e0b2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Atyrau differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Baghdad b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Baghdad new file mode 100644 index 0000000000000000000000000000000000000000..a3ce97599100c0e514afa0764879c3f104be87e9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Baghdad differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Bahrain b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Bahrain new file mode 100644 index 0000000000000000000000000000000000000000..7409d74983c8d0cd8347a663c3bfbc1c041124da Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Bahrain differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Baku b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Baku new file mode 100644 index 0000000000000000000000000000000000000000..96203d7a4266cd8646032165950374761090e318 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Baku differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Bangkok b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Bangkok new file mode 100644 index 0000000000000000000000000000000000000000..ed687d2985c208171adcaa3401496b05325edca4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Bangkok differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Barnaul b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Barnaul new file mode 100644 index 0000000000000000000000000000000000000000..ff976dd3b27ac5f14dcbac2362f1b4638c5684aa Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Barnaul differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Beirut b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Beirut new file mode 100644 index 0000000000000000000000000000000000000000..55dce5722cc9d913164747da068f37d3529e799f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Beirut differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Bishkek b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Bishkek new file mode 100644 index 0000000000000000000000000000000000000000..fe7832cdf99ed9da3b64e3b8f6c5cd0b8b4c8de7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Bishkek differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Brunei b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Brunei new file mode 100644 index 0000000000000000000000000000000000000000..59bc6e40b7bb0b4eb199dd8c17f416ee00ca4158 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Brunei differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Calcutta b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Calcutta new file mode 100644 index 0000000000000000000000000000000000000000..00bc80a65e9a7aa470d63fba1ce1b29ef173d922 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Calcutta differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Chita b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Chita new file mode 100644 index 0000000000000000000000000000000000000000..9d49cd35cd5e52c5ff0f2c0cc6bd3f4f6e856915 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Chita differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Choibalsan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Choibalsan new file mode 100644 index 0000000000000000000000000000000000000000..6f5d3a15abbe48b8a4dc72aadc88c416160a56a6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Choibalsan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Chongqing b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Chongqing new file mode 100644 index 0000000000000000000000000000000000000000..d6b66984a2f36ae36b35e174756707aa7286c292 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Chongqing differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Chungking b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Chungking new file mode 100644 index 0000000000000000000000000000000000000000..d6b66984a2f36ae36b35e174756707aa7286c292 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Chungking differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Colombo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Colombo new file mode 100644 index 0000000000000000000000000000000000000000..3eeb1b72b68993e26a2452afe98a6420ac66bafb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Colombo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dacca b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dacca new file mode 100644 index 0000000000000000000000000000000000000000..28136808b6d1029676448d8711265d8c55cb4bae Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dacca differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Damascus b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Damascus new file mode 100644 index 0000000000000000000000000000000000000000..bd1624de5148d5670e4585dfcb445d8b270c02df Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Damascus differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dhaka b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dhaka new file mode 100644 index 0000000000000000000000000000000000000000..28136808b6d1029676448d8711265d8c55cb4bae Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dhaka differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dili b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dili new file mode 100644 index 0000000000000000000000000000000000000000..22e705ca1ab1218e9f36b9f4f607258389853c8b Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dili differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dubai b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dubai new file mode 100644 index 0000000000000000000000000000000000000000..58d75bc26eec90272e97696f40483eb56c2b8b45 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dubai differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dushanbe b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dushanbe new file mode 100644 index 0000000000000000000000000000000000000000..d83fb076a256817ca0a3ec4e43c7768e6680dc84 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Dushanbe differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Famagusta b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Famagusta new file mode 100644 index 0000000000000000000000000000000000000000..cc44179564afe36db0f1f7aab0a19cbc3e4fa4d0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Famagusta differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Gaza b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Gaza new file mode 100644 index 0000000000000000000000000000000000000000..0d79662716b445f61e5577bdb09e7c91e4a40d28 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Gaza differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Harbin b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Harbin new file mode 100644 index 0000000000000000000000000000000000000000..d6b66984a2f36ae36b35e174756707aa7286c292 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Harbin differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Hebron b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Hebron new file mode 100644 index 0000000000000000000000000000000000000000..53a3c14312bc770bf9bca1d2e7518763fec7a485 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Hebron differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ho_Chi_Minh b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ho_Chi_Minh new file mode 100644 index 0000000000000000000000000000000000000000..86e21b0f524426287fb3b21a82369283c4040c0e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ho_Chi_Minh differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Hong_Kong b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Hong_Kong new file mode 100644 index 0000000000000000000000000000000000000000..c80e364801be87687625f72e8e2c3dbd0f7ae4bc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Hong_Kong differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Hovd b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Hovd new file mode 100644 index 0000000000000000000000000000000000000000..6e08a261274e48f93eb5e221ba294e54ca671b94 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Hovd differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Irkutsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Irkutsk new file mode 100644 index 0000000000000000000000000000000000000000..550e2a08773b328683ab10fb9feddee2038e9e58 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Irkutsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Istanbul b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Istanbul new file mode 100644 index 0000000000000000000000000000000000000000..c89186687300068ac4e8505cc0012a1dbf6a9960 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Istanbul differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Jakarta b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Jakarta new file mode 100644 index 0000000000000000000000000000000000000000..c9752d2f23ebbb8b1ca5b8ac604c6f24be5d0def Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Jakarta differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Jayapura b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Jayapura new file mode 100644 index 0000000000000000000000000000000000000000..7c22f539d948e5757a0847892da344309b582473 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Jayapura differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Jerusalem b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Jerusalem new file mode 100644 index 0000000000000000000000000000000000000000..4c49bbf52440631eca750cacb7d79f259eeb8bd2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Jerusalem differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kabul b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kabul new file mode 100644 index 0000000000000000000000000000000000000000..660ce4cf695702ee8c6eef5c0e2419de37d6df74 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kabul differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kamchatka b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kamchatka new file mode 100644 index 0000000000000000000000000000000000000000..c65155402db6a465c05a8cd71ec7a0fc0f792762 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kamchatka differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Karachi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Karachi new file mode 100644 index 0000000000000000000000000000000000000000..e56d5afdafb27c656a39e1dcdf1e3d2b880efa87 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Karachi differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kashgar b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kashgar new file mode 100644 index 0000000000000000000000000000000000000000..69ff7f6fb4973efb1185cad9f553f8c770c75934 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kashgar differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kathmandu b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kathmandu new file mode 100644 index 0000000000000000000000000000000000000000..3a0d330ffd2f08396290960527fc8fc186356161 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kathmandu differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Katmandu b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Katmandu new file mode 100644 index 0000000000000000000000000000000000000000..3a0d330ffd2f08396290960527fc8fc186356161 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Katmandu differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Khandyga b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Khandyga new file mode 100644 index 0000000000000000000000000000000000000000..aeb733202acd5d9d2a19a54fc64c226302887423 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Khandyga differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kolkata b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kolkata new file mode 100644 index 0000000000000000000000000000000000000000..00bc80a65e9a7aa470d63fba1ce1b29ef173d922 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kolkata differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Krasnoyarsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Krasnoyarsk new file mode 100644 index 0000000000000000000000000000000000000000..e0d4fcb5c3d781943a65dc53cca9fab5d1905f9f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Krasnoyarsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kuala_Lumpur b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kuala_Lumpur new file mode 100644 index 0000000000000000000000000000000000000000..dbbdea3c8149004cfd525a0fc26e5da72b20e8a1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kuala_Lumpur differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kuching b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kuching new file mode 100644 index 0000000000000000000000000000000000000000..59bc6e40b7bb0b4eb199dd8c17f416ee00ca4158 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kuching differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kuwait b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kuwait new file mode 100644 index 0000000000000000000000000000000000000000..01c47ccb86ccbde2bf9ad0803298e8df87178a34 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Kuwait differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Macao b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Macao new file mode 100644 index 0000000000000000000000000000000000000000..c22f75e42db6b12db3c837056436cb77d176b83e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Macao differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Macau b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Macau new file mode 100644 index 0000000000000000000000000000000000000000..c22f75e42db6b12db3c837056436cb77d176b83e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Macau differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Magadan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Magadan new file mode 100644 index 0000000000000000000000000000000000000000..16bac8444656c393288dcc0209a96c7c3f487a19 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Magadan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Makassar b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Makassar new file mode 100644 index 0000000000000000000000000000000000000000..5990010b649745369501c7641c401bcad4345b85 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Makassar differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Manila b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Manila new file mode 100644 index 0000000000000000000000000000000000000000..145bb6fb162e192da18e0991c00578d43475b384 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Manila differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Muscat b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Muscat new file mode 100644 index 0000000000000000000000000000000000000000..58d75bc26eec90272e97696f40483eb56c2b8b45 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Muscat differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Nicosia b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Nicosia new file mode 100644 index 0000000000000000000000000000000000000000..390347f442a486e296689c189e3346695bba5105 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Nicosia differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Novokuznetsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Novokuznetsk new file mode 100644 index 0000000000000000000000000000000000000000..9378d50539dfa8f1dabcb40d3720f64906d36202 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Novokuznetsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Novosibirsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Novosibirsk new file mode 100644 index 0000000000000000000000000000000000000000..65a9fa2cd2e8548b13f1d0895bcba46fa11600a4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Novosibirsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Omsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Omsk new file mode 100644 index 0000000000000000000000000000000000000000..dc0ed422f6193fb5d7dcb59dd0eb3e06eec8d4de Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Omsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Oral b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Oral new file mode 100644 index 0000000000000000000000000000000000000000..25a63ec8b9951c94fc00a8c6c9d18d2151b26dde Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Oral differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Phnom_Penh b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Phnom_Penh new file mode 100644 index 0000000000000000000000000000000000000000..ed687d2985c208171adcaa3401496b05325edca4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Phnom_Penh differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Pontianak b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Pontianak new file mode 100644 index 0000000000000000000000000000000000000000..285bed2c63a5debe034a661431d2a1c03dfb0dad Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Pontianak differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Pyongyang b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Pyongyang new file mode 100644 index 0000000000000000000000000000000000000000..57240cf89fb33139a92451ec2eb99cb67b2f49c1 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Pyongyang differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Qatar b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Qatar new file mode 100644 index 0000000000000000000000000000000000000000..7409d74983c8d0cd8347a663c3bfbc1c041124da Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Qatar differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Qostanay b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Qostanay new file mode 100644 index 0000000000000000000000000000000000000000..109fe41562e89a026f828125f960498f62fb5d95 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Qostanay differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Qyzylorda b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Qyzylorda new file mode 100644 index 0000000000000000000000000000000000000000..fe4d6c6d6d44f0f6b7dd1f55702c4d640270a1fc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Qyzylorda differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Rangoon b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Rangoon new file mode 100644 index 0000000000000000000000000000000000000000..14b2ad09ead50a62d5e2b426396c51f9beb293be Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Rangoon differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Riyadh b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Riyadh new file mode 100644 index 0000000000000000000000000000000000000000..01c47ccb86ccbde2bf9ad0803298e8df87178a34 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Riyadh differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Saigon b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Saigon new file mode 100644 index 0000000000000000000000000000000000000000..86e21b0f524426287fb3b21a82369283c4040c0e Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Saigon differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Sakhalin b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Sakhalin new file mode 100644 index 0000000000000000000000000000000000000000..69f0faad1e7247882721bb81a7242ddd4b1d269f Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Sakhalin differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Samarkand b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Samarkand new file mode 100644 index 0000000000000000000000000000000000000000..c43e27c5d4bd341649b3aa32de068d76618c81ed Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Samarkand differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Seoul b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Seoul new file mode 100644 index 0000000000000000000000000000000000000000..1755147fab44e07b7527ce1eaf3ae991473fb222 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Seoul differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Shanghai b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Shanghai new file mode 100644 index 0000000000000000000000000000000000000000..d6b66984a2f36ae36b35e174756707aa7286c292 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Shanghai differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Srednekolymsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Srednekolymsk new file mode 100644 index 0000000000000000000000000000000000000000..7fdee5cbee2b1ba0904a672dde16240404466fb9 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Srednekolymsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Taipei b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Taipei new file mode 100644 index 0000000000000000000000000000000000000000..35d89d036d07c3f28dec64092ab1b533c21ae2bc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Taipei differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tashkent b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tashkent new file mode 100644 index 0000000000000000000000000000000000000000..65ee428ce1c5093a4b3dd29512d98a33b4c753a0 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tashkent differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tbilisi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tbilisi new file mode 100644 index 0000000000000000000000000000000000000000..166e4341d6ce65728367641a467a925800044df6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tbilisi differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tehran b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tehran new file mode 100644 index 0000000000000000000000000000000000000000..824acb0426faaf659a7f209dda6e1ffd0f3ce2ec Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tehran differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tel_Aviv b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tel_Aviv new file mode 100644 index 0000000000000000000000000000000000000000..4c49bbf52440631eca750cacb7d79f259eeb8bd2 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tel_Aviv differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Thimbu b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Thimbu new file mode 100644 index 0000000000000000000000000000000000000000..0edc72cfe46b1976bff562929501f202a205d0cc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Thimbu differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Thimphu b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Thimphu new file mode 100644 index 0000000000000000000000000000000000000000..0edc72cfe46b1976bff562929501f202a205d0cc Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Thimphu differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tokyo b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tokyo new file mode 100644 index 0000000000000000000000000000000000000000..1aa066ce38fce7bd0a680f51d6f075718d153a77 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tokyo differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tomsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tomsk new file mode 100644 index 0000000000000000000000000000000000000000..c3c307d7b99f39328cf289360526399c55984af6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Tomsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ujung_Pandang b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ujung_Pandang new file mode 100644 index 0000000000000000000000000000000000000000..5990010b649745369501c7641c401bcad4345b85 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ujung_Pandang differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ulaanbaatar b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ulaanbaatar new file mode 100644 index 0000000000000000000000000000000000000000..6f5d3a15abbe48b8a4dc72aadc88c416160a56a6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ulaanbaatar differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ulan_Bator b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ulan_Bator new file mode 100644 index 0000000000000000000000000000000000000000..6f5d3a15abbe48b8a4dc72aadc88c416160a56a6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ulan_Bator differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Urumqi b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Urumqi new file mode 100644 index 0000000000000000000000000000000000000000..69ff7f6fb4973efb1185cad9f553f8c770c75934 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Urumqi differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ust-Nera b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ust-Nera new file mode 100644 index 0000000000000000000000000000000000000000..c39331e3aa7d7c3c9f38e8ef83e739f0d09194b3 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Ust-Nera differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Vientiane b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Vientiane new file mode 100644 index 0000000000000000000000000000000000000000..ed687d2985c208171adcaa3401496b05325edca4 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Vientiane differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Vladivostok b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Vladivostok new file mode 100644 index 0000000000000000000000000000000000000000..72a3d4e87a0d6f568eeb84b4a9dfae0b679d23ff Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Vladivostok differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yakutsk b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yakutsk new file mode 100644 index 0000000000000000000000000000000000000000..336f932e8d458b5096d4aa9483f3177f8d5888eb Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yakutsk differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yangon b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yangon new file mode 100644 index 0000000000000000000000000000000000000000..14b2ad09ead50a62d5e2b426396c51f9beb293be Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yangon differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yekaterinburg b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yekaterinburg new file mode 100644 index 0000000000000000000000000000000000000000..a3bf7f29b6f14debfbd0f8ccb45f1ea338009ef7 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yekaterinburg differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yerevan b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yerevan new file mode 100644 index 0000000000000000000000000000000000000000..6dd927cb94101609afa1d505129296370cd8aabe Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/Yerevan differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Asia/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Europe/Moscow b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Europe/Moscow new file mode 100644 index 0000000000000000000000000000000000000000..5e6b6de6451b4408fb71ef73950712a0827d49a6 Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/tzdata/zoneinfo/Europe/Moscow differ diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/xxhash-3.6.0.dist-info/licenses/LICENSE b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/xxhash-3.6.0.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..0103aae504db7ed40539656bf0997f32d698e335 --- /dev/null +++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/xxhash-3.6.0.dist-info/licenses/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2014-2024, Yue Du +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.