matlab - 행렬 - {} 연산자를 사용하여 함수를 'UniformOutput'의 유효한 대체로 포장하고 있습니까, cellfun에서 false입니까?




인덱스 가 배열 요소 개수 1 를 초과 합니다 (2)

당신 질문부터 ...

'UniformOutput'을 false로 설정하지 않으려면 항상 {}을 사용하여 함수를 래핑 할 수 있습니까? 또는 그러한 대체가 작동하지 않는 시나리오가 있습니까?

짧은 대답은 "아니오" 입니다. 그리고 익명의 함수가 실패하게되는 주된 이유는 타입 검사가 부족하고 프로그래머가 함수를 반환하는 함수에 대해 거의 알지 못하기 때문입니다.

사실, IMO는 셀 인덱스 연산자 {} 를 사용하여 익명 함수에서 반환 값을 감싸는 데 어려움을 겪지 않아야합니다. 보다 나은 방법은 cellfun 을 호출 한 후 반환 값 유형을 결정하거나 cellfun 을 호출하기 전에 입력 값 유형을 확인하는 cellfun . 틀림없이 타입 검사 절차를 구현하거나 함수 핸들 에서 try...catchtry...catch 하여 반환 유형을 완전히 제어 할 수 있습니다. 그리고 솔직히 말해서, 당신이 무엇을 보내고 무엇을 받을지 아는 것은 Matlab에서 매우 중요합니다.

요컨대, 셀 배열을 의도적으로 반환 유형으로 만들지 않는 한 익명의 함수를 캡슐화하기 위해 {} 을 사용해서는 안됩니다. 호출 한 함수의 반환 값을 사용하여 셀 어레이.

FYI가 2016b 이상인 경우 스크립트 기능이 가능 하지만 새 파일을 만들지 않고도 스크립트 내에서 cellfun 대한 함수 핸들을 만들 수 있습니다.

cellfun 을 사용하여 셀 배열의 각 셀에 함수를 적용합니다.

함수가 비 스칼라 값을 반환 할 때마다 'UniformOutput'false 설정해야 함수의 출력이 셀 배열에 캡슐화되어 반환되어야한다는 것을 알고 있습니다.

다음 셀 배열을 예로 들어 보겠습니다.

C1 = {[1 2 3], [4 5 6]};

C1 에는 두 개의 셀이 있고 각 셀에는 세 요소의 벡터가 포함됩니다.

C1 =

  1×2 cell array

    [1×3 double]    [1×3 double]

모든 셀의 내용에 @(x) x + 1 을 더하려면 다음과 같이 cellfun 을 사용하여 @(x) x + 1 함수를 정의하고 적용 할 수 있습니다.

C2 = cellfun(@(x) x + 1, C1, 'UniformOutput', false);

이것은 잘 작동하지만 앞에서 설명한 것처럼 'UniformOutput'false 로 설정되어 있는지 확인해야합니다. 그렇지 않으면 오류가 발생합니다.

그러나, 이 스레드를 읽은 후, 나는이 @(x) {x + 1} 처럼 셀 배열 생성 연산자 {} 함수를 래핑하면 'UniformOutput'false 로 설정할 필요가 없다는 것을 'UniformOutput' .

따라서 다음 명령은 오류를 발생시키지 않고 C2 에서와 동일한 결과를 생성합니다.

C3 = cellfun(@(x) {x + 1}, C1);

코드 레이아웃 측면에서 볼 때이 방법은 이전보다 더 간결하고 간결하므로이 방법을 선호합니다. 그러나 이것이 항상 안전한지 확실하지 않습니다.

따라서 내 질문은 :

'UniformOutput'false 설정하지 않으려면 항상 {} 을 사용하여 함수를 래핑 할 수 있습니까? 또는 그러한 대체가 작동하지 않는 시나리오가 있습니까?

내 연구 :

help cellfun

'UniformOutput' FUN 의 출력이 셀 배열에 캡슐화되지 않고 반환 될 수 있는지 여부를 나타내는 논리 값입니다. true (기본값) 인 경우 FUN 은 배열로 연결할 수있는 스칼라 값을 반환해야합니다. true 인 경우 출력은 numeric, logical, char, struct, cell 유형이어야합니다. false 이면 cellfun 은 (I, J, ...) 번째 셀에 FUN (C {I, J, ...}, ...) 값이 포함 된 셀 배열 (또는 여러 셀 배열)을 반환합니다. 'UniformOutput'false 이면 출력은 모든 유형이 될 수 있습니다.

다음 단편은 관련 질문에 대한 답변의 일부입니다.

[...] cellfun 은 루핑 할 때 (즉 {} ) 셀의 개별 요소에 대한 자세한 작업을 수행하는 데 필요한 역 참조 작업을 처리합니다.


추가 인수 대신 셀 캡슐화 를 사용하는 경우를 생각할 수있는 두 가지 시나리오가 있습니다 ...'UniformOutput', false) 는 문제를 일으킬 수 있습니다. 첫 번째 시나리오는 두 번째 시나리오보다 훨씬 가능성이 높습니다.

  • 여러 출력물 캡처 : 때로는 셀 배열의 각 요소에서 unique 호출 및 추가 인덱스 인수 가져 오기와 같이 적용중인 함수에서 여러 출력을 캡처 할 수 있습니다. Using ...'UniformOutput', false) 우리는 쉽게 이것을 할 수 있습니다 :

    >> C1 = {[1 2 3], [4 5 6]};
    >> [C2, index] = cellfun(@(x) unique(x), C1, 'UniformOutput', false)
    C2 =
      1×2 cell array
        [1×3 double]    [1×3 double]
    index =
      1×2 cell array
        [3×1 double]    [3×1 double]

    그러나 셀 캡슐화를 사용할 때는 실패합니다.

    >> [C2, index] = cellfun(@(x) {unique(x)}, C1)
    Output argument "varargout{2}" (and maybe others) not assigned during call to
    "@(x){unique(x)}".
  • 출력이없는 함수 : 저는 여러분이 생각하는 것을 알고 있습니다 : "그러나 출력이 나오지 않으면 비 스칼라 값을 수집하는 것에 대해 걱정할 필요가 없습니다!" 사실,하지만 평가할 함수가 인수로 전달 된 함수 핸들처럼 추가 매개 변수가 될 수있는 예외적 인 시나리오를 상상할 수 있습니다. 따라서 처리 할 출력의 수를 미리 알 수 없습니다. 그럼에도 불구하고 두 가지 접근법은 이러한 경우에 따라 다릅니다.

    >> C1 = {[1 2 3], [4 5 6]};
    >> cellfun(@(x) disp(x), C1, 'UniformOutput', false);
         1     2     3
         4     5     6
    
    >> cellfun(@(x) {disp(x)}, C1);
    Error using disp
    Too many output arguments.
    Error in @(x){disp(x)}

    아마도 당신이 걱정해야 할 부분은 아니 겠지만, 나는 그것을 완전성을 위해서 포함시킬 것이라고 생각했습니다.





cell-array