Giter VIP home page Giter VIP logo

spire's Introduction

Continuous Integration Discord codecov.io spire Scala version support

Spire

Spire is a numeric library for Scala which is intended to be generic, fast, and precise.

See the companion microsite

spire's People

Contributors

adampingel avatar andresilva avatar armanbilge avatar bishabosha avatar cquiroz avatar danicheg avatar denisrosset avatar dusank avatar dwijnand avatar erik-stripe avatar ghostroad avatar gkossakowski avatar i10416 avatar ijuma avatar jacksullivan avatar kevinmeredith avatar larsrh avatar non avatar paulp avatar r0estir0bbe avatar rklaehn avatar ryan-williams avatar scala-steward avatar sethtisue avatar thomas-stripe avatar tixxit avatar travisbrown avatar typelevel-steward[bot] avatar vpavkin avatar xuwei-k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spire's Issues

Move log from NRoot to Trig?

Right now NRoot[A] has a log, which is pretty strange given that there's no guarantee we can represent e.

We should probably move the natural log to Trig[A], and/or give NRoot#log a base argument.

signum is specified as Int, needs to be number-specific

Number currently defines signum with a result type of Int.

This is wrong, and will break as soon as you put almost anything non-Int into it.
For instance, what's the result of Double.NaN.signum? Not 0, for sure.
Another example is Complex: The result of complex.signum is another Complex value, not an Int.

signum should have a result type of type T where T is the actual numeric type.

cfor reporting ClassTag error on map

In console for spire 2.10.0 branch (project benchmark)

scala> import spire.syntax.cfor._
import spire.syntax.cfor._

scala> val a = Array.fill(10)(1)
a: Array[Int] = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)

scala> cfor(0)(_<10,_+1){ i => a.map(_+i) }
<console>:21: error: not found: value ClassTag
              cfor(0)(_<10,_+1){ i => a.map(_+i) }

also happening for spire 0.3 and 0.4

Review our use of ScalaNumber

ScalaNumber is a bit of a pain to use. We largely have to duplicate it's functionality anyway to get seamless integration working. So the question is, should we bother with it?

This task involves looking at the bytecode generated for things like 1 + Rational(2,3) and seeing if there's a real advantage over the bytecode we get using Spire's implicits and n + Rational(2,3).

Move unused code into benchmarking/tests/examples

Spire has accumulated some code which was used for prototyping, or for testing different approaches. One example of this was the binaryGcd algorithm.

It would be great to go through and move all this ancillary code to an appropriate subproject. We often want to keep this kind of thing around to be able to track benchmarks.

Create improved big integer and big decimal classes

It would be interesting to have our own implementation of these classes. Some possible improvements:

  1. Smarter context (decimal digit guarantees are annoying with binary representations)
  2. Faster implementation (possibly)
  3. MIT-licensed implementation
  4. Better methods/operators without needing implicits
  5. Laziness (possibly)
  6. Integration with Rational and Real where appropriate

type classes are not serializable

With version 0.3.0, I get serialization errors when I try to work with Spark and Spire. I can get around this by inheriting from the type classes and Serializable at the same time. For example

implicit object DoubleIsNumeric extends spire.math.DoubleIsNumeric with Serializable

promoting to Number on integer x number operation

I think any operation with an integer (i.e. SafeLong, BigInt) and an number (i.e. Number, Double) should lead to a Number.

Now you get:

scala> SafeLong(7) + Number(1)
:36: error: could not find implicit value for evidence parameter of type spire.algebra.AdditiveMonoid[scala.math.ScalaNumericConversions with scala.math.Ordered[_ >: spire.math.SafeLong with spire.math.Number <: scala.math.ScalaNumericConversions with scala.math.Ordered[_ >: spire.math.SafeLong with spire.math.Number <: scala.math.ScalaNumericConversions]]]

scala> SafeLong(7) * 1.0
:36: error: could not find implicit value for evidence parameter of type spire.algebra.MultiplicativeSemigroup[Any]
SafeLong(7) * 1.0

scala> BigInt(1) * 1.0
:36: error: could not find implicit value for evidence parameter of type spire.algebra.MultiplicativeSemigroup[Any]
BigInt(1) * 1.0

