Matroids Matheplanet Forum Index
Moderiert von mire2
Mathematische Software & Apps » Matlab » Arrayindices als Array angeben
Autor
Universität/Hochschule J Arrayindices als Array angeben
Greyfox
Ehemals Aktiv Letzter Besuch: vor mehr als 3 Monaten
Dabei seit: 12.08.2003
Mitteilungen: 319
Wohnort: Berlin
  Themenstart: 2019-08-15

Hallo allerseits, ich möchte ein paar langsame for-Schleifen vermeiden und brauche einen guten Tipp: In Dimension 1 ist für mich alles gut: Sei A=[2 3 2 3 1] und B=[0.3 0.2 0.1] dann ist B(A)=[0.2 0.1 0.2 0.1 0.3] Ich kann also die Werte von A als Indices nutzen um quasi an diesen Stellen bei B nachzuschauen. (Falls die Werte von A dafür geeignet sind.) NUN DAS PROBLEM Ich möchte dies viermal tun, ohne Schleifen zu verwenden. Sei also A vom Typ 2 x 2 x 5, z.B. A(1,1,:)=[1 1 1 1 1] A(1,2,:)=[1 1 1 1 1] A(2,1,:)=[2 3 2 3 1] A(2,2,:)=[3 3 3 1 1] und B(1,1,:)=[0.1 0.2 0.3] B(1,2,:)=[-0.1 -0.2 -0.3] B(2,1,:)=[0.1 0.2 0.3] B(2,2,:)=[-0.1 -0.2 -0.3] Dann würde ich mir wünschen, dass C=B(A) das Ergebnis C(1,1,:)=[0.1 0.1 0.1 0.1 0.1] C(1,2,:)=[-0.1 -0.1 -0.1 -0.1 -0.1] C(2,1,:)=[0.2 0.3 0.2 0.3 0.1] C(2,2,:)=[-0.3 -0.3 -0.3 -0.1 -0.1] wäre. Ich würde mir also wünschen, dass C(s,t,u)=B(s,t,A(s,t)) wäre. Ist es aber nich. Stattdessen kommt C(1,1,:)=[0.1 0.1 0.1 0.1 0.1] C(1,2,:)=[0.1 0.1 0.1 0.1 0.1] C(2,1,:)=[0.1 -0.1 0.1 -0.1 0.1] C(1,1,:)=[-0.1 -0.1 -0.1 0.1 0.1] raus. Statt C(s,t,u)=B(s,t,A(s,t)) ist also C(s,t,u)=B(A(s,t,u)), wobei B linear durchgezählt wird. Leider muss ich zugeben, dass das ja durchaus auch Sinn macht. Wie aber bekomme ich das Array C, so wie ich es mir wünsche? Beste Grüße Greyfox


   Profil
hyperG
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 03.02.2017
Mitteilungen: 2162
  Beitrag No.1, eingetragen 2019-08-15

Zunächst bitte sauberen Syntax verwenden, damit alles logisch bleibt: \sourceon Script Nicht B(A) sondern B(A(i)) \sourceoff i sei der horizontale Index (immer von links nach rechts). Dann würde ich jeden Index immer bei 0 beginnen, da sonst "Speicherplatz" verschenkt & Geschwindigkeit verloren geht. Die Erweiterung um 2 Dimensionen macht die ganze Sache langsamer & unübersichtlicher! Es sind eigentlich 2 Dimensionen: A(x,i) mit x=0...3 und i= 0...4 \sourceon Script A(0,i)=[1 1 1 1 1] A(1,i)=[1 1 1 1 1] A(2,i)=[2 3 2 3 1] A(3,i)=[3 3 3 1 1] \sourceoff B analog. Wenn Du unbedingt bei Deinen 3 Dimensionen A3 und dem verschobenen 1-Index bleiben willst, geht das mit dem Bezug zum 2D-Array: \sourceon Script A3(floor(x/2)+1,mod(x,2)+1, i+1) = A2(x,i) \sourceoff Nun ist alles viel einfacher: x entspricht der Zeile 0...3; i sind die 5 Werte pro Zeile, die vertauscht werden sollen \sourceon Script C(x,i) = B(x,A(x,i)) \sourceoff A ist das "Vertauscher-Array", was nur Werte von 0...2 beinhaltet, da das "Real-Array B" nur 3 Werte pro Zeile enthält.


   Profil
Greyfox
Ehemals Aktiv Letzter Besuch: vor mehr als 3 Monaten
Dabei seit: 12.08.2003
Mitteilungen: 319
Wohnort: Berlin
  Beitrag No.2, vom Themenstarter, eingetragen 2019-08-15

