/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="time"></param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(long time, DoubleArray input) { AssertTrue(Start >= 0 && Start < input.Properties, "Start is out of range from input's Properties."); AssertTrue(Stop >= 0 && Stop < input.Properties, "Stop is out of range from input's Properties."); AssertTrue(Stop >= 0 && Stop < input.Properties, "Stop and Start is out of range from input's Properties."); var propsLen = Stop - Start; if (input.Count == 1) { var ret = new DoubleArray2DManaged(1, propsLen); for (int i = 0; i < propsLen; i++) { ret[0, i] = input[0, i + Start]; } return(ret); } else { var ret = new DoubleArray2DManaged(input.Count, propsLen); var inputCount = input.Count; for (int cnt = 0; cnt < inputCount; cnt++) { for (int prop = 0; prop < propsLen; prop++) { ret[cnt, prop] = input[cnt, prop + Start]; } } return(ret); } }
public void JaggedArray(double value1, double value2, double value3, double value4) { var d = new double[2][]; d[0] = new[] { value1, value2 }; d[1] = new[] { value3, value4 }; var arr = new DoubleArray2DManaged(d); arr.ToArray().Should().BeEquivalentTo(value1, value2, value3, value4); }
/// <summary> /// Selects a <see cref="DoubleArray"/> to another <see cref="DoubleArray"/>. The result is stored in a <see cref="Identity"/>. /// </summary> /// <param name="input">The indicator that sends data via <see cref="IUpdatable.Updated"/></param> /// <param name="selector">A selector to choose what <see cref="DoubleArray"/>.</param> /// <param name="waitForFirstToReady">Input must be ready in order to push the updates forward.</param> /// <param name="name">Name of the new returned <see cref="Identity"/>.</param> public static Identity Select(this IUpdatable input, ArraySelectorFunctionHandler selector, int outputCount = 1, int properties = 1, bool waitForFirstToReady = true, string name = null) { if (selector == null) { throw new ArgumentNullException(nameof(selector)); } outputCount = outputCount > 0 ? outputCount : input.OutputCount; var idn = new Identity(ResolveName(input, name), outputCount, properties); if (outputCount > 1) { unsafe { if (waitForFirstToReady) { input.Updated += (time, updated) => { if (input.IsReady) { var ret = new DoubleArray2DManaged(outputCount, properties); fixed(double *dst = ret, selectSrc = updated) for (int i = 0; i < updated.Count; i++) { var result = selector(selectSrc[i * updated.Properties]); Guard.AssertTrue(result.Count == outputCount, "Passed outputCount must be matching to the updated array."); Guard.AssertTrue(properties == result.Properties, "Properties must match the properties argument passed."); fixed(double *src = result) Unsafe.CopyBlock(dst + i, src, (uint)(result.LinearLength * sizeof(double))); } idn.Update(time, ret); } }; } else { input.Updated += (time, updated) => { var ret = new DoubleArray2DManaged(updated.Count, properties); fixed(double *dst = ret, selectSrc = updated) for (int i = 0; i < outputCount; i++) { var result = selector(selectSrc[i * updated.Properties]); Guard.AssertTrue(result.Count == outputCount, "Passed outputCount must be matching to the updated array."); Guard.AssertTrue(properties == result.Properties, "Properties must match the properties argument passed."); fixed(double *src = result) Unsafe.CopyBlock(dst, src, (uint)(result.LinearLength * sizeof(double))); } idn.Update(time, ret); }; } input.Resetted += sender => idn.Reset(); } } if (waitForFirstToReady) { input.Updated += (time, updated) => { if (input.IsReady) { idn.Update(time, selector(updated)); } }; } else { input.Updated += (time, updated) => idn.Update(time, selector(updated)); } input.Resetted += sender => idn.Reset(); return(idn); }
/// <summary> /// Selects a <see cref="DoubleArray"/> to a <see cref="double"/>. The result is stored in a <see cref="Identity"/>. /// </summary> /// <param name="input">The indicator that sends data via <see cref="IUpdatable.Updated"/></param> /// <param name="selector">A selector to choose a <see cref="double"/>. </param> /// <param name="waitForFirstToReady">Input must be ready in order to push the updates forward.</param> /// <param name="name">Name of the new returned <see cref="Identity"/>.</param> public static Identity Select(this IUpdatable input, SelectorFunctionHandler selector, bool waitForFirstToReady = true, string name = null) { if (selector == null) { throw new ArgumentNullException(nameof(selector)); } var idn = new Identity(ResolveName(input, name), setReady: true); if (input.OutputCount > 1) { unsafe { if (waitForFirstToReady) { input.Updated += (time, updated) => { if (input.IsReady) { var ret = new DoubleArray2DManaged(updated.Count, 1); fixed(double *dst = ret, src = updated) for (int i = 0; i < updated.Count; i++) { dst[i] = selector(src[i * updated.Properties]); } idn.Update(time, ret); } }; } else { input.Updated += (time, updated) => { var ret = new DoubleArray2DManaged(updated.Count, 1); fixed(double *dst = ret, src = updated) for (int i = 0; i < updated.Count; i++) { dst[i] = selector(src[i * updated.Properties]); } idn.Update(time, ret); }; } input.Resetted += sender => idn.Reset(); } } else { if (waitForFirstToReady) { input.Updated += (time, updated) => { if (input.IsReady) { idn.Update(time, new DoubleArrayScalar(selector(updated))); } }; } else { input.Updated += (time, updated) => idn.Update(time, new DoubleArrayScalar(selector(updated))); } input.Resetted += sender => idn.Reset(); } return(idn); }