Bankers' rounding for BigQuery - google-bigquery

Simple question what is the way to use bankers' rounding in BigQuery.
The only thing which I can find is:
BAD WAY to do it but still works:
CREATE TEMP FUNCTION test(num FLOAT64, decimalPlaces INT64)
RETURNS FLOAT64
LANGUAGE js AS """
var d = decimalPlaces || 0;
var m = Math.pow(10, d);
var n = +(d ? num * m : num).toFixed(8); // Avoid rounding errors
var i = Math.floor(n), f = n - i;
var e = 1e-8; // Allow for rounding errors in f
var r = (f > 0.5 - e && f < 0.5 + e) ?
((i % 2 == 0) ? i : i + 1) : Math.round(n);
return d ? r / m : r;
""";
SELECT ROUND(1.525,2)

There is a simpler way of calculating it:
CREATE TEMP FUNCTION bankersRound(num FLOAT64, decimals INT64)
RETURNS FLOAT64
LANGUAGE js AS """
var scale = Math.pow(10, decimals);
var result = value = (Math.round((num * scale) / 2) * 2) / scale;
return result;
""";

Bad way, but still works:
CREATE TEMP FUNCTION test(num FLOAT64, decimalPlaces INT64)
RETURNS FLOAT64
LANGUAGE js AS """
var d = decimalPlaces || 0;
var m = Math.pow(10, d);
var n = +(d ? num * m : num).toFixed(8); // Avoid rounding errors
var i = Math.floor(n), f = n - i;
var e = 1e-8; // Allow for rounding errors in f
var r = (f > 0.5 - e && f < 0.5 + e) ?
((i % 2 == 0) ? i : i + 1) : Math.round(n);
return d ? r / m : r;
""";
SELECT ROUND(1.525,2)

Related

What will be the decreases value for multiply two integer in Dafny

Basically, my target is to learn dafny basics. But I am confused about invariant and decreases. In this code, my first while loop decreases by one so I have set decreases b but in my inner loop it is divided by 10, so when I was trying to set up b%10 as a decreases value, it always showed me an error. here I need some expert suggestions. What will be the decreases value for the second while loop in this code in this code invariant and decreases values are right?
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
decreases b
{
while (b % 10 != 0)
invariant M * N == a * b + x
decreases ?? // what will be the value here ??
{
x := x + a;
b := b - 1;
}
a := 10 * a;
b := b / 10;
}
Res := x;
}
Here is a verification debugging technique: you should first write the assertion that, if proven, would make your previous failing assertions to verify. Since you have two errors, one on the postcondition, and one on the outer decrease clause, here are two assertions you could insert.
If you want to see the solution, skip the steps and go to the end of this post.
Steps to solution
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
decreases b
{
var oldB := b;
while (b % 10 != 0)
invariant M * N == a * b + x
{
x := x + a;
b := b - 1;
}
a := 10 * a;
b := b / 10;
assert b < oldB; // Just added: If proven, the decreases condition holds
}
Res := x;
assert Res == M*N; // Just added: If proven, the postcondition would be ok
}
Now you see the two errors are on these assert. It's time to "move the asserts up" by applying weakest precondition rules. That means we keep the assert, but we write assert before their preceding statement such that, if these new assertions held, the old assertions would be verified:
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
decreases b
{
var oldB := b;
while (b % 10 != 0)
invariant M * N == a * b + x
{
x := x + a;
b := b - 1;
}
a := 10 * a;
assert b / 10 < oldB; // Just added. The next assert conditionally verify
b := b / 10;
assert b < oldB;
}
assert x == M * N; // Just added. The next assert conditionally verify.
Res := x;
assert Res == M*N;
}
See in your IDE how the error is now on the two most recent asserts.
Let's consider the second assert x == M * N;. Why is it wrong? There is an invariant that says M * N == a * b + x. So, if x == M * N;, it probably means that b should be equal to zero.
However, when we exit the while loop, we only know the negation of the guard, which is !(b > 0), or b <= 0. That's why we could not conclude!
Since we never intended b to be non-positive, we either need to add the invariant b >= 0 to the outer loop, or simply change the guard to b != 0 - but if you do that, then it will complain that with decreases b, b is not bounded by zero anymore. So the invariant is better.
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
invariant b >= 0 // Just added
decreases b
{
var oldB := b;
while (b % 10 != 0)
invariant M * N == a * b + x
{
x := x + a;
b := b - 1;
}
a := 10 * a;
assert b / 10 < oldB;
b := b / 10;
assert b < oldB;
}
assert x == M * N;
Res := x;
assert Res == M*N;
}
Now the invariant b >= 0 might not be maintained by the loop. This is because the inner while loop modifies b and does not give invariant on the value of b. Of course, we want b >= 0. So we add the invariant in the inner loop.
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
invariant b >= 0
decreases b
{
var oldB := b;
while (b % 10 != 0)
invariant M * N == a * b + x
invariant b >= 0 // Just added
{
x := x + a;
b := b - 1;
}
a := 10 * a;
assert b / 10 < oldB;
b := b / 10;
assert b < oldB;
}
assert x == M * N;
Res := x;
assert Res == M*N;
}
Ok, now the only assertion remaining is assert b / 10 < oldB;
Note that you don't need to write decreases in the inner clause because the default decreases for E > 0 is inferred to be decreases E, and in this case, Dafny can prove that b % 10 decreases.
However, knowing that b%10 == 0 at the end is not useful to prove that b itself decreased. If b was 7, it could be that the inner loop was increasing b to 10 before exiting...
The most basic strategy would be to convert the assertion b / 10 < oldB as an invariant. If you add it like that, everything verifies!
Solution
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
invariant b >= 0
decreases b
{
var oldB := b;
while (b % 10 != 0)
invariant M * N == a * b + x
invariant b >= 0
invariant b / 10 < oldB
{
x := x + a;
b := b - 1;
}
a := 10 * a;
assert b / 10 < oldB;
b := b / 10;
assert b < oldB;
}
assert x == M * N;
Res := x;
assert Res == M*N;
}
Now, you can experiment a bit about other invariant and observe that the following clauses would solve this last problem as well:
invariant b <= oldB
decreases b
Take some time to remove the asserts now because they were only used for scaffolding, but keep the invariant :-)

