public VectorParameterExpression GetParameter <T>(NArray <T> array) { var local = array as ILocalNArray; if (local != null) { return(_localParameters[local.Index] as VectorParameterExpression); } else { // if the array is a scalar and not an independent variable of any derivative calculation, we do not care where it came from; do not // add to argument list if (array.IsScalar && !IsIndependentVariable(array)) { return(new ConstantExpression <T>(array.First())); } VectorParameterExpression argument; // is this fast enough? if (!_argumentLookup.TryGetValue(array, out argument)) { argument = array.IsScalar ? new ReferencingVectorParameterExpression <T>(array.First(), ParameterType.Argument, _argumentLookup.Count) : new ReferencingVectorParameterExpression <T>(array, ParameterType.Argument, _argumentLookup.Count); _argumentLookup.Add(array, argument); } return(argument); } }
public NArray BinaryExpression(NArray operand1, NArray operand2, Func<Expression, Expression, BinaryExpression> operation) { CheckNArrays(operand1, operand2); NArray result; ParameterExpression parameterExpression; NewLocal(out result, out parameterExpression); Expression arg1, arg2; arg1 = (operand1.IsScalar) ? (Expression)GetConstant(operand1.First()) : (Expression)GetNArray(operand1); arg2 = (operand2.IsScalar) ? (Expression)GetConstant(operand2.First()) : (Expression)GetNArray(operand2); _expressions.Add( Expression.Assign(parameterExpression, operation(arg1, arg2) )); return result; }
public NArray BinaryExpression(NArray operand1, NArray operand2, Func <Expression, Expression, BinaryExpression> operation) { CheckNArrays(operand1, operand2); NArray result; ParameterExpression parameterExpression; NewLocal(out result, out parameterExpression); Expression arg1, arg2; arg1 = (operand1.IsScalar) ? (Expression)GetConstant(operand1.First()) : (Expression)GetNArray(operand1); arg2 = (operand2.IsScalar) ? (Expression)GetConstant(operand2.First()) : (Expression)GetNArray(operand2); _expressions.Add( Expression.Assign(parameterExpression, operation(arg1, arg2) )); return(result); }
/// <summary> /// Test of efficiency for a large number of simple vector operations. /// In particular, tests enhanced recycling of locals. /// </summary> public void SimpleTest() { // create 500 random vectors var vectorLength = 5000; var vectors = new NArray[500]; using (var randomStream = new RandomNumberStream(StorageLocation.Host, RandomNumberGeneratorType.MRG32K3A, 111)) { var normalDistribution = new Normal(randomStream, 0, 1); for (int i = 0; i < vectors.Length; ++i) { vectors[i] = NArray.CreateRandom(vectorLength, normalDistribution); } } var watch = new System.Diagnostics.Stopwatch(); watch.Start(); var result = NArray.CreateLike(vectors.First()); for (int i = 0; i < vectors.Length; ++i) { for (int j = 0; j < vectors.Length; ++j) { result.Add(vectors[i] * vectors[j] * 123); //result = result + vectors[i] * vectors[j] * 123; } } watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds); var arrays = vectors.Select(v => (v.Storage as ManagedStorage <double>).Array).ToArray(); watch.Restart(); var arrayResult = new double[vectors.First().Length]; for (int i = 0; i < vectors.Length; ++i) { for (int j = 0; j < vectors.Length; ++j) { for (int k = 0; k < arrayResult.Length; ++k) { arrayResult[k] += arrays[i][k] * arrays[j][k] * 123; } } } watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds); watch.Restart(); result = NArray.CreateLike(vectors.First()); for (int i = 0; i < vectors.Length; ++i) { var batch = NArray.Evaluate(() => { NArray res = NArray.CreateScalar(0); for (int j = 0; j < vectors.Length; ++j) { res = res + vectors[i] * vectors[j] * 123; } return(res); }); result += batch; } watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds); }