/// <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); }
/// <summary> /// Performs a math <paramref name="op"/> over <see cref="DoubleArray.Value"/> or value from <paramref name="selector"/>. The result is stored in a <see cref="Identity"/>. /// </summary> /// <param name="first">The indicator that sends data via <see cref="IUpdatable.Updated"/> even to the math <paramref name="op"/></param> /// <param name="op">The operation to perform on <see cref="DoubleArray.Value"/>.</param> /// <param name="selector">A selector to choose what <see cref="double"/> to pass to math <paramref name="op"/>. By default <see cref="DoubleArray.Value"/> is used.</param> /// <param name="waitForFirstToReady">First must be ready in order to push the updates forward.</param> /// <param name="name">Name of the new returned <see cref="Identity"/> representing the <paramref name="op"/>.</param> public static Identity Function(this IUpdatable first, UnaryFunctionHandler op, SelectorFunctionHandler selector = null, bool waitForFirstToReady = true, string name = null) { if (op == null) { throw new ArgumentNullException(nameof(op)); } var idn = new Identity(ResolveName(first, name)); if (selector == null) { if (waitForFirstToReady) { first.Updated += (time, updated) => { if (first.IsReady) { idn.Update(time, op(updated.Value)); } }; } else { first.Updated += (time, updated) => idn.Update(time, op(updated.Value)); } } else { if (waitForFirstToReady) { first.Updated += (time, updated) => { if (first.IsReady) { idn.Update(time, new DoubleArrayScalar(op(selector(updated)))); } }; } else { first.Updated += (time, updated) => idn.Update(time, new DoubleArrayScalar(op(selector(updated)))); } } first.Resetted += sender => idn.Reset(); return(idn); }