2017-11-10 13 views
0

저는 Sage 프로그래밍에 초보입니다. 나는 직사각형의 R * C 행렬 (R 행과 C 열)을 가지고 있으며 M의 랭크는 R과 C보다 작을 것입니다. 대상 벡터 T가 열의 하위 집합 범위에 있는지 확인하고 싶습니다. M. 저는 Sage에 다음 코드를 작성했습니다 (M 및 T를 얻는 방법이 다소 번거롭기 때문에 전체 코드를 포함하지 않았습니다). 코드가 원하는대로 작동하는지 확인하고 싶습니다.벡터가 Sage에있는 행렬의 열 하위 집합에 속하는지 확인하십시오.

간단히 말해서, 이것은 내 코드가 수행하려고 시도한 것입니다. M은 주어진 매트릭스이며, 먼저 T가 실제로 M의 열 (span)에 있는지 확인합니다. 그럴 경우, M (C 열을 가짐)을 행렬 M1으로 트림 (trim)하는 작업을 진행합니다.이 행렬 M1은 정확히 여러 열 (M)의 열이 있습니다 (첫 번째 while 루프가 수행하는 것입니다). 그 후, 나머지 컬럼이 스팬에 T를 포함하는지 점검하기 위해 하나씩 컬럼을 제거합니다 (이것은 두 번째 while 루프입니다). 두 번째 while 루프에서는 먼저 M2 (기본적으로 M1의 복사본)에서 열을 제거하고이 행렬을 M3라고 부릅니다. M3에. 벡터 T를 증가시키고 순위가 감소하는지 확인합니다. T가 이미 M2의 범위에 있으므로 순위 ([M2 T])는 순위 (M2)와 같아야합니다. 이제 열 C를 제거하고 T를 M2로 증가 시키면 순위가 감소하지 않는다는 것을 알기 때문에 C가 T를 생성하는 데 필요하지 않음을 알 수 있습니다.이 방법으로 T를 생성하는 데 필요한 열만 유지합니다.

반환합니다. 내가 시도한 예제에 대한 정답을 맞춰야하지만,이 코드는 크기가 매우 다양한 항목 (예 : 최대 값은 20^20이고 최소값은 1)과 같은 행렬에 대해 실행하려고합니다. 일반적으로 행렬 크기는 따라서 주말에 수백 건의 테스트 케이스를 거쳐 실행해야합니다. 비열한 것처럼 보이는 것이 있다면 예를 들어 말해 줄 수 있다면 정말 도움이 될 것입니다. 정밀도 오류가 발생합니까? 위에서 언급 한 모든 값/범위에서 작동하도록 코드를 수정해야합니까? 또한, 내 코드 속도를 높이거나 (더 짧거나 더 좋은 방법으로 같은 것을 쓰는) 방법이 있다면, 알고 싶습니다.

R = 155 
C= 167 
T = vector(QQ, R) 
M1 = matrix(ZZ, R, C) 

M1 = M 
C1 = C 
i2 = 0 

if rank(M.augment(T)) == rank(M): 
print("The rank of M is") 
print(rank(M)) 
while i2 < C1 : 
    if rank(M1.delete_columns([i2])) == rank(M1) : 
    M1 = M1.delete_columns([i2]) 
    C1 = C1 - 1 
    else : 
    i2 = i2+1 

C2 = M1.ncols() 
print("The number of columns in the trimmed down matrix M1 is") 
print(C2) 


i3 = 0 
M2 = M1 
print("The rank of M1 which is now also the rank of M2 is") 
print(rank(M2)) 
while i3 < C2 : 
    M3 = M2.delete_columns([i3]) 
    if rank(M3.augment(T)) < rank(M2) : 
    M2 = M3 
    C2 = C2 - 1 
    else : 
    i3 = i3 + 1 

print("Rank of matrix M is") 
print(M.rank()) 
+0

나는 또한 순위 패키지가 Sage에서 어떻게 작동하는지 궁금합니다. MatrixSpace (QQ, R, C) 대신 MatrixSpace (RR, R, C)를 사용하는 것으로, 행렬 M을 실제 이상으로 선언 할 때 다른 점이 있습니다. 왜 이런 일이 생길까요? 내 목적을 위해 매트릭스의 정확한 순위가 필요하고 근사치의 수에 기초한 수치 근사값이 아닌 내 맹점 (MATLAB이 생각하는 것인데 Sage를 사용하게 된 것)이 필요합니다. 나는 심볼릭 랭크 인 MatrixSpace (SR, R, C)를 사용하려고 시도했지만 코드를 매우 느리게 만들었습니다. 그래서이 줄 주변의 모든 포인터/팁? – Nikhil

+0

저는 수치 분석가는 아니지만 행렬에 대한 순위 계산은 행렬 항목의 작은 변화에 매우 민감한 경향이 있으므로 RR과 같은 부정확 한 필드에 대한 계급 계산은 의심 스럽습니다. 정확한 (수치 불확실성이없는) QQ와 같은 분야에서, 순위는 잘 작동합니다. –

답변

1

는 경우에 나는, 내가 이런 짓을 했을까 벡터 T 다른 매트릭스 M의 열 중 일부 부분 집합으로 구성 일부 매트릭스 M1의 이미지에 여부를 결정 세이지을 사용하고 싶었 :

M1 = M.matrix_from_columns([list of indices of the columns to use]) 
T in M1.column_space() 

또는 while 루프를 사용하여 매번 M1을 수정하십시오. (그러나 나는 T in M1.column_space()가 순위의 평등을 테스트하는 것보다 잘 작동해야한다고 생각합니다.)