2017-11-17 15 views
1

중력 보간 수식의 가중치를 계산하는 함수를 작성했습니다. 형태 안정성을 무시하고, 그 쉬운 충분하다 : 유형 안정성대소 문자 구별이 포함 된 함수의 유형 안정성

function baryweights(x) 
    n = length(x) 
    if n == 1; return [1.0]; end # This is obviously not type stable 

    xmin,xmax = extrema(x) 
    x *= 4/(xmax-xmin) 
    #^Multiply by capacity of interval to avoid overflow 
    return [ 
     1/prod(x[i]-x[j] for j in 1:n if j != i) 
     for i = 1:n 
    ] 
end 

문제는 그래서는 n == 1 경우에 올바른 유형의 배열을 반환 할 수 n > 1가지 경우 반환 형식을 해결하는 것입니다. 이것을 달성하기위한 쉬운 트릭이 있습니까?

+0

무엇 기대되는 결과인가? 왜냐하면'baryweights ([1,2,3]) '를 호출하면 매개 변수가'Array {Int}'이고 결과는'Array {Float64}'입니다! 정말로 당신이 지적하고있는 문제입니까? – Liso

+0

네, 그게 바람직합니다. 나는 반환 값의 타입을'n> 1'이 반환하는 값과 같게하고 싶습니다만,'n == 1 '을 포함하여'n = 1'의 값이면됩니다. – gTcV

+0

하지만 유스 케이스 란 무엇입니까? 나는 복소수를 시도했지만'extrema' 함수로는 작동하지 않습니다. 형식이 예상과 다른 경우 몇 가지 예를 보여줄 수 있습니까? – Liso

답변

1

은 단순히 더미 인수에 재귀 적으로 함수를 호출 :

function baryweights(x) 
    n = length(x) 
    if n == 1 
     T = eltype(baryweights(zeros(eltype(x),2))) 
     return [one(T)] 
    end 

    xmin,xmax = extrema(x) 
    let x = 4/(xmax-xmin) * x 
     #^Multiply by capacity of interval to avoid overflow, 
     # and wrap in let to avoid another source of type instability 
     # (https://github.com/JuliaLang/julia/issues/15276) 
     return [ 
      1/prod(x[i]-x[j] for j in 1:n if j != i) 
      for i = 1:n 
     ] 
    end 
end 
+0

테스트 해 보셨습니까? 당신은 아마도'T = eltype (baryweights (0, eltype (x), 2)))'를 의미했을 것입니다. – Liso

+0

오른쪽. 아니, 나는 다시 한번 모든 나무 뒤에있는 숲을 보지 못하고 시험하는 것을 잊었다. 나는 그것을 조사 할 것이다 – gTcV

2

내가 당신의 계획을 이해한다면 확실하지 않다. 하지만 어쩌면 이런 것이 도움이 될까요? ->

baryone(t::T) where T<:Real = [1.] 
baryone(t::T) where T<:Complex = [1im] # or whatever you like here 

function baryweights(x::Array{T,1}) where T<:Number 
    n = length(x) 
    n == 1 && return baryone(x[1]) 
    xmin,xmax = extrema(x) # don't forget fix extrema for complex! :) 
    x *= 4/(xmax-xmin) 
    #^Multiply by capacity of interval to avoid overflow 
    return [ 
     1/prod(x[i]-x[j] for j in 1:n if j != i) 
     for i = 1:n 
    ] 
end 

경고 : 아직 초보자입니다. 시도해 보면 @code_warntype baryweights([1]) 경고가 많이 표시됩니다. (또한 baryone으로 전화하지 마십시오.) 예 : nAny입니다.

function baryweights(x::Array{T,1}) where T<:Number 
    n = length(x) 
    n == 1 && return baryone(x[1]) 
    xmin,xmax = extrema(x) # don't forget fix extrema for complex! :) 
    let y = x * 4/(xmax-xmin) 
     #^Multiply by capacity of interval to avoid overflow 
     return [ 
      1/prod(y[i]-y[j] for j in 1:n if j != i) 
      for i = 1:n 
     ] 
    end 
end 

Edit2가 :

편집 : 우리는 다른 변수 (y)를 사용하는 경우 지금 I asked on discourse 및 그 @code_warn 반환 훨씬 더 나은 결과를 볼 수 Core.Box 에드로 y을 피하기 위해 내가 let 추가를

+0

이 문제에 관심을 가져 주셔서 감사합니다. 폐쇄가 다른 유형의 불안정성을 가져 왔다는 사실을 알지 못했고,'let' 해결 방법을 지적하면서 나에게 많은 시간을 구할 수있었습니다! – gTcV

+0

이제 내가 성취하고자하는 바는 : 입력 형식이 무엇이든 관계없이 'n == 1'사례가 다른 사례와 정확히 동일한 유형을 반환하도록하고 싶습니다. 고려해야 할 유한하고 알려진 일련의 사례가있는 경우 문제를 해결할 수 있지만 그다지 지루하고 오류가 발생하기 쉽고 유지하기 힘든 모든 것을 나열해야합니다. 내 솔루션의 트릭은 반환 유형이 내 함수에 어떤 유형으로 공급 되든지 상관없이 반환 유형을 보장 할 수 있다는 것입니다. – gTcV