2012-01-16 5 views
1

저는 C 및 MATLAB 사용자입니다. 파이썬 (1 주일 전)을 배우기 시작했을 때 나는 MATLAB의 잠재력, 특히 배열 연산을 사용하지 않는다는 것을 알았습니다.Python 및 Matlab에서 루프를 단순화하는 방법

alpha = [1e-4,1e-3,1e-4,1e-1,1e-2,1e-3,1e-6,1e-3]; 
zeta = alpha/(dz*dz) 
nz = 101 
l=[0.3,0.1,0.2,0.1,0.1,0.1,0.2]; 
wz = cumsum(l*(nz-1)); 
nl = lenght(l); 

이 가능 단순화되어 다음 : 나는 이전 팁에서

C.

프로그래밍을 배운 아마 때문에, 내가 예를 들어, cumsum 및 기타 효율적인 배열 작업을 사용하는 것을 배웠다, 종종 루프에 사용 Python (Numpy) 또는 MATLAB 코드?

 A = zeros(nz,nz); 
     i=1; 
     for j = 2:wz(i)-1 
     A(j,j-1) = zeta(1,1); 
     A(j,j) = -2*zeta(1,1); 
     A(j,j+1) = zeta(1,1); % layer 1 nodes 
     end 

     %cicle to n-layers 
     for i=2:nl 
      for j=wz(i-1):wz(i-1) 
       A(j,j-1) = zeta(1,i-1); 
       A(j,j) = -zeta(1,i-1)-zeta(1,i); 
       A(j,j+1) = zeta(1,i); 
      end 

      for j=wz(i-1)+1:wz(i) 
       A(j,j-1) = zeta(1,i); 
       A(j,j) = -2*zeta(1,i); 
       A(j,j+1) = zeta(1,i); 
      end 

     end 
end 
+2

또는 두 개의 코드가 수행뿐만 아니라 우리에게 일반 코드를 제공하도록되어 무엇을 ...이 코드는 1D 식 히트에 속하는 – Hans

+0

@Hans 솔버가 다중 레이어에 적용됩니다. 알파는 레이어 당 확산 계수가있는 배열이고, l은 레이어 당 높이가있는 배열이고, wz는 점의 누적 합계 (이산 포인트)를 집계하는 배열이고 A는 "상태 매트릭스"입니다. 상태 행렬을 계산 한 후 ode 해석기를 구현합니다. – marco

+0

@marco : 당신이 몰랐을 경우에 MATLAB은 다양한 [ODE 해결 자] (http://www.mathworks.co.uk/help/techdoc/ref/ode23.html)를 내장하고 있으며 파이썬의 경우에는 [Scipy] (http://docs.scipy.org/doc/scipy/reference/integrate.html)에서 ODE 해결사를 찾을 수 있습니다. – James

답변

1

나는 측 당신에 의해 내 컴퓨터 측에서 실행 할 수있는 기회를 가진 후 아래의 코드를 수정했습니다 :로

http://www.mathworks.fr/help/techdoc/ref/spdiags.html

은 예를 들어 첫 번째 루프는 기록 할 수 있습니다. 여전히 몇 가지 질문이 있습니다 (최종 루프에서 더 커질 것으로 생각하십니까?, dz 란 무엇입니까?). 이것을 실행하기 전에 만난 문제는 idx_matrix가 논리적이어야한다는 사실을 잊어 버렸습니다.

dz=0.1; 
alpha = [1e-4,1e-3,1e-4,1e-1,1e-2,1e-3,1e-6,1e-3]; 
zeta = alpha/(dz*dz); 
nz = 101; 
l=[0.3,0.1,0.2,0.1,0.1,0.1,0.2]; 
wz = cumsum(l*(nz-1)); 
nl = length(l); 

A = zeros(nz); 
i=1; 

%replaces 1st loop 
j_start = 2; 
j_end = wz(i)-1; 

idx_matrix = false(size(A)); 
idx_matrix(j_start:j_end,j_start:j_end) = eye(j_end-j_start+1); 
A(idx_matrix) = -2*zeta(1,1); 

idx_matrix(idx_matrix) = false; 
idx_matrix(j_start:j_end,j_start-1:j_end-1) = eye(j_end-j_start+1); 
A(idx_matrix) = zeta(1,1); 

idx_matrix(idx_matrix) = false; 
idx_matrix(j_start:j_end,j_start+1:j_end+1) = eye(j_end-j_start+1); 
A(idx_matrix) = zeta(1,1); 

%cicle to n-layers 
for i=2:nl 

    %replaces 3rd loop 
    j_start = wz(i-1); 
    A(j_start,j_start) = -zeta(1,i-1)-zeta(1,i); 
    A(j_start,j_start-1) = zeta(1,i-1); 
    A(j_start,j_start+1) = zeta(1,i); 

    %replaces 4th loop 
    j_start = wz(i-1)+1; 
    j_end = min(wz(i),size(A,2)-1); 
    idx_matrix = false(size(A)); 
    idx_matrix(j_start:j_end,j_start:j_end) = eye(j_end-j_start+1); 
    A(idx_matrix) = -2*zeta(1,i); 

    idx_matrix(idx_matrix) = false; 
    idx_matrix(j_start:j_end,j_start-1:j_end-1) = eye(j_end-j_start+1); 
    A(idx_matrix) = zeta(1,i); 

    idx_matrix(idx_matrix) = false; 
    idx_matrix(j_start:j_end,j_start+1:j_end+1) = eye(j_end-j_start+1); 
    A(idx_matrix) = zeta(1,i); 

end 
당신이 문장에서 설명 할 경우 우리에게 쉬울 것
+0

답변 해 주셔서 감사합니다. (http://chat.stackoverflow.com/rooms/6795/discussion-between-marco-and-oli) 코드에 오류가 있습니다 ??? 첨자 인덱스는 실수 양수 또는 논리 값이어야합니다. A (idx_matrix) = -2 * 제타 (1,1); 코드의 초기이므로 사용자가 원하는 것을 파악할 수 없습니다. 예, 세 번째주기, 과제가 될 수 있습니다.이 교육의 더 좋은 방법을 찾지 못했습니다. (이 코드는 @Hans에 대한 코드 설명을 읽으면 레이어 사이의 경계를 나타냅니다.) – marco

+0

AHh 및 "매트릭스가"배열 (A = 0 (nz))이 오류인지 여부는 무엇입니까? – marco

+0

A = 제로 (nz)는 A = 제로 (nz, nz)와 같습니다. – Miebster

1

루프를 단순화하기 위해 spdiags 함수를 사용할 수 있습니다.

A=full(spdiags(repmat([zeta(1,1),-2*zeta(1,1),zeta(1,1)],wz(i),1),[-1 0 1],wz(i),wz(i))) 
+0

참조 해 주셔서 감사합니다. 그러나이 문제는 해결되지 않습니다. =) 문제를 단순화하는 방법을 찾으려고합니다. 즉, 벡터 문제의 반복 문제를 변환합니다. – marco

+0

어떻게 대답을 편집했는지 보여줍니다. 귀하의 경우에 'spdiags'를 사용하려면 – Oli

+0

나는 그것을 얻지 못했고 Matlab에 코드를 붙여 넣으면 을 반환합니까 ??? 색인이 행렬 크기를 초과합니다. ==> spdiags in 114 a (len (k) +1) : len (k + 1), :) = [i i + d (k) B (i + (m> = n) * d (k), k)]; – marco

관련 문제