2392 | | |
2393 | | |
2394 | | class EnhancedCone(Cone_of_fan): |
2395 | | r""" |
2396 | | Construct an enhanced cone. |
2397 | | |
2398 | | Enhanced cones are similar to "regular" :class:`convex rational polyhedral |
2399 | | cones <sage.geometry.cone.ConvexRationalPolyhedralCone>` or, more |
2400 | | precisely, to :class:`cones of fans <Cone_of_fan>`, but may have some |
2401 | | extra functionality. :class:`EnhancedCone` class by itself does not |
2402 | | provide any of such extra functionality, but in conjunction with |
2403 | | :class:`EnhancedFan` allows convenient derivation of new classes and |
2404 | | ensures CPU- and memory-efficient interaction between regular cones and |
2405 | | their enhanced copies. |
2406 | | |
2407 | | INPUT: |
2408 | | |
2409 | | - ``cone`` -- :class:`Cone_of_fan`; |
2410 | | |
2411 | | - ``ambient`` -- ambient fan of this cone. If not given, will be the same |
2412 | | as for ``cone``; |
2413 | | |
2414 | | OR (these parameters must be given as keywords): |
2415 | | |
2416 | | - ``ambient`` -- ambient fan of this cone; |
2417 | | |
2418 | | - ``ambient_ray_indices`` -- increasing list or tuple of integers, indices |
2419 | | of rays of ``ambient`` generating this cone. |
2420 | | |
2421 | | OUTPUT: |
2422 | | |
2423 | | - enhanced cone of exactly the same structure as ``cone``. |
2424 | | |
2425 | | EXAMPLES:: |
2426 | | |
2427 | | sage: from sage.geometry.fan import EnhancedCone |
2428 | | sage: fan = FaceFan(lattice_polytope.octahedron(2)) |
2429 | | sage: econe = EnhancedCone(fan.generating_cone(0)) |
2430 | | sage: econe == fan.generating_cone(0) |
2431 | | True |
2432 | | sage: econe is fan.generating_cone(0) |
2433 | | False |
2434 | | """ |
2435 | | |
2436 | | def __init__(self, cone=None, ambient=None, ambient_ray_indices=None): |
2437 | | r""" |
2438 | | See :class:`EnhancedCone` for documentation. |
2439 | | |
2440 | | TESTS:: |
2441 | | |
2442 | | sage: from sage.geometry.fan import EnhancedCone |
2443 | | sage: fan = FaceFan(lattice_polytope.octahedron(2)) |
2444 | | sage: econe = EnhancedCone(fan.generating_cone(0)) |
2445 | | sage: econe == fan.generating_cone(0) |
2446 | | True |
2447 | | sage: econe is fan.generating_cone(0) |
2448 | | False |
2449 | | sage: TestSuite(econe).run() |
2450 | | """ |
2451 | | if cone is None: |
2452 | | # Then both other attributes must be given and we can make cone |
2453 | | # We try to keep "the level of enhancement" the same for all cones |
2454 | | # of the same ambient |
2455 | | base = ambient._base_fan if is_EnhancedFan(ambient) else ambient |
2456 | | if is_EnhancedFan(base): |
2457 | | cone_type = base._cone_type |
2458 | | elif is_Fan(base): |
2459 | | cone_type = Cone_of_fan |
2460 | | else: |
2461 | | cone_type = ConvexRationalPolyhedralCone |
2462 | | cone = cone_type(ambient=base, |
2463 | | ambient_ray_indices=ambient_ray_indices) |
2464 | | for attribute in [# Cone attributes |
2465 | | "_rays", |
2466 | | "_lattice", |
2467 | | # _ambient will be set later |
2468 | | "_ambient_ray_indices", |
2469 | | # Cached attributes copied for efficiency |
2470 | | "_is_strictly_convex"]: |
2471 | | setattr(self, attribute, getattr(cone, attribute)) |
2472 | | self._ambient = ambient if ambient is not None else cone.ambient() |
2473 | | |
2474 | | |
2475 | | def is_EnhancedCone(x): |
2476 | | r""" |
2477 | | Check if ``x`` is an enhanced cone. |
2478 | | |
2479 | | INPUT: |
2480 | | |
2481 | | - ``x`` -- anything. |
2482 | | |
2483 | | OUTPUT: |
2484 | | |
2485 | | - ``True`` if ``x`` is an enhanced cone and ``False`` otherwise. |
2486 | | |
2487 | | EXAMPLES:: |
2488 | | |
2489 | | sage: from sage.geometry.fan import ( |
2490 | | ... EnhancedCone, is_EnhancedCone) |
2491 | | sage: is_EnhancedCone(1) |
2492 | | False |
2493 | | sage: cone = Cone([(1,0), (0,1)]) |
2494 | | sage: is_EnhancedCone(cone) |
2495 | | False |
2496 | | sage: fan = FaceFan(lattice_polytope.octahedron(2)) |
2497 | | sage: econe = EnhancedCone(fan.generating_cone(0)) |
2498 | | sage: is_EnhancedCone(econe) |
2499 | | True |
2500 | | """ |
2501 | | return isinstance(x, EnhancedCone) |
2502 | | |
2503 | | |
2504 | | class EnhancedFan(RationalPolyhedralFan): |
2505 | | r""" |
2506 | | Construct an enhanced fan. |
2507 | | |
2508 | | Enhanced fans are similar to "regular" :class:`rational polyhedral fans |
2509 | | <RationalPolyhedralFan>`, but may have some extra functionality on the |
2510 | | levels of fans themselves as well as their cones. :class:`EnhancedFan` |
2511 | | class by itself does not provide any extra functionality, but allows |
2512 | | convenient derivation of new classes and ensures CPU- and memory-efficient |
2513 | | interaction between regular fans and their enhanced copies. |
2514 | | |
2515 | | INPUT: |
2516 | | |
2517 | | - ``fan`` -- :class:`rational polyhedral fan <RationalPolyhedralFan>`; |
2518 | | |
2519 | | - ``cone_type`` -- class derived from :class:`EnhancedCone`. |
2520 | | |
2521 | | OUTPUT: |
2522 | | |
2523 | | - enhanced fan of exactly the same structure as ``fan``, but all of its |
2524 | | associated cones are objects of ``cone_type``. |
2525 | | |
2526 | | EXAMPLES:: |
2527 | | |
2528 | | sage: from sage.geometry.fan import ( |
2529 | | ... EnhancedCone, EnhancedFan, is_EnhancedCone) |
2530 | | sage: fan = FaceFan(lattice_polytope.octahedron(2)) |
2531 | | sage: efan = EnhancedFan(fan, EnhancedCone) |
2532 | | sage: is_EnhancedCone(efan.generating_cone(0)) |
2533 | | True |
2534 | | """ |
2535 | | |
2536 | | def __init__(self, fan, cone_type): |
2537 | | r""" |
2538 | | See :class:`EnhancedFan` for documentation. |
2539 | | |
2540 | | TESTS:: |
2541 | | |
2542 | | sage: from sage.geometry.fan import ( |
2543 | | ... EnhancedCone, EnhancedFan, is_EnhancedCone) |
2544 | | sage: fan = FaceFan(lattice_polytope.octahedron(2)) |
2545 | | sage: efan = EnhancedFan(fan, EnhancedCone) |
2546 | | sage: is_EnhancedCone(efan.generating_cone(0)) |
2547 | | True |
2548 | | sage: TestSuite(efan).run() |
2549 | | """ |
2550 | | for attribute in [# Fan attributes |
2551 | | "_rays", |
2552 | | "_lattice"]: |
2553 | | setattr(self, attribute, getattr(fan, attribute)) |
2554 | | self._base_fan = fan |
2555 | | self._cone_type = cone_type |
2556 | | self._generating_cones = tuple(cone_type(cone, self) for cone in fan) |
2557 | | |
2558 | | def _compute_cone_lattice(self): |
2559 | | r""" |
2560 | | Compute the cone lattice of ``self``. |
2561 | | |
2562 | | See :meth:`~RationalPolyhedralFan.cone_lattice` for documentation. |
2563 | | |
2564 | | TESTS:: |
2565 | | |
2566 | | sage: from sage.geometry.fan import ( |
2567 | | ... EnhancedCone, EnhancedFan, is_EnhancedCone) |
2568 | | sage: fan = FaceFan(lattice_polytope.octahedron(2)) |
2569 | | sage: efan = EnhancedFan(fan, EnhancedCone) |
2570 | | sage: L = efan.cone_lattice() # indirect doctest |
2571 | | sage: L |
2572 | | Finite poset containing 10 elements |
2573 | | sage: is_EnhancedCone(L[0].element) |
2574 | | True |
2575 | | """ |
2576 | | # Actual computation of the lattice is done in the "usual" fan |
2577 | | L = self._base_fan.cone_lattice() |
2578 | | # We just copy its structure using the appropriate class for cones |
2579 | | elements = [] |
2580 | | for element in L: |
2581 | | cone = element.element |
2582 | | if is_Cone(cone): |
2583 | | elements.append(self._cone_type(cone, ambient=self)) |
2584 | | else: |
2585 | | # The last element is the fan itself |
2586 | | elements.append(self) |
2587 | | self._cone_lattice = FinitePoset(L, elements) |
2588 | | |
2589 | | |
2590 | | def is_EnhancedFan(x): |
2591 | | r""" |
2592 | | Check if ``x`` is an enhanced fan. |
2593 | | |
2594 | | INPUT: |
2595 | | |
2596 | | - ``x`` -- anything. |
2597 | | |
2598 | | OUTPUT: |
2599 | | |
2600 | | - ``True`` if ``x`` is an enhanced fan and ``False`` otherwise. |
2601 | | |
2602 | | EXAMPLES:: |
2603 | | |
2604 | | sage: from sage.geometry.fan import ( |
2605 | | ... EnhancedCone, EnhancedFan, is_EnhancedFan) |
2606 | | sage: is_EnhancedFan(1) |
2607 | | False |
2608 | | sage: fan = FaceFan(lattice_polytope.octahedron(2)) |
2609 | | sage: is_EnhancedFan(fan) |
2610 | | False |
2611 | | sage: efan = EnhancedFan(fan, EnhancedCone) |
2612 | | sage: is_EnhancedFan(efan) |
2613 | | True |
2614 | | """ |
2615 | | return isinstance(x, EnhancedFan) |