Kotlin Calculating with BigDecimal vs Double

I have 2 Functions. One uses BigInteger and BigDecimal. I want to calculate sin(z) using the Taylor series:
Here is my code:
fun sinus(z: BigDecimal, upperBound: Int = 100): BigDecimal = calcSin(z, upperBound)
fun cosinus(z: BigDecimal, upperBound: Int = 100): BigDecimal = calcSin(z, upperBound, false)
fun calcSin(z: BigDecimal, upperBound: Int = 100, isSin: Boolean = true): BigDecimal {
var erg: BigDecimal = BigDecimal.ZERO
for (n in 0..upperBound) {
// val zaehler = (-1.0).pow(n).toBigDecimal() * z.pow(2 * n + (if (isSin) 1 else 0))
// val nenner = fac(2 * n + (if (isSin) 1 else 0)).toBigDecimal()
val zaehler = (-1.0).pow(n).toBigDecimal() * z.pow(2 * n + 1)
val nenner = fac(2 * n + 1).toBigDecimal()
erg += (zaehler / nenner)
}
return erg
}
fun calcSin(z: Double, upperBound: Int = 100): Double {
var res = 0.0
for (n in 0..upperBound) {
val zaehler = (-1.0).pow(n) * z.pow(2 * n + 1)
val nenner = fac(2 * n + 1, true)
res += (zaehler / nenner)
}
return res
}
fun fac(n: Int): BigInteger = if (n == 0 || n == 1) BigInteger.ONE else n.toBigInteger() * fac(n - 1)
fun fac(n: Int, dummy: Boolean): Double = if (n == 0 || n == 1) 1.0 else n.toDouble() * fac(n - 1, dummy)
According to Google, Sin(1) is
0.8414709848
The Output of the following is however:
println("Sinus 1: ${sinus(1.0.toBigDecimal())}")
println("Sinus 1: ${sinus(1.0.toBigDecimal()).toDouble()}")
println("Sinus 1: ${sinus(1.0.toBigDecimal(), 1000)}")
println("Sinus 1: ${calcSin(1.0)}")
Output:
Sinus 1: 0.8414373208078281027995610599000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Sinus 1: 0.8414373208078281
Sinus 1: 0.8414373208078281027995610599000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Sinus 1: 0.8414709848078965
Wha am I missing? Why does the Double-Variant gives the correct value, while The BigDecimal doesn't? Even with 1000 Iterations.
The commented out code was meant for calculation Cos as well, but wanted to figure out that Problem first, so i made both Functions look the same
In the BigDecimal variant, try replacing erg += (zaehler / nenner) with erg += (zaehler.divide(nenner, 20, RoundingMode.HALF_EVEN))
I suspect that the defaults for scaling the division results (as described here https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/BigDecimal.html) are not what you want.
BTW - I assume that performance is not part of the exercise, otherwise your implementation of factorial is a low hanging fruit.