Hallo hyper G, ich glaube, wir reden noch leicht aneinander vorbei. Bei manchen Dingen kann ich Dir folgen, bei manchen nicht. Für das bessere Verständnis können wir die Dimension reduzieren. Keine Ahnung ob der Code dadurch viel schneller wird. Mein Skript könnte also so starten: \sourceon Script clear all; %declare A A(1,:)=[1 1 1 1 1]; A(2,:)=[1 1 1 1 1]; A(3,:)=[2 3 2 3 1]; A(4,:)=[3 3 3 1 1]; %declare B B(1,:)=[0.1 0.2 0.3]; B(2,:)=[-0.1 -0.2 -0.3]; B(3,:)=[0.1 0.2 0.3]; B(4,:)=[-0.1 -0.2 -0.3]; \sourceoff Ich bin mir nicht ganz sicher, was Du damit meinst, dass die Indizes von 0 starten sollen, denn ich dachte immer Matlab akzeptiert nur positive Indices. ("Subscript indices must either be real positive integers or logicals.") Tatsächlich würde ich das gewünschte Ergebnis erhalten wenn ich mein Skript wie folgt fortsetzen würde: \sourceon Script for x=1:4 for i=1:5 C(x,i)=B(x,A(x,i)); end end \sourceoff Ich möchte aber die for-schleifen vermeiden, weil die aus meiner Sicht sehr langsam sind und die Vorteile der GPU töten. Ich kann mir vorstellen, dass arrayfun oder pagefun mir helfen könnten mit einer Funktion wie z.B. \sourceon Script FUN=@(x,y)(y(x)); \sourceoff aber da kämpfe ich noch mit der Syntax um das Ziel zu erreichen.


   Profil
Greyfox
Ehemals Aktiv Letzter Besuch: vor mehr als 3 Monaten
Dabei seit: 12.08.2003
Mitteilungen: 319
Wohnort: Berlin
  Beitrag No.3, vom Themenstarter, eingetragen 2019-08-15

Okay ich habe mich doof angestellt. Hier meine Lösung mit der ich leben kann: \sourceon Script clear all; %declare A A(1,1,:)=[1 1 1 1 1]; A(1,2,:)=[1 1 1 1 1]; A(2,1,:)=[2 3 2 3 1]; A(2,2,:)=[3 3 3 1 1]; %declare B B(1,1,:)=[0.1 0.2 0.3]; B(1,2,:)=[-0.1 -0.2 -0.3]; B(2,1,:)=[0.1 0.2 0.3]; B(2,2,:)=[-0.1 -0.2 -0.3]; %declare Array for Row-number Row=repmat((1:2)',1,2,5); %declare Array for Column-number Col=repmat((1:2),2,1,5); %declare lookup-Function Fun=@(i,j,k)(B(i,j,k)); %Compute C C=arrayfun(Fun,Row,Col,A); \sourceoff Besten Dank für den Input. ------------------------------------------------------------------- Edit: ... dachte ich. Aber für GPU-arrays funktioniert das nicht, denn Fun ist zu komplex. Deshalb noch ein Workaround: \sourceon Script clear all; %declare A A(1,1,:)=[1 1 1 1 1]; A(1,2,:)=[1 1 1 1 1]; A(2,1,:)=[2 3 2 3 1]; A(2,2,:)=[3 3 3 1 1]; %declare B B(1,1,:)=[0.1 0.2 0.3]; B(1,2,:)=[-0.1 -0.2 -0.3]; B(2,1,:)=[0.1 0.2 0.3]; B(2,2,:)=[-0.1 -0.2 -0.3]; %declare Array for Row-number Row=repmat((1:2)',1,2,5); %declare Array for Column-number Col=repmat((1:2),2,1,5); %Make everything GPU-just to show that it works on GPU A=gpuArray(A); B=gpuArray(B); Col=gpuArray(Col); Row=gpuArray(Row); %Declare a funktion that is basicly sub2ind([2,2,5],i,j,k) %f=@(i,j,k)(sub2ind([2,2,5],i,j,k)); does not work on GPU f=@(i,j,k)(i+(j-1)*2+(k-1)*2*2); %Create an array of the corrected Indices: M=arrayfun(f,Row,Col,A); %Harvest the fruits C=B(M); \sourceoff


   Profil
Greyfox hat die Antworten auf ihre/seine Frage gesehen.
Greyfox hat selbst das Ok-Häkchen gesetzt.
Greyfox wird per Mail über neue Antworten informiert.

Wechsel in ein anderes Forum:
 Suchen    
 
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2001-2023 by Matroids Matheplanet
This web site was originally made with PHP-Nuke, a former web portal system written in PHP that seems no longer to be maintained nor supported. PHP-Nuke is Free Software released under the GNU/GPL license.
Ich distanziere mich von rechtswidrigen oder anstößigen Inhalten, die sich trotz aufmerksamer Prüfung hinter hier verwendeten Links verbergen mögen.
Lesen Sie die Nutzungsbedingungen, die Distanzierung, die Datenschutzerklärung und das Impressum.
[Seitenanfang]