Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Pakiet System.Numerics.Tensors udostępnia Tensor<T>, TensorSpan<T> i ReadOnlyTensorSpan<T> dla danych wielowymiarowych. Kształty tensorów opisują wymiary logiczne; kroki opisują odległość, w elementach, między kolejnymi pozycjami wzdłuż każdego wymiaru.
Opisane tutaj zachowanie jest zawarte w pakiecie we wszystkich obsługiwanych platformach docelowych. Aktualizowanie pakietu może mieć wpływ na aplikacje przeznaczone dla wcześniejszych .NET wersji.
Te typy mają wiele wspólnych konwencji z NumPy, ale nie są one wymienne. Uwzględnij następujące różnice podczas przenoszenia algorytmu.
Puste kształty i wyniki podobne do skalarnych
Podczas tworzenia tensoru na podstawie pustego kształtu ([]) bez danych bazowych tensor ma kształt [0] i nie ma żadnych elementów. W NumPy kształt () ma rangę zero i zawiera jeden element skalarny. W szczególności np.empty(()) przydziela skalar z niezainicjowaną wartością; „empty” nie oznacza, że nie ma żadnych elementów.
Natomiast w przypadku pominięcia długości z konstruktora tensor-span na istniejących danych konstruktor wywnioskuje kształt jednowymiarowy z podanej tablicy lub zakresu.
Gdy ściśniesz tensor z kształtem [1, 1], wynik ma kształt [1], a nie kształt rangi zero biblioteki NumPy (). Oba wyniki zawierają jeden element i mogą być rozgłaszane jako skalar, ale kod, który sprawdza liczbę wymiarów, wybiera osie lub indeksuje wynik, musi uwzględniać zachowany wymiar.
Po pominięciu kroków każdy kształt, który zawiera wymiar o zerowej długości, ma zerowe kroki w każdym wymiarze. Jego liczba elementów i wymagana pamięć są zerowe, niezależnie od innych długości wymiarów. Długości ujemne pozostają nieprawidłowe. Jawne wartości stride muszą nadal spełniać walidację układu.
Skoki i odwrócone dane
Skoki muszą być nieujemne. Biblioteka NumPy może reprezentować odwrócony widok z negatywnym krokiem, na przykład array[::-1].
Aby odwrócić pierwszą oś, wywołaj metodę Tensor.ReverseDimension dla wymiaru 0:
using System.Numerics.Tensors;
Tensor<int> source = Tensor.Create(new[] { 1, 2, 3, 4 }, new nint[] { 2, 2 });
Tensor<int> reversed = Tensor.ReverseDimension<int>(source.AsReadOnlyTensorSpan(), 0);
Logicznymi elementami reversed są [3, 4, 1, 2]. Przeciążenie alokujące generuje nowy tensor; nie jest to widok o ujemnym kroku w oryginalnym magazynie.
Zmień rozmiar tensora
Tensor.Resize i Tensor.ResizeTo wypełnij dodane elementy logiczne za pomocą polecenia default(T). Jeśli na przykład zwiększysz liczbę elementów [1, 2] do pięciu int, wynik zawiera [1, 2, 0, 0, 0]. Zamiast tego np.resize NumPy powtarza dane wejściowe i generuje wartość [1, 2, 1, 2, 1].
Jeśli miejsce docelowe jest mniejsze, operacja odrzuca elementy po logicznej liczbie elementów miejsca docelowego. Jeśli jest większy, operacja inicjuje pozostałe logiczne elementy docelowe nawet wtedy, gdy miejsce docelowe zawiera luki między elementami. Pamięć masowa poza logicznym miejscem docelowym nie jest częścią operacji zmiany rozmiaru.
Tensor.ResizeTo i łączenie z istniejącym miejscem docelowym odrzuca wymiar o zerowym kroku, który zawiera więcej niż jeden element logiczny. Taki wymiar powoduje, że wiele pozycji wyjściowych odwołuje się do tej samej pamięci i nie może przechowywać unikatowych wartości wyjściowych. Zerowe kroki w wymiarach singletonowych i puste miejsca docelowe nie tworzą tego konfliktu.
Nakładające się źródła i miejsca docelowe
Oddzielne obiekty tensorowe i zakresy mogą odwoływać się do nakładających się regionów tej samej tablicy. Obsługiwane przypadki zależą od operacji i układu:
| Działanie | Obsługiwane nakładanie |
|---|---|
CopyTo i TryCopyTo |
Zagęszczone źródło i miejsce docelowe z taką samą liczbą elementów lub dokładnie identycznymi widokami. Gęste kopie używają kopiowania zakresów bezpiecznego przy nakładaniu. |
FlattenTo i TryFlattenTo |
Zwarte źródło i rozpiętość docelowa. |
| Operacje elementowe z miejscem przeznaczenia | Dane wejściowe i wyjściowe z tym samym odwołaniem początkowym, długościami i krokami, pod warunkiem, że widok nie ma powtarzających się logicznych lokalizacji pamięci. Każde wejście jest sprawdzane niezależnie. |
Tensor.ResizeTo |
Zagęszczone źródło i cel. Nieobsługiwane nakładanie z krokiem jest odrzucane. |
| Odwrócenie w tym samym widoku | Gęsty widok można odwrócić na miejscu. Obsługiwane są również odwrócenia typu no-op. |
Inne nieobsługiwane układy nakładające się powodują wystąpienie ArgumentException, zanim operacja zapisze dane wyjściowe. Sam gęsty tensor nie gwarantuje obsługi każdej operacji: na przykład przesunięte gęste miejsce docelowe jest obsługiwane dla kopii, ale nie dla operacji elementowej.
Metody TryCopyTo i TryFlattenTo zwracają false bez kopiowania, gdy miejsce docelowe jest zbyt krótkie.
TryCopyTo zwraca false również dla niezgodnych kształtów źródłowych i docelowych. W przypadku zgodnych kształtów z wystarczającą pojemnością docelową te metody mogą nadal zgłaszać wyjątek z powodu nieobsługiwanego nakładania się; Try nie tłumi wyjątków związanych z nieprawidłowym układem.
Na przykład następujące źródło skokowe i gęsty bufor docelowy nakładają się na siebie:
int[] storage = { 1, 2, 3, 4, 5, 6 };
ReadOnlyTensorSpan<int> source = new(storage, new nint[] { 2, 2 }, new nint[] { 3, 1 });
TensorSpan<int> destination = new(storage, new nint[] { 2, 2 });
Aby skopiować z tego nieobsługiwanego nakładającego się układu, najpierw utwórz migawkę w niezależnej pamięci:
int[] snapshot = new int[checked((int)source.FlattenedLength)];
source.FlattenTo(snapshot);
ReadOnlyTensorSpan<int> independentSource = new(snapshot, source.Lengths);
independentSource.CopyTo(destination);
Migawka zawiera element [1, 2, 4, 5]. Kopia zapisuje te elementy w miejscu docelowym bez zmiany oryginalnych wartości przed ich odczytaniem.
W przypadku operacji elementowej przyjmującej tensor docelowy należy przydzielić oddzielny tensor wyniku lub migawkę każdego nakładającego się tensora wejściowego przed zapisaniem danych wyjściowych. W przypadku docelowego obiektu rozsyłania z powtarzającymi się lokalizacjami przechowywania należy zamiast tego użyć niezależnego magazynu danych wyjściowych; migawka wejściowa nie sprawia, że ten obiekt docelowy może przechowywać odrębne wartości.
Biblioteka nie przydziela niejawnie migawki pełnego tensora, aby obsługiwać dowolne nakładające się układy. Nienakładające się kopie skokowe nie wymagają tej pamięci tymczasowej.