private void Test(string Script, object[][] ExpectedOutput) { Variables v = new Variables(); Expression Exp = new Expression(Script); object Obj = Exp.Evaluate(v); Console.Out.WriteLine(Expression.ToString(Obj)); ObjectMatrix M = Obj as ObjectMatrix; int NrRows, RowIndex; int NrColumns, ColumnIndex; Assert.IsNotNull(M, "Object matrix expected."); Assert.AreEqual(NrRows = ExpectedOutput.Length, M.Rows, "Number of rows in response incorrect."); for (RowIndex = 0; RowIndex < NrRows; RowIndex++) { object[] ExpectedRow = ExpectedOutput[RowIndex]; IVector Row = M.GetRow(RowIndex); Assert.IsNotNull(Row, "Object row vector expected."); Assert.AreEqual(NrColumns = ExpectedRow.Length, Row.Dimension, "Number of columns in response incorrect."); for (ColumnIndex = 0; ColumnIndex < NrColumns; ColumnIndex++) { Assert.AreEqual(ExpectedRow[ColumnIndex], Row.GetElement(ColumnIndex).AssociatedObjectValue); } } }
/// <summary> /// Evaluates the vector index operator. /// </summary> /// <param name="Vector">Vector</param> /// <param name="Index">Index</param> /// <param name="Node">Node performing the operation.</param> /// <returns>Result</returns> public static IElement EvaluateIndex(IVector Vector, IElement Index, ScriptNode Node) { if (Index is DoubleNumber RE) { double d = RE.Value; if (d < 0 || d > int.MaxValue || d != Math.Truncate(d)) { throw new ScriptRuntimeException("Index must be a non-negative integer.", Node); } return(Vector.GetElement((int)d)); } if (Index.IsScalar) { throw new ScriptRuntimeException("Index must be a non-negative integer.", Node); } else { LinkedList <IElement> Elements = new LinkedList <IElement>(); foreach (IElement E in Index.ChildElements) { Elements.AddLast(EvaluateIndex(Vector, E, Node)); } return(Index.Encapsulate(Elements, Node)); } }
/// <summary> /// Evaluates the function. /// </summary> /// <param name="Arguments">Function arguments.</param> /// <param name="Variables">Variables collection.</param> /// <returns>Function result.</returns> public override IElement Evaluate(IElement[] Arguments, Variables Variables) { Type T = Arguments[0].AssociatedObjectValue as Type; if (T == null) { throw new ScriptRuntimeException("First parameter must be a type.", this); } int Offset = (int)Expression.ToDouble(Arguments[1].AssociatedObjectValue); int MaxCount = (int)Expression.ToDouble(Arguments[2].AssociatedObjectValue); object FilterObj = Arguments[3].AssociatedObjectValue; Filter Filter = FilterObj as Filter; IVector V = Arguments[4] as IVector; int i, c = V.Dimension; string[] SortOrder = new string[c]; for (i = 0; i < c; i++) { SortOrder[i] = V.GetElement(i).AssociatedObjectValue.ToString(); } if (Filter == null && FilterObj != null) { Expression Exp = new Expression(FilterObj.ToString()); Filter = this.Convert(Exp.Root, Variables); } MethodInfo MI = findMethodGeneric.MakeGenericMethod(new Type[] { T }); object Result = MI.Invoke(null, new object[] { Offset, MaxCount, Filter, SortOrder }); if (Result is Task Task) { Task.Wait(); PropertyInfo PI = Task.GetType().GetRuntimeProperty("Result"); Result = PI.GetMethod.Invoke(Task, null); } if (Result is IEnumerable E) { LinkedList <IElement> Elements = new LinkedList <IElement>(); IEnumerator e = E.GetEnumerator(); while (e.MoveNext()) { Elements.AddLast(Expression.Encapsulate(e.Current)); } return(new ObjectVector(Elements)); } else { return(Expression.Encapsulate(Result)); } }
/// <summary> /// Evaluates the function on a vector argument. /// </summary> /// <param name="Argument">Function argument.</param> /// <param name="Variables">Variables collection.</param> /// <returns>Function result.</returns> public override IElement EvaluateVector(IVector Argument, Variables Variables) { int i, c = Argument.Dimension; IElement[] E = new IElement[c]; for (i = 0; i < c; i++) { E[c - i - 1] = Argument.GetElement(i); } return(Argument.Encapsulate(E, this)); }
/// <summary> /// Evaluates the function. /// </summary> /// <param name="Arguments">Function arguments.</param> /// <param name="Variables">Variables collection.</param> /// <returns>Function result.</returns> public override IElement Evaluate(IElement[] Arguments, Variables Variables) { IVector Colors = Arguments[0] as IVector; int c = Colors.Dimension; if (c == 0) { throw new ScriptRuntimeException("No colors defined.", this); } if (c == 1) { return(Colors.GetElement(0)); } double p = Expression.ToDouble(Arguments[1].AssociatedObjectValue); p *= c - 1; int Offset = (int)p; if (Offset < 0) { Offset = 0; } else if (Offset > c - 2) { Offset = c - 2; } p -= Offset; SKColor c1 = Graph.ToColor(Colors.GetElement(Offset).AssociatedObjectValue); SKColor c2 = Graph.ToColor(Colors.GetElement(Offset + 1).AssociatedObjectValue); return(new ObjectValue(Blend.BlendColors(c1, c2, p))); }
/// <summary> /// Evaluates the function. /// </summary> /// <param name="Argument">Function argument.</param> /// <param name="Variables">Variables collection.</param> /// <returns>Function result.</returns> public override IElement EvaluateVector(IVector Argument, Variables Variables) { int Width = 800; int i, c = Argument.Dimension; object Obj; SKColor cl; int j; using (SKSurface Surface = SKSurface.Create(Width, 100, SKImageInfo.PlatformColorType, SKAlphaType.Premul)) { SKCanvas Canvas = Surface.Canvas; for (i = 0; i < Width; i++) { j = i * c / Width; if (j >= c) { j = c - 1; } Obj = Argument.GetElement(j).AssociatedObjectValue; if (Obj is SKColor || Obj is string) { cl = Graph.ToColor(Obj); SKPaint Pen = new SKPaint() { Style = SKPaintStyle.Stroke, Color = cl, StrokeWidth = 1 }; Canvas.DrawLine(i, 0, i, 100, Pen); Pen.Dispose(); Pen = null; } } return(new GraphBitmap(Surface.Snapshot())); } }
public override IElement Evaluate(IElement[] Arguments, Variables Variables) { string ColorExpression = null; SKColor[] Palette; double[] Coefficients = null; Complex[] CoefficientsZ = null; ILambdaExpression f = null; ScriptNode fDef = null; double rc, ic; double dr; Complex R; int dimx, dimy; int c = Arguments.Length; int i = 0; object Obj; Complex z; Obj = Arguments[i++].AssociatedObjectValue; if (Obj is Complex) { z = (Complex)Obj; rc = z.Real; ic = z.Imaginary; } else { rc = Expression.ToDouble(Obj); ic = Expression.ToDouble(Arguments[i++].AssociatedObjectValue); } if (i >= c) { throw new ScriptRuntimeException("Insufficient parameters in call to NewtonSmoothFractal().", this); } dr = Expression.ToDouble(Arguments[i++].AssociatedObjectValue); if (i < c && (Arguments[i] is DoubleNumber || Arguments[i] is ComplexNumber)) { R = Expression.ToComplex(Arguments[i++].AssociatedObjectValue); } else { R = Complex.One; if (i < c && this.Arguments[i] == null) { i++; } } if (i < c) { if (Arguments[i] is DoubleVector) { Coefficients = (double[])Arguments[i++].AssociatedObjectValue; } else if (Arguments[i] is ComplexVector) { CoefficientsZ = (Complex[])Arguments[i++].AssociatedObjectValue; } /*else if (Parameters[i] is RealPolynomial) * Coefficients = ((RealPolynomial)Arguments[i++].AssociatedObjectValue).Coefficients; * else if (Parameters[i] is ComplexPolynomial) * CoefficientsZ = ((ComplexPolynomial)Arguments[i++].AssociatedObjectValue).Coefficients;*/ else if (Arguments[i] is IVector) { IVector Vector = (IVector)Arguments[i++]; int j, d = Vector.Dimension; CoefficientsZ = new Complex[d]; for (j = 0; j < d; j++) { CoefficientsZ[j] = Expression.ToComplex(Vector.GetElement(j).AssociatedObjectValue); } } else if (Arguments[i].AssociatedObjectValue is ILambdaExpression) { f = (ILambdaExpression)Arguments[i]; if (f.NrArguments != 1) { throw new ScriptRuntimeException("Lambda expression in calls to NewtonSmoothFractal() must be of one variable.", this); } fDef = this.Arguments[i++]; } else { throw new ScriptRuntimeException("Parameter " + (i + 1).ToString() + " in call to NewtonSmoothFractal has to be a vector of numbers, containing coefficients " + "of the polynomial to use. Now it was of type " + Arguments[i].GetType().FullName, this); } } else { throw new ScriptRuntimeException("Missing coefficients or lambda expression.", this); } if (i < c && this.Arguments[i] != null && Arguments[i] is ObjectVector) { ColorExpression = this.Arguments[i].SubExpression; Palette = FractalGraph.ToPalette((ObjectVector)Arguments[i++]); } else { Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(128, 4, out int Seed, this, Variables); ColorExpression = "RandomLinearAnalogousHSL(128,4," + Seed.ToString() + ")"; if (i < c && this.Arguments[i] == null) { i++; } } if (i < c) { dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue); } else { dimx = 320; } if (i < c) { dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue); } else { dimy = 200; } if (i < c) { throw new ScriptRuntimeException("Parameter mismatch in call to NewtonSmoothFractal(r,c,dr,Coefficients[,Palette][,dimx[,dimy]]).", this); } if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000) { throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this); } if (f != null) { return(CalcNewtonSmooth(rc, ic, dr, R, f, fDef, Variables, Palette, dimx, dimy, this, this.FractalZoomScript, new object[] { Palette, dimx, dimy, R, fDef, ColorExpression })); } else if (CoefficientsZ != null) { return(CalcNewtonSmooth(rc, ic, dr, R, CoefficientsZ, Palette, dimx, dimy, this, Variables, this.FractalZoomScript, new object[] { Palette, dimx, dimy, R, CoefficientsZ, ColorExpression })); } else { return(CalcNewtonSmooth(rc, ic, dr, R, Coefficients, Palette, dimx, dimy, this, Variables, this.FractalZoomScript, new object[] { Palette, dimx, dimy, R, Coefficients, ColorExpression })); } }
public override IElement Evaluate(IElement[] Arguments, Variables Variables) { string ColorExpression = null; SKColor[] Palette; double[] Coefficients = null; Complex[] CoefficientsZ = null; double rc, ic; double dr; Complex R; int dimx, dimy; int c = Arguments.Length; int i = 0; object Obj; Complex z; Obj = Arguments[i++].AssociatedObjectValue; if (Obj is Complex) { z = (Complex)Obj; rc = z.Real; ic = z.Imaginary; } else { rc = Expression.ToDouble(Obj); ic = Expression.ToDouble(Arguments[i++].AssociatedObjectValue); } if (i >= c) { throw new ScriptRuntimeException("Insufficient parameters in call to NewtonBuilderFractal().", this); } dr = Expression.ToDouble(Arguments[i++].AssociatedObjectValue); if (i < c && (Arguments[i] is DoubleNumber || Arguments[i] is ComplexNumber)) { R = Expression.ToComplex(Arguments[i++].AssociatedObjectValue); } else { R = Complex.One; if (i < c && this.Arguments[i] == null) { i++; } } if (i < c && Arguments[i] is DoubleVector) { Coefficients = (double[])Arguments[i++].AssociatedObjectValue; int j, d = Coefficients.Length; CoefficientsZ = new Complex[d]; for (j = 0; j < d; j++) { CoefficientsZ[j] = new Complex(Coefficients[j], 0); } } else if (i < c && Arguments[i] is ComplexVector) { CoefficientsZ = (Complex[])Arguments[i++].AssociatedObjectValue; } /*else if (i < c && Parameters[i] is RealPolynomial) * Coefficients = ((RealPolynomial)Arguments[i++].AssociatedObjectValue).Coefficients; * else if (i < c && Parameters[i] is ComplexPolynomial) * CoefficientsZ = ((ComplexPolynomial)Arguments[i++].AssociatedObjectValue).Coefficients;*/ else if (i < c && Arguments[i] is IVector) { IVector Vector = (IVector)Arguments[i++]; int j, d = Vector.Dimension; CoefficientsZ = new Complex[d]; for (j = 0; j < d; j++) { CoefficientsZ[j] = Expression.ToComplex(Vector.GetElement(j).AssociatedObjectValue); } } else { CoefficientsZ = new Complex[0]; } if (i < c && this.Arguments[i] != null && Arguments[i] is ObjectVector) { ColorExpression = this.Arguments[i].SubExpression; Palette = FractalGraph.ToPalette((ObjectVector)Arguments[i++]); } else { Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(128, 4, out int Seed, this, Variables); ColorExpression = "RandomLinearAnalogousHSL(128,4," + Seed.ToString() + ")"; if (i < c && this.Arguments[i] == null) { i++; } } if (i < c) { dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue); } else { dimx = 320; } if (i < c) { dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue); } else { dimy = 200; } if (i < c) { throw new ScriptRuntimeException("Parameter mismatch in call to NewtonBuilderFractal(r,c,dr,Coefficients[,Palette][,dimx[,dimy]]).", this); } if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000) { throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this); } return(NewtonFractal.CalcNewton(rc, ic, dr, R, CoefficientsZ, Palette, dimx, dimy, this, this.FractalZoomScript, new object[] { Palette, dimx, dimy, R, CoefficientsZ, ColorExpression, rc, ic })); }