Two projections in same IQueryable - linq

Is it possible to have two projections, .Select(...), in one same query?
int total = ...;
var sendersInfo = db.Persons
.Select(p => new
{
sentSMS = p.SentSMS.Count(...large expression...),
})
// Calculate percentages
.Select(i => new
{
sentSMS = i.sentSMS,
percentage = i.sentSMS/total * 100
});
The above is not working because apparently "i.sentSMS" isn't calculated yet and so a 0 (zero) is being used instead of the result.
What I'm trying to avoid is this (below), which does work, but has repeated code "...large expression...":
int total = ...;
var sendersInfo = db.Persons
.Select(p => new
{
sentSMS = p.SentSMS.Count(...large expression...),
percentage = p.SentSMS.Count(...large expression...) / total * 100
});
Beside my question ("is it possible..."), is there a best way to achieve this? I don't like uggly code. Also I'm trying to achieve this in pure Linq-to-entities (no linq-to-objects)

Commenting on your comment:
You do not need to cast to float every time - as soon as one of the operands is a float, the other is promoted, so the result is of type which bears a higher precision (float > int).
There are two arithmetic operations in line:
i.sentSMS / total * 100
// (1) (2)
Division, then multiplying. Both operators / and * have the same priority (refer to e.g. this), so the expression is evaluated from the left side, first computing the quotient (because both dividend and divisor are int, the result is also int), then multiplying the result with 100 (also int).
So, instead of doing
(float)i.sentSMS / (float)total * 100
It suffices to do:
// ┌─ (float) thanks to casting
// │ ┌─ (int) -> (float) promotion here, making the result of division a (float) too
// │ │ ┌─ then 100 gets promoted in the second step the same way
(float)i.sentSMS / total * 100
And even shorter so:
// ┌─ (float) literal, because 100 is an (int) literal and 100.0 (or 100d) is a (double) literal
// │ ┌─ (int) -> (float) promotion
// │ │ ┌─ and again
100f * i.sentSMS / total
100f being a literal for float (same as (float)100, but neater) :)
In my opinion 100.0 looks even better, but it is a literal for double, even greater precision, so all the floats will get promoted to double, making the result double as well, and so you would get a compiler warning for losing precision while assigning double result to float variable.

Related

How to keep precision for big numbers in golang when converting from float to big.Int

I have an input that could be a very big or a very small float and need to convert it to big.Int, but for some reason, there is some precision loss.
I understand that this should happen for very small numbers, but why does it happen for a big number, and how to avoid it?
https://go.dev/play/p/AySnKAikSRx
All positive integers up to 9007199254740992 can be represented in a float64 without any loss of precision. Anything higher, you run the risk of precision loss, which is happening in your case.
To give a basic idea of why..
Say we're inventing an extremely compact scheme for representing floating point numbers using the following formula:
m.mm * 10^+-e
.. where:
e = exponent, [1-9]
m.mm = mantissa [0.01-9.99]
With this, we can figure out what range of values can be represented:
lowest = 0.01 * 10^-9 = 0.00000000001
highest = 9.99 * 10^9 = 9990000000
So that's a pretty decent range of numbers.
We can represent a fair few positive integers without any difficulty, e.g.
1 = 1.00 * 10^0
2 = 2.00 * 10^0
3 = 3.00 * 10^0
⋮
10 = 1.00 * 10^1
11 = 1.10 * 10^1
12 = 1.20 * 10^1
⋮
100 = 1.00 * 10^2
101 = 1.01 * 10^2
102 = 1.02 * 10^2
⋮
999 = 9.99 * 10^2
The problem starts when we exceed 9.99 * 10^2. It's not an issue to represent 1000:
1000 = 1.00 * 10^3
But how do represent 1001? The next possible value is
1.01 * 10^3 = 1010
Which is +9 loss of precision, so we have to settle on 1.00 * 10^3 with -1 loss of precision.
The above is in essence how this plays out with float64, except in base 2 and with a 52 bit mantissa in play. With all 52 bits set, and then adding one, the value is:
1.0 * 2^53 = 9007199254740992
So all positive integers up to this value can be represented without precision loss. Integers higher than this may incur precision loss - it very much depends on the value.
Now, the value referenced in your Go code:
var x float64 = 827273999999999954
There is no way to represent this exact value as a float64.
package main
import (
"fmt"
)
func main() {
var x float64 = 827273999999999954
fmt.Printf("%f\n", x)
}
yields..
827274000000000000.000000
So essentially precision is lost by the time x is initialized. But when does that occur? If we run..
$ go build -o tmp
$ go tool objdump tmp
And search for TEXT main.main(SB), we can find the instruction:
main.go:10 0x108b654 48b840d5cba322f6a643 MOVQ $0x43a6f622a3cbd540, AX
So 0x43a6f622a3cbd540 is being set into AX - this is our float64 value.
package main
import (
"fmt"
"math"
)
func main() {
fmt.Printf("float: %f\n", math.Float64frombits(0x43a6f622a3cbd540))
}
prints
float: 827274000000000000.000000
So the precision has essentially been lost at compile time (which makes sense). So on the line of code with big.NewFloat(x).Int(nil), the value being passed as x is 827274000000000000.000000
how to avoid it?
With the code you've provided, there is no way.
If you're able to represent the value as an integer..
package main
import (
"fmt"
"math/big"
)
func main() {
var x uint64 = 827273999999999954
bf := (&big.Float{}).SetUint64(x)
fmt.Println(bf)
}
yields
8.27273999999999954e+17
which is the value you're expecting. Or alternatively via a string:
package main
import (
"fmt"
"math/big"
)
func main() {
var x string = "827273999999999954"
bf, ok := (&big.Float{}).SetString(x)
if !ok {
panic("failed to set string")
}
fmt.Println(bf)
}

