public void Evaluate(VectorExecutionOptions options, NArray[] outputs, NArray dependentVariable, IList <NArray> independentVariables, ExecutionTimer timer, StringBuilder expressionsOut = null, Aggregator aggregator = Aggregator.ElementwiseAdd) { if (aggregator != Aggregator.ElementwiseAdd) { throw new NotImplementedException(); } var dependentVariableExpression = _builder.GetParameter <double>(dependentVariable); var independentVariableExpressions = independentVariables.Select(v => _builder.GetParameter <double>(v)).ToArray(); // and important special case // this can only occur if the dependent variable is a scalar that does not depend on any independent variables if (dependentVariableExpression.Index == -1) { var scalarValue = (dependentVariableExpression as ReferencingVectorParameterExpression <double>).ScalarValue; outputs[0].Add(scalarValue); // all derivatives remains zero return; } _builder.UpdateLocalsNumbering(); timer.MarkEvaluateSetupComplete(); // differentiate, extending the block as necessary IList <Expression> derivativeExpressions; AlgorithmicDifferentiator.Differentiate(_builder, out derivativeExpressions, dependentVariableExpression, independentVariableExpressions); timer.MarkDifferentationComplete(); // arrange output storage var outputIndices = new int[1 + independentVariables.Count]; for (int i = 0; i < independentVariables.Count + 1; ++i) { var referencingExpression = (i > 0) ? derivativeExpressions[i - 1] as ReferencingVectorParameterExpression <double> : dependentVariableExpression as ReferencingVectorParameterExpression <double>; if (referencingExpression.IsScalar) // common case: constant derivative (especially zero) { outputs[i].Add(referencingExpression.ScalarValue); outputIndices[i] = int.MaxValue; // TODO if storage passed in, update here in case of non-zero constant? } else // not a scalar so we will need storage { outputIndices[i] = referencingExpression.Index; if (outputs[i].IsScalar) { // we increase the storage, copying the scalar value outputs[i] = new NArray(new VectorAccelerator.NArrayStorage.ManagedStorage <double>(_builder.VectorLength, 1, outputs[i].First())); } } } timer.MarkStorageSetupComplete(); // run VectorBlockExpressionRunner.RunNonCompiling(_builder, Provider(StorageLocation.Host), new VectorExecutionOptions(), outputs, outputIndices, aggregator, timer); timer.MarkExecuteComplete(); if (expressionsOut != null) { var block = _builder.ToBlock(); expressionsOut.AppendLine("Result in expression " + dependentVariableExpression.ToString()); if (derivativeExpressions != null && derivativeExpressions.Any()) { expressionsOut.AppendLine("Derivatives in expressions " + String.Join(", ", derivativeExpressions.Select(e => e.ToString()))); } foreach (var item in block.Operations) { var display = item.ToString(); expressionsOut.AppendLine(new string(display.ToArray())); } } }