WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Vektorieller Ausdruck für Zuweisung von Ebene in 3D-Matrix?

 

randfee2
Forum-Anfänger

Forum-Anfänger


Beiträge: 16
Anmeldedatum: 21.05.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.12.2012, 07:08     Titel: Vektorieller Ausdruck für Zuweisung von Ebene in 3D-Matrix?
  Antworten mit Zitat      
Hallo,

ich würde gerne eine for-Schleife umgehen, mir fehlt aber die Kenntnis, wie ich das in diesem Fallen machen kann:

Kurzbeschreibung:
Ich habe eine heightmap (n x n) und will mir eine 3D Matrix generieren in der alle Einträge "unter" dem surface-plot dieser heightmap was zugewiesen bekommen. Anders: Ich würde gerne alle "Voxel" V(i,j,k) mit k< Z(i,j) mit einem Wert versehen. Wie mache ich das elegant?
Bei einer Matrix ist's ja kein Problem mit der Zuweisung:
Code:
V(V<Z-k)=x

Mir fehlt quasi eine Möglichkeit der Beschränkung auf eine Ebene von V. So geht's jedenfalls nicht.
Code:

for i=k:dimension;
           
    V((V(:,:,k)<Z-k) = n_si
           
end


Das muss doch schöner gehen als mit einer Hand voller for-Schleifen?! Wahlweise wäre mir auch eine ganz andere Funktion, die das leistet, völlig recht!

Beispiel: surf(Z) ergibt eine Pyramide. Alles darunter in V hätte ich gerne gefüllt. Es versteht sich, dass ich mit deutlich größeren und komplexeren Datensätzen arbeite, aber immer durch eine "heigtmap" quasi vollständig definierbar.
Code:
V=zeros(5,5,5);
Z =

  Columns 1 through 5                      
                                           
         0    0.0000    0.0000    0.0000           0
         0    2.1225    2.1225    2.1225           0
         0    2.1225    4.2449    2.1225           0
         0    2.1225    2.1225    2.1225           0
         0         0         0             0                0
 
Private Nachricht senden Benutzer-Profile anzeigen


randfee2
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 16
Anmeldedatum: 21.05.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.12.2012, 01:15     Titel:
  Antworten mit Zitat      
Ich habs jetzt nach bestem Wissen realisiert, es ist erwartungsgemäß langsam.
Hier im Beispiel hat Z die Dimensionen d = 1001 (^3). Wie man sieht ist das blöde rauskopieren der einen Ebene klar der Bottleneck.



Hm, hat denn keiner ne Idee?
ich merke überdies: ich brauch mehr RAM. Matrizen mit einer Milliarde Elementen sind halt schon groß.


edit:
Hier mal als Beispiel eine Pyramide mit Kantenlänge 101. Die Rechenzeit ist oben für eine mit Kantenlänge 1001, ergo 1000x mehr "Voxeln".
.
Ich brauche die Auflösung, damit die dünne Schicht, die man da hellblau sieht, auch noch halbwegs ordentlich aufgelöst werden kann.
Private Nachricht senden Benutzer-Profile anzeigen
 
dmjr
Forum-Century

Forum-Century


Beiträge: 199
Anmeldedatum: 02.10.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.12.2012, 01:58     Titel:
  Antworten mit Zitat      
Kannst du bitte vollständig lauffähigen (und kopierbaren) Code posten?
Private Nachricht senden Benutzer-Profile anzeigen
 
randfee2
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 16
Anmeldedatum: 21.05.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.12.2012, 02:43     Titel:
  Antworten mit Zitat      
klar... hätte auch die Zeitanalyse oben als code gepostet, aber dann erkennt man nix mehr Smile

Auflösung auf 100 stellen, wenn du >8GB RAM hast Smile
Code:
%% v3 - Pyramiden-Generator
clc
clear;

%% Vars

a=11;               % Kantenlänge der Pyramiden [µm] (UNGERADE ZAHL!)
                    % a/2 muss Ganze Zahl sein!
resolution=10;      %[px/µm]  
d1=0.1;  %[µm]      % Schichtdicke AR1

n_Si    =   3.7;
n_SiN   =   2.2;


%% Berechnungen
angle = deg2rad(54.75);         % Winkel der 111 Ebenen
d = resolution*(a-1)+1; % Dimension der Einheitszelle
d1=d1*resolution;               % Schichtdicke 1 in [px]

%% Pyramide

x=[1 1 a a 1+(a-1)/2];
y=[1 a a 1 1+(a-1)/2];
z=[0 0 0 0 tan(angle)*(1+(a-1)/2)];

[xq,yq]=meshgrid(1:1/resolution:a,1:1/resolution:a);

[X,Y,Z]=griddata(x,y,z,xq,yq,'linear');

Z=Z*resolution;
mitte=floor(size(Z,1)/2)+1;

%% generiere Volumen

hp = floor(max(max(Z))) + d1;       % berechne Pyramidenhöhe, runde nach
                                    % unten ab und erhöhe um AR Coatings
       
                                 
V = ones(d,d,d);                    % pre allocate V
temp = zeros(d,d);                  % pre allocate temp

for i=1:hp;                         % von unten bis zur Spitze durchlaufen
    temp = V(:,:,i);                % horizontalen slice aus 3D Matrix rauskopieren
    temp(temp < (Z-i+d1)) = n_SiN;  % AR1 einfügen
    temp(temp < (Z-i)) = n_Si;      % AR2 einfügen
    V(:,:,i)=temp;                  % slice wieder in 3D Matrix einfügen
end

%% Histogramm

[y,x]=hist(V(:),[1,2,3]);

%% Plot

figure;
subplot(2,1,1);
slice(V,mitte,mitte,[1,hp/4,hp/2,hp*3/4]);
    shading flat;
    axis equal;
    axis tight;
    rotate3d on;
   
subplot(2,1,2);
bar(x,y); axis tight;
   
Private Nachricht senden Benutzer-Profile anzeigen
 
dmjr
Forum-Century

Forum-Century


Beiträge: 199
Anmeldedatum: 02.10.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.12.2012, 04:16     Titel:
  Antworten mit Zitat      
mal mit
temp=ones(d,d)
anstelle von
temp=V(:,:,i)
versucht? Da stehen doch sowieso nur 1er drin.
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 13.12.2012, 12:27     Titel:
  Antworten mit Zitat      
Hallo randfee2,
Code:

Nun haben alle Elemente von V den gleichen Wert.
Code:

    temp = V(:,:,i);
    temp(temp < (Z-i+d1)) = n_SiN;
    temp(temp < (Z-i)) = n_Si;

Hier wird aber auf verschiedene Werte getestet. Aber warum?
Dies erzeugt das gleiche Ergebnis:
Code:
if 1 < (Z-i+d1)
  V(:, :, i) = n_SiN;
elseif 1 < (Z-i)
    V(:,:,i) = n_Si;
end

Oder:
Code:
V = ones(d,d,d);
V(:, :, 1 < (Z - (1:hp) + d1)) = n_SiN;
V(:, :, 1 < (Z - (1:hp))) = n_Si;

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
randfee2
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 16
Anmeldedatum: 21.05.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.12.2012, 22:16     Titel:
  Antworten mit Zitat      
Hi Jan,

edit:
Hm, keines deiner Beispiele macht das was mein code oben macht. Oben wird in jeder "Schicht" von V, unten beginnend geprüft, welche Einträge in Z größer sind als bsp. i+1. Nur dort wird dann ein Wert gesetzt, nicht auf dieser ganzen Ebene, das ist leider falsch.
Bei deinem ersten Beispiel fehlt das jedenfalls komplett. Ich habe es anhand der Syntax aus dem zweiten Beispiel dann so umgeschrieben wie ich dachte, dass es laufen müsste, ist aber extrem langsam.
Habe noch einen dritten layer eingebaut, das ändert aber nix!

Code:
for i=1:hp;                                    
    if 0 < (Z-i+d1+d2)
        V(:,:,i < (Z-i+d1+d2))  = n_SiN;
    elseif 0 < (Z-i+d1)
        V(:,:,i < (Z-i+d1))     = n_SiO2;
    elseif 0 < (Z-i);
        V(:,:,i < (Z-i))        = n_Si;
    elseif 0 >= Z-i;
        V(:,:,i) = 1;
    end;
end;



Das zweite Beispiel verstehe ich aber nicht. Erstens gehe ich davon aus, dass es ebenfalls V(:,:,i) ... mit 'i' heißen soll statt mit 1, dann auch in einer For-Schleife laufen soll, weil ja alle iZweitens läuft es in keiner Variante wie ich es probier. Bekomme immer nen dimensions-mismatch.

Ich habs jetzt mal so umgeschrieben, dass zumindest die eine dimension passt. V(:,:,i) ist aber ein dxd Array, und rechts vom '<' steht nur ein 1xd Vektor, daher raffe ich's nicht.

Code:
for i=1:d;
    V(:,:,i < (Z - (1:d) + d1 + d2)) = n_SiN;
    V(:,:,i < (Z - (1:d) + d1))      = n_SiO2;
    V(:,:,i < (Z - (1:d)))             = n_Si;
end;


Code:
>> size(d)

ans =

     1     1

>> size(Z)

ans =

   801   801

>> size(V)

ans =

   801   801   801

>> size(d1)

ans =

     1     1

>>


Die Schreibweise ist jedenfalls sehr interessant, wusste nicht, dass ich man das grundsätzlich so verpacken kann.


Hab noch nix Besseres als die For-Schleifen ganz oben gefunden.
Private Nachricht senden Benutzer-Profile anzeigen
 
randfee2
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 16
Anmeldedatum: 21.05.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.12.2012, 23:25     Titel:
  Antworten mit Zitat      
So, besseres, kleineres Beispiel, damit ihr besser versteht worum's geht:
Ich denke, das ist jetzt wirklich selbsterklärend.

Ich will einen Ausdruck, der wörtlich:
A(:,:,i) soll an den Indizes wo A(:,:,i) > 1 ist den Eintrag 10 bekommen! Dafür muss es doch eine Schreibweise geben?


Führt das Beispiel aus, dann sollte alles klar sein:
Code:
%% kleines Beispiel
clc;

display('A=ones(4,4,4)')
A=ones(4,4,4);
display('A(2:3,2:3,2:3)=2');
A(2:3,2:3,2:3)=2


display('ich will einen Ausdruck, wo in jedem A(:,:,i) Einträge größer 1 ersetzt werden!, nicht nur in A(:,:,1)!!');
display('so funktioniert es aber nicht!');
display('A(A(:,:,2) > 1)=10');
A(A(:,:,2) > 1)=10



Hier direkt auch noch die passende Ausgabe dazu. Mir fehlt der Ausdruck der Zuweisung für A(:,:,2) für A(:,:,3) und für A(:,:,4)!
Code:
A=ones(4,4,4)
A(2:3,2:3,2:3)=2

A(:,:,1) =

     1     1     1     1
     1     1     1     1
     1     1     1     1
     1     1     1     1


A(:,:,2) =

     1     1     1     1
     1     2     2     1
     1     2     2     1
     1     1     1     1


A(:,:,3) =

     1     1     1     1
     1     2     2     1
     1     2     2     1
     1     1     1     1


A(:,:,4) =

     1     1     1     1
     1     1     1     1
     1     1     1     1
     1     1     1     1

display('ich will einen Ausdruck, wo dies auf A(:,:,2) angewandt wird, nicht auf A(:,:,1)! So funktioniert es aber nicht, ich verstehe einersetzs nicht warum (sollte wenn dann auf alle A(:,:,i) angewandt werden. Auf der anderen Seite will ich ja eben nur eine dedizierte Ebene ansprechen!');
A(A(:,:,2) > 1)=10

A(:,:,1) =

     1     1     1     1
     1    10    10     1
     1    10    10     1
     1     1     1     1


A(:,:,2) =

     1     1     1     1
     1     2     2     1
     1     2     2     1
     1     1     1     1


A(:,:,3) =

     1     1     1     1
     1     2     2     1
     1     2     2     1
     1     1     1     1


A(:,:,4) =

     1     1     1     1
     1     1     1     1
     1     1     1     1
     1     1     1     1

>>
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.