Set value for Progress bar in xamarin

I have value of a field coming from server lfrom 1 to 100 which is to show progress of that field. But I checked that we can provide value to progress bar from 0 to1. How can i convert this. I did something like this but didn't work
Int Field = 12;
Decimal d = Field / 100;
Decimal dc = Math.Round(d,1); //to round to one decimal place
return dc;
This is returning 0.
I tried this too:
double d = (double)(Progress / 100);
double dc = Math.Round(d, 1);
return dc;
This is also returning 0.
if you want maximum precision, you can convert an old range of values in a new range maintaining the ratio with this formula:
var OldRange = (OldMax - OldMin);
var NewRange = (NewMax - NewMin);
//i'm using round here has you requested, but its better to dont use it to achieve best results
var NewValue = Math.Round(((OldValue - OldMin) * NewRange) / OldRange) + NewMin, 1);
In your case, taking for example the number 12, this will be:
var OldRange = 99 //(100 - 1);
var NewRange = 1 //(1 - 0);
var NewValue = Math.Round(((12 - 1) * NewRange) / OldRange) + 0, 1);
Concluding the number 12 in the old range is 0.1 in the new range.
Or if you dont care that the old range starts from 1 and the new from 0, you can just divide by 100 and round the value:
Int field = 12;
Decimal d = field / 100;
Decimal dc = Math.Round(d,1); //to round to one decimal place
return dc;
Please note that in c# the divide operator is / and not % (wich is the modulus)
Turns out "/" operator doesn't work in C#
NO, "/" operator do work in C#.
You get a zero because Field / 100; is int/int, the result is 0;
Progress / 100 is the same, int/int get 0;
To make your code work. You can define the field as type Decimal :
Decimal Field = 12;
Decimal d = Field / 100;
Decimal dc = Math.Round(d, 1);
Or cast the 100 to Decimal:
int Field = 12;
Decimal d = Field /(Decimal)100;
Decimal dc = Math.Round(d, 1);
You can see detailed answer in these two threads: why-does-integer-division-in-c-sharp-return-an-integer-and-not-a-float
and
how-can-i-divide-two-integers-to-get-a-double

Go: Converting float64 to int with multiplier

