首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >scala的spire框架:我无法对一个组进行操作

scala的spire框架:我无法对一个组进行操作
EN

Stack Overflow用户
提问于 2013-10-02 13:02:50
回答 1查看 628关注 0票数 2

我尝试使用spire,一种数学框架,但是我有一条错误消息:

代码语言:javascript
运行
复制
import spire.algebra._
import spire.implicits._

trait AbGroup[A] extends Group[A]

final class Rationnel_Quadratique(val n1: Int = 2)(val coef: (Int, Int)) {
  override def toString = {
    coef match {
        case (c, i) =>
            s"$c + $i√$n"
    }
  }

  def a() = coef._1

  def b() = coef._2

  def n() = n1


} 

object Rationnel_Quadratique {

  def apply(coef: (Int, Int),n: Int = 2)= {
    new Rationnel_Quadratique(n)(coef)
  }

}

object AbGroup {

  implicit object RQAbGroup extends AbGroup[Rationnel_Quadratique] {

    def +(a: Rationnel_Quadratique, b: Rationnel_Quadratique): Rationnel_Quadratique = Rationnel_Quadratique(coef=(a.a() + b.a(), a.b() + b.b()))

    def inverse(a: Rationnel_Quadratique): Rationnel_Quadratique = Rationnel_Quadratique((-a.a(), -a.b()))

    def id: Rationnel_Quadratique = Rationnel_Quadratique((0, 0))
  }

} 


object euler66_2 extends App {

  val c = Rationnel_Quadratique((1, 2))
  val d = Rationnel_Quadratique((3, 4))
  val e = c + d
  println(e)

}

程序需要添加1+2√2和3+4√2,但是我有以下错误:

spire.algebra.AdditiveSemigroupRationnel_Quadratique val e=c+d ^类型的证据参数的隐式值找不到

我认为我错过了一些重要的东西(使用implicits?)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-03 15:58:33

看起来你没有正确地使用尖塔。

Spire已经有了一个AbGroup类型,所以您应该使用它而不是重新定义您自己的类型。下面是一个使用我创建的名为X的简单类型的示例。

代码语言:javascript
运行
复制
import spire.implicits._
import spire.algebra._

case class X(n: BigInt)

object X {
  implicit object XAbGroup extends AbGroup[X] {
    def id: X = X(BigInt(0))
    def op(lhs: X, rhs: X): X = X(lhs.n + rhs.n)
    def inverse(lhs: X): X = X(-lhs.n)
  }
}

def test(a: X, b: X): X = a |+| b

注意,对于组(以及半群和一元),您将使用|+|而不是+。要获得加法,您需要用AdditiveSemigroup定义一些东西(例如,SemiringRingField或其他东西)。

如果这有意义的话,您还将使用.inverse|-|,而不是一元和二进制-

看看您的代码,我也不确定您的实际数字类型是否正确。如果我想为n添加两个不同值的数字,会发生什么?

不管怎么说,希望这能帮你弄清楚一点。

编辑:既然你似乎也被挂在Scala语法上了,让我试着勾勒出一些可能有效的设计。首先,总是有一个更通用的解决方案:

代码语言:javascript
运行
复制
import spire.implicits._
import spire.algebra._
import spire.math._

case class RQ(m: Map[Natural, SafeLong]) {
  override def toString: String = m.map {
    case (k, v) => if (k == 1) s"$v" else s"$v√$k" }.mkString(" + ")
}

object RQ {
  implicit def abgroup[R <: Radical](implicit r: R): AbGroup[RQ] =
    new AbGroup[RQ] {
      def id: RQ = RQ(Map.empty)
      def op(lhs: RQ, rhs: RQ): RQ = RQ(lhs.m + rhs.m)
      def inverse(lhs: RQ): RQ = RQ(-lhs.m)
    }
}

object Test {
  def main(args: Array[String]) {
    implicit val radical = _2
    val x = RQ(Map(Natural(1) -> 1, Natural(2) -> 2))
    val y = RQ(Map(Natural(1) -> 3, Natural(2) -> 4))
    println(x)
    println(y)
    println(x |+| y)
  }
}

这允许您在一起添加不同的根,没有问题,而代价是一些间接的。您也可以更密切地遵循您的设计如下:

代码语言:javascript
运行
复制
import spire.implicits._
import spire.algebra._

abstract class Radical(val n: Int) { override def toString: String = n.toString }
case object _2 extends Radical(2)
case object _3 extends Radical(3)

case class RQ[R <: Radical](a: Int, b: Int)(implicit r: R) {
  override def toString: String = s"$a + $b√$r"
}

object RQ {
  implicit def abgroup[R <: Radical](implicit r: R): AbGroup[RQ[R]] =
    new AbGroup[RQ[R]] {
      def id: RQ[R] = RQ[R](0, 0)
      def op(lhs: RQ[R], rhs: RQ[R]): RQ[R] = RQ[R](lhs.a + rhs.a, lhs.b + rhs.b)
      def inverse(lhs: RQ[R]): RQ[R] = RQ[R](-lhs.a, -lhs.b)
    }
}

object Test {
  def main(args: Array[String]) {
    implicit val radical = _2
    val x = RQ[_2.type](1, 2)
    val y = RQ[_2.type](3, 4)
    println(x)
    println(y)
    println(x |+| y)
  }
}

这种方法创建一个假类型来表示您所使用的任何根类型(例如,QR 2),并对该类型的√进行参数化。这样,您就可以确保没有人会尝试做无效的添加。

希望这些方法中的一种会对你有用。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19137572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档