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, 'CoordinateVectorNd']): _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, 'CoordinateVectorNd']): _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, 'CoordinateVectorNd']): _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, 'CoordinateVectorNd']): _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
Inappropriate argument value (of correct type).
Inherited Members
- builtins.ValueError
- ValueError
- builtins.BaseException
- with_traceback
- args
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
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_
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_
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_
Inappropriate argument value (of correct type).
Inherited Members
- builtins.ValueError
- ValueError
- builtins.BaseException
- with_traceback
- args
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, 'CoordinateVectorNd']): _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, 'CoordinateVectorNd']): _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, 'CoordinateVectorNd']): _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, 'CoordinateVectorNd']): _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 # Направление слева-направо: слева нулевой индекс, а справа - максимальный индекс)
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_
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_
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_
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
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_
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_
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_
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()
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()
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()
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()
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()
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
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)
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_
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_
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_