Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Scala'更高级的数学;s数字和小数_Scala_Math_Exponent - Fatal编程技术网

使用Scala'更高级的数学;s数字和小数

使用Scala'更高级的数学;s数字和小数,scala,math,exponent,Scala,Math,Exponent,最近,我(终于)开始使用Scala的数字特性,这确实很神奇。例如: def square[A](x: A)(implicit num: Numeric[A]): A = num.times(x, x) 现在我可以对任何数字进行平方运算,无论是双精度、整数、大十进制,还是其他数字。然而,如果我想做一些更高级的数学呢?例如,我的ForDouble数字如下所示: def logisticFunction(x: Double): Double = 1.0 / (1.0 + math.exp(-x))

最近,我(终于)开始使用Scala的数字特性,这确实很神奇。例如:

def square[A](x: A)(implicit num: Numeric[A]): A = num.times(x, x)
现在我可以对任何数字进行平方运算,无论是
双精度
整数
大十进制
,还是其他数字。然而,如果我想做一些更高级的数学呢?例如,我的For
Double
数字如下所示:

def logisticFunction(x: Double): Double = 1.0 / (1.0 + math.exp(-x))
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))
我可以很容易地做加法和除法(我只需要使用trait
fractive
而不是
Numeric
),但是指数呢?我当然不想编写自己的
exp
函数(或任何接受
双参数的任意函数)

所以,我的问题是:如何将我的
A
转换为
Double
,在这方面做数学运算,然后再转换回
A
。有可能吗

编辑:

这就是我的函数签名的外观:

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

我已经了解了转换为double的部分,这与
num.toDouble(x)
一样简单。但是,转换回
A
的问题仍然存在。

您需要一个提供三角函数的类型类,例如
exp
。Scala的标准库并没有超出
分数
。你可以尝试使用

例如:

$ 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))

我仍然怀疑这种方法是否真的有用。但根据您的描述,您将需要以下内容:

def logisticFunction(x: Double): Double = 1.0 / (1.0 + math.exp(-x))
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))
或使用专用类型类别:

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))

logisticFunction永远不会返回例如Integer的有效成员,因此,我看不出这是怎么可能的,除非你想开始将它作为一个部分应用的函数使用,并修改它以匹配函数的有效数字类型。
导入numeric.Implicits.\u
并写入
x*x
而不是
num.times(x,x)
。很抱歉问这个明显的问题,但我假设这里有更复杂的应用程序在工作?考虑到这些函数有多简单,为什么要使用数值函数来编写它们?我这样说是因为,老实说,你想在日常生活中避免使用Scala的大部分花哨功能,相信我,在强健的金融系统中,许多功能,如隐式功能,是没有立足之地的。@RichardTodd我不确定“在这方面相信我”在问答网站上有多大的地位,特别是当人们不知道你是谁的时候。为你的位置提供理由有多难?Shadowlands,我会使用分数[a],而不是数字[a]作为逻辑函数。不管怎样,这个函数对整数没有任何意义。Jean-Philippe Pellet,我试过了,但是编译器给了我一些毛茸茸的错误(“错误:类型不匹配;[…]请注意,隐式转换不适用,因为它们是不明确的”)。Richard Todd,是的,这些只是最小的示例,不是我的实际代码。如果我不想使用Scala的特性,我只想使用Java:)我的问题不在于数字。我想创建一个通用方法,它接受任何分数(Double,Float,BigDecimal),对其进行运算并返回相同类型的结果。我可以用简单的运算(+,*,等等)来实现这一点,但不能用接受Double的任意函数。然后,您需要类型类来转换为Double或从Double转换为Double,尽管奇怪的是,如果使用
Double
进行此运算,您首先要进行前后转换