Lookup from a 3-column table and interpolate one of the columns? - c#

I have a table with 3 columns: Temperature, Pressure, and Gain.
interface IEntry
{
public float Temperature {get;}
public int Pressure {get;}
public float Gain {get;}
}
Given a certain "input" pair (Temperature_input, Pressure_input), I would like to match this pair with the ones in the table and lookup the corresponding gains, interpolating in certain cases.
Example:
T P G
3 1 0
3 2 1
3 3 2
3 5 4
6 1 0
6 2 2
6 3 3
8 1 0
8 2 3
9 1 0
Input pair (T = 4, P = 2):
Step 1: As the exact temperature T = 4 is not in the table, the immediate lower and upper temperatures 3 and 6 are examined (8 table entries)
Step 2: The pairs for T = 3, T = 6 are sorted by Pressure (which is an int)
3 1 0
6 1 0
3 2 1
6 2 2
3 3 2
6 3 3
3 5 4
3 5 4
Step 3: Linear interpolation between temperatures of the same pressure:
3 2 1
6 2 2
Result is the interpolated Gain = 1 + (2-1)/(6-3) = 1.33
What is an efficient way of implementing the lookup part of the table, that will be accessed millions of times?

Related

Why Random range give same output value every time? [duplicate]

This question already has answers here:
Random.Next returns always the same values [duplicate]
(4 answers)
Closed 8 months ago.
Here is the code which i used to for implementing Random class
class Program
{
public static void Main()
{
for (int j = 0; j < 5; j++)
{
foreach (var item in GenerateRandomList(new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }))
Console.Write(item + " ");
Console.WriteLine(" ");
}
}
public static List<int> GenerateRandomList(List<int> arr)
{
var random = new Random(new Random().Next(1,10000));
var ls = new List<int>();
while(arr.Count>0)
{
var index = random.Next(0, arr.Count-1);
ls.Add(arr[index]);
arr.RemoveAt(index);
}
return ls;
}
}
below are the results I am getting
first time
4 3 8 2 1 6 7 5 9 0
4 3 8 2 1 6 7 5 9 0
4 3 8 2 1 6 7 5 9 0
4 3 8 2 1 6 7 5 9 0
4 3 8 2 1 6 7 5 9 0
second time
6 3 4 2 8 5 9 1 7 0
6 3 4 2 8 5 9 1 7 0
6 3 4 2 8 5 9 1 7 0
6 3 4 2 8 5 9 1 7 0
6 3 4 2 8 5 9 1 7 0
third time
9 2 4 8 1 6 3 5 7 0
9 2 4 8 1 6 3 5 7 0
9 2 4 8 1 6 3 5 7 0
9 2 4 8 1 6 3 5 7 0
7 1 3 6 5 2 8 9 4 0
and So on..
what am i Missing?
sometimes it give different result but again it starts to repeat previous result.
new Random() creates a new random number generator instance, with the default seed.
In .NET Framework, the default seed value is time-dependent. In .NET Core, the default seed value is produced by the thread-static, pseudo-random number generator. From docs:
If the same seed is used for separate Random objects, they will generate the same series of random numbers.
If the default seed is time-based, and you create five Random objects in a quick succession, each of your generators will get the same seed (since time is not as precise that each instruction executes on a different timestamp), and thus produce the same pseudorandom number sequence.
You will want to create a Random instance only once; for example, as a class field.

C#'s Random producing recognisable pattern when using sequential seeds

