How to fix stackoverflow exception in scala - scala

def factorial(n : Int) : Int = {
if(n==1)
1
else
n * factorial(n-1)
}
println(factorial(500000))
While I am passing large value its throwing stackoverflow exception Can we fix it?

The question seems theoretical, because factorial of 500000 is really a huge number. The result is so huge it is not representable by IEEE Double, and I doubt there is any practical reason why to compute it.
Some math calculators (like SpeedCrunch) let you compute factorial using the gamma function, probably using some approximation for large numbers. The SpeedCrunch result of gamma(500000 + 1)is 1.02280158465190236533 * 10 2632341.
However, if you insist on doing it, this is how it can be done:
Implement factorial using tail recursion instead. See Tail Recursion in Scala: A Simple Example or http://alvinalexander.com/scala/scala-recursion-examples-recursive-programming
Note: you will still get integer arithmetics overflow for large inputs, and the result will be wrong for them. The largest input for a 32b signed integer for which the result will still fit in a 32b signed result is 12 (cf. Factorial does not work for all values)
You can avoid this by using Double to compute the result (you will get approximate result only for large numbers, and Infinity for 500000) or by using BigInt - the calculation will work for all values, but it will get slower.
Following code should produce the correct result, but it might take very long, and the result will be very long - you might perhaps even get out of memory errors. I tried computing factorial of 50000 with it and it took several seconds, and the resulting number was several pages long.
def factorial(n: Long): BigInt = {
#tailrec
def factorialAccumulator(acc: BigInt, n: Long): BigInt = {
if (n == 0) acc
else factorialAccumulator(n*acc, n-1)
}
factorialAccumulator(1, n)
}

Related

SCALA: Function for Square root of BigInt