I want to convert a float64 number, let's say it 1.003 to 1003 (integer type). My implementation is simply multiply the float64 with 1000 and cast it to int.
package main
import "fmt"
func main() {
var f float64 = 1.003
fmt.Println(int(f * 1000))
}
But when I run that code, what I got is 1002 not 1003. Because Go automatically stores 1.003 as 1.002999... in the variable. What is the correct approach to do this kind of operation on Golang?
Go spec: Conversions:
Conversions between numeric types
When converting a floating-point number to an integer, the fraction is discarded (truncation towards zero).
So basically when you convert a floating-point number to an integer, only the integer part is kept.
If you just want to avoid errors arising from representing with finite bits, just add 0.5 to the number before converting it to int. No external libraries or function calls (from standard library) required.
Since float -> int conversion is not rounding but keeping the integer part, this will give you the desired result. Taking into consideration both the possible smaller and greater representation:
1002.9999 + 0.5 = 1003.4999; integer part: 1003
1003.0001 + 0.5 = 1003.5001; integer part: 1003
So simply just write:
var f float64 = 1.003
fmt.Println(int(f * 1000 + 0.5))
To wrap this into a function:
func toint(f float64) int {
return int(f + 0.5)
}
// Using it:
fmt.Println(toint(f * 1000))
Try them on the Go Playground.
Note:
Be careful when you apply this in case of negative numbers! For example if you have a value of -1.003, then you probably want the result to be -1003. But if you add 0.5 to it:
-1002.9999 + 0.5 = -1002.4999; integer part: -1002
-1003.0001 + 0.5 = -1002.5001; integer part: -1002
So if you have negative numbers, you have to either:
subtract 0.5 instead of adding it
or add 0.5 but subtract 1 from the result
Incorporating this into our helper function:
func toint(f float64) int {
if f < 0 {
return int(f - 0.5)
}
return int(f + 0.5)
}
As Will mentions, this comes down to how floats are represented on various platforms. Essentially you need to round the float rather than let the default truncating behavior to happen. There's no standard library function for this, probably because there's a lot of possible behavior and it's trivial to implement.
If you knew you'd always have errors of the sort described, where you're slightly below (1299.999999) the value desired (1300.00000) you could use the math library's Ceil function:
f := 1.29999
n := math.Ceil(f*1000)
But if you have different kinds of floating error and want a more general sorting behavior? Use the math library's Modf function to separate the your floating point value by the decimal point:
f := 1.29999
f1,f2 := math.Modf(f*1000)
n := int(f1) // n = 1299
if f2 > .5 {
n++
}
fmt.Println(n)
You can run a slightly more generalized version of this code in the playground yourself.
This is probably likely a problem with floating points in general in most programming languages though some have different implementations than others. I wouldn't go into the intricacies here but most languages usually have a "decimal" approach either as a standard library or a third party library to get finer precision.
For instance, I've found the inf.v0 package largely useful. Underlying the library is a Dec struct that holds the exponents and the integer value. Therefore, it's able to hold 1.003 as 1003 * 10^-3. See below for an example:
package main
import (
"fmt"
"gopkg.in/inf.v0"
)
func main() {
// represents 1003 * 10^-3
someDec := inf.NewDec(1003, 3)
// multiply someDec by 1000 * 10^0
// which translates to 1003 * 10^-3 * 1000 * 10^0
someDec.Mul(someDec, inf.NewDec(1000, 0))
// inf.RoundHalfUp rounds half up in the 0th scale, eg. 0.5 rounds to 1
value, ok := someDec.Round(someDec, 0, inf.RoundHalfUp).Unscaled()
fmt.Println(value, ok)
}
Hope this helps!

RX LINQ partition the input stream

I have a input stream where the input element consist of Date, Depth and Area.
I want to plot the Area against the Depth and want therefor to take out a window of Depth e.g. between 1.0-100.0m.
The problem is that I want to down sample the input stream since there can be many inputs with close Depth values.
I want to partition the input into x bins, e.g. 2 bins means all depth values between 1-50 is averaged in the first bin and 51-100 in the second bin.
I was thinking something like this:
var q = from e in input
where (e.Depth > 1) && (e.Depth <= 100)
// here I need some way of partition the sequence into bins
// and averaging the elements.
Split a collection into `n` parts with LINQ? wants to do something similar without rx.
Modified answer as per your comment. steps = number of buckets.
var min = 1, max = 100;
var steps = 10;
var f = (max - min + 1) / steps; // The extra 1 is really an epsilon. #hack
var q = from e in input
where e.Depth > 1 && e.depth <= 100
let x = e.Depth - min
group e by x < max ? (x - (x % f)) : ;
This is the function we're grouping by for the given e.Depth.
This probably won't work so great with floating point values (due to precision), unless you floor/ceil the selection, but then you might run out of integers, so you may need to scale a bit... something like group e by Math.Floor((x - (x % f)) * scaleFactor).
This should do what you want
static int GetBucket(double value, double min, double max, int bucketCount)
{
return (int)((value - min) / (max - min) * bucketCount + 0.5);
}
var grouped = input.GroupBy(e => GetBucket(e.Depth, 1, 100, 50));

Approximating inverse trigonometric functions