Given the following:
for(int seed = 0; seed < 100; seed++) {
var random = new Random(seed);
var roll = (random.Next() % 6) + 1;
Console.Write(roll + " ");
}
I'm seeing a clear pattern in the output:
1 1 2 2 3 3 4 4 5 5 6 6 1 1 1 2 2 3 3 4 4 5 5 6 6
1 1 2 2 3 3 4 4 5 5 5 6 6 1 1 2 2 3 3 4 4 5 5 6 6
1 1 2 2 3 3 4 4 4 5 5 6 6 1 1 2 2 3 3 4 4 5 5 6 6
1 1 2 2 3 3 3 4 4 5 5 6 6 1 1 2 2 3 3 4 4 5 5 6 6
I do understand that recreating a new Random object every time with a sequential seed isn't the "proper" way of using the class, and that strictly speaking I should be keep the Random instance around, calling Next() on it each time.
However, my use case is that I need to be able to exit my program and restore the state at any moment, and continue the sequence of numbers.
I also need the user to be able to set a seed manually, so I was hoping to be able to do something like:
var random = new Random(userSeed + nextValueIndex);
var chosenValue = random.Next();
I've also tried random.Next(min, max), and it gives different results, but also in a clear pattern.
Clearly my approach isn't the right way to use the Random class, but what is, for my use case?
I understand that random number generation is a very complex topic, so while I'm sort of interested in an explanation of why this is happening, I'm most interested in a practical (easy?) solution ;-)
Here's my solution, which seems to work nicely. Rather than seeding Random with userSeed + index (where index counts from zero), I simply cache the exact result from Random as previousRandom, and then seed with userSeed + previousRandom. That way, I get nice big numbers as the seed, and it avoids the sequential pattern. (previousRandom is initialised as zero, but that's not a problem.)
So, this is roughly what my code looks like:
var nextSeed = userSeed + this.previousRandom;
var randomObj = new Random(nextSeed);
var nextRandomValue = randomObj.Next ();
var chosenValue = (nextRandomValue % randomRange) + rangeMin;
this.previousRandom = nextRandomValue;
return chosenValue;
The one remaining thing I should probably do is make sure that userSeed + previousRandom doesn't overflow (or overflows predictably), because previousRandom might get very close to int's upper bound (up to whatever range I allow for userSeed).

True pixel quantity

I know that my question will be a littel strange but i need realy some help. I have an algorithme to calculate true pixel quantity in a binary image. Her is an example how it work:
Binary Image :
0 0 1 0 0 1
1 1 1 1 0 1
1 1 1 1 1 1
1 1 0 0 0 1
0 1 0 0 0 1
Her is the result :
18 15 11 8 6 5
16 13 9 7 5 4
11 9 6 5 4 3
5 4 2 2 2 2
2 2 1 1 1 1
And this is how it work :
Result (i,j) = result (i+1, j) + result (i, j+1) - result(i + 1, j + 1) + Image(i,j)
Her an example for the 18 value:
18 = 16 + 15 - 13 + 0
My question :
What is the name of this algorithm because I need to get some more information about it?
Thank you for help.
This is called an integral image, or summed area table. It is used to speedup box filtering, among others. It is a 2D generalization of a prefix sum.

permutations of k objects from a set of n algorithm

I'm looking for an efficient way to achieve this:
you have a set of numbers, let's say that our set is equal to 4 (N = 4);
you have to generate all permutations of 3 elements (K = 3);
Output for N = 4 and K = 3:
1 2 3
1 2 4
1 3 2
1 3 4
1 4 2
1 4 3
2 1 3
2 1 4
2 3 1
2 3 4
2 4 1
2 4 3
3 1 2
3 1 4
3 2 1
3 2 4
3 4 1
3 4 2
4 1 2
4 1 3
4 2 1
4 2 3
4 3 1
4 3 2
Anyone have a great, nice'n'quick algorithm up their sleeve or web reference??
Thanks!
Something like this pseudocode:
permute(set, output, len) //output will hold all the permutations
for each number in the set do
choose number and store it at output[0]
if(!empty(set))
call permute(set{without the number}, output + (len - 1)!, len-1) //adjust the position
Invoke by permute(set, output, k)

Get max x rows plus all row info per group by in mysql to linq