I searched internet for a function to find exact square root of BigInt using scala programming language. I didn't get one, But saw one Java Program and I converted that function into Scala version. It is working but I am not sure, whether it can handle very large BigInt. But it returns BigInt only. Not BigDecimal as Square Root. It shows there is some bit manipulation done in the code with some hard coding of numbers like shiftRight(5), BigInt("8") and shiftRight(1). I can understand the logic clearly, But not the hard coding of these bitshift numbers and the number 8. May be these bitshift functions are not available in scala, and thats why it is needed to convert to java BigInteger at few places. These hard coded numbers may impact the precision of the result.I just changed the java code into scala code just copying the exact algorithm. And here is the code I have written in scala:
def sqt(n:BigInt):BigInt = {
var a = BigInt(1)
var b = (n>>5)+BigInt(8)
while((b-a) >= 0) {
var mid:BigInt = (a+b)>>1
if(mid*mid-n> 0) b = mid-1
else a = mid+1
}
a-1
}
My Points are:
Can't we return a BigDecimal instead of BigInt? How can we do that?
How these hardcoded numbers shiftRight(5), shiftRight(1) and 8 are related
to precision of the result.
I tested for one number in scala REPL: The function sqt is giving exact square root of the squared number. but not for the actual number as below:
scala> sqt(BigInt("19928937494873929279191794189"))
res9: BigInt = 141169888768369
scala> res9*res9
res10: scala.math.BigInt = 19928937494873675935734920161
scala> sqt(res10)
res11: BigInt = 141169888768369
scala>
I understand shiftRight(5) means divide by 2^5 ie.by 32 in decimal and so on..but why 8 is added here after shift operation? why exactly 5 shifts? as a first guess?
Your question 1 and question 3 are actually the same question.
How [do] these bitshifts impact [the] precision of the result?
They don't.
How [are] these hardcoded numbers ... related to precision of the result?
They aren't.
There are many different methods/algorithms for estimating/calculating the square root of a number (as can be seen here). The algorithm you've posted appears to be a pretty straight forward binary search.
Pick a number a guaranteed to be smaller than the target (square root of n).
Pick a number b guaranteed to be larger than the target (square root of n).
Calculate mid, the whole number mid-point between a and b.
If mid is larger than (or equal to) the target then move b to mid (-1 because we know it's too large).
If mid is smaller than the target then move a to mid (+1 because we know it's too small).
Repeat 3,4,5 until a is no longer less than b.
Return a-1 as the square root of n rounded down to a whole number.
The bitshifts and hardcoded numbers are used in selecting the initial value of b. But b only has be greater than the target. We could have just done var b = n. Why all the bother?
It's all about efficiency. The closer b is to the target, the fewer iterations are needed to find the result. Why add 8 after the shift? Because 31>>5 is zero, which is not greater than the target. The author chose (n>>5)+8 but he/she might have chosen (n>>7)+12. There are trade-offs.
Can't we return a BigDecimal instead of BigInt? How can we do that?
Here's one way to do that.
def sqt(n:BigInt) :BigDecimal = {
val d = BigDecimal(n)
var a = BigDecimal(1.0)
var b = d
while(b-a >= 0) {
val mid = (a+b)/2
if (mid*mid-d > 0) b = mid-0.0001 //adjust down
else a = mid+0.0001 //adjust up
}
b
}
There are better algorithms for calculating floating-point square root values. In this case you get better precision by using smaller adjustment values but the efficiency gets much worse.
Can't we return a BigDecimal instead of BigInt? How can we do that?
This makes no sense if you want exact roots: if a BigInt's square root can be represented exactly by a BigDecimal, it can be represented by a BigInt. If you don't want exact roots, you'll need to specify precision and modify the algorithm (and for most cases, Double will be good enough and much much much faster than BigDecimal).
I understand shiftRight(5) means divide by 2^5 ie.by 32 in decimal and so on..but why 8 is added here after shift operation? why exactly 5 shifts? as a first guess?
These aren't the only options. The point is that for every positive n, n/32 + 8 >= sqrt(n) (where sqrt is the mathematical square root). This is easiest to show by a bit of calculus (or just by building a graph of the difference). So at the start we know a <= sqrt(n) <= b (unless n == 0 which can be checked separately), and you can verify this remains true on each step.

chisel3 arithmetic operations on Doubles

Please I have problems manipulating arithmetic operations with doubles in chisel. I have been seeing examples that uses just the following types: Int,UInt,SInt.
I saw here that arithmetic operations where described only for SInt and UInt. What about Double?
I tried to declare my output out as Double, but didn't know how. Because the output of my code is Double.
Is there a way to declare in Bundle an input and an output of type Double?
Here is my code:
class hashfunc(val k:Int, val n: Int ) extends Module {
val a = k + k
val io = IO(new Bundle {
val b=Input(UInt(k.W))
val w=Input(UInt(k.W))
var out = Output(UInt(a.W))
})
val tabHash1 = new Array[Array[Double]](n)
val x = new ArrayBuffer[(Double, Data)]
val tabHash = new Array[Double](tabHash1.size)
for (ind <- tabHash1.indices){
var sum=0.0
for (ind2 <- 0 until x.size){
sum += ( x(ind2) * tabHash1(ind)(ind2) )
}
tabHash(ind) = ((sum + io.b) / io.w)
}
io.out := tabHash.reduce(_ + _)
}
When I compile the code, I get the following error:
code error
Thank you for your kind attention, looking forward to your responses.
Chisel does have a native FixedPoint type which maybe of use. It is in the experimental package
import chisel3.experimental.FixedPoint
There is also a project DspTools that has simulation support for Doubles. There are some nice features, e.g. it that allows modules to parameterized on the numeric types (Complex, Double, FixedPoint, SInt) so that you can run simulations on double to validate the desired mathematical behavior and then switch to a synthesizable number format that meets your precision criteria.
DspTools is an ongoing research projects and the team would appreciate outside users feedback.
Operations on floating point numbers (Double in this case) are not supported directly by any HDL. The reason for this is that while addition/subtraction/multiplication of fixed point numbers is well defined there are a lot of design space trade-offs for floating point hardware as it is a much more complex piece of hardware.
That is to say, a high performance floating point unit is a significant piece of hardware in it's own right and would be time shared in any realistic design.

How to randomly sample p percent of users in user event stream

I am looking for an algorithm that fairly samples p percent of users from an infinite list of users.
A naive algorithm looks something like this:
//This is naive.. what is a better way??
def userIdToRandomNumber(userId: Int): Float = userId.toString.hashCode % 1000)/1000.0
//An event listener will call this every time a new event is received
def sampleEventByUserId(event: Event) = {
//Process all events for 3% percent of users
if (userIdToRandomNumber(event.user.userId) <= 0.03) {
processEvent(event)
}
}
There are issues with this code though (hashCode may favor shorter strings, modulo arithmetic is discretizing value so its not exactly p, etc.).
Was is the "more correct" way of finding a deterministic mapping of userIds to a random number for the function userIdToRandomNumber above?
Try the method(s) below instead of the hashCode. Even for short strings, the values of the characters as integers ensure that the sum goes over 100. Also, avoid the division, so you avoid rounding errors
def inScope(s: String, p: Double) = modN(s, 100) < p * 100
def modN(s: String, n: Int): Int = {
var sum = 0
for (c <- s) { sum += c }
sum % n
}
Here is a very simple mapping, assuming your dataset is large enough:
For every user, generate a random number x, say in [0, 1].
If x <= p, pick that user
This is a practically used method on large datasets, and gives you entirely random results!
I am hoping you can easily code this in Scala.
EDIT: In the comments, you mention deterministic. I am interpreting that to mean if you sample again, it gives you the same results. For that, simply store x for each user.
Also, this will work for any number of users (even infinite). You just need to generate x for each user once. The mapping is simply userId -> x.
EDIT2: The algorithm in your question is biased. Suppose p = 10%, and there are 1100 users (userIds 1-1100). The first 1000 userIds have a 10% chance of getting picked, the next 100 have a 100% chance. Also, the hashing will map user ids to new values, but there is still no guarentee that modulo 1000 would give you a uniform sample!
I have come up with a deterministic solution to randomly sample users from a stream that is completely random (assuming the random number generator is completely random):
def sample(x: AnyRef, percent: Double): Boolean = {
new Random(seed=x.hashCode).nextFloat() <= percent
}
//sample 3 percent of users
if (sample(event.user.userId, 0.03)) {
processEvent(event)
}

Why can't I compute the factorial of 100 in scala?

I'm unit testing and I can't compute the factorial of 100. I read that using BigInt would help, but I'm not sure what I'm doing wrong, because it still doesn't work.
Here is my function.
package Factorial{
class factorial
{
def recursive_factorial(number:BigInt) : BigInt =
{
if (number == 0)
return 1
number * recursive_factorial (number - 1)
}
}
}
If I call the function with recursive_factorial(100).. I get an error that the number is too large for an int
The code you posted works fine. The problem is the code you use to test your code (which you posted in a comment to another answer):
assertResult(93326215443944152681699238856266700490715968264‌​38162146859296389521‌​75999932299156089414‌​63976156518286253697‌​92082722375825118521‌​09168640000000000000‌​00000000000) {
factorial.recursive_factorial(100)
}
The problem is that integer literals have type Int and the number 93326... is obviously too large to fit into an int, so you can't use an integer literal to represent it.
One way to create a BigInt of a large number is to write it as a string and convert that to a BigInt. So this will work fine:
assertResult(BigInt("93326215443944152681699238856266700490715968264‌​38162146859296389521‌​75999932299156089414‌​63976156518286253697‌​92082722375825118521‌​09168640000000000000‌​00000000000")) {
factorial.recursive_factorial(100)
}
first of all, your function has the problem of causing a stackoverflow when number is too large. You should write it tail-recursively:
#annotation.tailrec
def recursive_factorial(number: BigInt, result: BigInt = 1): BigInt = {
if (number == 0)
result
else
recursive_factorial(number -1, result * number)
}
otherwise, your code example works perfectly for me and I don't know what your problem is. Probably, you try to write the result of this function (which is a BigInt) into an Int at some point which triggers the error.
The function is just fine. Only limitation is the data type BigInt/BigInteger does not support arbitrary-precision point integer operation which can be done by BigDecimal. It works like a wrapper to BigInt. That's why instead of showing the big number it shows 9.332621544394415268169923885626674E+157. There is a discussion on which data type to use and when in the link below.
Performace of BigDecimal vs. BigInteger and BigDecimal

Does `Random.nextString()` take O(n) time in Scala?

When calling nextString() from the built-in scala.util.Random library, what time does it take to run? Is that O(n)?
Yes, it's O(n). It can't be any lower, because it creates a new string and that has O(n) cost. It shouldn't be any higher, because creating a random number is O(1) and that's enough to pick a character or word or something. And in practice it's actually O(n).
The constant factor is pretty high, though, due to how it's implemented. If it is important to you to make random strings really fast, you should get your own high-performance random number generator and pack chars into a char array.
Couldn't find anything on Scala docs, but from the source code:
def nextString(length: Int) = {
def safeChar() = {
val surrogateStart: Int = 0xD800
val res = nextInt(surrogateStart - 1) + 1
res.toChar
}
List.fill(length)(safeChar()).mkString
}
I would say O(n), assuming O(1) from nextInt(), on the length of the string asked