(or did i just forget to import something?)

Fraction operators

scala> val f = Fraction(1,2)
f: Fraction = (1 / 2)

scala> 1 + f
:37: error: type mismatch;
found : Int(1)
required: ?{def +(x$1: ? >: Fraction): ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method literalIntOps in trait OpsImplicits of type (lhs: Int)spire.LiteralIntOps
and method FractionFromInt of type (i: Int)Fraction
are possible conversion functions from Int(1) to ?{def +(x$1: ? >: Fraction): ?}
1 + f
^

scala> -f
:37: error: could not find implicit value for evidence parameter of type spire.algebra.AdditiveGroup[Fraction]
-f
^
:37: error: value unary_- is not a member of Fraction
-f
^

scala> 0 - f
:37: error: type mismatch;
found : Int(0)
required: ?{def -(x$1: ? >: Fraction): ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method literalIntOps in trait OpsImplicits of type (lhs: Int)spire.LiteralIntOps
and method FractionFromInt of type (i: Int)Fraction
are possible conversion functions from Int(0) to ?{def -(x$1: ? >: Fraction): ?}
0 - f
^

scala> 1 * f
:37: error: type mismatch;
found : Int(1)
required: ?{def *(x$1: ? >: Fraction): ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method literalIntOps in trait OpsImplicits of type (lhs: Int)spire.LiteralIntOps
and method FractionFromInt of type (i: Int)Fraction
are possible conversion functions from Int(1) to ?{def *(x$1: ? >: Fraction): ?}
1 * f
^

scala> 1 / f
:37: error: type mismatch;
found : Int(1)
required: ?{def /(x$1: ? >: Fraction): ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method literalIntOps in trait OpsImplicits of type (lhs: Int)spire.LiteralIntOps
and method FractionFromInt of type (i: Int)Fraction
are possible conversion functions from Int(1) to ?{def /(x$1: ? >: Fraction): ?}
1 / f
^

scala> 1.0 + f
:37: error: could not find implicit value for parameter ev: spire.algebra.Ring[Fraction]
1.0 + f
^

scala> 1.0 - f
:37: error: could not find implicit value for parameter ev: spire.algebra.Ring[Fraction]
1.0 - f
^

scala> 1.0 * f
:37: error: could not find implicit value for parameter ev: spire.algebra.Ring[Fraction]
1.0 * f
^

scala> 1.0 / f
:37: error: could not find implicit value for parameter ev: spire.algebra.Field[Fraction]
1.0 / f
^

scala> f + 1.0
:37: error: could not find implicit value for evidence parameter of type spire.algebra.AdditiveSemigroup[Fraction]
f + 1.0
^

scala> f - 1.0
:37: error: could not find implicit value for evidence parameter of type spire.algebra.AdditiveGroup[Fraction]
f - 1.0
^

scala> f / 1.0
:37: error: could not find implicit value for evidence parameter of type spire.algebra.MultiplicativeGroup[Fraction]
f / 1.0
^

scala> f * 1.0
:37: error: could not find implicit value for evidence parameter of type spire.algebra.MultiplicativeSemigroup[Fraction]
f * 1.0

          ^

scala> Fraction(SafeLong(1), 2)
:36: error: type mismatch;
found : spire.math.SafeLong
required: BigInt
Fraction(SafeLong(1), 2)
^

cfor does not handle rename on import

From console:

scala> import spire.syntax._
import spire.syntax._

scala> import scala.{ math => jawn }
import scala.{math=>jawn}

scala> cfor(0)(_<10,_+1){ i => println(jawn.min(5,i)) }
<console>:12: error: object jawn is not a member of package scala
              cfor(0)(_<10,_+1){ i => println(jawn.min(5,i)) }
                                                         ^

implicit power conversion

Suddenly double:

scala> 120L pow 5
res343: Double = 2.48832E10

scala> 120L ** 5
res344: Double = 2.48832E10

scala> 120L ** 5L
res345: Double = 2.48832E10

Then I wanted to get a square root:

scala> 120 ** 0.5
:37: error: ambiguous reference to overloaded definition,
both method ** in class LiteralIntOps of type [A](rhs: spire.math.Complex[A])(implicit evidence$15: spire.math.Fractional[A], implicit evidence$16: spire.math.Trig[A])spire.math.Complex[A]
and method ** in class LiteralIntOps of type (rhs: spire.math.Rational)(implicit ev: spire.math.ApproximationContext[spire.math.Rational])spire.math.Rational
match argument types (Double)
120 ** 0.5

scala> Rational(120,1) pow 0.5
:37: error: could not find implicit value for parameter ctxt: spire.math.ApproximationContext[spire.math.Rational]
Rational(120,1) pow 0.5

scala> 120L pow 0.5 //at least this works due to the double conversion above...
res337: Double = 10.954451150103322

And now, the WTF:

scala> SafeLong(100) ** 0.5
res358: spire.math.SafeLong = 1

That does not make any sense.

cfor inlining bug

It seems like there's currently a problem with tuple destructuring:

val arr = Array((1,2), (2,3), (4,5))
var t = 0
cfor(0)(_ < arr.length, _ + 1) { i =>
  val (a, b) = arr(i)
  t += a + 2 * b
}

Subtraction of Naturals gives unexpected result.

Ben Hutchison noticed that Natural(1) - Natural(2) == Natural(18446744073709551615L), which is clearly not correct. We should either throw an ArithmeticException in this case and/or rename the method and return an Option[Natural] instead.

Get -Xmx working correctly for Caliper

I am pretty sure that the benchmark memory settings are no longer being passed to Caliper.

This is a problem because we'd like to test gigantic arrays--currently some of the benchmarks overflow the heap.

javaOptions used to work, but seems to no longer.

big prefix

scala> big"100"
res168: scala.math.BigInt = 100

scala> big"1000"
error: exception during macro expansion:
java.lang.NumberFormatException: illegal SI BigInt constant
at spire.macrosk.Macros$.handleBigInt(Macros.scala:186)
at spire.macrosk.Macros$.siBigInt(Macros.scala:205)

scala> BigInt("1000")
res170: scala.math.BigInt = 1000

Implementing RationalNumber

Dear all,

I need an implementation of RationalNumber in Spire, so I am in the process of making one.

I am struggling with the implementation of "equals", especially with respect to non-Number classes such as Rational, BigDecimal, etc...

What is the contract that the Number trait is supposed to obey ?

Also, I wondered how should a Number should behave with respect to hashCode; it is probably impossible to design a good solution for that.

Cheers,

Denis

Wrong method name in Generator

spire/random/Generator.scala, line 100, 0.4 version:

/**

  • Generates a random float in [0.0, n).
    */
    def nextDouble(n: Float): Float = nextFloat() * n

Double <op> Number

scala> 0.1 - Number(0.0)
res29: spire.math.Number = 0.0

scala> 0.1 * Number(0.1)
res31: spire.math.Number = 0.0

scala> 0.1 + Number(0.1)
res32: spire.math.Number = 0.1

scala> 0.1 / Number(0.1)
res33: spire.math.Number = 0.0

IntIsIntegral.fromInt throws StackOverflowError

I get these while testing the wip-spire-stats branch, it boils down to this:

scala> spire.math.Integral.IntIsIntegral.fromInt(42)
java.lang.StackOverflowError
        at spire.math.Integral$IntIsIntegral$.fromInt$mcI$sp(Integral.scala:18)
        at spire.math.ConvertableToInt$class.fromInt(Convertable.scala:53)
        at spire.math.Integral$IntIsIntegral$.spire$math$IntIsIntegral$$super$fromInt(Integral.scala:18)
        at spire.math.IntIsIntegral$class.fromInt$mcI$sp(Integral.scala:28)
        at spire.math.Integral$IntIsIntegral$.fromInt$mcI$sp(Integral.scala:18)
        at spire.math.ConvertableToInt$class.fromInt(Convertable.scala:53)
        at spire.math.Integral$IntIsIntegral$.spire$math$IntIsIntegral$$super$fromInt(Integral.scala:18)
        at spire.math.IntIsIntegral$class.fromInt$mcI$sp(Integral.scala:28)
        at spire.math.Integral$IntIsIntegral$.fromInt$mcI$sp(Integral.scala:18)
        ...

The boiled down example above uses no spire imports.

dividing ints by SafeLong

You cannot divide an int by a SafeLong:

scala> 10 / SafeLong(2)
:36: error: could not find implicit value for parameter ev: spire.algebra.Field[spire.math.SafeLong]
10 / SafeLong(2)

dividing by an actual long works ofc, although dividing by a BigInt does not work. So if it should be allowed, depends on if you consider SafeLong to be a safe long, or a faster BigInt...

cfor param replacements are not hygienic :-S

spire.macrosk.Syntax.Util.inlineApplyRecursive performs name-based replacements instead of using symbols.

As a result, hell breaks loose in case of symbol collision:

import spire.syntax._
import scala.collection.mutable.ArrayBuffer

object Test extends App {
  val result = ArrayBuffer[Int]()

  cfor(0)(_ < 3, _ + 1) { x => {
    cfor(0)(_ < 2, _ + 1) { y => 
      val x = y
      result += x // name-based replace of x causes this to use the outer x...
    }
  }}

  println(result)
  assert(result.toList == List(0, 1, 0, 1, 0, 1)) 
}

Result ends up being:

(0, 0, 1, 1, 2, 2)

Using following build.sbt:

scalaVersion := "2.10.0"

libraryDependencies += "org.spire-math" %% "spire" % "0.3.0-RC1"

cfor compilation crashes

Each of the following cfor tests causes a compilation crash:

  test("capture value in closure") {
    val b = collection.mutable.ArrayBuffer[() => Int]()
    cfor(0)(_ < 3, _ + 1) { x =>
      b += (() => x)
    }
    assert(b.toList === List(0, 1, 2))
  }
  test("capture value in inner class") {
    val b = collection.mutable.ArrayBuffer[Int]()
    cfor(0)(_ < 3, _ + 1) { x => {
      class A { def f = x }
      b += (new A().f)
    }}
    assert(b.toList === List(0, 1, 2))
  }

(test cases derived from Scalaxy/Loops optimized Range tests)

Excerpt from the crash log:

[error] (core/test:compile) java.lang.AssertionError: assertion failed: 
[error]      while compiling: /Users/ochafik/Documents/Perso/spire/core/src/test/scala/spire/SyntaxTest.scala
[error]         during phase: constructors
[error]      library version: version 2.10.0
[error]     compiler version: version 2.10.0
[error]   reconstructed args: -optimise -feature -Yinline -Yclosure-elim -bootclasspath /Library/Java/JavaVirtualMachines/jdk1.7.0_13.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_13.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_13.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_13.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_13.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_13.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_13.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_13.jdk/Contents/Home/jre/lib/JObjC.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_13.jdk/Contents/Home/jre/classes:/Users/ochafik/.sbt/0.12.2/boot/scala-2.10.0/lib/scala-library.jar -unchecked -language:experimental.macros -language:higherKinds -language:implicitConversions -Ydead-code -deprecation -Yinline-warnings -Yinline-handlers -d /Users/ochafik/Documents/Perso/spire/core/target/scala-2.10/test-classes -classpath /Users/ochafik/Documents/Perso/spire/core/target/scala-2.10/test-classes:/Users/ochafik/Documents/Perso/spire/core/target/scala-2.10/classes:/Users/ochafik/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.10.0.jar:/Users/ochafik/.ivy2/cache/org.scalatest/scalatest_2.10/jars/scalatest_2.10-1.9.1.jar:/Users/ochafik/.ivy2/cache/org.scala-lang/scala-actors/jars/scala-actors-2.10.0.jar:/Users/ochafik/.ivy2/cache/org.scalacheck/scalacheck_2.10/jars/scalacheck_2.10-1.10.0.jar:/Users/ochafik/.ivy2/cache/org.scala-tools.testing/test-interface/jars/test-interface-0.5.jar
[error] 
[error]   last tree to typer: Assign
[error]               symbol: null
[error]    symbol definition: null
[error]                  tpe: Unit
[error]        symbol owners: 
[error]       context owners: class A$1 -> anonymous class $anonfun$4 -> class SyntaxTest -> package spire
[error] 
...
== Expanded type of tree ==

TypeRef(TypeSymbol(final abstract class Unit extends ))

1 not in List(value $outer, value 1)
    at scala.tools.nsc.transform.Constructors$ConstructorTransformer.scala$tools$nsc$transform$Constructors$ConstructorTransformer$$parameterNamed$1(Constructors.scala:71)
    at scala.tools.nsc.transform.Constructors$ConstructorTransformer.scala$tools$nsc$transform$Constructors$ConstructorTransformer$$parameter$1(Constructors.scala:63)
    at scala.tools.nsc.transform.Constructors$ConstructorTransformer$$anonfun$8.apply(Constructors.scala:268)
    at scala.tools.nsc.transform.Constructors$ConstructorTransformer$$anonfun$8.apply(Constructors.scala:259)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.immutable.List.foreach(List.scala:309)

BigInt + String

Usually you can do

scala> BigInt(3)+":"
res0: String = 3:

to create a string.

With spire loaded:

scala> BigInt(3)+":"
:39: error: type mismatch;
found : scala.math.BigInt
required: ?{def +(x$1: ? >: String(":")): ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method any2stringadd in object Predef of type (x: Any)scala.runtime.StringAdd
and method additiveMonoidOps in trait OpsImplicits of type [A](a: A)(implicit evidence$53: spire.algebra.AdditiveSemigroup[A])spire.algebra.AdditiveSemigroupOps[A]
are possible conversion functions from scala.math.BigInt to ?{def +(x$1: ? >: String(":")): ?}
BigInt(3)+":"
^

collection operations

It would be nice, if you could use the spire numbers with the sum/product methods on collections:

scala> Array(Number(1), Number(2), Number(3)) sum
:48: error: could not find implicit value for parameter num: Numeric[spire.math.Number]
Array(Number(1), Number(2), Number(3)) sum
^

scala> Array(Number(1), Number(2), Number(3)) product
:48: error: could not find implicit value for parameter num: Numeric[spire.math.Number]
Array(Number(1), Number(2), Number(3)) product

scala> Array(SafeLong(1), SafeLong(2)) sum
:48: error: could not find implicit value for parameter num: Numeric[spire.math.SafeLong]
Array(SafeLong(1), SafeLong(2)) sum

incorrect types for implicit conversions in Number

in Number, it seems like the implicits are not always taking in the correct types.

implicit def byteToNumber(n:Int) = Number(n)
implicit def shortToNumber(n:Int) = Number(n)

Maybe should be

implicit def byteToNumber(n:Byte) = Number(n)
implicit def shortToNumber(n:Short) = Number(n)

Move Sign instances into companion object

Sign current leaves all its values (eg. Positive, Negative, and Zero) in spire.algebra. It would be nice to move these into Sign, especially given that Zero may cause people confusion.

Anyone have any problems with this?

no implicit conversion on BigInt operator (SafeLong|Number)

scala> BigInt(1) + SafeLong(2)
:36: error: could not find implicit value for evidence parameter of type spire.algebra.AdditiveSemigroup[scala.math.ScalaNumericConversions]
BigInt(1) + SafeLong(2)
^

scala> BigInt(1) - SafeLong(2)
:36: error: could not find implicit value for evidence parameter of type spire.algebra.AdditiveGroup[scala.math.ScalaNumericConversions]
BigInt(1) - SafeLong(2)
^

scala> BigInt(1) * SafeLong(2)
:36: error: could not find implicit value for evidence parameter of type spire.algebra.MultiplicativeSemigroup[scala.math.ScalaNumericConversions]
BigInt(1) * SafeLong(2)
^

scala> BigInt(1) / SafeLong(2)
:36: error: could not find implicit value for evidence parameter of type spire.algebra.MultiplicativeGroup[scala.math.ScalaNumericConversions]
BigInt(1) / SafeLong(2)

scala> BigInt(1) + Number(2)
:36: error: could not find implicit value for evidence parameter of type spire.algebra.AdditiveSemigroup[scala.math.BigInt]
BigInt(1) + Number(2)

scala> BigInt(1) - Number(2)
:36: error: could not find implicit value for evidence parameter of type spire.algebra.AdditiveGroup[scala.math.BigInt]
BigInt(1) - Number(2)

scala> BigInt(1) * Number(2)
:36: error: could not find implicit value for evidence parameter of type spire.algebra.MultiplicativeSemigroup[scala.math.BigInt]
BigInt(1) * Number(2)

scala> BigInt(1) / Number(2)
:36: error: could not find implicit value for evidence parameter of type spire.algebra.MultiplicativeSemigroup[scala.math.BigInt]
BigInt(1) / Number(2)

(the other way around works:
scala> SafeLong(1) + BigInt(2)
res82: spire.math.SafeLong = 3

scala> Number(1) + BigInt(2)
res83: spire.math.Number = IntNumber(3)
)

modPow

BigInt has the useful BigInt(7).modPow(2, 10) function, SafeLong does not...

Or perhaps you can write a macro that replaces (x ** y) % z by x.modPow(y, z)?

EuclideanRing's euclid algorithm depends on equality w/o Eq.

I noticed that the euclid method in EuclideanRing uses ==. Since we are trying to avoid equality within our typeclasses, we should probably add an implicit Eq[A] to gcd and use that equality. I imagine pretty much all gcd algorithms will require Eq for some stopping condition, so I think it'll fit:

def gcd(x: A, y: A)(implicit A: Eq[A])

linear algebra: vector spaces, matrices

not an issue, more an enquiry into future plans:

being very impressed by the mathematically rigorous and computationally efficient (at runtime) approach taken by spire, i wonder whether there are any concrete plans of implementing vector spaces (similar to, and building upon your implementation of fields), matrices, and ultimately the linear algebra that flows from that?

cfor treats functions as "by name" parameters

If the expression of the test, increment or loop functions given to cfor contain any side-effect, these side effects are executed at each iteration (in other terms, params are passed "by name" instead of "by value"):

  test("functions with side effects") {
    val b = mutable.ArrayBuffer.empty[Int]
    var v = 0
    cfor(0)({ v += 1; _ < 3 }, { v += 10; _ + 1})({
      v += 100
      x => {
        b += x
      }
    })
    assert(v == 111, s"v == $v")
    assert(b.toList === List(0, 1, 2), s"b.toList == ${b.toList}")
  }

(v ends up being 334)

to operator

scala> SafeLong(2) to SafeLong(80)
:36: error: value to is not a member of spire.math.SafeLong
SafeLong(2) to SafeLong(80)

Literal Operations with Numerics

Would be great to allow for the following:

val y = x * 2.1 + 4.2
val z = 8.5 + 4.1 * y

without using implicitly [Numeric[T}].fromDouble() for every literal

where x, y, and z are all Numeric[T], and where T is Double, Complex, for Float. Int is not so clear. note that:

val y = 2 + 5 * x // works, but only with Ints
val z = x * 5 + 2 // compilation error

I'm not sure if this is possible without breaking everything else or messing with the intent of the class to begin with. Even an optional import would be better than sprinkling fromDouble() everywhere I have a literal constant. Would obviously produce much cleaner code and readable.

Thanks for all of your contributions.

David

No bit operations in wrapped numbers

There are no bit operations available in SafeLong/Number, like needed for these functions:

def isPowerOf2(i: SafeLong) = ((i-1) & i) == 0
def even(x: SafeLong) = (x & 1) == 0
def even(x: Number) = (x & 1) == 0

(might be useful to have such functions as well)

x16 for large numbers

The x16 prefix does not work for large numbers. E.g:

scala> x16"ABABABAB"
error: exception during macro expansion:
java.lang.NumberFormatException: For input string: "ABABABAB"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:495)
at spire.macrosk.Macros$.radix(Macros.scala:228)

Publish 0.4.0 against 2.9.x

Given that 0.3.0 had some bugs and 0.4.0 has a lot of nice new features, we should try to backport it to 2.9.x and publish it on Sonatype.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.