Translating Obj-C RGBtoHSV() function to Swift. min = MIN( r, MIN(g, b )); etc

Could someone please help me with this function? This function is inside of a camera app that uses a filter algorithm to detect differences in colour variants etc. The syntax is very difficult for me. I don't know how to deal with the pointers in the arguments, the min and max variable syntax, what is delta etc? Could someone please translate for me? Much appreciated.
Also should I be doing something with UIColor? Someone mentioned it below. I have no idea how to convert though.
// r,g,b values are from 0 to 1 // h = [0,360], s = [0,1], v = [0,1]
// if s == 0, then h = -1 (undefined)
void RGBtoHSV( float r, float g, float b, float *h, float *s, float *v ) {
float min, max, delta;
min = MIN( r, MIN(g, b ));
max = MAX( r, MAX(g, b ));
*v = max;
delta = max - min;
if( max != 0 )
*s = delta / max;
else {
// r = g = b = 0
*s = 0;
*h = -1;
return;
}
if( r == max )
*h = ( g - b ) / delta;
else if( g == max )
*h=2+(b-r)/delta;
else
*h=4+(r-g)/delta;
*h *= 60;
if( *h < 0 )
*h += 360;
}
Swift translation attempt
// r,g,b values are from 0 to 1 // h = [0,360], s = [0,1], v = [0,1]
// if s == 0, then h = -1 (undefined)
func RGBtoHSV(r:Float, g:Float, b:Float, h:Float, s:Float, v:Float) {
var min:Float = 0.0
var max:Float = 0.0
var delta:Float = 0.0
min = MIN(r, MIN(g, b))
max = MAX(r, MAX(g, b))
var v = max
delta = max - min
if max != 0 {
var s = delta / max
}
else{
// r = g = b = 0
var s = 0
var h = -1
return
}
if r == max {
var h = (g - b) / delta
}
else if (g == max) {
var h = 2 + (b - r ) / delta
}
else{
var h = 4 + (r - g) / delta
var h = 60
}
if (h < 0) {
var h += 360 // how to deal with all of these pointers here in the original Obj-C function above?
}
}
The Swift equivalent of passing a pointer (the address of a variable)
is an "inout parameter":
func RGBtoHSV(r : Float, g : Float, b : Float, inout h : Float, inout s : Float, inout v : Float) {
let rgbMin = min(r, g, b)
let rgbMax = max(r, g, b)
let delta = rgbMax - rgbMin
v = rgbMax
s = delta/rgbMax
h = Float(0.0) // Replace by your actual calculation
}
This would be called as
let r : Float = 0.3
let g : Float = 0.5
let b : Float = 0.7
var h : Float = 0.0
var s : Float = 0.0
var v : Float = 0.0
RGBtoHSV(r, g, b, &h, &s, &v)
println([h, s, v])
But in Swift there is a better way to return multiple values:
You can return a tuple:
func RGBtoHSV(r : Float, g : Float, b : Float) -> (h : Float, s : Float, v : Float) {
let rgbMin = min(r, g, b)
let rgbMax = max(r, g, b)
let delta = rgbMax - rgbMin
let v = rgbMax
let s = delta/rgbMax
let h = Float(0.0) // Replace by your actual calculation
return (h, s, v)
}
And this would be called as
let r : Float = 0.3
let g : Float = 0.5
let b : Float = 0.7
let (h, s, v) = RGBtoHSV(r, g, b)
println([h, s, v])
Note that on iOS you can simply use the UIColor class to convert
between RGB and HSV (== HSB):
func RGBtoHSV(r : CGFloat, g : CGFloat, b : CGFloat) -> (h : CGFloat, s : CGFloat, v : CGFloat) {
var h : CGFloat = 0.0
var s : CGFloat = 0.0
var v : CGFloat = 0.0
let col = UIColor(red: r, green: g, blue: b, alpha: 1.0)
col.getHue(&h, saturation: &s, brightness: &v, alpha: nil)
return (h, s, v)
}
(or use the various extension/convenience methods from
What is the best/shortest way to convert a UIColor to hex (web color) in Swift?)

Maya-like camera implementation

