2014-11-30 3 views
0

목록의 가장 가까운 두 점 사이의 보간법을 사용하여 언제든지 값을 계산하려고합니다. Swift에서이 작업을 수행하는 더 좋고/더 쉬운 방법이 있습니까? 코드가 당신이 원하는 않는 경우Swift에서 값 목록의 보간 수

func CalculateDelta(ratio: Double) -> Double { 
    let ratioArray = [ 1.0, 1.05, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 500 ] 
    let deltaArray = [ 0.15, 0.15, 0.103, 0.072, 0.053, 0.04, 0.03, 0.023, 0.017, 0.011, 0.006, 0.001, 0 ] 

    var delta = deltaArray[0] 
    if (ratio > ratioArray[ratioArray.count - 1]) { 
     delta = deltaArray[deltaArray.count - 1] 
    } else { 
     for var i=0; i<ratioArray.count-1; i++ { 
      if (ratio > deltaArray[i]) { 
       delta = deltaArray[i] + (((ratio - ratioArray[i])/(ratioArray[i+1] - ratioArray[i])) * (deltaArray[i+1] - deltaArray[i])); 
       break; 
      } 
     } 
    } 
    return delta 
} 
+0

나는 이해하고 싶다 ...이 코드는 당신이 원하는 출력을 내고 있다고 말하지만, 보다 효율적인 알고리즘? –

+0

코드를 실행할 때 'ratio'가 500보다 크지 않으면 항상 0.15의 결과를 생성하는 것으로 보입니다. –

답변

0

는 다음이 더 효율적입니다 :

func CalculateDelta(ratio: Double) -> Double { 
    var result: Double = 0 
    if ratio <= 500 { 
     result = 0.15 
    } 
    return result 
} 

하지만 난 당신의 코드가 뭔가 다른 일을하도록되어 생각한다. 나는 아래의 코드가 맞을 것으로 의심한다.

// returns the index of the first element that satisfies the predicate 
func find<Seq: SequenceType>(seq: Seq, pred: (Seq.Generator.Element) -> Bool) -> Int? { 
    for (index, obj) in enumerate(seq) { 
     if pred(obj) { 
      return index 
     } 
    } 
    return nil 
} 

// returns the linear interpolation between two values 
func lerp(start: Double, end: Double, percent: Double) -> Double { 
    return start + percent * (end - start) 
} 

// returns the percent of value between start and end 
func percent(start: Double, end: Double, value: Double) -> Double { 
    assert(start <= value && value <= end) 
    return (value - start)/(end - start) 
} 

func calculateDelta(ratio: Double) -> Double { 
    let ratioArray = [1.0, 1.05, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 500] 
    let deltaArray = [0.15, 0.15, 0.103, 0.072, 0.053, 0.04, 0.03, 0.023, 0.017, 0.011, 0.006, 0.001, 0] 

    // if ratio is below range, return bottom of delta 
    if ratio < ratioArray[0] { 
     return deltaArray[0] 
    } 

    if let index = find(ratioArray, { ratio <= $0 }) { 
     if ratioArray[index] == ratio { 
      // if ratio is equal to element of range, return delta of same index 
      return deltaArray[index] 
     } 
     else { 
      // figure lerp between too low index and too high index 
      let p = percent(ratioArray[index - 1], ratioArray[index], ratio) 
      return lerp(deltaArray[index - 1], deltaArray[index], p) 
     } 
    } 

    // if ratio is above range, return top of delta (0.0) 
    return 0.0 
}