cengal.math.geometry.vector.versions.v_0.vector

   1#!/usr/bin/env python
   2# coding=utf-8
   3
   4# Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>
   5# 
   6# Licensed under the Apache License, Version 2.0 (the "License");
   7# you may not use this file except in compliance with the License.
   8# You may obtain a copy of the License at
   9# 
  10#     http://www.apache.org/licenses/LICENSE-2.0
  11# 
  12# Unless required by applicable law or agreed to in writing, software
  13# distributed under the License is distributed on an "AS IS" BASIS,
  14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15# See the License for the specific language governing permissions and
  16# limitations under the License.
  17
  18__all__ = ['VectorDimentionConflictError', 'VectorBase', 'CoordinateVectorDimentionsAreNotMatch', 'CoordinateVectorNd', 'VectorNd', 'DirectedGraphNd']
  19
  20
  21"""
  22Module Docstring
  23Docstrings: http://www.python.org/dev/peps/pep-0257/
  24"""
  25
  26__author__ = "ButenkoMS <gtalk@butenkoms.space>"
  27__copyright__ = "Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>"
  28__credits__ = ["ButenkoMS <gtalk@butenkoms.space>", ]
  29__license__ = "Apache License, Version 2.0"
  30__version__ = "4.4.1"
  31__maintainer__ = "ButenkoMS <gtalk@butenkoms.space>"
  32__email__ = "gtalk@butenkoms.space"
  33# __status__ = "Prototype"
  34__status__ = "Development"
  35# __status__ = "Production"
  36
  37
  38from time import perf_counter
  39from cengal.entities.copyable import *
  40from cengal.math.geometry.point import *
  41from typing import Any, FrozenSet, Optional, Sequence, List, Set, Tuple, Dict, Union
  42from math import sqrt
  43numpy_present = True
  44try:
  45    import numpy as np
  46    from numpy import linalg, array
  47except:
  48    numpy_present = False
  49
  50
  51class VectorDimentionConflictError(ValueError):
  52    pass
  53
  54
  55class VectorBase(CopyableMixin):
  56    def copy(self) -> 'VectorBase':
  57        raise NotImplementedError
  58
  59    def shallow_copy(self) -> 'VectorBase':
  60        raise NotImplementedError
  61    
  62    def updated_copy(self, update: Dict) -> 'VectorBase':
  63        raise NotImplementedError
  64
  65    @property
  66    def dim(self) -> int:
  67        raise NotImplementedError
  68    
  69    def _is_dimension_ok(self) -> bool:
  70        raise NotImplementedError
  71
  72    def _is_new_points_dimension_ok(self, new_point: PointNd) -> bool:
  73        raise NotImplementedError
  74
  75    def _set_forgotten_points_to_zero(self):
  76        raise NotImplementedError
  77
  78    def __call__(self
  79            , *args: Tuple[PointNd]
  80            , **kwargs: Dict[str, PointNd]
  81            ) -> PointNd:
  82        raise NotImplementedError
  83    
  84    def __len__(self):
  85        raise NotImplementedError
  86
  87
  88class CoordinateVectorDimentionsAreNotMatch(ValueError):
  89    pass
  90
  91
  92class CoordinateVectorNd(VectorBase):
  93    _terminal_point_names = {'tp', 'terminal_point', 'terminal point'}
  94
  95    def __init__(self, terminal_point: PointNd) -> None:
  96        self.terminal_point: PointNd = terminal_point
  97    
  98    def __repr__(self):
  99        return f'{type(self).__name__}(tp={repr(self.terminal_point)})'
 100    
 101    def copy(self) -> 'CoordinateVectorNd':
 102        cls = self.__class__
 103        result = cls.__new__(cls)
 104        result.__dict__['terminal_point'] = self.terminal_point.copy()
 105        return result
 106    
 107    def shallow_copy(self) -> 'CoordinateVectorNd':
 108        cls = self.__class__
 109        result = cls.__new__(cls)
 110        result.__dict__['terminal_point'] = self.terminal_point
 111        return result
 112    
 113    def updated_copy(self, update: Dict) -> 'CoordinateVectorNd':
 114        cls = self.__class__
 115        result = cls.__new__(cls)
 116        result.__dict__['terminal_point'] = get_dict_key_with_callable_default(update, 'terminal_point', lambda: self.terminal_point.copy())
 117        return result
 118    
 119    @property
 120    def dim(self):
 121        return self.terminal_point.dim
 122    
 123    def _is_dimension_ok(self) -> bool:
 124        return True
 125
 126    def __call__(self
 127            , *args: Tuple[PointNd]
 128            , **kwargs: Dict[str, PointNd]
 129            ) -> PointNd:
 130        if args:
 131            first_item = args[0]
 132            if isinstance(first_item, CoordinateVectorNd):
 133                data = first_item()
 134            elif isinstance(first_item, PointNd):
 135                data = first_item
 136            else:
 137                raise ValueError
 138            
 139            self.terminal_point = data
 140        elif kwargs:
 141            terminal_point = kwargs.get('terminal_point')
 142            for terminal_point_name_variant in self._terminal_point_names:
 143                terminal_point = kwargs.get(terminal_point_name_variant, None)
 144                if terminal_point is not None:
 145                    self.terminal_point = terminal_point
 146        
 147        return self.terminal_point
 148    
 149    def __getitem__(self, index):
 150        if isinstance(index, int):
 151            if 0 == index:
 152                return self.terminal_point
 153            else:
 154                raise IndexError
 155        else:
 156            if index in self._terminal_point_names:
 157                return self.terminal_point
 158            else:
 159                raise KeyError
 160    
 161    def __setitem__(self, index, value):
 162        if isinstance(index, int):
 163            if 0 == index:
 164                self.terminal_point = value
 165            else:
 166                raise IndexError
 167        else:
 168            if index in self._terminal_point_names:
 169                self.terminal_point = value
 170            else:
 171                raise KeyError
 172    
 173    def __len__(self):
 174        return 1
 175
 176    def magnitude(self) -> float:
 177        if numpy_present:
 178            return linalg.norm(self.terminal_point())
 179        else:
 180            result = 0
 181            for item in self.terminal_point:
 182                result += item * item
 183            
 184            return sqrt(result)
 185    
 186    def length(self) -> float:
 187        return self.magnitude()
 188
 189    def magnitude_square(self) -> float:
 190        if numpy_present:
 191            tp = self.terminal_point()
 192            return sum(tp * tp)
 193        else:
 194            result = 0
 195            for item in self.terminal_point:
 196                result += item * item
 197            
 198            return result
 199    
 200    # add
 201    def __add__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 202        result = list()
 203        if isinstance(other, CoordinateVectorNd):
 204            for index in range(self.dim):
 205                result.append(self.terminal_point[index] + other.terminal_point[index])
 206        elif isinstance(other, (float, int)):
 207            for index in range(self.dim):
 208                result.append(self.terminal_point[index] + other)
 209        else:
 210            raise NotImplemented
 211        
 212        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 213    
 214    def __radd__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 215        return self.__add__(other)
 216    
 217    def __iadd__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 218        if numpy_present:
 219            if isinstance(other, CoordinateVectorNd):
 220                self.terminal_point._point += other.terminal_point()
 221            elif isinstance(other, (float, int)):
 222                self.terminal_point._point += other
 223            else:
 224                raise NotImplemented
 225        else:
 226            if isinstance(other, CoordinateVectorNd):
 227                for index in range(self.dim):
 228                    self.terminal_point[index] += other.terminal_point[index]
 229            elif isinstance(other, (float, int)):
 230                for index in range(self.dim):
 231                    self.terminal_point[index] += other
 232            else:
 233                raise NotImplemented
 234
 235        return self
 236    
 237    # sub
 238    def __sub__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 239        if numpy_present:
 240            result = None
 241            if isinstance(other, CoordinateVectorNd):
 242                result = self.terminal_point() - other.terminal_point()
 243            elif isinstance(other, (float, int)):
 244                result = self.terminal_point() - other
 245            else:
 246                raise NotImplemented
 247            
 248            return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result, ndarray_type=type(result[0].item()))))
 249        else:
 250            result = list()
 251            if isinstance(other, CoordinateVectorNd):
 252                for index in range(self.dim):
 253                    result.append(self.terminal_point[index] - other.terminal_point[index])
 254            elif isinstance(other, (float, int)):
 255                for index in range(self.dim):
 256                    result.append(self.terminal_point[index] - other)
 257            else:
 258                raise NotImplemented
 259            
 260            return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 261    
 262    def __rsub__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 263        result = list()
 264        if isinstance(other, CoordinateVectorNd):
 265            for index in range(self.dim):
 266                result.append(other.terminal_point[index] - self.terminal_point[index])
 267        elif isinstance(other, (float, int)):
 268            for index in range(self.dim):
 269                result.append(other - self.terminal_point[index])
 270        else:
 271            raise NotImplemented
 272        
 273        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 274    
 275    def __isub__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 276        if isinstance(other, CoordinateVectorNd):
 277            for index in range(self.dim):
 278                self.terminal_point[index] -= other.terminal_point[index]
 279        elif isinstance(other, (float, int)):
 280            for index in range(self.dim):
 281                self.terminal_point[index] -= other
 282        else:
 283            raise NotImplemented
 284
 285        return self
 286    
 287    # mul
 288    def __mul__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 289        """Multiplication to number or to other coordinate vector (item by item)
 290
 291        v1 = [1, 2, 3]
 292        v2 = [2, 3, 1]
 293        v3 = v1 * v2 = [1 * 2, 2 * 3, 3 * 1] = [2, 6, 3]
 294
 295        Args:
 296            other (Union[float, int, &#39;CoordinateVectorNd&#39;]): _description_
 297
 298        Raises:
 299            NotImplemented: _description_
 300
 301        Returns:
 302            CoordinateVectorNd: _description_
 303        """
 304        result = list()
 305        if isinstance(other, CoordinateVectorNd):
 306            for index in range(self.dim):
 307                result.append(self.terminal_point[index] * other.terminal_point[index])
 308        elif isinstance(other, (float, int)):
 309            for index in range(self.dim):
 310                result.append(self.terminal_point[index] * other)
 311        else:
 312            raise NotImplemented
 313        
 314        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 315    
 316    def __rmul__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 317        """Multiplication to number or to other coordinate vector (item by item)
 318
 319        v1 = [1, 2, 3]
 320        v2 = [2, 3, 1]
 321        v3 = v1 * v2 = [1 * 2, 2 * 3, 3 * 1] = [2, 6, 3]
 322
 323        Args:
 324            other (Union[float, int, &#39;CoordinateVectorNd&#39;]): _description_
 325
 326        Returns:
 327            CoordinateVectorNd: _description_
 328        """
 329        return self.__mul__(other)
 330    
 331    def __imul__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 332        """Multiplication to number or to other coordinate vector (item by item)
 333
 334        v1 = [1, 2, 3]
 335        v2 = [2, 3, 1]
 336        v3 = v1 * v2 = [1 * 2, 2 * 3, 3 * 1] = [2, 6, 3]
 337
 338        Args:
 339            other (Union[float, int, &#39;CoordinateVectorNd&#39;]): _description_
 340
 341        Raises:
 342            NotImplemented: _description_
 343
 344        Returns:
 345            CoordinateVectorNd: _description_
 346        """
 347        if numpy_present:
 348            if isinstance(other, CoordinateVectorNd):
 349                self.terminal_point._point *= other.terminal_point()
 350            elif isinstance(other, (float, int)):
 351                self.terminal_point._point *= other
 352            else:
 353                raise NotImplemented
 354        else:
 355            if isinstance(other, CoordinateVectorNd):
 356                for index in range(self.dim):
 357                    self.terminal_point[index] *= other.terminal_point[index]
 358            elif isinstance(other, (float, int)):
 359                for index in range(self.dim):
 360                    self.terminal_point[index] *= other
 361            else:
 362                raise NotImplemented
 363
 364        return self
 365    
 366    # matmul
 367    def __matmul__(self, other: Union[float, int, 'CoordinateVectorNd']) -> Union[float, int]:
 368        """Dot product
 369        >> cv0 = CoordinateVectorNd(2, 4)
 370        >> cv1 = CoordinateVectorNd(1, 3)
 371        >> dot_product = cv0 @ cv1
 372        >> print(dot_product)
 373        14
 374
 375        Args:
 376            other (Union[float, int, &#39;CoordinateVectorNd&#39;]): _description_
 377
 378        Raises:
 379            NotImplemented: _description_
 380            CoordinateVectorDimentionsAreNotMatch: _description_
 381
 382        Returns:
 383            Union[float, int]: _description_
 384        """
 385        if not isinstance(other, CoordinateVectorNd):
 386            raise NotImplemented
 387        
 388        dim = self.dim
 389        if dim != other.dim:
 390            raise CoordinateVectorDimentionsAreNotMatch
 391
 392        result = 0
 393        for index in range(dim):
 394            result += self.terminal_point[index] * other.terminal_point[index]
 395        
 396        return result
 397    
 398    # truediv
 399    def __truediv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 400        result = list()
 401        if isinstance(other, CoordinateVectorNd):
 402            for index in range(self.dim):
 403                result.append(self.terminal_point[index] / other.terminal_point[index])
 404        elif isinstance(other, (float, int)):
 405            for index in range(self.dim):
 406                result.append(self.terminal_point[index] / other)
 407        else:
 408            raise NotImplemented
 409        
 410        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 411    
 412    def __rtruediv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 413        result = list()
 414        if isinstance(other, CoordinateVectorNd):
 415            for index in range(self.dim):
 416                result.append(other.terminal_point[index] / self.terminal_point[index])
 417        elif isinstance(other, (float, int)):
 418            for index in range(self.dim):
 419                result.append(other / self.terminal_point[index])
 420        else:
 421            raise NotImplemented
 422        
 423        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 424    
 425    def __itruediv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 426        if numpy_present:
 427            if isinstance(other, CoordinateVectorNd):
 428                self.terminal_point._point /= other.terminal_point()
 429            elif isinstance(other, (float, int)):
 430                self.terminal_point._point /= other
 431            else:
 432                raise NotImplemented
 433        else:
 434            if isinstance(other, CoordinateVectorNd):
 435                for index in range(self.dim):
 436                    self.terminal_point[index] /= other.terminal_point[index]
 437            elif isinstance(other, (float, int)):
 438                for index in range(self.dim):
 439                    self.terminal_point[index] /= other
 440            else:
 441                raise NotImplemented
 442
 443        return self
 444    
 445    # floordiv
 446    def __floordiv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 447        result = list()
 448        if isinstance(other, CoordinateVectorNd):
 449            for index in range(self.dim):
 450                result.append(self.terminal_point[index] // other.terminal_point[index])
 451        elif isinstance(other, (float, int)):
 452            for index in range(self.dim):
 453                result.append(self.terminal_point[index] // other)
 454        else:
 455            raise NotImplemented
 456        
 457        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 458    
 459    def __rfloordiv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 460        result = list()
 461        if isinstance(other, CoordinateVectorNd):
 462            for index in range(self.dim):
 463                result.append(other.terminal_point[index] // self.terminal_point[index])
 464        elif isinstance(other, (float, int)):
 465            for index in range(self.dim):
 466                result.append(other // self.terminal_point[index])
 467        else:
 468            raise NotImplemented
 469        
 470        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 471    
 472    def __ifloordiv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 473        if numpy_present:
 474            if isinstance(other, CoordinateVectorNd):
 475                self.terminal_point._point //= other.terminal_point()
 476            elif isinstance(other, (float, int)):
 477                self.terminal_point._point //= other
 478            else:
 479                raise NotImplemented
 480        else:
 481            if isinstance(other, CoordinateVectorNd):
 482                for index in range(self.dim):
 483                    self.terminal_point[index] //= other.terminal_point[index]
 484            elif isinstance(other, (float, int)):
 485                for index in range(self.dim):
 486                    self.terminal_point[index] //= other
 487            else:
 488                raise NotImplemented
 489
 490        return self
 491    
 492    # mod
 493    def __mod__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 494        result = list()
 495        if isinstance(other, CoordinateVectorNd):
 496            for index in range(self.dim):
 497                result.append(self.terminal_point[index] % other.terminal_point[index])
 498        elif isinstance(other, (float, int)):
 499            for index in range(self.dim):
 500                result.append(self.terminal_point[index] % other)
 501        else:
 502            raise NotImplemented
 503        
 504        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 505    
 506    def __rmod__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 507        result = list()
 508        if isinstance(other, CoordinateVectorNd):
 509            for index in range(self.dim):
 510                result.append(other.terminal_point[index] % self.terminal_point[index])
 511        elif isinstance(other, (float, int)):
 512            for index in range(self.dim):
 513                result.append(other % self.terminal_point[index])
 514        else:
 515            raise NotImplemented
 516        
 517        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 518    
 519    def __imod__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 520        if isinstance(other, CoordinateVectorNd):
 521            for index in range(self.dim):
 522                self.terminal_point[index] %= other.terminal_point[index]
 523        elif isinstance(other, (float, int)):
 524            for index in range(self.dim):
 525                self.terminal_point[index] %= other
 526        else:
 527            raise NotImplemented
 528
 529        return self
 530    
 531    # pow
 532    def __pow__(self, other: Union[float, int, 'CoordinateVectorNd'], modulo) -> 'CoordinateVectorNd':
 533        result = list()
 534        if isinstance(other, CoordinateVectorNd):
 535            for index in range(self.dim):
 536                result.append(pow(self.terminal_point[index], other.terminal_point[index], modulo))
 537        elif isinstance(other, (float, int)):
 538            for index in range(self.dim):
 539                result.append(pow(self.terminal_point[index], other, modulo))
 540        else:
 541            raise NotImplemented
 542        
 543        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 544    
 545    def __rpow__(self, other: Union[float, int, 'CoordinateVectorNd'], modulo) -> 'CoordinateVectorNd':
 546        result = list()
 547        if isinstance(other, CoordinateVectorNd):
 548            for index in range(self.dim):
 549                result.append(pow(other.terminal_point[index], self.terminal_point[index], modulo))
 550        elif isinstance(other, (float, int)):
 551            for index in range(self.dim):
 552                result.append(pow(other, self.terminal_point[index], modulo))
 553        else:
 554            raise NotImplemented
 555        
 556        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 557    
 558    def __ipow__(self, other: Union[float, int, 'CoordinateVectorNd'], modulo) -> 'CoordinateVectorNd':
 559        if isinstance(other, CoordinateVectorNd):
 560            for index in range(self.dim):
 561                self.terminal_point[index].__ipow__(other.terminal_point[index], modulo)
 562        elif isinstance(other, (float, int)):
 563            for index in range(self.dim):
 564                self.terminal_point[index].__ipow__(other, modulo)
 565        else:
 566            raise NotImplemented
 567
 568        return self
 569    
 570    # lshift
 571    def __lshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 572        result = list()
 573        if isinstance(other, CoordinateVectorNd):
 574            for index in range(self.dim):
 575                result.append(self.terminal_point[index] << other.terminal_point[index])
 576        elif isinstance(other, (float, int)):
 577            for index in range(self.dim):
 578                result.append(self.terminal_point[index] << other)
 579        else:
 580            raise NotImplemented
 581        
 582        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 583    
 584    def __rlshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 585        result = list()
 586        if isinstance(other, CoordinateVectorNd):
 587            for index in range(self.dim):
 588                result.append(other.terminal_point[index] << self.terminal_point[index])
 589        elif isinstance(other, (float, int)):
 590            for index in range(self.dim):
 591                result.append(other << self.terminal_point[index])
 592        else:
 593            raise NotImplemented
 594        
 595        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 596    
 597    def __ilshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 598        if isinstance(other, CoordinateVectorNd):
 599            for index in range(self.dim):
 600                self.terminal_point[index] <<= other.terminal_point[index]
 601        elif isinstance(other, (float, int)):
 602            for index in range(self.dim):
 603                self.terminal_point[index] <<= other
 604        else:
 605            raise NotImplemented
 606
 607        return self
 608    
 609    # rshift
 610    def __rshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 611        result = list()
 612        if isinstance(other, CoordinateVectorNd):
 613            for index in range(self.dim):
 614                result.append(self.terminal_point[index] >> other.terminal_point[index])
 615        elif isinstance(other, (float, int)):
 616            for index in range(self.dim):
 617                result.append(self.terminal_point[index] >> other)
 618        else:
 619            raise NotImplemented
 620        
 621        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 622    
 623    def __rrshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 624        result = list()
 625        if isinstance(other, CoordinateVectorNd):
 626            for index in range(self.dim):
 627                result.append(other.terminal_point[index] >> self.terminal_point[index])
 628        elif isinstance(other, (float, int)):
 629            for index in range(self.dim):
 630                result.append(other >> self.terminal_point[index])
 631        else:
 632            raise NotImplemented
 633        
 634        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 635    
 636    def __irshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 637        if isinstance(other, CoordinateVectorNd):
 638            for index in range(self.dim):
 639                self.terminal_point[index] >>= other.terminal_point[index]
 640        elif isinstance(other, (float, int)):
 641            for index in range(self.dim):
 642                self.terminal_point[index] >>= other
 643        else:
 644            raise NotImplemented
 645
 646        return self
 647    
 648    # and
 649    def __and__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 650        result = list()
 651        if isinstance(other, CoordinateVectorNd):
 652            for index in range(self.dim):
 653                result.append(self.terminal_point[index] & other.terminal_point[index])
 654        elif isinstance(other, (float, int)):
 655            for index in range(self.dim):
 656                result.append(self.terminal_point[index] & other)
 657        else:
 658            raise NotImplemented
 659        
 660        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 661    
 662    def __rand__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 663        result = list()
 664        if isinstance(other, CoordinateVectorNd):
 665            for index in range(self.dim):
 666                result.append(other.terminal_point[index] & self.terminal_point[index])
 667        elif isinstance(other, (float, int)):
 668            for index in range(self.dim):
 669                result.append(other & self.terminal_point[index])
 670        else:
 671            raise NotImplemented
 672        
 673        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 674    
 675    def __iand__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 676        if isinstance(other, CoordinateVectorNd):
 677            for index in range(self.dim):
 678                self.terminal_point[index] &= other.terminal_point[index]
 679        elif isinstance(other, (float, int)):
 680            for index in range(self.dim):
 681                self.terminal_point[index] &= other
 682        else:
 683            raise NotImplemented
 684
 685        return self
 686    
 687    # xor
 688    def __xor__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 689        result = list()
 690        if isinstance(other, CoordinateVectorNd):
 691            for index in range(self.dim):
 692                result.append(self.terminal_point[index] ^ other.terminal_point[index])
 693        elif isinstance(other, (float, int)):
 694            for index in range(self.dim):
 695                result.append(self.terminal_point[index] ^ other)
 696        else:
 697            raise NotImplemented
 698        
 699        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 700    
 701    def __rxor__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 702        result = list()
 703        if isinstance(other, CoordinateVectorNd):
 704            for index in range(self.dim):
 705                result.append(other.terminal_point[index] ^ self.terminal_point[index])
 706        elif isinstance(other, (float, int)):
 707            for index in range(self.dim):
 708                result.append(other ^ self.terminal_point[index])
 709        else:
 710            raise NotImplemented
 711        
 712        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 713    
 714    def __ixor__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 715        if isinstance(other, CoordinateVectorNd):
 716            for index in range(self.dim):
 717                self.terminal_point[index] ^= other.terminal_point[index]
 718        elif isinstance(other, (float, int)):
 719            for index in range(self.dim):
 720                self.terminal_point[index] ^= other
 721        else:
 722            raise NotImplemented
 723
 724        return self
 725    
 726    # or
 727    def __or__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 728        result = list()
 729        if isinstance(other, CoordinateVectorNd):
 730            for index in range(self.dim):
 731                result.append(self.terminal_point[index] | other.terminal_point[index])
 732        elif isinstance(other, (float, int)):
 733            for index in range(self.dim):
 734                result.append(self.terminal_point[index] | other)
 735        else:
 736            raise NotImplemented
 737        
 738        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 739    
 740    def __ror__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 741        result = list()
 742        if isinstance(other, CoordinateVectorNd):
 743            for index in range(self.dim):
 744                result.append(other.terminal_point[index] | self.terminal_point[index])
 745        elif isinstance(other, (float, int)):
 746            for index in range(self.dim):
 747                result.append(other | self.terminal_point[index])
 748        else:
 749            raise NotImplemented
 750        
 751        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 752    
 753    def __ior__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
 754        if isinstance(other, CoordinateVectorNd):
 755            for index in range(self.dim):
 756                self.terminal_point[index] |= other.terminal_point[index]
 757        elif isinstance(other, (float, int)):
 758            for index in range(self.dim):
 759                self.terminal_point[index] |= other
 760        else:
 761            raise NotImplemented
 762
 763        return self
 764    
 765    # neg
 766    def __neg__(self) -> 'CoordinateVectorNd':
 767        if numpy_present:
 768            result = self.terminal_point().__neg__()
 769            return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result, ndarray_type=type(result[0].item()))))
 770        else:
 771            result = list()
 772            for index in range(self.dim):
 773                result.append(self.terminal_point[index].__neg__())
 774            
 775            return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 776    
 777    # pos
 778    def __pos__(self) -> 'CoordinateVectorNd':
 779        result = list()
 780        for index in range(self.dim):
 781            result.append(self.terminal_point[index].__pos__())
 782        
 783        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 784    
 785    # abs
 786    def __abs__(self) -> 'CoordinateVectorNd':
 787        result = list()
 788        for index in range(self.dim):
 789            result.append(self.terminal_point[index].__abs__())
 790        
 791        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 792    
 793    # invert
 794    def __invert__(self) -> 'CoordinateVectorNd':
 795        result = list()
 796        for index in range(self.dim):
 797            result.append(self.terminal_point[index].__invert__())
 798        
 799        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 800    
 801    # complex
 802    def __complex__(self) -> 'CoordinateVectorNd':
 803        result = list()
 804        for index in range(self.dim):
 805            result.append(self.terminal_point[index].__complex__())
 806        
 807        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 808    
 809    # int
 810    def __int__(self) -> 'CoordinateVectorNd':
 811        result = list()
 812        for index in range(self.dim):
 813            result.append(self.terminal_point[index].__int__())
 814        
 815        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 816    
 817    # float
 818    def __float__(self) -> 'CoordinateVectorNd':
 819        result = list()
 820        for index in range(self.dim):
 821            result.append(self.terminal_point[index].__float__())
 822        
 823        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 824    
 825    # round
 826    def __round__(self, ndigits) -> 'CoordinateVectorNd':
 827        result = list()
 828        for index in range(self.dim):
 829            result.append(self.terminal_point[index].__round__(ndigits))
 830        
 831        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 832    
 833    # trunc
 834    def __trunc__(self) -> 'CoordinateVectorNd':
 835        result = list()
 836        for index in range(self.dim):
 837            result.append(self.terminal_point[index].__trunc__())
 838        
 839        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 840    
 841    # floor
 842    def __floor__(self) -> 'CoordinateVectorNd':
 843        result = list()
 844        for index in range(self.dim):
 845            result.append(self.terminal_point[index].__floor__())
 846        
 847        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 848    
 849    # ceil
 850    def __ceil__(self) -> 'CoordinateVectorNd':
 851        result = list()
 852        for index in range(self.dim):
 853            result.append(self.terminal_point[index].__ceil__())
 854        
 855        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
 856    
 857    def __eq__(self, other) -> bool:
 858        if isinstance(other, PointNd):
 859            return self.terminal_point == other.terminal_point
 860        
 861        return False
 862    
 863    def __ne__(self, other) -> bool:
 864        return not self.__eq__(other)
 865    
 866    def __hash__(self) -> int:
 867        return hash(self.terminal_point)
 868    
 869    def __bool__(self) -> bool:
 870        """If not zero point
 871
 872        Returns:
 873            bool: _description_
 874        """
 875        return self.terminal_point.__bool__()
 876
 877    # TODO: Другие операции умножения применимые к координатным векторам - реализовать в методах.
 878    # А неприменимые - в соответствующих классах (например DirectedGraphNd отлично подходит на роль 
 879    # матрицы с которой будут производится манипуляции. Каждая точка - отдельный столбец. 
 880    # Направление слева-направо: слева нулевой индекс, а справа - максимальный индекс)
 881
 882
 883class VectorNd(VectorBase):
 884    _initial_point_names = {'ip', 'initial_point', 'initial point'}
 885    _terminal_point_names = {'tp', 'terminal_point', 'terminal point'}
 886
 887    def __init__(self
 888            , *args: Tuple[PointNd]
 889            , **kwargs: Dict[str, PointNd]
 890            ) -> None:
 891        self.initial_point: PointNd = None
 892        self.terminal_point: PointNd = None
 893        self(*args, **kwargs)
 894    
 895    def copy(self) -> 'VectorNd':
 896        cls = self.__class__
 897        result = cls.__new__(cls)
 898        result.__dict__['initial_point'] = self.initial_point.copy()
 899        result.__dict__['terminal_point'] = self.terminal_point.copy()
 900        return result
 901    
 902    def shallow_copy(self) -> 'VectorNd':
 903        cls = self.__class__
 904        result = cls.__new__(cls)
 905        result.__dict__['initial_point'] = self.initial_point
 906        result.__dict__['terminal_point'] = self.terminal_point
 907        return result
 908    
 909    def updated_copy(self, update: Dict) -> 'VectorNd':
 910        cls = self.__class__
 911        result = cls.__new__(cls)
 912        result.__dict__['initial_point'] = get_dict_key_with_callable_default(update, 'initial_point', lambda: self.initial_point.copy())
 913        result.__dict__['terminal_point'] = get_dict_key_with_callable_default(update, 'terminal_point', lambda: self.terminal_point.copy())
 914        return result
 915    
 916    @property
 917    def dim(self):
 918        if self.initial_point is None:
 919            return None
 920        
 921        return self.initial_point.dim
 922
 923    def _is_dimension_ok(self) -> bool:
 924        if (self.initial_point is None) and (self.terminal_point is None):
 925            return True
 926        
 927        initial_dim = self.initial_point.dim
 928        terminal_dim = self.terminal_point.dim
 929        if initial_dim == terminal_dim:
 930            return True
 931        else:
 932            raise VectorDimentionConflictError
 933    
 934    def _set_forgotten_points_to_zero(self):
 935        if (self.initial_point is not None) and (self.terminal_point is None):
 936            dim = self.initial_point.dim
 937            self.terminal_point = PointNd(dim, [0] * dim)
 938        elif (self.initial_point is None) and (self.terminal_point is not None):
 939            dim = self.terminal_point.dim
 940            self.initial_point = PointNd(dim, [0] * dim)
 941        elif (self.initial_point is None) and (self.terminal_point is None):
 942            pass
 943
 944    def __call__(self
 945            , *args: Tuple[PointNd]
 946            , **kwargs: Dict[str, PointNd]
 947            ) -> Tuple[PointNd]:
 948        if args:
 949            first_item = args[0]
 950            data = first_item
 951            if isinstance(first_item, VectorNd):
 952                data = first_item()
 953            if isinstance(first_item, CoordinateVectorNd):
 954                terminal_point = first_item()
 955                data = [PointNd(terminal_point.dim), terminal_point]
 956            elif isinstance(first_item, PointNd):
 957                data = args
 958            
 959            self.initial_point = data[0]
 960            data_len = len(data)
 961            if data_len == 2:
 962                self.terminal_point = data[1]
 963            elif data_len > 2:
 964                raise IndexError
 965            
 966            self._set_forgotten_points_to_zero()
 967            self._is_dimension_ok()
 968        elif kwargs:
 969            for initial_point_name_variant in self._initial_point_names:
 970                initial_point = kwargs.get(initial_point_name_variant, None)
 971                if initial_point is not None:
 972                    self.initial_point = initial_point
 973                    break
 974
 975            for terminal_point_name_variant in self._terminal_point_names:
 976                terminal_point = kwargs.get(terminal_point_name_variant, None)
 977                if terminal_point is not None:
 978                    self.terminal_point = terminal_point
 979                    break
 980            
 981            self._set_forgotten_points_to_zero()
 982            self._is_dimension_ok()
 983        
 984        return [self.initial_point, self.terminal_point]
 985    
 986    def __getitem__(self, index):
 987        if isinstance(index, int):
 988            if 0 == index:
 989                return self.initial_point
 990            elif 1 == index:
 991                return self.terminal_point
 992            else:
 993                raise IndexError
 994        else:
 995            if index in self._initial_point_names:
 996                return self.initial_point
 997            elif index in self._terminal_point_names:
 998                return self.terminal_point
 999            else:
1000                raise KeyError
1001    
1002    def __setitem__(self, index, value):
1003        if isinstance(index, int):
1004            if 0 == index:
1005                self.initial_point = value
1006            elif 1 == index:
1007                self.terminal_point = value
1008            else:
1009                raise IndexError
1010        else:
1011            if index in self._initial_point_names:
1012                self.initial_point = value
1013            elif index in self._terminal_point_names:
1014                self.terminal_point = value
1015            else:
1016                raise KeyError
1017        
1018        self._set_forgotten_points_to_zero()
1019        self._is_dimension_ok()
1020    
1021    def __len__(self):
1022        return 2
1023
1024    def magnitude(self) -> float:
1025        if numpy_present:
1026            distance_vec = self.terminal_point() - self.initial_point()
1027            return linalg.norm(distance_vec)
1028        else:
1029            init_vec: CoordinateVectorNd = CoordinateVectorNd(self.initial_point)
1030            term_vec: CoordinateVectorNd = CoordinateVectorNd(self.terminal_point)
1031            distance_vec: CoordinateVectorNd = term_vec - init_vec
1032            return distance_vec.magnitude()
1033    
1034    def length(self) -> float:
1035        return self.magnitude()
1036
1037    def magnitude_square(self) -> float:
1038        if numpy_present:
1039            distance_vec = self.terminal_point() - self.initial_point()
1040            return sum(distance_vec * distance_vec)
1041        else:
1042            init_vec: CoordinateVectorNd = CoordinateVectorNd(self.initial_point)
1043            term_vec: CoordinateVectorNd = CoordinateVectorNd(self.terminal_point)
1044            distance_vec: CoordinateVectorNd = term_vec - init_vec
1045            return distance_vec.magnitude_square()
1046    
1047    def is_convergence(self, other: 'VectorNd'):
1048        if numpy_present:
1049            init_dist = other.initial_point() - self.initial_point()
1050            term_dist = other.terminal_point() - self.terminal_point()
1051            return sum(init_dist * init_dist) > sum(term_dist * term_dist)
1052        else:
1053            return VectorNd(self.initial_point, other.initial_point).magnitude_square() \
1054                > VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
1055    
1056    def is_divergence(self, other: 'VectorNd'):
1057        if numpy_present:
1058            init_dist = other.initial_point() - self.initial_point()
1059            term_dist = other.terminal_point() - self.terminal_point()
1060            return sum(init_dist * init_dist) < sum(term_dist * term_dist)
1061        else:
1062            return VectorNd(self.initial_point, other.initial_point).magnitude_square() \
1063                < VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
1064    
1065    def is_conver_diver_parity(self, other: 'VectorNd'):
1066        if numpy_present:
1067            init_dist = other.initial_point() - self.initial_point()
1068            term_dist = other.terminal_point() - self.terminal_point()
1069            return sum(init_dist * init_dist) == sum(term_dist * term_dist)
1070        else:
1071            return VectorNd(self.initial_point, other.initial_point).magnitude_square() \
1072                == VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
1073    
1074    def conver_diver_state(self, other: 'VectorNd') -> int:
1075        if numpy_present:
1076            init_dist = other.initial_point() - self.initial_point()
1077            term_dist = other.terminal_point() - self.terminal_point()
1078            init_magnitude_square = sum(init_dist * init_dist)
1079            term_magnitude_square = sum(term_dist * term_dist)
1080        else:
1081            init_magnitude_square = VectorNd(self.initial_point, other.initial_point).magnitude_square()
1082            term_magnitude_square = VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
1083
1084        if init_magnitude_square > term_magnitude_square:
1085            return 1
1086        elif init_magnitude_square == term_magnitude_square:
1087            return 0
1088        elif init_magnitude_square < term_magnitude_square:
1089            return -1
1090
1091
1092class DirectedGraphNd(VectorBase):
1093    def __init__(self
1094            , *args: Union[Tuple[PointNd], Tuple[Sequence[PointNd]]]
1095            ) -> None:
1096        self.points_list: List[PointNd] = None
1097        self(*args)
1098    
1099    def copy(self) -> 'DirectedGraphNd':
1100        cls = self.__class__
1101        result = cls.__new__(cls)
1102        if self.points_list is None:
1103            result.__dict__['points_list'] = self.points_list
1104        else:
1105            result.__dict__['points_list'] = [point.copy() for point in self.points_list]
1106
1107        return result
1108    
1109    def shallow_copy(self) -> 'DirectedGraphNd':
1110        cls = self.__class__
1111        result = cls.__new__(cls)
1112        result.__dict__['points_list'] = self.points_list
1113        return result
1114    
1115    def updated_copy(self, update: Dict) -> 'DirectedGraphNd':
1116        cls = self.__class__
1117        result = cls.__new__(cls)
1118        def copy_points():
1119            if self.points_list is None:
1120                return self.points_list
1121            else:
1122                return [point.copy() for point in self.points_list]
1123
1124        result.__dict__['points_list'] = get_dict_key_with_callable_default(update, 'points_list', copy_points)
1125        return result
1126    
1127    @property
1128    def dim(self):
1129        if self.points_list:
1130            return self.points_list[0].dim
1131        else:
1132            return None
1133
1134    def _is_dimension_ok(self) -> bool:
1135        if self.points_list:
1136            initial_dim = self.points_list[0].dim
1137            for point in self.points_list:
1138                if initial_dim != point.dim:
1139                    raise VectorDimentionConflictError
1140        else:
1141            return True
1142
1143    def _is_new_points_dimension_ok(self, new_point: PointNd) -> bool:
1144        dim = self.dim
1145        if dim is None:
1146            return True
1147        else:
1148            if dim == new_point.dim:
1149                return True
1150            else:
1151                raise VectorDimentionConflictError
1152
1153    def __call__(self
1154            , *args: Union[Tuple[PointNd], Tuple[Sequence[PointNd]]]
1155            ) -> Optional[List[PointNd]]:
1156        if args:
1157            first_item = args[0]
1158            data = first_item
1159            if isinstance(first_item, VectorNd):
1160                data = first_item()
1161            elif isinstance(first_item, PointNd):
1162                data = args
1163            
1164            self.points_list = list(data)
1165        
1166        self._is_dimension_ok()
1167        return self.points_list
1168    
1169    def get_vector(self, index: int) -> VectorNd:
1170        if 0 <= index < (len(self) - 1):
1171            return VectorNd(self[index], self[index + 1])
1172        else:
1173            raise IndexError
1174    
1175    def get_vector_reversed(self, index: int) -> VectorNd:
1176        if 1 <= index < len(self):
1177            return VectorNd(self[index], self[index - 1])
1178        else:
1179            raise IndexError
1180    
1181    def __getitem__(self, index):
1182        return self.points_list[index]
1183    
1184    def __setitem__(self, index, value):
1185        self._is_new_points_dimension_ok(value)
1186        self.points_list[index] = value
1187    
1188    def __len__(self):
1189        return len(self.points_list)
1190
1191
1192# class VectorBase:
1193#     def move(self, point: PointBase):
1194#         raise NotImplementedError
1195
1196# class Vector1d:
1197#     pass
1198
1199# class Vector3d:
1200#     pass
class VectorDimentionConflictError(builtins.ValueError):
52class VectorDimentionConflictError(ValueError):
53    pass

Inappropriate argument value (of correct type).

Inherited Members
builtins.ValueError
ValueError
builtins.BaseException
with_traceback
args
class VectorBase(cengal.entities.copyable.versions.v_0.copyable.CopyableMixin):
56class VectorBase(CopyableMixin):
57    def copy(self) -> 'VectorBase':
58        raise NotImplementedError
59
60    def shallow_copy(self) -> 'VectorBase':
61        raise NotImplementedError
62    
63    def updated_copy(self, update: Dict) -> 'VectorBase':
64        raise NotImplementedError
65
66    @property
67    def dim(self) -> int:
68        raise NotImplementedError
69    
70    def _is_dimension_ok(self) -> bool:
71        raise NotImplementedError
72
73    def _is_new_points_dimension_ok(self, new_point: PointNd) -> bool:
74        raise NotImplementedError
75
76    def _set_forgotten_points_to_zero(self):
77        raise NotImplementedError
78
79    def __call__(self
80            , *args: Tuple[PointNd]
81            , **kwargs: Dict[str, PointNd]
82            ) -> PointNd:
83        raise NotImplementedError
84    
85    def __len__(self):
86        raise NotImplementedError
def copy(self) -> VectorBase:
57    def copy(self) -> 'VectorBase':
58        raise NotImplementedError

Should make relevant copy of an object (not so general and deep as a deepcopy()). should copy only known object fields. Example: def copy(self): cls = self.__class__ result = cls.__new__(cls) result.__dict__['dimension'] = self.dimension result.__dict__['_point'] = self._point.copy() return result

Raises: NotImplementedError: _description_

def shallow_copy(self) -> VectorBase:
60    def shallow_copy(self) -> 'VectorBase':
61        raise NotImplementedError

Same as copy.copy(self), but should copy only known object fields. Example: def shallow_copy(self): cls = self.__class__ result = cls.__new__(cls) result.__dict__['dimension'] = self.dimension result.__dict__['_point'] = self._point return result

Raises: NotImplementedError: _description_

def updated_copy( self, update: Dict) -> VectorBase:
63    def updated_copy(self, update: Dict) -> 'VectorBase':
64        raise NotImplementedError

Will make updated copy of an object. Other behavior should be the same as in the def copy(self) method. Example: # from cengal.data_manipulation.get_dict_key_with_callable_default import get_dict_key_with_callable_default from cengal.entities.copyable import CopyableMixin, get_dict_key_with_callable_default

def updated_copy(self, update: Dict):
    cls = self.__class__
    result = cls.__new__(cls)
    result.__dict__['dimension'] = update.get('dimension', self.dimension)
    result.__dict__['_point'] = get_dict_key_with_callable_default(update, '_point', lambda: self._point.copy())
    return result

Raises: NotImplementedError: _description_

dim: int
66    @property
67    def dim(self) -> int:
68        raise NotImplementedError
class CoordinateVectorDimentionsAreNotMatch(builtins.ValueError):
89class CoordinateVectorDimentionsAreNotMatch(ValueError):
90    pass

Inappropriate argument value (of correct type).

Inherited Members
builtins.ValueError
ValueError
builtins.BaseException
with_traceback
args
class CoordinateVectorNd(VectorBase):
 93class CoordinateVectorNd(VectorBase):
 94    _terminal_point_names = {'tp', 'terminal_point', 'terminal point'}
 95
 96    def __init__(self, terminal_point: PointNd) -> None:
 97        self.terminal_point: PointNd = terminal_point
 98    
 99    def __repr__(self):
100        return f'{type(self).__name__}(tp={repr(self.terminal_point)})'
101    
102    def copy(self) -> 'CoordinateVectorNd':
103        cls = self.__class__
104        result = cls.__new__(cls)
105        result.__dict__['terminal_point'] = self.terminal_point.copy()
106        return result
107    
108    def shallow_copy(self) -> 'CoordinateVectorNd':
109        cls = self.__class__
110        result = cls.__new__(cls)
111        result.__dict__['terminal_point'] = self.terminal_point
112        return result
113    
114    def updated_copy(self, update: Dict) -> 'CoordinateVectorNd':
115        cls = self.__class__
116        result = cls.__new__(cls)
117        result.__dict__['terminal_point'] = get_dict_key_with_callable_default(update, 'terminal_point', lambda: self.terminal_point.copy())
118        return result
119    
120    @property
121    def dim(self):
122        return self.terminal_point.dim
123    
124    def _is_dimension_ok(self) -> bool:
125        return True
126
127    def __call__(self
128            , *args: Tuple[PointNd]
129            , **kwargs: Dict[str, PointNd]
130            ) -> PointNd:
131        if args:
132            first_item = args[0]
133            if isinstance(first_item, CoordinateVectorNd):
134                data = first_item()
135            elif isinstance(first_item, PointNd):
136                data = first_item
137            else:
138                raise ValueError
139            
140            self.terminal_point = data
141        elif kwargs:
142            terminal_point = kwargs.get('terminal_point')
143            for terminal_point_name_variant in self._terminal_point_names:
144                terminal_point = kwargs.get(terminal_point_name_variant, None)
145                if terminal_point is not None:
146                    self.terminal_point = terminal_point
147        
148        return self.terminal_point
149    
150    def __getitem__(self, index):
151        if isinstance(index, int):
152            if 0 == index:
153                return self.terminal_point
154            else:
155                raise IndexError
156        else:
157            if index in self._terminal_point_names:
158                return self.terminal_point
159            else:
160                raise KeyError
161    
162    def __setitem__(self, index, value):
163        if isinstance(index, int):
164            if 0 == index:
165                self.terminal_point = value
166            else:
167                raise IndexError
168        else:
169            if index in self._terminal_point_names:
170                self.terminal_point = value
171            else:
172                raise KeyError
173    
174    def __len__(self):
175        return 1
176
177    def magnitude(self) -> float:
178        if numpy_present:
179            return linalg.norm(self.terminal_point())
180        else:
181            result = 0
182            for item in self.terminal_point:
183                result += item * item
184            
185            return sqrt(result)
186    
187    def length(self) -> float:
188        return self.magnitude()
189
190    def magnitude_square(self) -> float:
191        if numpy_present:
192            tp = self.terminal_point()
193            return sum(tp * tp)
194        else:
195            result = 0
196            for item in self.terminal_point:
197                result += item * item
198            
199            return result
200    
201    # add
202    def __add__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
203        result = list()
204        if isinstance(other, CoordinateVectorNd):
205            for index in range(self.dim):
206                result.append(self.terminal_point[index] + other.terminal_point[index])
207        elif isinstance(other, (float, int)):
208            for index in range(self.dim):
209                result.append(self.terminal_point[index] + other)
210        else:
211            raise NotImplemented
212        
213        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
214    
215    def __radd__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
216        return self.__add__(other)
217    
218    def __iadd__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
219        if numpy_present:
220            if isinstance(other, CoordinateVectorNd):
221                self.terminal_point._point += other.terminal_point()
222            elif isinstance(other, (float, int)):
223                self.terminal_point._point += other
224            else:
225                raise NotImplemented
226        else:
227            if isinstance(other, CoordinateVectorNd):
228                for index in range(self.dim):
229                    self.terminal_point[index] += other.terminal_point[index]
230            elif isinstance(other, (float, int)):
231                for index in range(self.dim):
232                    self.terminal_point[index] += other
233            else:
234                raise NotImplemented
235
236        return self
237    
238    # sub
239    def __sub__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
240        if numpy_present:
241            result = None
242            if isinstance(other, CoordinateVectorNd):
243                result = self.terminal_point() - other.terminal_point()
244            elif isinstance(other, (float, int)):
245                result = self.terminal_point() - other
246            else:
247                raise NotImplemented
248            
249            return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result, ndarray_type=type(result[0].item()))))
250        else:
251            result = list()
252            if isinstance(other, CoordinateVectorNd):
253                for index in range(self.dim):
254                    result.append(self.terminal_point[index] - other.terminal_point[index])
255            elif isinstance(other, (float, int)):
256                for index in range(self.dim):
257                    result.append(self.terminal_point[index] - other)
258            else:
259                raise NotImplemented
260            
261            return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
262    
263    def __rsub__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
264        result = list()
265        if isinstance(other, CoordinateVectorNd):
266            for index in range(self.dim):
267                result.append(other.terminal_point[index] - self.terminal_point[index])
268        elif isinstance(other, (float, int)):
269            for index in range(self.dim):
270                result.append(other - self.terminal_point[index])
271        else:
272            raise NotImplemented
273        
274        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
275    
276    def __isub__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
277        if isinstance(other, CoordinateVectorNd):
278            for index in range(self.dim):
279                self.terminal_point[index] -= other.terminal_point[index]
280        elif isinstance(other, (float, int)):
281            for index in range(self.dim):
282                self.terminal_point[index] -= other
283        else:
284            raise NotImplemented
285
286        return self
287    
288    # mul
289    def __mul__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
290        """Multiplication to number or to other coordinate vector (item by item)
291
292        v1 = [1, 2, 3]
293        v2 = [2, 3, 1]
294        v3 = v1 * v2 = [1 * 2, 2 * 3, 3 * 1] = [2, 6, 3]
295
296        Args:
297            other (Union[float, int, &#39;CoordinateVectorNd&#39;]): _description_
298
299        Raises:
300            NotImplemented: _description_
301
302        Returns:
303            CoordinateVectorNd: _description_
304        """
305        result = list()
306        if isinstance(other, CoordinateVectorNd):
307            for index in range(self.dim):
308                result.append(self.terminal_point[index] * other.terminal_point[index])
309        elif isinstance(other, (float, int)):
310            for index in range(self.dim):
311                result.append(self.terminal_point[index] * other)
312        else:
313            raise NotImplemented
314        
315        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
316    
317    def __rmul__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
318        """Multiplication to number or to other coordinate vector (item by item)
319
320        v1 = [1, 2, 3]
321        v2 = [2, 3, 1]
322        v3 = v1 * v2 = [1 * 2, 2 * 3, 3 * 1] = [2, 6, 3]
323
324        Args:
325            other (Union[float, int, &#39;CoordinateVectorNd&#39;]): _description_
326
327        Returns:
328            CoordinateVectorNd: _description_
329        """
330        return self.__mul__(other)
331    
332    def __imul__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
333        """Multiplication to number or to other coordinate vector (item by item)
334
335        v1 = [1, 2, 3]
336        v2 = [2, 3, 1]
337        v3 = v1 * v2 = [1 * 2, 2 * 3, 3 * 1] = [2, 6, 3]
338
339        Args:
340            other (Union[float, int, &#39;CoordinateVectorNd&#39;]): _description_
341
342        Raises:
343            NotImplemented: _description_
344
345        Returns:
346            CoordinateVectorNd: _description_
347        """
348        if numpy_present:
349            if isinstance(other, CoordinateVectorNd):
350                self.terminal_point._point *= other.terminal_point()
351            elif isinstance(other, (float, int)):
352                self.terminal_point._point *= other
353            else:
354                raise NotImplemented
355        else:
356            if isinstance(other, CoordinateVectorNd):
357                for index in range(self.dim):
358                    self.terminal_point[index] *= other.terminal_point[index]
359            elif isinstance(other, (float, int)):
360                for index in range(self.dim):
361                    self.terminal_point[index] *= other
362            else:
363                raise NotImplemented
364
365        return self
366    
367    # matmul
368    def __matmul__(self, other: Union[float, int, 'CoordinateVectorNd']) -> Union[float, int]:
369        """Dot product
370        >> cv0 = CoordinateVectorNd(2, 4)
371        >> cv1 = CoordinateVectorNd(1, 3)
372        >> dot_product = cv0 @ cv1
373        >> print(dot_product)
374        14
375
376        Args:
377            other (Union[float, int, &#39;CoordinateVectorNd&#39;]): _description_
378
379        Raises:
380            NotImplemented: _description_
381            CoordinateVectorDimentionsAreNotMatch: _description_
382
383        Returns:
384            Union[float, int]: _description_
385        """
386        if not isinstance(other, CoordinateVectorNd):
387            raise NotImplemented
388        
389        dim = self.dim
390        if dim != other.dim:
391            raise CoordinateVectorDimentionsAreNotMatch
392
393        result = 0
394        for index in range(dim):
395            result += self.terminal_point[index] * other.terminal_point[index]
396        
397        return result
398    
399    # truediv
400    def __truediv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
401        result = list()
402        if isinstance(other, CoordinateVectorNd):
403            for index in range(self.dim):
404                result.append(self.terminal_point[index] / other.terminal_point[index])
405        elif isinstance(other, (float, int)):
406            for index in range(self.dim):
407                result.append(self.terminal_point[index] / other)
408        else:
409            raise NotImplemented
410        
411        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
412    
413    def __rtruediv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
414        result = list()
415        if isinstance(other, CoordinateVectorNd):
416            for index in range(self.dim):
417                result.append(other.terminal_point[index] / self.terminal_point[index])
418        elif isinstance(other, (float, int)):
419            for index in range(self.dim):
420                result.append(other / self.terminal_point[index])
421        else:
422            raise NotImplemented
423        
424        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
425    
426    def __itruediv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
427        if numpy_present:
428            if isinstance(other, CoordinateVectorNd):
429                self.terminal_point._point /= other.terminal_point()
430            elif isinstance(other, (float, int)):
431                self.terminal_point._point /= other
432            else:
433                raise NotImplemented
434        else:
435            if isinstance(other, CoordinateVectorNd):
436                for index in range(self.dim):
437                    self.terminal_point[index] /= other.terminal_point[index]
438            elif isinstance(other, (float, int)):
439                for index in range(self.dim):
440                    self.terminal_point[index] /= other
441            else:
442                raise NotImplemented
443
444        return self
445    
446    # floordiv
447    def __floordiv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
448        result = list()
449        if isinstance(other, CoordinateVectorNd):
450            for index in range(self.dim):
451                result.append(self.terminal_point[index] // other.terminal_point[index])
452        elif isinstance(other, (float, int)):
453            for index in range(self.dim):
454                result.append(self.terminal_point[index] // other)
455        else:
456            raise NotImplemented
457        
458        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
459    
460    def __rfloordiv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
461        result = list()
462        if isinstance(other, CoordinateVectorNd):
463            for index in range(self.dim):
464                result.append(other.terminal_point[index] // self.terminal_point[index])
465        elif isinstance(other, (float, int)):
466            for index in range(self.dim):
467                result.append(other // self.terminal_point[index])
468        else:
469            raise NotImplemented
470        
471        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
472    
473    def __ifloordiv__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
474        if numpy_present:
475            if isinstance(other, CoordinateVectorNd):
476                self.terminal_point._point //= other.terminal_point()
477            elif isinstance(other, (float, int)):
478                self.terminal_point._point //= other
479            else:
480                raise NotImplemented
481        else:
482            if isinstance(other, CoordinateVectorNd):
483                for index in range(self.dim):
484                    self.terminal_point[index] //= other.terminal_point[index]
485            elif isinstance(other, (float, int)):
486                for index in range(self.dim):
487                    self.terminal_point[index] //= other
488            else:
489                raise NotImplemented
490
491        return self
492    
493    # mod
494    def __mod__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
495        result = list()
496        if isinstance(other, CoordinateVectorNd):
497            for index in range(self.dim):
498                result.append(self.terminal_point[index] % other.terminal_point[index])
499        elif isinstance(other, (float, int)):
500            for index in range(self.dim):
501                result.append(self.terminal_point[index] % other)
502        else:
503            raise NotImplemented
504        
505        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
506    
507    def __rmod__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
508        result = list()
509        if isinstance(other, CoordinateVectorNd):
510            for index in range(self.dim):
511                result.append(other.terminal_point[index] % self.terminal_point[index])
512        elif isinstance(other, (float, int)):
513            for index in range(self.dim):
514                result.append(other % self.terminal_point[index])
515        else:
516            raise NotImplemented
517        
518        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
519    
520    def __imod__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
521        if isinstance(other, CoordinateVectorNd):
522            for index in range(self.dim):
523                self.terminal_point[index] %= other.terminal_point[index]
524        elif isinstance(other, (float, int)):
525            for index in range(self.dim):
526                self.terminal_point[index] %= other
527        else:
528            raise NotImplemented
529
530        return self
531    
532    # pow
533    def __pow__(self, other: Union[float, int, 'CoordinateVectorNd'], modulo) -> 'CoordinateVectorNd':
534        result = list()
535        if isinstance(other, CoordinateVectorNd):
536            for index in range(self.dim):
537                result.append(pow(self.terminal_point[index], other.terminal_point[index], modulo))
538        elif isinstance(other, (float, int)):
539            for index in range(self.dim):
540                result.append(pow(self.terminal_point[index], other, modulo))
541        else:
542            raise NotImplemented
543        
544        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
545    
546    def __rpow__(self, other: Union[float, int, 'CoordinateVectorNd'], modulo) -> 'CoordinateVectorNd':
547        result = list()
548        if isinstance(other, CoordinateVectorNd):
549            for index in range(self.dim):
550                result.append(pow(other.terminal_point[index], self.terminal_point[index], modulo))
551        elif isinstance(other, (float, int)):
552            for index in range(self.dim):
553                result.append(pow(other, self.terminal_point[index], modulo))
554        else:
555            raise NotImplemented
556        
557        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
558    
559    def __ipow__(self, other: Union[float, int, 'CoordinateVectorNd'], modulo) -> 'CoordinateVectorNd':
560        if isinstance(other, CoordinateVectorNd):
561            for index in range(self.dim):
562                self.terminal_point[index].__ipow__(other.terminal_point[index], modulo)
563        elif isinstance(other, (float, int)):
564            for index in range(self.dim):
565                self.terminal_point[index].__ipow__(other, modulo)
566        else:
567            raise NotImplemented
568
569        return self
570    
571    # lshift
572    def __lshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
573        result = list()
574        if isinstance(other, CoordinateVectorNd):
575            for index in range(self.dim):
576                result.append(self.terminal_point[index] << other.terminal_point[index])
577        elif isinstance(other, (float, int)):
578            for index in range(self.dim):
579                result.append(self.terminal_point[index] << other)
580        else:
581            raise NotImplemented
582        
583        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
584    
585    def __rlshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
586        result = list()
587        if isinstance(other, CoordinateVectorNd):
588            for index in range(self.dim):
589                result.append(other.terminal_point[index] << self.terminal_point[index])
590        elif isinstance(other, (float, int)):
591            for index in range(self.dim):
592                result.append(other << self.terminal_point[index])
593        else:
594            raise NotImplemented
595        
596        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
597    
598    def __ilshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
599        if isinstance(other, CoordinateVectorNd):
600            for index in range(self.dim):
601                self.terminal_point[index] <<= other.terminal_point[index]
602        elif isinstance(other, (float, int)):
603            for index in range(self.dim):
604                self.terminal_point[index] <<= other
605        else:
606            raise NotImplemented
607
608        return self
609    
610    # rshift
611    def __rshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
612        result = list()
613        if isinstance(other, CoordinateVectorNd):
614            for index in range(self.dim):
615                result.append(self.terminal_point[index] >> other.terminal_point[index])
616        elif isinstance(other, (float, int)):
617            for index in range(self.dim):
618                result.append(self.terminal_point[index] >> other)
619        else:
620            raise NotImplemented
621        
622        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
623    
624    def __rrshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
625        result = list()
626        if isinstance(other, CoordinateVectorNd):
627            for index in range(self.dim):
628                result.append(other.terminal_point[index] >> self.terminal_point[index])
629        elif isinstance(other, (float, int)):
630            for index in range(self.dim):
631                result.append(other >> self.terminal_point[index])
632        else:
633            raise NotImplemented
634        
635        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
636    
637    def __irshift__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
638        if isinstance(other, CoordinateVectorNd):
639            for index in range(self.dim):
640                self.terminal_point[index] >>= other.terminal_point[index]
641        elif isinstance(other, (float, int)):
642            for index in range(self.dim):
643                self.terminal_point[index] >>= other
644        else:
645            raise NotImplemented
646
647        return self
648    
649    # and
650    def __and__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
651        result = list()
652        if isinstance(other, CoordinateVectorNd):
653            for index in range(self.dim):
654                result.append(self.terminal_point[index] & other.terminal_point[index])
655        elif isinstance(other, (float, int)):
656            for index in range(self.dim):
657                result.append(self.terminal_point[index] & other)
658        else:
659            raise NotImplemented
660        
661        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
662    
663    def __rand__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
664        result = list()
665        if isinstance(other, CoordinateVectorNd):
666            for index in range(self.dim):
667                result.append(other.terminal_point[index] & self.terminal_point[index])
668        elif isinstance(other, (float, int)):
669            for index in range(self.dim):
670                result.append(other & self.terminal_point[index])
671        else:
672            raise NotImplemented
673        
674        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
675    
676    def __iand__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
677        if isinstance(other, CoordinateVectorNd):
678            for index in range(self.dim):
679                self.terminal_point[index] &= other.terminal_point[index]
680        elif isinstance(other, (float, int)):
681            for index in range(self.dim):
682                self.terminal_point[index] &= other
683        else:
684            raise NotImplemented
685
686        return self
687    
688    # xor
689    def __xor__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
690        result = list()
691        if isinstance(other, CoordinateVectorNd):
692            for index in range(self.dim):
693                result.append(self.terminal_point[index] ^ other.terminal_point[index])
694        elif isinstance(other, (float, int)):
695            for index in range(self.dim):
696                result.append(self.terminal_point[index] ^ other)
697        else:
698            raise NotImplemented
699        
700        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
701    
702    def __rxor__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
703        result = list()
704        if isinstance(other, CoordinateVectorNd):
705            for index in range(self.dim):
706                result.append(other.terminal_point[index] ^ self.terminal_point[index])
707        elif isinstance(other, (float, int)):
708            for index in range(self.dim):
709                result.append(other ^ self.terminal_point[index])
710        else:
711            raise NotImplemented
712        
713        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
714    
715    def __ixor__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
716        if isinstance(other, CoordinateVectorNd):
717            for index in range(self.dim):
718                self.terminal_point[index] ^= other.terminal_point[index]
719        elif isinstance(other, (float, int)):
720            for index in range(self.dim):
721                self.terminal_point[index] ^= other
722        else:
723            raise NotImplemented
724
725        return self
726    
727    # or
728    def __or__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
729        result = list()
730        if isinstance(other, CoordinateVectorNd):
731            for index in range(self.dim):
732                result.append(self.terminal_point[index] | other.terminal_point[index])
733        elif isinstance(other, (float, int)):
734            for index in range(self.dim):
735                result.append(self.terminal_point[index] | other)
736        else:
737            raise NotImplemented
738        
739        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
740    
741    def __ror__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
742        result = list()
743        if isinstance(other, CoordinateVectorNd):
744            for index in range(self.dim):
745                result.append(other.terminal_point[index] | self.terminal_point[index])
746        elif isinstance(other, (float, int)):
747            for index in range(self.dim):
748                result.append(other | self.terminal_point[index])
749        else:
750            raise NotImplemented
751        
752        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
753    
754    def __ior__(self, other: Union[float, int, 'CoordinateVectorNd']) -> 'CoordinateVectorNd':
755        if isinstance(other, CoordinateVectorNd):
756            for index in range(self.dim):
757                self.terminal_point[index] |= other.terminal_point[index]
758        elif isinstance(other, (float, int)):
759            for index in range(self.dim):
760                self.terminal_point[index] |= other
761        else:
762            raise NotImplemented
763
764        return self
765    
766    # neg
767    def __neg__(self) -> 'CoordinateVectorNd':
768        if numpy_present:
769            result = self.terminal_point().__neg__()
770            return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result, ndarray_type=type(result[0].item()))))
771        else:
772            result = list()
773            for index in range(self.dim):
774                result.append(self.terminal_point[index].__neg__())
775            
776            return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
777    
778    # pos
779    def __pos__(self) -> 'CoordinateVectorNd':
780        result = list()
781        for index in range(self.dim):
782            result.append(self.terminal_point[index].__pos__())
783        
784        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
785    
786    # abs
787    def __abs__(self) -> 'CoordinateVectorNd':
788        result = list()
789        for index in range(self.dim):
790            result.append(self.terminal_point[index].__abs__())
791        
792        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
793    
794    # invert
795    def __invert__(self) -> 'CoordinateVectorNd':
796        result = list()
797        for index in range(self.dim):
798            result.append(self.terminal_point[index].__invert__())
799        
800        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
801    
802    # complex
803    def __complex__(self) -> 'CoordinateVectorNd':
804        result = list()
805        for index in range(self.dim):
806            result.append(self.terminal_point[index].__complex__())
807        
808        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
809    
810    # int
811    def __int__(self) -> 'CoordinateVectorNd':
812        result = list()
813        for index in range(self.dim):
814            result.append(self.terminal_point[index].__int__())
815        
816        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
817    
818    # float
819    def __float__(self) -> 'CoordinateVectorNd':
820        result = list()
821        for index in range(self.dim):
822            result.append(self.terminal_point[index].__float__())
823        
824        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
825    
826    # round
827    def __round__(self, ndigits) -> 'CoordinateVectorNd':
828        result = list()
829        for index in range(self.dim):
830            result.append(self.terminal_point[index].__round__(ndigits))
831        
832        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
833    
834    # trunc
835    def __trunc__(self) -> 'CoordinateVectorNd':
836        result = list()
837        for index in range(self.dim):
838            result.append(self.terminal_point[index].__trunc__())
839        
840        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
841    
842    # floor
843    def __floor__(self) -> 'CoordinateVectorNd':
844        result = list()
845        for index in range(self.dim):
846            result.append(self.terminal_point[index].__floor__())
847        
848        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
849    
850    # ceil
851    def __ceil__(self) -> 'CoordinateVectorNd':
852        result = list()
853        for index in range(self.dim):
854            result.append(self.terminal_point[index].__ceil__())
855        
856        return CoordinateVectorNd(convert_point_to_xyz(PointNd(len(result), result)))
857    
858    def __eq__(self, other) -> bool:
859        if isinstance(other, PointNd):
860            return self.terminal_point == other.terminal_point
861        
862        return False
863    
864    def __ne__(self, other) -> bool:
865        return not self.__eq__(other)
866    
867    def __hash__(self) -> int:
868        return hash(self.terminal_point)
869    
870    def __bool__(self) -> bool:
871        """If not zero point
872
873        Returns:
874            bool: _description_
875        """
876        return self.terminal_point.__bool__()
877
878    # TODO: Другие операции умножения применимые к координатным векторам - реализовать в методах.
879    # А неприменимые - в соответствующих классах (например DirectedGraphNd отлично подходит на роль 
880    # матрицы с которой будут производится манипуляции. Каждая точка - отдельный столбец. 
881    # Направление слева-направо: слева нулевой индекс, а справа - максимальный индекс)
CoordinateVectorNd( terminal_point: cengal.math.geometry.point.versions.v_0.point.PointNd)
96    def __init__(self, terminal_point: PointNd) -> None:
97        self.terminal_point: PointNd = terminal_point
terminal_point: cengal.math.geometry.point.versions.v_0.point.PointNd
def copy( self) -> CoordinateVectorNd:
102    def copy(self) -> 'CoordinateVectorNd':
103        cls = self.__class__
104        result = cls.__new__(cls)
105        result.__dict__['terminal_point'] = self.terminal_point.copy()
106        return result

Should make relevant copy of an object (not so general and deep as a deepcopy()). should copy only known object fields. Example: def copy(self): cls = self.__class__ result = cls.__new__(cls) result.__dict__['dimension'] = self.dimension result.__dict__['_point'] = self._point.copy() return result

Raises: NotImplementedError: _description_

def shallow_copy( self) -> CoordinateVectorNd:
108    def shallow_copy(self) -> 'CoordinateVectorNd':
109        cls = self.__class__
110        result = cls.__new__(cls)
111        result.__dict__['terminal_point'] = self.terminal_point
112        return result

Same as copy.copy(self), but should copy only known object fields. Example: def shallow_copy(self): cls = self.__class__ result = cls.__new__(cls) result.__dict__['dimension'] = self.dimension result.__dict__['_point'] = self._point return result

Raises: NotImplementedError: _description_

def updated_copy( self, update: Dict) -> CoordinateVectorNd:
114    def updated_copy(self, update: Dict) -> 'CoordinateVectorNd':
115        cls = self.__class__
116        result = cls.__new__(cls)
117        result.__dict__['terminal_point'] = get_dict_key_with_callable_default(update, 'terminal_point', lambda: self.terminal_point.copy())
118        return result

Will make updated copy of an object. Other behavior should be the same as in the def copy(self) method. Example: # from cengal.data_manipulation.get_dict_key_with_callable_default import get_dict_key_with_callable_default from cengal.entities.copyable import CopyableMixin, get_dict_key_with_callable_default

def updated_copy(self, update: Dict):
    cls = self.__class__
    result = cls.__new__(cls)
    result.__dict__['dimension'] = update.get('dimension', self.dimension)
    result.__dict__['_point'] = get_dict_key_with_callable_default(update, '_point', lambda: self._point.copy())
    return result

Raises: NotImplementedError: _description_

dim
120    @property
121    def dim(self):
122        return self.terminal_point.dim
def magnitude(self) -> float:
177    def magnitude(self) -> float:
178        if numpy_present:
179            return linalg.norm(self.terminal_point())
180        else:
181            result = 0
182            for item in self.terminal_point:
183                result += item * item
184            
185            return sqrt(result)
def length(self) -> float:
187    def length(self) -> float:
188        return self.magnitude()
def magnitude_square(self) -> float:
190    def magnitude_square(self) -> float:
191        if numpy_present:
192            tp = self.terminal_point()
193            return sum(tp * tp)
194        else:
195            result = 0
196            for item in self.terminal_point:
197                result += item * item
198            
199            return result
class VectorNd(VectorBase):
 884class VectorNd(VectorBase):
 885    _initial_point_names = {'ip', 'initial_point', 'initial point'}
 886    _terminal_point_names = {'tp', 'terminal_point', 'terminal point'}
 887
 888    def __init__(self
 889            , *args: Tuple[PointNd]
 890            , **kwargs: Dict[str, PointNd]
 891            ) -> None:
 892        self.initial_point: PointNd = None
 893        self.terminal_point: PointNd = None
 894        self(*args, **kwargs)
 895    
 896    def copy(self) -> 'VectorNd':
 897        cls = self.__class__
 898        result = cls.__new__(cls)
 899        result.__dict__['initial_point'] = self.initial_point.copy()
 900        result.__dict__['terminal_point'] = self.terminal_point.copy()
 901        return result
 902    
 903    def shallow_copy(self) -> 'VectorNd':
 904        cls = self.__class__
 905        result = cls.__new__(cls)
 906        result.__dict__['initial_point'] = self.initial_point
 907        result.__dict__['terminal_point'] = self.terminal_point
 908        return result
 909    
 910    def updated_copy(self, update: Dict) -> 'VectorNd':
 911        cls = self.__class__
 912        result = cls.__new__(cls)
 913        result.__dict__['initial_point'] = get_dict_key_with_callable_default(update, 'initial_point', lambda: self.initial_point.copy())
 914        result.__dict__['terminal_point'] = get_dict_key_with_callable_default(update, 'terminal_point', lambda: self.terminal_point.copy())
 915        return result
 916    
 917    @property
 918    def dim(self):
 919        if self.initial_point is None:
 920            return None
 921        
 922        return self.initial_point.dim
 923
 924    def _is_dimension_ok(self) -> bool:
 925        if (self.initial_point is None) and (self.terminal_point is None):
 926            return True
 927        
 928        initial_dim = self.initial_point.dim
 929        terminal_dim = self.terminal_point.dim
 930        if initial_dim == terminal_dim:
 931            return True
 932        else:
 933            raise VectorDimentionConflictError
 934    
 935    def _set_forgotten_points_to_zero(self):
 936        if (self.initial_point is not None) and (self.terminal_point is None):
 937            dim = self.initial_point.dim
 938            self.terminal_point = PointNd(dim, [0] * dim)
 939        elif (self.initial_point is None) and (self.terminal_point is not None):
 940            dim = self.terminal_point.dim
 941            self.initial_point = PointNd(dim, [0] * dim)
 942        elif (self.initial_point is None) and (self.terminal_point is None):
 943            pass
 944
 945    def __call__(self
 946            , *args: Tuple[PointNd]
 947            , **kwargs: Dict[str, PointNd]
 948            ) -> Tuple[PointNd]:
 949        if args:
 950            first_item = args[0]
 951            data = first_item
 952            if isinstance(first_item, VectorNd):
 953                data = first_item()
 954            if isinstance(first_item, CoordinateVectorNd):
 955                terminal_point = first_item()
 956                data = [PointNd(terminal_point.dim), terminal_point]
 957            elif isinstance(first_item, PointNd):
 958                data = args
 959            
 960            self.initial_point = data[0]
 961            data_len = len(data)
 962            if data_len == 2:
 963                self.terminal_point = data[1]
 964            elif data_len > 2:
 965                raise IndexError
 966            
 967            self._set_forgotten_points_to_zero()
 968            self._is_dimension_ok()
 969        elif kwargs:
 970            for initial_point_name_variant in self._initial_point_names:
 971                initial_point = kwargs.get(initial_point_name_variant, None)
 972                if initial_point is not None:
 973                    self.initial_point = initial_point
 974                    break
 975
 976            for terminal_point_name_variant in self._terminal_point_names:
 977                terminal_point = kwargs.get(terminal_point_name_variant, None)
 978                if terminal_point is not None:
 979                    self.terminal_point = terminal_point
 980                    break
 981            
 982            self._set_forgotten_points_to_zero()
 983            self._is_dimension_ok()
 984        
 985        return [self.initial_point, self.terminal_point]
 986    
 987    def __getitem__(self, index):
 988        if isinstance(index, int):
 989            if 0 == index:
 990                return self.initial_point
 991            elif 1 == index:
 992                return self.terminal_point
 993            else:
 994                raise IndexError
 995        else:
 996            if index in self._initial_point_names:
 997                return self.initial_point
 998            elif index in self._terminal_point_names:
 999                return self.terminal_point
1000            else:
1001                raise KeyError
1002    
1003    def __setitem__(self, index, value):
1004        if isinstance(index, int):
1005            if 0 == index:
1006                self.initial_point = value
1007            elif 1 == index:
1008                self.terminal_point = value
1009            else:
1010                raise IndexError
1011        else:
1012            if index in self._initial_point_names:
1013                self.initial_point = value
1014            elif index in self._terminal_point_names:
1015                self.terminal_point = value
1016            else:
1017                raise KeyError
1018        
1019        self._set_forgotten_points_to_zero()
1020        self._is_dimension_ok()
1021    
1022    def __len__(self):
1023        return 2
1024
1025    def magnitude(self) -> float:
1026        if numpy_present:
1027            distance_vec = self.terminal_point() - self.initial_point()
1028            return linalg.norm(distance_vec)
1029        else:
1030            init_vec: CoordinateVectorNd = CoordinateVectorNd(self.initial_point)
1031            term_vec: CoordinateVectorNd = CoordinateVectorNd(self.terminal_point)
1032            distance_vec: CoordinateVectorNd = term_vec - init_vec
1033            return distance_vec.magnitude()
1034    
1035    def length(self) -> float:
1036        return self.magnitude()
1037
1038    def magnitude_square(self) -> float:
1039        if numpy_present:
1040            distance_vec = self.terminal_point() - self.initial_point()
1041            return sum(distance_vec * distance_vec)
1042        else:
1043            init_vec: CoordinateVectorNd = CoordinateVectorNd(self.initial_point)
1044            term_vec: CoordinateVectorNd = CoordinateVectorNd(self.terminal_point)
1045            distance_vec: CoordinateVectorNd = term_vec - init_vec
1046            return distance_vec.magnitude_square()
1047    
1048    def is_convergence(self, other: 'VectorNd'):
1049        if numpy_present:
1050            init_dist = other.initial_point() - self.initial_point()
1051            term_dist = other.terminal_point() - self.terminal_point()
1052            return sum(init_dist * init_dist) > sum(term_dist * term_dist)
1053        else:
1054            return VectorNd(self.initial_point, other.initial_point).magnitude_square() \
1055                > VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
1056    
1057    def is_divergence(self, other: 'VectorNd'):
1058        if numpy_present:
1059            init_dist = other.initial_point() - self.initial_point()
1060            term_dist = other.terminal_point() - self.terminal_point()
1061            return sum(init_dist * init_dist) < sum(term_dist * term_dist)
1062        else:
1063            return VectorNd(self.initial_point, other.initial_point).magnitude_square() \
1064                < VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
1065    
1066    def is_conver_diver_parity(self, other: 'VectorNd'):
1067        if numpy_present:
1068            init_dist = other.initial_point() - self.initial_point()
1069            term_dist = other.terminal_point() - self.terminal_point()
1070            return sum(init_dist * init_dist) == sum(term_dist * term_dist)
1071        else:
1072            return VectorNd(self.initial_point, other.initial_point).magnitude_square() \
1073                == VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
1074    
1075    def conver_diver_state(self, other: 'VectorNd') -> int:
1076        if numpy_present:
1077            init_dist = other.initial_point() - self.initial_point()
1078            term_dist = other.terminal_point() - self.terminal_point()
1079            init_magnitude_square = sum(init_dist * init_dist)
1080            term_magnitude_square = sum(term_dist * term_dist)
1081        else:
1082            init_magnitude_square = VectorNd(self.initial_point, other.initial_point).magnitude_square()
1083            term_magnitude_square = VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
1084
1085        if init_magnitude_square > term_magnitude_square:
1086            return 1
1087        elif init_magnitude_square == term_magnitude_square:
1088            return 0
1089        elif init_magnitude_square < term_magnitude_square:
1090            return -1
VectorNd( *args: Tuple[cengal.math.geometry.point.versions.v_0.point.PointNd], **kwargs: Dict[str, cengal.math.geometry.point.versions.v_0.point.PointNd])
888    def __init__(self
889            , *args: Tuple[PointNd]
890            , **kwargs: Dict[str, PointNd]
891            ) -> None:
892        self.initial_point: PointNd = None
893        self.terminal_point: PointNd = None
894        self(*args, **kwargs)
initial_point: cengal.math.geometry.point.versions.v_0.point.PointNd
terminal_point: cengal.math.geometry.point.versions.v_0.point.PointNd
def copy(self) -> VectorNd:
896    def copy(self) -> 'VectorNd':
897        cls = self.__class__
898        result = cls.__new__(cls)
899        result.__dict__['initial_point'] = self.initial_point.copy()
900        result.__dict__['terminal_point'] = self.terminal_point.copy()
901        return result

Should make relevant copy of an object (not so general and deep as a deepcopy()). should copy only known object fields. Example: def copy(self): cls = self.__class__ result = cls.__new__(cls) result.__dict__['dimension'] = self.dimension result.__dict__['_point'] = self._point.copy() return result

Raises: NotImplementedError: _description_

def shallow_copy(self) -> VectorNd:
903    def shallow_copy(self) -> 'VectorNd':
904        cls = self.__class__
905        result = cls.__new__(cls)
906        result.__dict__['initial_point'] = self.initial_point
907        result.__dict__['terminal_point'] = self.terminal_point
908        return result

Same as copy.copy(self), but should copy only known object fields. Example: def shallow_copy(self): cls = self.__class__ result = cls.__new__(cls) result.__dict__['dimension'] = self.dimension result.__dict__['_point'] = self._point return result

Raises: NotImplementedError: _description_

def updated_copy( self, update: Dict) -> VectorNd:
910    def updated_copy(self, update: Dict) -> 'VectorNd':
911        cls = self.__class__
912        result = cls.__new__(cls)
913        result.__dict__['initial_point'] = get_dict_key_with_callable_default(update, 'initial_point', lambda: self.initial_point.copy())
914        result.__dict__['terminal_point'] = get_dict_key_with_callable_default(update, 'terminal_point', lambda: self.terminal_point.copy())
915        return result

Will make updated copy of an object. Other behavior should be the same as in the def copy(self) method. Example: # from cengal.data_manipulation.get_dict_key_with_callable_default import get_dict_key_with_callable_default from cengal.entities.copyable import CopyableMixin, get_dict_key_with_callable_default

def updated_copy(self, update: Dict):
    cls = self.__class__
    result = cls.__new__(cls)
    result.__dict__['dimension'] = update.get('dimension', self.dimension)
    result.__dict__['_point'] = get_dict_key_with_callable_default(update, '_point', lambda: self._point.copy())
    return result

Raises: NotImplementedError: _description_

dim
917    @property
918    def dim(self):
919        if self.initial_point is None:
920            return None
921        
922        return self.initial_point.dim
def magnitude(self) -> float:
1025    def magnitude(self) -> float:
1026        if numpy_present:
1027            distance_vec = self.terminal_point() - self.initial_point()
1028            return linalg.norm(distance_vec)
1029        else:
1030            init_vec: CoordinateVectorNd = CoordinateVectorNd(self.initial_point)
1031            term_vec: CoordinateVectorNd = CoordinateVectorNd(self.terminal_point)
1032            distance_vec: CoordinateVectorNd = term_vec - init_vec
1033            return distance_vec.magnitude()
def length(self) -> float:
1035    def length(self) -> float:
1036        return self.magnitude()
def magnitude_square(self) -> float:
1038    def magnitude_square(self) -> float:
1039        if numpy_present:
1040            distance_vec = self.terminal_point() - self.initial_point()
1041            return sum(distance_vec * distance_vec)
1042        else:
1043            init_vec: CoordinateVectorNd = CoordinateVectorNd(self.initial_point)
1044            term_vec: CoordinateVectorNd = CoordinateVectorNd(self.terminal_point)
1045            distance_vec: CoordinateVectorNd = term_vec - init_vec
1046            return distance_vec.magnitude_square()
def is_convergence( self, other: VectorNd):
1048    def is_convergence(self, other: 'VectorNd'):
1049        if numpy_present:
1050            init_dist = other.initial_point() - self.initial_point()
1051            term_dist = other.terminal_point() - self.terminal_point()
1052            return sum(init_dist * init_dist) > sum(term_dist * term_dist)
1053        else:
1054            return VectorNd(self.initial_point, other.initial_point).magnitude_square() \
1055                > VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
def is_divergence( self, other: VectorNd):
1057    def is_divergence(self, other: 'VectorNd'):
1058        if numpy_present:
1059            init_dist = other.initial_point() - self.initial_point()
1060            term_dist = other.terminal_point() - self.terminal_point()
1061            return sum(init_dist * init_dist) < sum(term_dist * term_dist)
1062        else:
1063            return VectorNd(self.initial_point, other.initial_point).magnitude_square() \
1064                < VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
def is_conver_diver_parity( self, other: VectorNd):
1066    def is_conver_diver_parity(self, other: 'VectorNd'):
1067        if numpy_present:
1068            init_dist = other.initial_point() - self.initial_point()
1069            term_dist = other.terminal_point() - self.terminal_point()
1070            return sum(init_dist * init_dist) == sum(term_dist * term_dist)
1071        else:
1072            return VectorNd(self.initial_point, other.initial_point).magnitude_square() \
1073                == VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
def conver_diver_state( self, other: VectorNd) -> int:
1075    def conver_diver_state(self, other: 'VectorNd') -> int:
1076        if numpy_present:
1077            init_dist = other.initial_point() - self.initial_point()
1078            term_dist = other.terminal_point() - self.terminal_point()
1079            init_magnitude_square = sum(init_dist * init_dist)
1080            term_magnitude_square = sum(term_dist * term_dist)
1081        else:
1082            init_magnitude_square = VectorNd(self.initial_point, other.initial_point).magnitude_square()
1083            term_magnitude_square = VectorNd(self.terminal_point, other.terminal_point).magnitude_square()
1084
1085        if init_magnitude_square > term_magnitude_square:
1086            return 1
1087        elif init_magnitude_square == term_magnitude_square:
1088            return 0
1089        elif init_magnitude_square < term_magnitude_square:
1090            return -1
class DirectedGraphNd(VectorBase):
1093class DirectedGraphNd(VectorBase):
1094    def __init__(self
1095            , *args: Union[Tuple[PointNd], Tuple[Sequence[PointNd]]]
1096            ) -> None:
1097        self.points_list: List[PointNd] = None
1098        self(*args)
1099    
1100    def copy(self) -> 'DirectedGraphNd':
1101        cls = self.__class__
1102        result = cls.__new__(cls)
1103        if self.points_list is None:
1104            result.__dict__['points_list'] = self.points_list
1105        else:
1106            result.__dict__['points_list'] = [point.copy() for point in self.points_list]
1107
1108        return result
1109    
1110    def shallow_copy(self) -> 'DirectedGraphNd':
1111        cls = self.__class__
1112        result = cls.__new__(cls)
1113        result.__dict__['points_list'] = self.points_list
1114        return result
1115    
1116    def updated_copy(self, update: Dict) -> 'DirectedGraphNd':
1117        cls = self.__class__
1118        result = cls.__new__(cls)
1119        def copy_points():
1120            if self.points_list is None:
1121                return self.points_list
1122            else:
1123                return [point.copy() for point in self.points_list]
1124
1125        result.__dict__['points_list'] = get_dict_key_with_callable_default(update, 'points_list', copy_points)
1126        return result
1127    
1128    @property
1129    def dim(self):
1130        if self.points_list:
1131            return self.points_list[0].dim
1132        else:
1133            return None
1134
1135    def _is_dimension_ok(self) -> bool:
1136        if self.points_list:
1137            initial_dim = self.points_list[0].dim
1138            for point in self.points_list:
1139                if initial_dim != point.dim:
1140                    raise VectorDimentionConflictError
1141        else:
1142            return True
1143
1144    def _is_new_points_dimension_ok(self, new_point: PointNd) -> bool:
1145        dim = self.dim
1146        if dim is None:
1147            return True
1148        else:
1149            if dim == new_point.dim:
1150                return True
1151            else:
1152                raise VectorDimentionConflictError
1153
1154    def __call__(self
1155            , *args: Union[Tuple[PointNd], Tuple[Sequence[PointNd]]]
1156            ) -> Optional[List[PointNd]]:
1157        if args:
1158            first_item = args[0]
1159            data = first_item
1160            if isinstance(first_item, VectorNd):
1161                data = first_item()
1162            elif isinstance(first_item, PointNd):
1163                data = args
1164            
1165            self.points_list = list(data)
1166        
1167        self._is_dimension_ok()
1168        return self.points_list
1169    
1170    def get_vector(self, index: int) -> VectorNd:
1171        if 0 <= index < (len(self) - 1):
1172            return VectorNd(self[index], self[index + 1])
1173        else:
1174            raise IndexError
1175    
1176    def get_vector_reversed(self, index: int) -> VectorNd:
1177        if 1 <= index < len(self):
1178            return VectorNd(self[index], self[index - 1])
1179        else:
1180            raise IndexError
1181    
1182    def __getitem__(self, index):
1183        return self.points_list[index]
1184    
1185    def __setitem__(self, index, value):
1186        self._is_new_points_dimension_ok(value)
1187        self.points_list[index] = value
1188    
1189    def __len__(self):
1190        return len(self.points_list)
DirectedGraphNd( *args: Union[Tuple[cengal.math.geometry.point.versions.v_0.point.PointNd], Tuple[Sequence[cengal.math.geometry.point.versions.v_0.point.PointNd]]])
1094    def __init__(self
1095            , *args: Union[Tuple[PointNd], Tuple[Sequence[PointNd]]]
1096            ) -> None:
1097        self.points_list: List[PointNd] = None
1098        self(*args)
points_list: List[cengal.math.geometry.point.versions.v_0.point.PointNd]
def copy(self) -> DirectedGraphNd:
1100    def copy(self) -> 'DirectedGraphNd':
1101        cls = self.__class__
1102        result = cls.__new__(cls)
1103        if self.points_list is None:
1104            result.__dict__['points_list'] = self.points_list
1105        else:
1106            result.__dict__['points_list'] = [point.copy() for point in self.points_list]
1107
1108        return result

Should make relevant copy of an object (not so general and deep as a deepcopy()). should copy only known object fields. Example: def copy(self): cls = self.__class__ result = cls.__new__(cls) result.__dict__['dimension'] = self.dimension result.__dict__['_point'] = self._point.copy() return result

Raises: NotImplementedError: _description_

def shallow_copy(self) -> DirectedGraphNd:
1110    def shallow_copy(self) -> 'DirectedGraphNd':
1111        cls = self.__class__
1112        result = cls.__new__(cls)
1113        result.__dict__['points_list'] = self.points_list
1114        return result

Same as copy.copy(self), but should copy only known object fields. Example: def shallow_copy(self): cls = self.__class__ result = cls.__new__(cls) result.__dict__['dimension'] = self.dimension result.__dict__['_point'] = self._point return result

Raises: NotImplementedError: _description_

def updated_copy( self, update: Dict) -> DirectedGraphNd:
1116    def updated_copy(self, update: Dict) -> 'DirectedGraphNd':
1117        cls = self.__class__
1118        result = cls.__new__(cls)
1119        def copy_points():
1120            if self.points_list is None:
1121                return self.points_list
1122            else:
1123                return [point.copy() for point in self.points_list]
1124
1125        result.__dict__['points_list'] = get_dict_key_with_callable_default(update, 'points_list', copy_points)
1126        return result

Will make updated copy of an object. Other behavior should be the same as in the def copy(self) method. Example: # from cengal.data_manipulation.get_dict_key_with_callable_default import get_dict_key_with_callable_default from cengal.entities.copyable import CopyableMixin, get_dict_key_with_callable_default

def updated_copy(self, update: Dict):
    cls = self.__class__
    result = cls.__new__(cls)
    result.__dict__['dimension'] = update.get('dimension', self.dimension)
    result.__dict__['_point'] = get_dict_key_with_callable_default(update, '_point', lambda: self._point.copy())
    return result

Raises: NotImplementedError: _description_

dim
1128    @property
1129    def dim(self):
1130        if self.points_list:
1131            return self.points_list[0].dim
1132        else:
1133            return None
def get_vector( self, index: int) -> VectorNd:
1170    def get_vector(self, index: int) -> VectorNd:
1171        if 0 <= index < (len(self) - 1):
1172            return VectorNd(self[index], self[index + 1])
1173        else:
1174            raise IndexError
def get_vector_reversed( self, index: int) -> VectorNd:
1176    def get_vector_reversed(self, index: int) -> VectorNd:
1177        if 1 <= index < len(self):
1178            return VectorNd(self[index], self[index - 1])
1179        else:
1180            raise IndexError