public static TermBuilder EulerPower_(Term power) { TermBuilder builder = new TermBuilder(); builder.term.EulerPower = power; return(builder); }
public Term GetDeterminant() { Contract.Requires(RowsCount == ColsCount); if (RowsCount > 2) // General case { // get minor determinants (recursively) var minorDets = new Term[RowsCount]; for (int i = 0; i < minorDets.Length; ++i) { minorDets[i] = GetMinor(i, 0).GetDeterminant(); } // negate every second determinant for (int i = 1; i < minorDets.Length; i += 2) { minorDets[i] = -1 * minorDets[i]; } return(TermBuilder.Sum(minorDets)); } else if (RowsCount == 2) { return(rows[0][0] * rows[1][1] - rows[1][0] * rows[0][1]); // 2D determinant } else // RowsCount == 1 { return(rows[0][0]); // 1D determinant - simply the term value } }
public static TermBuilder Coefficient_(double coefficient) { TermBuilder builder = new TermBuilder(); builder.term.Coefficient = new Constant(coefficient); return(builder); }
public static TermBuilder Variable_(Variable variable, Operation power) { TermBuilder builder = new TermBuilder(); builder.term.TermVariables[variable] = power; return(builder); }
protected override Tuple <Term, Term[]> Reconstruct(SnappedStraightGenCylinder snappedPrimitive, Dictionary <FeatureCurve, ISet <Annotation> > curvesToAnnotations) { var silhouettesCount = (new PointsSequence[] { snappedPrimitive.LeftSilhouette, snappedPrimitive.RightSilhouette }) .Count(curve => curve != null); var featuresCount = snappedPrimitive.FeatureCurves .Cast <CircleFeatureCurve>() .Count(curve => curve.SnappedTo != null); // get annotated feature curves of this primitive. var annotated = new HashSet <FeatureCurve>(curvesToAnnotations.Keys.Where(key => curvesToAnnotations[key].Count > 0)); annotated.Intersect(snappedPrimitive.FeatureCurves); // default objective function and no constraints.. if we can't match a case, we don't optimize. Tuple <Term, Term[]> result = Tuple.Create(TermBuilder.Constant(0), new Term[0]); if (silhouettesCount == 2 && featuresCount == 2) { result = FullInfo(snappedPrimitive); } else if (silhouettesCount == 1 && featuresCount == 2) { result = SingleSilhouetteTwoFeatures(snappedPrimitive, annotated); } else if (silhouettesCount == 2 && featuresCount == 1) { result = SingleFeatureTwoSilhouettes(snappedPrimitive, annotated); } return(result); }
/// <summary> /// Generates a term that gets smaller as the given 2D point fits a 3D points set projection. /// </summary> /// <param name="pointsSet">A representation for the 3D points set</param> /// <param name="point">The 2D point</param> /// <returns>The term that measures fitness of <paramref name="point"/> being on the 2D projection of the set specified by <paramref name="pointsSet"/></returns> public static Term Compute(CircleFeatureCurve pointsSet, Point point) { // here we explicitly assume that the view vector is (0, 0, 1) or (0, 0, -1) var x_ = point.X; var y_ = point.Y; var cx = pointsSet.Center.X; var cy = pointsSet.Center.Y; var cz = pointsSet.Center.Z; var nx = pointsSet.Normal.X; var ny = pointsSet.Normal.Y; var nz = pointsSet.Normal.Z; var r = pointsSet.Radius; var dx = cx - x_; var dy = cy + y_; var lhs = TermBuilder.Sum( TermBuilder.Power(dx * nz, 2), TermBuilder.Power(dy * nz, 2), TermBuilder.Power(dx * nx + dy * ny, 2)); var rhs = TermBuilder.Power(r * nz, 2); return(TermBuilder.Power(lhs - rhs, 2)); }
public SubstitutionResult Visit(Sum sum) { var summmandResults = sum.Terms.Select(x => x.Accept(this)).ToArray(); var nonConstants = new List <Term>(); double sumValue = 0; foreach (var summandResult in summmandResults) { double value; if (TryGetConstant(summandResult, out value)) { sumValue += value; } else { nonConstants.Add(summandResult.Term); } } if (nonConstants.Count == 0) // all are constants { return(CreateResult(sumValue)); } else { var newSummands = nonConstants.Concat(Enumerable.Repeat(TermBuilder.Constant(sumValue), 1)); return(CreateResult(TermBuilder.Sum(newSummands))); } }
private static OptimizationProblem GetOptimizationProblem(IEnumerable <PrimitiveEditConstraint> constraints) { // generate constraint terms var constraintTerms = new List <Term>(); var paramsToVars = new Dictionary <IEditParameter, ParameterVariable[]>(); foreach (var constraint in constraints) { TryAxisOnLine(constraintTerms, paramsToVars, constraint); TryPointOnPlane(constraintTerms, paramsToVars, constraint); } // get variables var variables = (from vars in paramsToVars.Values from var in vars select var).ToArray(); // construct objective --> sum of squared distances to current values var values = GetCurrentValues(variables); var objective = TermUtils.SafeSum( from i in Enumerable.Range(0, variables.Length) select TermBuilder.Power(variables[i] - values[i], 2)); return(new OptimizationProblem { Constraints = constraintTerms.ToArray(), Variables = variables, Objective = objective, }); }
static void Main(string[] args) { // we will use a function of two variables Variable x = new Variable(); Variable y = new Variable(); // func(x, y) = (x + y) * exp(x - y) var func = (x + y) * TermBuilder.Exp(x - y); // create compiled term and use it for many gradient/value evaluations var compiledFunc = func.Compile(x, y); // we can now efficiently compute the gradient of "func" 64 times with different inputs. // compilation helps when we need many evaluations of the same function. for (int i = 0; i < 64; ++i) { var xVal = i / 64.0; var yVal = 1 + i / 128.0; var diffResult = compiledFunc.Differentiate(xVal, yVal); var gradient = diffResult.Item1; var value = diffResult.Item2; Console.WriteLine("The value of func at x = {0}, y = {1} is {2} and the gradient is ({3}, {4})", xVal, yVal, value, gradient[0], gradient[1]); } }
public void ProductContract() { Assert.Throws <ArgumentNullException>(() => TermBuilder.Product(x, null)); Assert.Throws <ArgumentNullException>(() => TermBuilder.Product(null, x)); Assert.Throws <ArgumentNullException>(() => TermBuilder.Product(x, y, null)); Assert.Throws <ArgumentException>(() => TermBuilder.Product(x, y, Vec(x, null))); Assert.IsType <Product>(TermBuilder.Product(x, y)); }
public void SumValidationContract() { Assert.Throws <ArgumentNullException>(() => TermBuilder.Sum(null)); Assert.Throws <ArgumentNullException>(() => TermBuilder.Sum(x, null)); Assert.Throws <ArgumentNullException>(() => TermBuilder.Sum(null, x)); Assert.Throws <ArgumentNullException>(() => TermBuilder.Sum(x, y, null)); Assert.Throws <ArgumentException>(() => TermBuilder.Sum(x, y, Vec(x, null))); Assert.Throws <ArgumentException>(() => TermBuilder.Sum(Vec(x, null))); }
public IEnumerable <double[]> Solve(Term objective, IEnumerable <Term> constraints, Variable[] variables, double[] startPoint) { var constraintSquares = constraints.Select(c => TermBuilder.Power(c, 2)); var penalizedObjective = objective + penaltyWeight * TermUtils.SafeSum(constraintSquares); var compiledPenalizedObjective = penalizedObjective.Compile(variables); var solution = unconstrainedOptimizer.Solve(x => compiledPenalizedObjective.Differentiate(x), startPoint, gradientNormThreshold); yield return(solution); }
protected override Tuple <Term, Term[]> Reconstruct(SnappedSphere snappedPrimitive, Dictionary <FeatureCurve, ISet <Annotation> > curvesToAnnotations) { var circle = CircleFitter.Fit(snappedPrimitive.ProjectionParallelCircle.SnappedTo.Points); var result = TermBuilder.Power(snappedPrimitive.Center.X - circle.Center.X, 2) + TermBuilder.Power(snappedPrimitive.Center.Y + circle.Center.Y, 2) + TermBuilder.Power(snappedPrimitive.Radius - circle.Radius, 2); return(Tuple.Create(result, NO_TERMS)); }
public static Term DiffSquared(Term[] left, Term[] right) { Contract.Requires(left != null); Contract.Requires(right != null); Contract.Requires(left.Length == right.Length); var toSum = from i in System.Linq.Enumerable.Range(0, left.Length) select TermBuilder.Power(left[i] - right[i], 2); return(TermBuilder.Sum(toSum)); }
public static Term SoftMin(Term[] terms, double exponent = 6) { Contract.Requires(terms != null); Contract.Requires(terms.Length > 0); Contract.Requires(Contract.ForAll(terms, term => term != null)); Contract.Requires(exponent > 1); Contract.Ensures(Contract.Result <Term>() != null); var powers = terms.Select(term => TermBuilder.Power(term, -exponent)); return(TermBuilder.Power(TermBuilder.Sum(powers), -1 / exponent)); }
public void PowerContract() { Assert.Throws <ArgumentNullException>(() => TermBuilder.Power(null, 1)); Assert.Throws <ArgumentNullException>(() => TermBuilder.Power(x, null)); Assert.Throws <ArgumentNullException>(() => TermBuilder.Power(null, x)); Assert.IsType <ConstPower>(TermBuilder.Power(x, 1)); Assert.Throws <ArgumentException>(() => TermBuilder.Power(x, double.NaN)); Assert.Throws <ArgumentException>(() => TermBuilder.Power(x, double.PositiveInfinity)); Assert.IsType <TermPower>(TermBuilder.Power(x, y)); Assert.IsType <TermPower>(TermBuilder.Power(1, y)); }
private Term[] GetConcreteAnnotationTerm(OnSphere onSphere) { var center = onSphere.SphereOwned.Center; var radius = onSphere.SphereOwned.Radius; var touchingPoint = onSphere.CenterTouchesSphere.Center; var touchingNormal = onSphere.CenterTouchesSphere.Normal; var radiusConstraint = (center - touchingPoint).NormSquared - TermBuilder.Power(radius, 2); var normalConstraint = VectorParallelism(center - touchingPoint, touchingNormal); return(normalConstraint.Append(radiusConstraint).ToArray()); }
private static Term MeanSquaredError(Term[] terms, double[] values) { Contract.Requires(terms != null); Contract.Requires(values != null); Contract.Requires(terms.Length == values.Length); Contract.Requires(Contract.ForAll(terms, term => term != null)); Contract.Ensures(Contract.Result <Term>() != null); var errorTerms = from i in Enumerable.Range(0, terms.Length) select TermBuilder.Power(terms[i] + (-values[i]), 2); return((1 / (double)terms.Length) * TermUtils.SafeSum(errorTerms)); }
private static Tuple <Term, Term[]> CreateSGCTerms(SnappedStraightGenCylinder snappedPrimitive, double[] radii, Point spineStart, Point spineEnd) { var constraints = new Term[] { snappedPrimitive.Axis.NormSquared - 1 }; if (radii.Length > 0) { var featureCurveTerms = from item in snappedPrimitive.FeatureCurves.Cast <CircleFeatureCurve>() where item != null where item.SnappedTo != null from term in ProjectionFit.Compute(item) select term; var featureCurvesTerm = 0.1 * TermUtils.SafeAvg(featureCurveTerms); // the difference between the primitive's radii and the computed radii is minimized var radiiApproxTerm = TermUtils.SafeAvg( from i in Enumerable.Range(0, snappedPrimitive.Components.Length) let component = snappedPrimitive.Components[i] let radius = radii[i] select TermBuilder.Power(component.Radius - radius, 2)); // the smoothness of the primitive's radii (laplacian norm) is minimized var radiiSmoothTerm = TermUtils.SafeAvg( from pair in snappedPrimitive.Components.SeqTripples() let r1 = pair.Item1.Radius let r2 = pair.Item2.Radius let r3 = pair.Item3.Radius select TermBuilder.Power(r2 - 0.5 * (r1 + r3), 2)); // how far is r2 from the avg of r1 and r3 // we specifically wish to give higher weight to first and last radii, so we have // an additional first/last radii term. var endpointsRadiiTerm = TermBuilder.Power(radii[0] - snappedPrimitive.Components.First().Radius, 2) + TermBuilder.Power(radii.Last() - snappedPrimitive.Components.Last().Radius, 2); // objective - weighed average of all terms var objective = radiiApproxTerm + radiiSmoothTerm + featureCurvesTerm + endpointsRadiiTerm; return(Tuple.Create(objective, constraints)); } else { return(Tuple.Create((Term)0, constraints)); // if we can't extract radii approximation, we don't do any snapping } }
private static ICompiledTerm ConstructTerm(Coefficient[][] coefficients, Variable[] variables) { var squareTerms = from i in Enumerable.Range(0, coefficients.Length) let termCoefficients = coefficients[i] let sumTerms = from j in Enumerable.Range(0, termCoefficients.Length) select termCoefficients[j].Value * variables[termCoefficients[j].Index] let sum = TermBuilder.Sum(sumTerms) select TermBuilder.Power(sum, 2); var finalTerm = TermBuilder.Sum(squareTerms); var compiled = finalTerm.Compile(variables); return(compiled); }
public SubstitutionResult Visit(Log log) { var argResult = log.Arg.Accept(this); double argValue; if (TryGetConstant(argResult, out argValue)) { return(CreateResult(Math.Log(argValue))); } else { return(CreateResult(TermBuilder.Log(argResult.Term))); } }
static void Main(string[] args) { Variable x = new Variable(); // f(x) = e^(-x) + x - 2 // it has two roots. See plot.png image attached to this project. var func = TermBuilder.Exp(-x) + x - 2; // find the root near 2 var root1 = RootFinder.NewtonRaphson(func, x, 2); // find the root near -1 var root2 = RootFinder.NewtonRaphson(func, x, -1); Console.WriteLine("The equation e^(-x) + x - 2 = 0 has two solutions:\nx = {0}\nx = {1}", root1, root2); }
static void Main(string[] args) { var x = new Variable(); var y = new Variable(); var z = new Variable(); // f(x, y, z) = (x-2)² + (y+4)² + (z-1)² // the min should be (x, y, z) = (2, -4, 1) var func = TermBuilder.Power(x - 2, 2) + TermBuilder.Power(y + 4, 2) + TermBuilder.Power(z - 1, 2); var compiled = func.Compile(x, y, z); // perform optimization var vec = new double[3]; vec = GradientDescent(compiled, vec, stepSize: 0.01, iterations: 1000); Console.WriteLine("The approx. minimizer is: {0}, {1}, {2}", vec[0], vec[1], vec[2]); }
protected Term EndpointsProjectionFit(CircleFeatureCurve pointsSet, Point p1, Point p2) { var x1 = p1.X; var y1 = -p1.Y; var x2 = p2.X; var y2 = -p2.Y; var cx = pointsSet.Center.X; var cy = pointsSet.Center.Y; var r = pointsSet.Radius; var eq1 = TermBuilder.Power(x1 - cx, 2) + TermBuilder.Power(y1 - cy, 2) - TermBuilder.Power(r, 2); var eq2 = TermBuilder.Power(x2 - cx, 2) + TermBuilder.Power(y2 - cy, 2) - TermBuilder.Power(r, 2); var result = TermBuilder.Power(eq1, 2) + TermBuilder.Power(eq2, 2); return(result); }
public static Term SafeSum(IEnumerable <Term> terms) { Contract.Requires(terms != null); Contract.Requires(Contract.ForAll(terms, term => term != null)); Contract.Ensures(Contract.Result <Term>() != null); terms = terms.Where(term => !(term is Zero)); if (!terms.Any()) { return(0); } else if (!terms.Skip(1).Any()) { return(terms.First()); } else { return(TermBuilder.Sum(terms)); } }
static void Main(string[] args) { // we will use a function of two variables Variable x = new Variable(); Variable y = new Variable(); // func(x, y) = (x + y) * exp(x - y) var func = (x + y) * TermBuilder.Exp(x - y); // define the ordering of variables, and a point where the function will be evaluated/differentiated Variable[] vars = { x, y }; double[] point = { 1, -2 }; // calculate the value and the gradient at the point (x, y) = (1, -2) double eval = func.Evaluate(vars, point); double[] gradient = func.Differentiate(vars, point); // write the results Console.WriteLine("f(1, -2) = " + eval); Console.WriteLine("Gradient of f at (1, -2) = ({0}, {1})", gradient[0], gradient[1]); }
private Term PrepareStDevFunction(int count = 5) { Term stDev = null; for (int i = 0; i < count; ++i) { Variable w = new Variable(); if (!variables.ContainsKey(i)) { variables.Add(i, w); } var std_mul_w = TermBuilder.Power(variables[i], 2) * TermBuilder.Power(stDevs[i], 2); if (i == 0) { stDev = std_mul_w; } else { stDev += std_mul_w; } for (int k = i + 1; k < count; ++k) { Variable w2 = new Variable(); if (!variables.ContainsKey(k)) { variables.Add(k, w2); } var cov = 2 * matCov[i, k] * variables[i] * variables[k]; stDev += cov; } } stDev = TermBuilder.Power(stDev, 0.5); return(stDev); }
private AutoDiff.Term ConvertToAutoDiff(ISymbolicExpressionTreeNode node) { if (node.Symbol is Constant) { initialConstants.Add(((ConstantTreeNode)node).Value); var var = new AutoDiff.Variable(); variables.Add(var); return(var); } if (node.Symbol is Variable || node.Symbol is BinaryFactorVariable) { var varNode = node as VariableTreeNodeBase; var factorVarNode = node as BinaryFactorVariableTreeNode; // factor variable values are only 0 or 1 and set in x accordingly var varValue = factorVarNode != null ? factorVarNode.VariableValue : string.Empty; var par = FindOrCreateParameter(parameters, varNode.VariableName, varValue); if (makeVariableWeightsVariable) { initialConstants.Add(varNode.Weight); var w = new AutoDiff.Variable(); variables.Add(w); return(AutoDiff.TermBuilder.Product(w, par)); } else { return(varNode.Weight * par); } } if (node.Symbol is FactorVariable) { var factorVarNode = node as FactorVariableTreeNode; var products = new List <Term>(); foreach (var variableValue in factorVarNode.Symbol.GetVariableValues(factorVarNode.VariableName)) { var par = FindOrCreateParameter(parameters, factorVarNode.VariableName, variableValue); initialConstants.Add(factorVarNode.GetValue(variableValue)); var wVar = new AutoDiff.Variable(); variables.Add(wVar); products.Add(AutoDiff.TermBuilder.Product(wVar, par)); } return(AutoDiff.TermBuilder.Sum(products)); } if (node.Symbol is LaggedVariable) { var varNode = node as LaggedVariableTreeNode; var par = FindOrCreateParameter(parameters, varNode.VariableName, string.Empty, varNode.Lag); if (makeVariableWeightsVariable) { initialConstants.Add(varNode.Weight); var w = new AutoDiff.Variable(); variables.Add(w); return(AutoDiff.TermBuilder.Product(w, par)); } else { return(varNode.Weight * par); } } if (node.Symbol is Addition) { List <AutoDiff.Term> terms = new List <Term>(); foreach (var subTree in node.Subtrees) { terms.Add(ConvertToAutoDiff(subTree)); } return(AutoDiff.TermBuilder.Sum(terms)); } if (node.Symbol is Subtraction) { List <AutoDiff.Term> terms = new List <Term>(); for (int i = 0; i < node.SubtreeCount; i++) { AutoDiff.Term t = ConvertToAutoDiff(node.GetSubtree(i)); if (i > 0) { t = -t; } terms.Add(t); } if (terms.Count == 1) { return(-terms[0]); } else { return(AutoDiff.TermBuilder.Sum(terms)); } } if (node.Symbol is Multiplication) { List <AutoDiff.Term> terms = new List <Term>(); foreach (var subTree in node.Subtrees) { terms.Add(ConvertToAutoDiff(subTree)); } if (terms.Count == 1) { return(terms[0]); } else { return(terms.Aggregate((a, b) => new AutoDiff.Product(a, b))); } } if (node.Symbol is Division) { List <AutoDiff.Term> terms = new List <Term>(); foreach (var subTree in node.Subtrees) { terms.Add(ConvertToAutoDiff(subTree)); } if (terms.Count == 1) { return(1.0 / terms[0]); } else { return(terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b))); } } if (node.Symbol is Absolute) { var x1 = ConvertToAutoDiff(node.GetSubtree(0)); return(abs(x1)); } if (node.Symbol is AnalyticQuotient) { var x1 = ConvertToAutoDiff(node.GetSubtree(0)); var x2 = ConvertToAutoDiff(node.GetSubtree(1)); return(x1 / (TermBuilder.Power(1 + x2 * x2, 0.5))); } if (node.Symbol is Logarithm) { return(AutoDiff.TermBuilder.Log( ConvertToAutoDiff(node.GetSubtree(0)))); } if (node.Symbol is Exponential) { return(AutoDiff.TermBuilder.Exp( ConvertToAutoDiff(node.GetSubtree(0)))); } if (node.Symbol is Square) { return(AutoDiff.TermBuilder.Power( ConvertToAutoDiff(node.GetSubtree(0)), 2.0)); } if (node.Symbol is SquareRoot) { return(AutoDiff.TermBuilder.Power( ConvertToAutoDiff(node.GetSubtree(0)), 0.5)); } if (node.Symbol is Cube) { return(AutoDiff.TermBuilder.Power( ConvertToAutoDiff(node.GetSubtree(0)), 3.0)); } if (node.Symbol is CubeRoot) { return(cbrt(ConvertToAutoDiff(node.GetSubtree(0)))); } if (node.Symbol is Sine) { return(sin( ConvertToAutoDiff(node.GetSubtree(0)))); } if (node.Symbol is Cosine) { return(cos( ConvertToAutoDiff(node.GetSubtree(0)))); } if (node.Symbol is Tangent) { return(tan( ConvertToAutoDiff(node.GetSubtree(0)))); } if (node.Symbol is HyperbolicTangent) { return(tanh( ConvertToAutoDiff(node.GetSubtree(0)))); } if (node.Symbol is Erf) { return(erf( ConvertToAutoDiff(node.GetSubtree(0)))); } if (node.Symbol is Norm) { return(norm( ConvertToAutoDiff(node.GetSubtree(0)))); } if (node.Symbol is StartSymbol) { if (addLinearScalingTerms) { // scaling variables α, β are given at the beginning of the parameter vector var alpha = new AutoDiff.Variable(); var beta = new AutoDiff.Variable(); variables.Add(beta); variables.Add(alpha); var t = ConvertToAutoDiff(node.GetSubtree(0)); return(t * alpha + beta); } else { return(ConvertToAutoDiff(node.GetSubtree(0))); } } throw new ConversionException(); }
protected override Term GetRadiusSoftConstraint(SnappedCylinder snapped, double expectedTop, double expectedBottom) { var avg = 0.5 * (expectedTop + expectedBottom); return(TermBuilder.Power(snapped.Radius - avg, 2)); }
protected override Term GetRadiusSoftConstraint(SnappedCone snapped, double expectedTop, double expectedBottom) { return(0.5 * ( TermBuilder.Power(snapped.TopRadius - expectedTop, 2) + TermBuilder.Power(snapped.BottomRadius - expectedBottom, 2))); }