I have to implement asin, acos and atan in environment where I have only following math tools:
sine
cosine
elementary fixed point arithmetic (floating point numbers are not available)
I also already have reasonably good square root function.
Can I use those to implement reasonably efficient inverse trigonometric functions?
I don't need too big precision (the floating point numbers have very limited precision anyways), basic approximation will do.
I'm already half decided to go with table lookup, but I would like to know if there is some neater option (that doesn't need several hundred lines of code just to implement basic math).
EDIT:
To clear things up: I need to run the function hundreds of times per frame at 35 frames per second.
In a fixed-point environment (S15.16) I successfully used the CORDIC algorithm (see Wikipedia for a general description) to compute atan2(y,x), then derived asin() and acos() from that using well-known functional identities that involve the square root:
asin(x) = atan2 (x, sqrt ((1.0 + x) * (1.0 - x)))
acos(x) = atan2 (sqrt ((1.0 + x) * (1.0 - x)), x)
It turns out that finding a useful description of the CORDIC iteration for atan2() on the double is harder than I thought. The following website appears to contain a sufficiently detailed description, and also discusses two alternative approaches, polynomial approximation and lookup tables:
http://ch.mathworks.com/examples/matlab-fixed-point-designer/615-calculate-fixed-point-arctangent
Do you need a large precision for arcsin(x) function? If no you may calculate arcsin in N nodes, and keep values in memory. I suggest using line aproximation. if x = A*x_(N) + (1-A)*x_(N+1) then x = A*arcsin(x_(N)) + (1-A)*arcsin(x_(N+1)) where arcsin(x_(N)) is known.
you might want to use approximation: use an infinite series until the solution is close enough for you.
for example:
arcsin(z) = Sigma((2n!)/((2^2n)*(n!)^2)*((z^(2n+1))/(2n+1))) where n in [0,infinity)
http://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Expression_as_definite_integrals
You could do that integration numerically with your square root function, approximating with an infinite series:
Submitting here my answer from this other similar question.
nVidia has some great resources I've used for my own uses, few examples: acos asin atan2 etc etc...
These algorithms produce precise enough results. Here's a straight up Python example with their code copy pasted in:
import math
def nVidia_acos(x):
negate = float(x<0)
x=abs(x)
ret = -0.0187293
ret = ret * x
ret = ret + 0.0742610
ret = ret * x
ret = ret - 0.2121144
ret = ret * x
ret = ret + 1.5707288
ret = ret * math.sqrt(1.0-x)
ret = ret - 2 * negate * ret
return negate * 3.14159265358979 + ret
And here are the results for comparison:
nVidia_acos(0.5) result: 1.0471513828611643
math.acos(0.5) result: 1.0471975511965976
That's pretty close! Multiply by 57.29577951 to get results in degrees, which is also from their "degrees" formula.
It should be easy to addapt the following code to fixed point. It employs a rational approximation to calculate the arctangent normalized to the [0 1) interval (you can multiply it by Pi/2 to get the real arctangent). Then, you can use well known identities to get the arcsin/arccos from the arctangent.
normalized_atan(x) ~ (b x + x^2) / (1 + 2 b x + x^2)
where b = 0.596227
The maximum error is 0.1620º
#include <stdint.h>
#include <math.h>
// Approximates atan(x) normalized to the [-1,1] range
// with a maximum error of 0.1620 degrees.
float norm_atan( float x )
{
static const uint32_t sign_mask = 0x80000000;
static const float b = 0.596227f;
// Extract the sign bit
uint32_t ux_s = sign_mask & (uint32_t &)x;
// Calculate the arctangent in the first quadrant
float bx_a = ::fabs( b * x );
float num = bx_a + x * x;
float atan_1q = num / ( 1.f + bx_a + num );
// Restore the sign bit
uint32_t atan_2q = ux_s | (uint32_t &)atan_1q;
return (float &)atan_2q;
}
// Approximates atan2(y, x) normalized to the [0,4) range
// with a maximum error of 0.1620 degrees
float norm_atan2( float y, float x )
{
static const uint32_t sign_mask = 0x80000000;
static const float b = 0.596227f;
// Extract the sign bits
uint32_t ux_s = sign_mask & (uint32_t &)x;
uint32_t uy_s = sign_mask & (uint32_t &)y;
// Determine the quadrant offset
float q = (float)( ( ~ux_s & uy_s ) >> 29 | ux_s >> 30 );
// Calculate the arctangent in the first quadrant
float bxy_a = ::fabs( b * x * y );
float num = bxy_a + y * y;
float atan_1q = num / ( x * x + bxy_a + num );
// Translate it to the proper quadrant
uint32_t uatan_2q = (ux_s ^ uy_s) | (uint32_t &)atan_1q;
return q + (float &)uatan_2q;
}
In case you need more precision, there is a 3rd order rational function:
normalized_atan(x) ~ ( c x + x^2 + x^3) / ( 1 + (c + 1) x + (c + 1) x^2 + x^3)
where c = (1 + sqrt(17)) / 8
which has a maximum approximation error of 0.00811º
Maybe some kind of intelligent brute force like newton rapson.
So for solving asin() you go with steepest descent on sin()
Use a polynomial approximation. Least-squares fit is easiest (Microsoft Excel has it) and Chebyshev approximation is more accurate.
This question has been covered before: How do Trigonometric functions work?
Only continous functions are approximable by polynomials. And arcsin(x) is discontinous in point x=1.same arccos(x).But a range reduction to interval 1,sqrt(1/2) in that case avoid this situation. We have arcsin(x)=pi/2- arccos(x),arccos(x)=pi/2-arcsin(x).you can use matlab for minimax approximation.Aproximate only in range [0,sqrt(1/2)](if angle for that arcsin is request is bigger that sqrt(1/2) find cos(x).arctangent function only for x<1.arctan(x)=pi/2-arctan(1/x).

Resources