Conditional Future in Scala - scala

Given these two futures, I need to run the first one only if a condition is true (see if y>2). But I get an exception Future.filter predicate is not satisfied. What does this mean and how to fix the example?
object TestFutures extends App {
val f1 = Future {
1
}
val f2 = Future {
2
}
val y = 1
val x = for {
x1 <- f1 if y>2
x2 <- f2
} yield x1 + x2
Thread.sleep(5000)
println(x)
}

The question contains some terminology issues.
Given the requirement, "I need to run the first (future) one only if a condition is true", then one possible implementation of the requirement would be:
val f1 = if (cond) Some(Future(op)) else None
This is because a Future will start its execution once it's defined.
Going back to the expression in the question:
val x = for {
x1 <- f1 if y>2
x2 <- f2
} yield x1 + x2
This is saying "I want the result of f1 if(cond)" and not "I want to execute f1 if(cond)".
This would be a way: (note how the futures are defined within the for-comprehension, and the condition is outside):
val x = if (y > 2) {
for {
x1 <- Future(op1)
x2 <- Future(op2)
} yield x1 + x2
} else ???
The proper use of guards in for-comprehensions is to evaluate an expression against values coming from the computation expressed by the for-comprehension. For example:
"I want to execute f2 only if the result of f1 is greater than y"
val x = for {
x1 <- f1
x2 <- Future(op) if x1 > y
} yield x1 + x2
Note how the condition here involves an intermediate result of the computation (x1 in this case)
One side note: to wait for the result of a future, use Await.result(fut, duration) instead of Thread.sleep(duration)

filter is not really something you should be able to do on a Future - what would a Future that didn't pass the condition return? From your example: we still need to have a value for x1 (even if it fails the if) to use in the yield x1 + x2.
Therefore, the filter method on Future is designed to fail hard when the predicate evaluates to false. It is an "assert" of sorts. You probably would prefer something like this (that provides a default value for x1 if the condition fails):
val x = for {
x1 <- if (y > 2) f1 else Future.successful(/* some-default-value-for-x1 */)
x2 <- f2
} yield x1 + x2

Related

Scala for-yield with multiple conditions

I have a bitmap object that is a 3-dimensional array with third dimension equal to 3. I want to split it into 64x64x3 blocks. For this I have the following code snippet:
val tiles: someType = for {
x <- bitmap.indices by 64
y <- bitmap(0).indices by 64
data = for {
//For all X and Y within one future tile coordinates
tx <- x until x + 64
ty <- y until y + 64
} yield bitmap(tx)(ty)
...
}
In the data for loop yield will cause an ArrayIndexOutOfBoundsException at the last chunk. How can I check, whether x and y don't exceed array borders in this loop? Is it possible to have multiple until conditions for the same variable in the same loop?
What about this?
val tiles: someType = for {
x <- bitmap.indices by 64
y <- bitmap(0).indices by 64
data = for {
//For all X and Y within one future tile coordinates
tx <- x until math.min(x + 64, bitmap.length)
ty <- y until math.min(y + 64, bitmap(0).length)
} yield bitmap(tx)(ty)
}

Add a vector to every column of a matrix, using Scala Breeze

I have a matrix M of (L x N) rank and I want to add the same vector v of length L to every column of the matrix. Is there a way do this please, using Scala Breeze?
I tried:
val H = DenseMatrix.zeros(L,N)
for (j <- 0 to L) {
H (::,j) = M(::,j) + v
}
but this doesn't really fit Scala's immutability as H is then already defined and therefore gives a reassignment to val error. Any suggestions appreciated!
To add a vector to all columns of a matrix, you don't need to loop through columns; you can use the column broadcasting feature, for your example:
H(::,*) + v // assume v is breeze dense vector
Should work.
import breeze.linalg._
val L = 3
val N = 2
val v = DenseVector(1.0,2.0,3.0)
val H = DenseMatrix.zeros[Double](L, N)
val result = H(::,*) + v
//result: breeze.linalg.DenseMatrix[Double] = 1.0 1.0
// 2.0 2.0
// 3.0 3.0

logicblox simple rule intermediate representation

I have a logiql file with many "complicated" rules.
Here are some examples:
tuple1(x), tuple2(x), function1[y, z] = x <- in_tuple1(x), in_tuple2(x, y), in_tuple3[x, y] = z.
tuple1(x,y) <- (in_tuple1(x,z), in_tuple2(y,z)); in_tuple2(x,y)
For my purposes it would be much better to have only rules in the simple form: only one derived tuple per rule and no "OR" combinations of rules.
Does logicblox offer some intermediate representation output that only consists of the simpler rules?
I think there are intermediate representations created, but I don't know how to unearth them. Even if I did, I think my first advice would be to write the simpler rules you want.
I'm quite confident that the first example can be re-written as follows.
Example 1 Before
tuple1(x),
tuple2(x),
function1[y, z] = x
<-
in_tuple1(x),
in_tuple2(x, y),
in_tuple3[x, y] = z.
Example 1 After
tuple1(x) <- in_tuple1(x), in_tuple2(x, y), in_tuple3[x, y] = _.
tuple2(x) <- in_tuple1(x), in_tuple2(x, y), in_tuple3[x, y] = _.
/** alternatively
tuple1(x) <- function1[_, _] = x.
tuple2(x) <- function1[_, _] = x.
**/
function1[y, z] = x
<-
in_tuple1(x),
in_tuple2(x, y),
in_tuple3[x, y] = z.
I'm a little less confident with the second one. No conflicts between the two rules jump out at me. If there is a problem here you may get a functional dependency violation, which you'll know by the output or logging of "Error: Function cannot contain conflicting records."
Example 2 Before (assumed complete clause with "." at end)
tuple1(x,y)
<-
(
in_tuple1(x,z),
in_tuple2(y,z)
)
;
in_tuple2(x,y).
Example 2 After
tuple1(x,y)
<-
in_tuple1(x,z),
in_tuple2(y,z).
tuple1(x,y)
<-
in_tuple2(x,y).

