Given 2 arrays of double of the same length (The 'Master' array 'A' and secondary 'B'). I want to write a function that 'align' B to A.
I defined alignment such that for each element of A, if B contains that element, then the element should be placed at the same index as A's.
Some specificity on A and B :
A and B are both initially sorted. After the alignment, B DON'T needs to be sorted.
A and B are of the same length.
There is no duplicate neither in A nor in B
A and B are rather small (10 elements max, more usually around 3-5 elements).
A should not change.
I tagged the question C# because it will be my final implementation, but I can adapt the answers
The function will be called often (100k/1M per seconds), I need something efficient ideally.
Ex1 :
A = [10, 11, 12, 13]
B = [10, 12, 14, 16] (initial)
= > [10, 16, 12, 14] B Final ([10, 14, 12, 16] is also valid, only the placement of the elements '10' and '12' are relevant (the other elements are not in A))
Ex2:
A = [10, 11, 12, 13]
B = [08, 09, 10, 11] (initial)
= > [10, 11, 08, 09] B Final
I write two different ways of doing this: one with a dictionary to keep the place of the existing elements, a second one with two pointers that advance in tandem. However, I found the code rather complicated/messy for what it is supposed to do.
Does someone know an existing algorithm for this or a clean and efficient way to do it?
Here's one way. Not optimal, but the code isn't bad.
private static double[] align(double[] A, double[] B)
{
var extras = B.Where(b => !A.Contains(b)).ToArray();
int i = 0;
var result = A.Select(a => B.Contains(a) ? a : extras[i++]).ToArray();
return result;
}
Related
Assuming I have:
double[] someArray = new [] { 11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44 };
Is there any out of the box way of creating a 4x4 matrix out of this array without having to split it into 4 arrays myself?
I know it is simple to do this, but I'm exploring how much is ready out of the box.
EDIT
Sorry for not being clear (thought title was):
What I'm wondering is if there is out of the box functionality with the Matrix builder in Math.NET Numerics. Something like:
Matrix<double> someMatrix = DenseMatrix.OfArray(columns: 4, rows: 4, data: someArray);
From looking at the documentation, you could use the constructor directly, or the function OfColumnMajor(int rows, int columns, IEnumerable<double> columnMajor), if your data is in column-major order.
The code would look like this:
//Using the constructor
Matrix<double> someMatrix = new DenseMatrix(4, 4, someArray)
//Using the static function
Matrix<double> someMatrix = DenseMatrix.OfColumnMajor(4, 4, someArray);
If your data is in row-major order, you could split into arrays and use one of the OfRows function, or use the constructor and transpose the matrix, as suggested by Christoph.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Let's say I have array which contains unique random numbers (where numbers have small possible range of 0 to 20). For example:
[6, 3, 11, 9, 4, 5]
How can I convert following array to something like this:
[3, 0, 5, 4, 1, 2]
The second array starts from 0 and ends with (array.Length-1), but placement is relative to magnitude in the first array.
How can I implement this in an efficient way in C/C++/C#? (more interested in the method)
I gave just one example. It can be really anything:
[7, 10, 0, 19, 50, 33, 45, 100]
[1, 2, 0, 3, 6, 4, 5, 7]
Smallest number from array A is 0 in array B. Biggest number in array A is (array.Length-1) in array B. Array A can be completely random (just it will never contain two or more identical numbers), but array A have to contain all numbers from 0 to array.Length-1) in same order as in array A.
int[] list1 = new[] { 7, 10, 0, 19, 50, 33, 45, 100 };
var orderedList = list1.OrderBy(x => x).ToList();
int[] list2 = list1.Select(x => orderedList.IndexOf(x)).ToArray();
EDIT
Per #Blorgbeard's request
int[] list1 = new[] { 6, 3, 11, 9, 4, 5 };
var dict = list1.OrderBy(x => x)
.Select((i, inx) => new { i, inx })
.ToDictionary(x => x.i, x => x.inx);
int[] list2 = list1.Select(x => dict[x]).ToArray();
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Finding all possible combinations of numbers to reach a given sum
I have to create method which from array of numbers selects numbers, which sum will be exact as required one or if such doesn't exist select the minimal greater one.
What would be the algorithm of this function?
public int[] selectExactSum(int[] X, int SUM) {
}
example:
numbers are: {5, 2, 8, 4, 6} and required sum is 12.
The result would be: {2, 4, 6}
If required sum is 13, the result would be:{2, 8, 4} - so, the sum would be in this case 14 - the first minimal greater one.
If Required sum is 15, the possible results would be: {5, 2, 8} or {5, 4, 6}. In this case return the one of your choice - probably the first one you get.
What would be the algorithm for custom numbers and sum?
Thanks,
Simon
This is a generalized case of the problem called subset sum. It's an NP-complete problem, thus the best known algorithm is pseudo-polynomial.
If you understand the above linked algorithm, you can deduct the modification necessary to solve your problem.
How about recursively?
public static int[] SelectExactSum(int[] x, int sum) {
int[]
rest = x.Skip(1).ToArray(),
with = x.Length == 1 ? x : x.Take(1).Concat(SelectExactSum(rest, sum - x[0])).ToArray(),
without = x.Length == 1 ? new int[0] : SelectExactSum(rest, sum);
int withSum = with.Sum(), withoutSum = without.Sum();
return
withSum >= sum ? (withoutSum >= sum ? (withSum < withoutSum ? with : without) : with) :
withoutSum >= sum ? without : new int[0];
}
Note: Calling SelectExactSum(new int[] {5,2,8,4,6}, 13) doesn't return {2,8,4} as stated in the question, but {5,8} as that actually sums up to 13.
Took me about 15 minutes to made it, you can see it running here:
http://jesuso.net/projects/selectExactSum/index.php?numbers=5%2C2%2C8%2C4%2C6&reqSum=15
And here's the code:
http://jesuso.net/projects/selectExactSum/selectExactSum.txt
I made it as simple as possible, but its made on PHP, let me know if you need some help translating it to c#.
I have a function that receives a power of two value.
I need to convert it to an enum range (0, 1, 2, 3, and so on), and then shift it back to the power of two range.
0 1
1 2
2 4
3 8
4 16
5 32
6 64
7 128
8 256
9 512
10 1024
... and so on.
If my function receives a value of 1024, I need to convert it to 10. What is the best way to do this in C#? Should I just keep dividing by 2 in a loop and count the iterations?
I know I can put it back with (1 << 10).
Just use the logarithm of base 2:
Math.Log(/* your number */, 2)
For example, Math.Log(1024, 2) returns 10.
Update:
Here's a rather robust version that checks if the number passed in is a power of two:
public static int Log2(uint number)
{
var isPowerOfTwo = number > 0 && (number & (number - 1)) == 0;
if (!isPowerOfTwo)
{
throw new ArgumentException("Not a power of two", "number");
}
return (int)Math.Log(number, 2);
}
The check for number being a power of two is taken from http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2
There are more tricks to find log2 of an integer on that page, starting here:
http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
This is the probably fastest algorithm when your CPU doesn't have a bit scan instruction or you can't access that instruction:
unsigned int v; // find the number of trailing zeros in 32-bit v
int r; // result goes here
static const int MultiplyDeBruijnBitPosition[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
r = MultiplyDeBruijnBitPosition[((uint32_t)((v & -v) * 0x077CB531U)) >> 27];
See this paper if you want to know how it works, basically, it's just a perfect hash.
Use _BitScanForward. It does exactly this.
This excellent article on implementing a Hidden Markov Model in C# does a fair job of classifying a single bit sequence based on training data.
How to modify the algorithm, or build it out (multiple HMMs?) to support the classification of multiple simultaneous bit sequences?
Example
Instead of classifying just one stream:
double t1 = hmm.Evaluate(new int[] { 0,1 }); // 0.49999423004045024
double t2 = hmm.Evaluate(new int[] { 0,1,1,1 }); // 0.11458685045803882
Rather classify a dual bit stream:
double t1 = hmm.Evaluate(new int[] { [0, 0], [0, 1] });
double t2 = hmm.Evaluate(new int[] { [0, 0], [1, 1], [0, 1], [1, 1] });
Or even better, three streams:
double t1 = hmm.Evaluate(new int[] { [0, 0, 1], [0, 0, 1] });
double t2 = hmm.Evaluate(new int[] { [0, 0, 1], [1, 1, 0], [0, 1, 1], [1, 1, 1] });
Obviously the training data would also be expanded.
The trick is to model the set of observations as the n-ary cartesian product of all possible values of each sequence, in your case the HMM will have 2^n output symbol where n is the number of bit sequences.
Example: for three bit sequences, the 8 symbols are: 000 001 010 011 100 101 110 111, as if we created a megavariable whose values are all the possible tuples of values of the individual observation sequences (0/1 of each bit sequence)
The article mentioned deals with the hidden Markov model implementation in the Accord.NET Framework. When using the complete version of the framework, and not just the subproject available in that article, one can use the generic HiddenMarkovModel model and use any suitable emission symbol distribution. If the user would like to express the joint probability between two or three discrete variables, it would be worth to use the JointDistribution class.
If, however, there are many symbol variables, such that expression all possible variable combinations is not practical, it should be better to use a continuous representation for the features and use a Multivariate Normal distribution instead.
An example would be:
// Specify a initial normal distribution for the samples.
var initialDensity = MultivariateNormalDistribution(3); // 3 dimensions
// Create a continuous hidden Markov Model with two states organized in a forward
// topology and an underlying multivariate Normal distribution as probability density.
var model = new HiddenMarkovModel<MultivariateNormalDistribution>(new Ergodic(2), density);
// Configure the learning algorithms to train the sequence classifier until the
// difference in the average log-likelihood changes only by as little as 0.0001
var teacher = new BaumWelchLearning<MultivariateNormalDistribution>(model)
{
Tolerance = 0.0001,
Iterations = 0,
};
// Fit the model
double likelihood = teacher.Run(sequences);