@@ -450,7 +450,7 @@ public int GetOffset(params int[] indices)
450
450
}
451
451
452
452
var orig_strides = vi . OriginalShape . strides ;
453
- var orig_dims = vi . OriginalShape . dimensions ;
453
+ // var orig_dims = vi.OriginalShape.dimensions;
454
454
offset = 0 ;
455
455
unchecked
456
456
{
@@ -485,6 +485,104 @@ public int GetOffset(params int[] indices)
485
485
return vi . ParentShape . GetOffset ( parent_coords1 ) ;
486
486
}
487
487
488
+ /// <summary>
489
+ /// Get offset index out of coordinate indices.
490
+ /// </summary>
491
+ /// <param name="index">The coordinates to turn into linear offset</param>
492
+ /// <returns>The index in the memory block that refers to a specific value.</returns>
493
+ /// <remarks>Handles sliced indices and broadcasting</remarks>
494
+ [ MethodImpl ( ( MethodImplOptions ) 768 ) ]
495
+ internal int GetOffset_1D ( int index )
496
+ {
497
+ int offset ;
498
+ if ( ! IsSliced )
499
+ {
500
+ if ( dimensions . Length == 0 )
501
+ return index ;
502
+
503
+ offset = 0 ;
504
+ unchecked
505
+ {
506
+ offset += strides [ 0 ] * index ;
507
+ }
508
+
509
+ if ( IsBroadcasted )
510
+ return offset % BroadcastInfo . OriginalShape . size ;
511
+
512
+ return offset ;
513
+ }
514
+
515
+ //if both sliced and broadcasted
516
+ if ( IsBroadcasted )
517
+ return GetOffset_broadcasted_1D ( index ) ;
518
+
519
+ // we are dealing with a slice
520
+
521
+ var vi = ViewInfo ;
522
+ if ( IsRecursive && vi . Slices == null )
523
+ {
524
+ // we are dealing with an unsliced recursively reshaped slice
525
+ offset = GetOffset_IgnoreViewInfo ( index ) ;
526
+ var parent_coords = vi . ParentShape . GetCoordinates ( offset , ignore_view_info : true ) ;
527
+ return vi . ParentShape . GetOffset ( parent_coords ) ;
528
+ }
529
+
530
+ var coords = new List < int > ( 1 ) { index } ;
531
+ if ( vi . UnreducedShape . IsScalar && index == 0 && ! IsRecursive )
532
+ return 0 ;
533
+ if ( 1 > vi . UnreducedShape . dimensions . Length )
534
+ throw new ArgumentOutOfRangeException ( nameof ( index ) , $ "select has too many coordinates for this shape") ;
535
+ var orig_ndim = vi . OriginalShape . NDim ;
536
+ if ( orig_ndim > NDim && orig_ndim > 1 )
537
+ {
538
+ // fill in reduced dimensions in the provided coordinates
539
+ for ( int i = 0 ; i < vi . OriginalShape . NDim ; i ++ )
540
+ {
541
+ var slice = ViewInfo . Slices [ i ] ;
542
+ if ( slice . IsIndex )
543
+ coords . Insert ( i , 0 ) ;
544
+ if ( coords . Count == orig_ndim )
545
+ break ;
546
+ }
547
+ }
548
+
549
+ var orig_strides = vi . OriginalShape . strides ;
550
+ //var orig_dims = vi.OriginalShape.dimensions;
551
+ offset = 0 ;
552
+ unchecked
553
+ {
554
+ for ( int i = 0 ; i < coords . Count ; i ++ )
555
+ {
556
+ // note: we can refrain from bounds checking here, because we should not allow negative indices at all, this should be checked higher up though.
557
+ //var coord = coords[i];
558
+ //var dim = orig_dims[i];
559
+ //if (coord < -dim || coord >= dim)
560
+ // throw new ArgumentException($"index {coord} is out of bounds for axis {i} with a size of {dim}");
561
+ //if (coord < 0)
562
+ // coord = dim + coord;
563
+ if ( vi . Slices . Length <= i )
564
+ {
565
+ offset += orig_strides [ i ] * coords [ i ] ;
566
+ continue ;
567
+ }
568
+
569
+ var slice = vi . Slices [ i ] ;
570
+ var start = slice . Start ;
571
+ if ( slice . IsIndex )
572
+ offset += orig_strides [ i ] * start ; // the coord is irrelevant for index-slices (they are reduced dimensions)
573
+ else
574
+ offset += orig_strides [ i ] * ( start + coords [ i ] * slice . Step ) ;
575
+ }
576
+ }
577
+
578
+ if ( ! IsRecursive )
579
+ return offset ;
580
+ // we are dealing with a sliced recursively reshaped slice
581
+ var parent_coords1 = vi . ParentShape . GetCoordinates ( offset , ignore_view_info : true ) ;
582
+ return vi . ParentShape . GetOffset ( parent_coords1 ) ;
583
+ }
584
+
585
+
488
586
/// <summary>
489
587
/// Calculate the offset in an unsliced shape. If the shape is sliced, ignore the ViewInfo
490
588
/// Note: to be used only inside of GetOffset()
@@ -606,6 +704,104 @@ private int GetOffset_broadcasted(params int[] indices)
606
704
return vi . ParentShape . GetOffset ( parent_coords1 ) ;
607
705
}
608
706
707
+ /// <summary>
708
+ /// Get offset index out of coordinate indices.
709
+ /// </summary>
710
+ /// <param name="index">The coordinates to turn into linear offset</param>
711
+ /// <returns>The index in the memory block that refers to a specific value.</returns>
712
+ /// <remarks>Handles sliced indices and broadcasting</remarks>
713
+ [ MethodImpl ( ( MethodImplOptions ) 768 ) ]
714
+ private int GetOffset_broadcasted_1D ( int index )
715
+ {
716
+ int offset ;
717
+ var vi = ViewInfo ;
718
+ var bi = BroadcastInfo ;
719
+ if ( IsRecursive && vi . Slices == null )
720
+ {
721
+ // we are dealing with an unsliced recursively reshaped slice
722
+ offset = GetOffset_IgnoreViewInfo ( index ) ;
723
+ var parent_coords = vi . ParentShape . GetCoordinates ( offset , ignore_view_info : true ) ;
724
+ return vi . ParentShape . GetOffset ( parent_coords ) ;
725
+ }
726
+
727
+ var coords = new List < int > ( 1 ) { index } ;
728
+ if ( vi . UnreducedShape . IsScalar && index == 0 && ! IsRecursive )
729
+ return 0 ;
730
+ if ( 1 > vi . UnreducedShape . dimensions . Length )
731
+ throw new ArgumentOutOfRangeException ( nameof ( index ) , $ "select has too many coordinates for this shape") ;
732
+ var orig_ndim = vi . OriginalShape . NDim ;
733
+ if ( orig_ndim > NDim && orig_ndim > 1 )
734
+ {
735
+ // fill in reduced dimensions in the provided coordinates
736
+ for ( int i = 0 ; i < vi . OriginalShape . NDim ; i ++ )
737
+ {
738
+ var slice = ViewInfo . Slices [ i ] ;
739
+ if ( slice . IsIndex )
740
+ coords . Insert ( i , 0 ) ;
741
+ if ( coords . Count == orig_ndim )
742
+ break ;
743
+ }
744
+ }
745
+
746
+ var orig_strides = vi . OriginalShape . strides ;
747
+ Shape unreducedBroadcasted ;
748
+ if ( ! bi . UnbroadcastShape . HasValue )
749
+ {
750
+ if ( bi . OriginalShape . IsScalar )
751
+ {
752
+ unreducedBroadcasted = vi . OriginalShape . Clone ( true , false , false ) ;
753
+ for ( int i = 0 ; i < unreducedBroadcasted . NDim ; i ++ )
754
+ {
755
+ unreducedBroadcasted . dimensions [ i ] = 1 ;
756
+ unreducedBroadcasted . strides [ i ] = 0 ;
757
+ }
758
+ }
759
+ else
760
+ {
761
+ unreducedBroadcasted = vi . OriginalShape . Clone ( true , false , false ) ;
762
+ for ( int i = Math . Abs ( vi . OriginalShape . NDim - NDim ) , j = 0 ; i < unreducedBroadcasted . NDim ; i ++ , j ++ )
763
+ {
764
+ if ( strides [ j ] == 0 )
765
+ {
766
+ unreducedBroadcasted . dimensions [ i ] = 1 ;
767
+ unreducedBroadcasted . strides [ i ] = 0 ;
768
+ }
769
+ }
770
+ }
771
+
772
+ bi . UnbroadcastShape = unreducedBroadcasted ;
773
+ }
774
+ else
775
+ unreducedBroadcasted = bi . UnbroadcastShape . Value ;
776
+
777
+ orig_strides = unreducedBroadcasted . strides ;
778
+ offset = 0 ;
779
+ unchecked
780
+ {
781
+ for ( int i = 0 ; i < coords . Count ; i ++ )
782
+ {
783
+ if ( vi . Slices . Length <= i )
784
+ {
785
+ offset += orig_strides [ i ] * coords [ i ] ;
786
+ continue ;
787
+ }
788
+
789
+ var slice = vi . Slices [ i ] ;
790
+ var start = slice . Start ;
791
+ if ( slice . IsIndex )
792
+ offset += orig_strides [ i ] * start ; // the coord is irrelevant for index-slices (they are reduced dimensions)
793
+ else
794
+ offset += orig_strides [ i ] * ( start + coords [ i ] * slice . Step ) ;
795
+ }
796
+ }
797
+
798
+ if ( ! IsRecursive )
799
+ return offset ;
800
+ // we are dealing with a sliced recursively reshaped slice
801
+ var parent_coords1 = vi . ParentShape . GetCoordinates ( offset , ignore_view_info : true ) ;
802
+ return vi . ParentShape . GetOffset ( parent_coords1 ) ;
803
+ }
804
+
609
805
610
806
/// <summary>
611
807
/// Gets the shape based on given <see cref="indicies"/> and the index offset (C-Contiguous) inside the current storage.
0 commit comments