I am working on Maya-like camera implementation, and I've done track and dolly functions correctly but I just cannot implement tumble.
I am working in PhiloGL engine (WebGL base), so I would really appreciate some help with code in this engine.
I've looked at how Maya's camera actually work, but I cannot find out. Here is my code so-far
if(mode == "rot")
{
var angleX = diffx / 150;
var angleY = diffy / 150;
//var angleZ = sign * Math.sqrt((diffx * diffx)+(diffy * diffy)) / 150;
e.stop();
//axe Z
//camera.position.x = x * Math.cos(angleX) - y * Math.sin(angleX);
//camera.position.y = x * Math.sin(angleX) + y * Math.cos(angleX);
//axe X
//camera.position.y = y * Math.cos(angleY) - z * Math.sin(angleY);
//camera.position.z = y * Math.sin(angleY) + z * Math.cos(angleY);
//camera.update();
//axe Y
camera.position.z = z * Math.cos(angleX) - x * Math.sin(angleX);
camera.position.x = z * Math.sin(angleX) + x * Math.cos(angleX);
camera.update();
position.x = e.x;
position.y = e.y;
position.z = e.z;
}
This isn't working nor do I know what am I doing wrong.
Any clues?
I use this in inka3d (www.inka3d.com) but it does not depend on inka3d. The output is a 4x4 matrix. Can you make use of that?
// turntable like camera, y is up-vector
// tx, ty and tz are camera target position
// rx, ry and rz are camera rotation angles (rad)
// di is camera distance from target
// fr is an array where the resulting view matrix is written into (16 values, row major)
control.cameraY = function(tx, ty, tz, rx, ry, rz, di, fr)
{
var a = rx * 0.5;
var b = ry * 0.5;
var c = rz * 0.5;
var d = Math.cos(a);
var e = Math.sin(a);
var f = Math.cos(b);
var g = Math.sin(b);
var h = Math.cos(c);
var i = Math.sin(c);
var j = f * e * h + g * d * i;
var k = f * -e * i + g * d * h;
var l = f * d * i - g * e * h;
var m = f * d * h - g * -e * i;
var n = j * j;
var o = k * k;
var p = l * l;
var q = m * m;
var r = j * k;
var s = k * l;
var t = j * l;
var u = m * j;
var v = m * k;
var w = m * l;
var x = q + n - o - p;
var y = (r + w) * 2.0;
var z = (t - v) * 2.0;
var A = (r - w) * 2.0;
var B = q - n + o - p;
var C = (s + u) * 2.0;
var D = (t + v) * 2.0;
var E = (s - u) * 2.0;
var F = q - n - o + p;
var G = di;
var H = -(tx + D * G);
var I = -(ty + E * G);
var J = -(tz + F * G);
fr[0] = x;
fr[1] = A;
fr[2] = D;
fr[3] = 0.0;
fr[4] = y;
fr[5] = B;
fr[6] = E;
fr[7] = 0.0;
fr[8] = z;
fr[9] = C;
fr[10] = F;
fr[11] = 0.0;
fr[12] = x * H + y * I + z * J;
fr[13] = A * H + B * I + C * J;
fr[14] = D * H + E * I + F * J;
fr[15] = 1.0;
};

Web Audio API WaveShaperNode

How do you use the waveshapernode in the web audio api? particular the curve Float32Array attribute?
Feel free to look at an example here.
In detail, I create a waveshaper curve with this function:
WAAMorningStar.prototype.createWSCurve = function (amount, n_samples) {
if ((amount >= 0) && (amount < 1)) {
ND.dist = amount;
var k = 2 * ND.dist / (1 - ND.dist);
for (var i = 0; i < n_samples; i+=1) {
// LINEAR INTERPOLATION: x := (c - a) * (z - y) / (b - a) + y
// a = 0, b = 2048, z = 1, y = -1, c = i
var x = (i - 0) * (1 - (-1)) / (n_samples - 0) + (-1);
this.wsCurve[i] = (1 + k) * x / (1+ k * Math.abs(x));
}
}
Then "load" it in a waveshaper node like this:
this.createWSCurve(ND.dist, this.nSamples);
this.sigmaDistortNode = this.context.createWaveShaper();
this.sigmaDistortNode.curve = this.wsCurve;
Everytime I need to change the distortion parameter, I re-create the waveshaper curve:
WAAMorningStar.prototype.setDistortion = function (distValue) {
var distCorrect = distValue;
if (distValue < -1) {
distCorrect = -1;
}
if (distValue >= 1) {
distCorrect = 0.985;
}
this.createWSCurve (distCorrect, this.nSamples);
}
(I use distCorrect to make the distortion sound nicer, values found euristically).
You can find the algorithm I use to create the waveshaper curve here