Want to take part in these discussions? Sign in if you have an account, or apply for one below
Vanilla 1.1.4 is a product of Lussumo. More Information: Documentation, Community Support.
hm, like the name says: this array is to be used with extreme care! It is by no means garanteed, that it reflects the underlying elements in the way represented by the ILArray itself !!!! For example, if you build a reference array from ILArray<T> A by - lets say- transposing A, than A.T is a reference array. the ordering of A.T elements is different for matrices than that of A - even if both share the same underlying "InternalArray4Experts" System.T[] array.
In general, a more better way is to work around adressing single elements at all. There will most probably be a way to get rid of any loops and work on the ILArrays itself. ("A * B"). Post your code, if you need any help on that.
PS: One more note on "InternalArray4Experts": technically spoken, there is nothing wrong by accessing this System.Array - as long as the following restrictions are hold at least:
* make sure to only read from that underlying data array! There might be other ILArrays using this storage. The result of writing to it would be corruption of those arrays.
* make sure, the "InternalArray4Experts" reflects the storage of the ILArray correctly. This can be done by "ILArray.Detach()" which will change any referencing array into an solid array.
* anyway - trying not to use the "InternalArray4Experts" will always be safer :)
I see... Dont know exactly, why and how this restriction you are using comes into play. But the "true" cross corellation is much faster implemented via fft. I tested your code against the fft version and the speed up seems to be significant.
using System;
using System.Collections.Generic;
using System.Text;
using ILNumerics;
using ILNumerics.BuiltInFunctions;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
int len = 50000;
ILArray<double> accBuf = Computation.createTestData(len);
int shift = 102;
ILArray<double> data = accBuf["0;" + shift + ":end,0:" + (shift - 1)];
int sFFT = Computation.FindCorrelationShiftFFT(data, accBuf);
int s = Computation.FindCorrelationShift(data, accBuf);
System.Diagnostics.Debug.Print(String.Format(
"OrigShift:{0} FoundShift:{1} FoundViaFFT:{2}", shift, s, sFFT));
}
private class Computation : ILMath {
public static int FindCorrelationShift(
ILArray<double> inArray, ILArray<double> accumulationBuffer) {
// calculates how many elements to shift a data array by to line up with the accumulation array
// positive index shifts to the left, discarding earlier indices
// ... THIS IS YOUR CODE ABOVE ...
return iShift;
}
public static int FindCorrelationShiftFFT(
ILArray<double> A, ILArray<double> acc) {
ILArray<double> cc = ifftsym(conj(fft(A)) * fft(acc));
ILArray<double> shift = empty();
max(cc, ref shift, A.Dimensions.FirstNonSingleton());
return (int)shift.GetValue(0);
}
public static ILArray<double> createTestData(int len) {
return rand(1, len) + sin(linspace(0, pi, len));
}
}
}
}
See the full console application file here.
If you need to "restrict" the search for the shift to some fraction of the whole length, this could easily be done in the max(..) statement: cc["0:"+limit+"," + endlimit + ":end"] (or similar, not tested!)
Thank you. One more note to the "InternalArray4Experts". Whenever such problems come up, one should try to get around it in the following order:
1) "Unloop" the code - prevent loops over any elements. This can most often be done be reformulating the algorithm.
2) Check, if you can utilize one of the iterators. The ILArray<T>.Values collection iterates over all elements in a safe manner and gives read-only access to them. Also, it is faster than querying elements via GetValue()
3) When single element access is needed nevertheless:
3.1) Detach the array at first. This may also speed up the GetValue() functions.
3.2) Use GetValue(), specify only one parameter if possible, (ie. sequential access on one dimension)
3.3) Export the array into a predefined System.Array and work on that
3.4) Use "InternalArray4Experts" with lots of care...
thanks :)
just one more note: be carefull on assignments like those:
outArray = inArray,
since both will point to the same object afterwards! If this is not required behaviour, use
outArray = inArray.C to clone the array or outArray = inArray.R to create a reference instead.
1 to 9 of 9