How to write/code several functions as one

I am trying to write a line composed of two segments as a single equation in :
y = m1*x + c1 , for x<=x1
y = m2*x + c2 , for x>=x1
My questions are:
How can I write the function of this combined line as a single equation?
How can I write multiple functions (valid in separate regions of a linear parameter space) as a single equation?
Please explain both how to express this mathematically and how to program this in general and in Matlab specifically.
You can write this equation as a single line by using the Heaviside step function, https://en.wikipedia.org/wiki/Heaviside_step_function.
Combining two functions into one:
In fact, what you are trying to do is
f(x) = a(x) (for x < x1)
f(x) = q (for x = x1), where q = a(x1) = b(x1)
f(x) = b(x) (for x > x1)
The (half-maximum) Heaviside function is defined as
H(x) = 0 (for x < 0)
H(x) = 0.5 (for x = 0)
H(x) = 1 (for x > 0)
Hence, your function will be
f(x) = H(x1-x) * a(c) + H(x-x1) * b(x)
and, therefore,
f(x) = H(x1-x) * (m1*x+c1) + H(x-x1) * (m2x+c2)
If you want to implement this, note that many programming languages will allow you to write something like
f(x) = (x<x1)?a(x):b(x)
which means if x<x1, then return value a(x), else return b(x), or in your case:
f(x) = (x<x1)?(m1*x+c1):(m2x+c2)
Matlab implementation:
In Matlab, you can write simple functions such as
a = #(x) m1.*x+c1,
b = #(x) m2.*x+c2,
assuming that you have previously defined m1, m2, and c1, c2.
There are several ways to using/implementing the Heaviside function
If you have the Symbolic Math Toolbox for Matlab, you can directly use heaviside() as a function.
#AndrasDeak (see comments below) pointed out that you can write your own half-maximum Heaviside function H in Matlab by entering
iif = #(varargin) varargin{2 * find([varargin{1:2:end}], 1, 'first')}();
H = #(x) iif(x<0,0,x>0,1,true,0.5);
If you want a continuous function that approximates the Heaviside function, you can use a logistic function H defined as
H = #(x) 1./(1+exp(-100.*x));
Independently of your implementation of the Heaviside function H, you can, create a one-liner in the following way (I am using x1=0 for simplicity) :
a = #(x) 2.*x + 3;
b = #(x) -1.5.*x + 3;
Which allows you to write your original function as a one-liner:
f = #(x) H(-x).*a(x) + H(x).*b(x);
You can then plot this function, for example from -10 to 10 by writing plot(-10:10, f(-10:10)) you will get the plot below.
Generalization:
Imagine you have
f(x) = a(x) (for x < x1)
f(x) = q (for x = x1), where q = a(x1) = b(x1)
f(x) = b(x) (for x1 < x < x2)
f(x) = r (for x = x2), where r = b(x2) = c(x2)
f(x) = c(x) (for x2 < x < x3)
f(x) = s (for x = x2), where s = c(x3) = d(x3)
f(x) = d(x) (for x3 < x)
By multiplying Heaviside functions, you can now determine zones where specific functions will be computed.
f(x) = H(x1-x)*a(c) + H(x-x1)*H(x2-x)*b(x) + H(x-x2)*H(x3-x)*c(x) + H(x-x3)*d(x)
PS: just realized that one of the comments above talks about the Heaviside function, too. Kudos to #AndrasDeak .

How to solve a linear system of matrices in scala breeze?

How to solve a linear system of matrices in scala breeze? ie, I have Ax = b, where A is a matrix (usually positive definite), and x and b are vectors.
I can see that there is a cholesky decomposition available, but I couldn't seem to find a solver? (if it was matlab I could do x = b \ A. If it was scipy I could do x = A.solve(b) )
Apparently, it is quite simple in fact, and built into scala-breeze as an operator:
x = A \ b
It doesnt use Cholesky, it uses LU decomposition, which is I think about half as fast, but they are both O(n^3), so comparable.
Well, I wrote my own solver in the end. I'm not sure if this is the optimal way to do it, but it doesn't seem unreasonable? :
// Copyright Hugh Perkins 2012
// You can use this under the terms of the Apache Public License 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package root
import breeze.linalg._
object Solver {
// solve Ax = b, for x, where A = choleskyMatrix * choleskyMatrix.t
// choleskyMatrix should be lower triangular
def solve( choleskyMatrix: DenseMatrix[Double], b: DenseVector[Double] ) : DenseVector[Double] = {
val C = choleskyMatrix
val size = C.rows
if( C.rows != C.cols ) {
// throw exception or something
}
if( b.length != size ) {
// throw exception or something
}
// first we solve C * y = b
// (then we will solve C.t * x = y)
val y = DenseVector.zeros[Double](size)
// now we just work our way down from the top of the lower triangular matrix
for( i <- 0 until size ) {
var sum = 0.
for( j <- 0 until i ) {
sum += C(i,j) * y(j)
}
y(i) = ( b(i) - sum ) / C(i,i)
}
// now calculate x
val x = DenseVector.zeros[Double](size)
val Ct = C.t
// work up from bottom this time
for( i <- size -1 to 0 by -1 ) {
var sum = 0.
for( j <- i + 1 until size ) {
sum += Ct(i,j) * x(j)
}
x(i) = ( y(i) - sum ) / Ct(i,i)
}
x
}
}