2013-07-29 1 views
2

최근에는 (궁극적으로) 불가사의 한 스칼라의 숫자 특성을 사용하기 시작했습니다. 예를 들어 :스칼라의 숫자와 소수를 사용하는 고급 수학

def square[A](x: A)(implicit num: Numeric[A]): A = num.times(x, x) 

지금 내가 어떤 번호가 될 사각형 수 그것을 Double, Integer, BigDecimal, 또는 무엇 없습니다. 그러나 좀 더 진보 된 수학을 원한다면 어떻게 될까요? 예를 들어, 내 logistic functionDouble에 대한 번호는 다음과 같습니다

def logisticFunction(x: Double): Double = 1.0/(1.0 + math.exp(-x)) 

내가 할 수있는 추가하고 쉽게 나누어 지수에 대해,하지만 (나는 단지 특성 Fractional 대신 Numeric를 사용해야 할 것)? 내 자신의 exp 함수 (또는 Double 인수를 취하는 임의의 함수)를 작성하고 싶지는 않습니다.

그래서 내 질문은 다음과 같습니다. ADouble으로 변환하고, 내 수학을 수행 한 다음 A으로 다시 변환하십시오. 심지어 가능할까요?

편집 :처럼 내 함수의 서명이 보일 것입니다 방법

: 나는 num.toDouble(x)만큼 쉽게하는 두 배로 변환하는 방법에 대한 부분을 알아 냈어요

def logisticFunction[A](x: A)(implicit num: Fractional[A]): A = 
    /* Magic happens here */ 

. 그러나 A으로 다시 변환 할 때의 문제가 남아 있습니다.

+2

, 정수, 그래서, 부분적으로 적용된 함수로 사용하고 함수의 유효한 숫자 형식과 일치하도록 수정하지 않으면 가능한 방법을 알 수 없습니다. – Shadowlands

+1

'Numeric.Implicits._'을 import하고'numx (x, x) '대신'x * x'를 써라. –

+0

분명히 물어봐서 미안하지만 여기서는 더 복잡한 응용 프로그램이 있다고 가정하고 있습니까? 숫자를 사용하여 이러한 함수를 작성하는 이유는 간단합니다. 솔직히 평소 사용을 위해 스칼라의 멋진 기능을 대부분 피하고 싶기 때문에 강력한 재무 시스템에서는 암묵적인 기능이 없다는 점을 믿어주십시오. –

답변

6

나는 아직도이 방법은 정말 유용 의심한다. 그러나 귀하의 설명과 함께, 당신이 뭔가를 원할 것입니다 :

type FromDouble[A] = Double => A 
type ToDouble [A] = A => Double 

def logisticFunction[A: FromDouble: ToDouble](x: A): A = 1.0/(1.0 + math.exp(-x)) 

logisticFunction(0.5) 
implicit def bigDecimalToDouble(b: BigDecimal) = b.toDouble  
logisticFunction(BigDecimal(0.5)) 

또는 전용 형 클래스

다음 logisticFunction 결코 예를 들어,에 대한 유효한 멤버를 반환하려고하지

object FromDouble { 
    implicit object _Double extends FromDouble[Double] { 
    def apply(d: Double) = d 
    } 
    implicit object _BigDecimal extends FromDouble[BigDecimal] { 
    def apply(d: Double) = BigDecimal(d) 
    } 
} 
trait FromDouble[A] extends (Double => A) 

object ToDouble { 
    implicit object _Double extends ToDouble[Double] { 
    def apply(d: Double) = d 
    } 
    implicit object _BigDecimal extends ToDouble[BigDecimal] { 
    def apply(b: BigDecimal) = b.toDouble 
    } 
} 
trait ToDouble[A] extends (A => Double) 

def logisticFunction[A: FromDouble: ToDouble](x: A): A = 1.0/(1.0 + math.exp(-x)) 

logisticFunction(0.5) 
logisticFunction(BigDecimal(0.5)) 
3

exp과 같은 삼각 함수를 제공하는 형식 클래스가 필요합니다. Scala의 표준 라이브러리는 Fractional을 넘지 않습니다. Spire을 사용해보세요.

예 :

$ sbt core/console 

import spire.math._ 
import spire.algebra._ 
import spire.implicits._ 

def logisticFunction[A](x: A)(implicit m: Field[A], t: Trig[A]): A = 
    m.one/(m.one + exp(-x)) 

logisticFunction(0.5) 
logisticFunction(BigDecimal(0.5)) 
+0

내 문제는 숫자가 그리 많지 않다. 소수 (Double, Float, BigDecimal) 숫자를 받아들이고 수학을 수행하며 같은 형식의 결과를 반환하는 일반 메서드를 만들고 싶다. Doubles를 받아들이는 임의의 함수로는 안된다. –

+0

그런 다음 Double과의 변환을 위해 클래스를 입력해야하는데,이 연산을'Double'으로하면 앞뒤가 바뀌므로 그리고 처음부터 –

관련 문제