A while ago I found a handy query for mysql to get the top X per group by.
This is what I mean:
if this is the table:
rid id1 id2 id3 value
1 1 1 1 10
2 1 1 2 11
3 1 1 3 9
4 1 2 1 20
5 1 2 2 18
6 1 2 3 23
7 1 3 1 30
8 1 3 2 34
9 1 3 3 31
10 1 3 4 27
11 1 3 5 32
12 1 4 1 41
13 1 4 2 40
14 1 4 3 43
15 1 5 1 53
16 1 5 2 51
17 1 5 3 50
18 2 1 1 11
19 2 1 2 9
20 2 1 3 12
I want to get this result:
rid id1 id2 id3 value
2 1 1 2 11
6 1 2 3 23
8 1 3 2 34
14 1 4 3 43
15 1 5 1 53
I can get this by running the following mysql query:
SELECT * FROM
(SELECT * FROM idsandvalue
WHERE id1=1 AND
(SELECT COUNT(*) FROM idsandvalue AS helper
WHERE helper.id1 = idsandvalue.id1
AND helper.id2= idsandvalue.id2
AND helper.value > idsandvalue.value
) < 1
)a;
if I change < 1 to lets say 2, 3 or x I can get the top x per id2 where id1=1 (so, two of the same id2's with different id3's) like this:
rid id1 id2 id3 value
1 1 1 1 10
2 1 1 2 11
4 1 2 1 20
6 1 2 3 23
8 1 3 2 34
11 1 3 5 32
12 1 4 1 41
14 1 4 3 43
15 1 5 1 53
16 1 5 2 51
two questions.
A) the query is not really fast in MySQL. Takes a while (runs a table with 3207394 rows). Can I get the same result with the use of a different query (I was not able to get it).
B) How can I translate this to linq? Due to the strange where statement, I have no clue how to translate this into linq.
(later I added this extra question as well)
in MySQL I use this query:
SELECT *,COUNT(*) AS Counter FROM idsandvalue GROUP BY id1,id2;
to get this result:
rid id1 id2 id3 value Counter
1 1 1 1 10 3
4 1 2 1 20 3
7 1 3 1 30 5
12 1 4 1 41 3
15 1 5 1 53 3
18 2 1 1 11 3
I'm also having difficulties translating this to Linq.
(extra info was too big for comment)
Hi John (thanks for the quick respond).
with this mysql query
SELECT * FROM
(SELECT * FROM idsandvalue
WHERE id1=1 AND
(SELECT COUNT(*) FROM idsandvalue AS helper
WHERE helper.id1 = idsandvalue.id1
AND helper.id2= idsandvalue.id2
AND helper.value > idsandvalue.value
) < 1
)a
I try to get the rows for each grouped id1 and id2 with it's biggest value. That's why in this case I get for instance row with id 2. 11 is the biggest of 10,11 and 9 where id1=1 and id2=1. and that's why I get the row with id 8, because where id1=1 and id2=3 the biggest value for column value is 34. If I change the query to < 2, I get the top two. for id2=1 and id2=3 this would give the rows with id 8 and 11. Is this better explained?
Recreated your table in SQL Server and ran your query against it, than converted the query via linqer:
from a in ((from idsandvalue in db.idsandvalue whereidsandvalue.id1 == 1 &&
(from helper in db.idsandvalue
where
helper.id1 == idsandvalue.id1 &&
helper.id2 == idsandvalue.id2 &&
helper.value > idsandvalue.value
select new {
helper
}).Count() < 1
select new {
idsandvalue
}))
select new {
a.idsandvalue.rid,
a.idsandvalue.id1,
a.idsandvalue.id2,
a.idsandvalue.id3,
a.idsandvalue.value
}
How's this:
var takeRows = 2; // or whatever value you want
var q = from i in idsandvalue
group i by new { i.ID1, i.ID2 } into g
orderby g.Key.ID1, g.Key.ID2
select new { g.Key.ID1, g.Key.ID2, TopValues = g.OrderByDescending(i => i.Value).Take(takeRows) };

Categories

Resources