public static TVec Normal3D(TVec p, TVec q, TVec r) { Contract.Requires(Contract.ForAll(new TVec[] { p, q, r }, x => x != null)); Contract.Requires(Contract.ForAll(new TVec[] { p, q, r }, x => x.Dimension == 3)); return(TVec.CrossProduct(q - p, r - p)); }
private static IEnumerable <Term> VectorParallelism(TVec u, TVec v) { yield return(u.X * v.Y - v.X * u.Y); yield return(u.Y * v.Z - u.Z * v.Y); yield return(u.X * v.Z - v.X * u.Z); }
private static Term ConstructAugmentedLagrangian(Term objective, IEnumerable <Term> constraints, Variable[] multipliers, Variable mu) { var constraintsVec = new TVec(constraints); var multipliersVec = new TVec(multipliers); var augmentedLagrangian = objective + TVec.InnerProduct(multipliersVec, constraintsVec) + 0.5 * mu * constraintsVec.NormSquared; return(augmentedLagrangian); }
private Term[] PointsOnPlaneConstraint(TVec p, TVec n, IEnumerable <TVec> pts) { var constraints = from x in pts let diff = p - x select diff * n; return(constraints.ToArray()); }
public VariableVectorsWriter Write(TVec vec) { Contract.Requires(vec != null); Contract.Requires(Contract.ForAll(0, vec.Dimension, i => vec[i] != null)); Contract.Requires(Contract.ForAll(0, vec.Dimension, i => vec[i] is Variable)); Contract.Ensures(Length - Contract.OldValue(Length) == vec.Dimension); Contract.Ensures(Contract.Result <VariableVectorsWriter>() == this); variables.AddRange(vec.GetTerms().Cast <Variable>()); return(this); }
public static Term Coplanarity3D(params TVec[] vecs) { Contract.Requires(Contract.ForAll(vecs, vec => vec != null)); Contract.Requires(Contract.ForAll(vecs, vec => vec.Dimension == 3)); var a = vecs[0]; var b = vecs[1]; var c = vecs[2]; var d = vecs[3]; var dot = TVec.CrossProduct(b - a, c - a) * (d - a); // the normal to (b-a) and (c-a) is also normal of (d-a) return(dot); }
private IEnumerable <TVec> GetPointsOnPlane(TVec p, TVec n) { var vec3d = random.NextVector3D().Normalized(); var tvec = new TVec(vec3d.X, vec3d.Y, vec3d.Z); var t = TVec.CrossProduct(n, tvec); var u = TVec.CrossProduct(n, t); yield return(p + t); yield return(p + u); yield return(p - t); yield return(p - u); }
public static Term SubsequencesTest(TVec[] pts, int subsequenceSize, [Pure] Func <TVec[], Term> subsequenceTest) { Contract.Requires(pts != null); Contract.Requires(pts.Length >= subsequenceSize); var testResults = new Term[pts.Length - subsequenceSize + 1]; var subArray = new TVec[subsequenceSize]; for (int i = 0; i < testResults.Length; ++i) { Array.Copy(pts, i, subArray, 0, subsequenceSize); testResults[i] = subsequenceTest(subArray); } return(new TVec(testResults).NormSquared); }
/// <summary> /// Projects a 3D term point to 2D coordinates /// </summary> /// <param name="sketchPlane">The sketch plane that defines the projection parameters</param> /// <param name="point3d">The point to project</param> /// <returns>The projected point's coordinates</returns> public static TVec Project(this SketchPlane sketchPlane, TVec point3d) { Contract.Requires(sketchPlane != null); Contract.Requires(point3d != null); Contract.Requires(point3d.Dimension == 3); Contract.Ensures(Contract.Result <TVec>() != null); Contract.Ensures(Contract.Result <TVec>().Dimension == 2); var center = new TVec(sketchPlane.Center.X, sketchPlane.Center.Y, sketchPlane.Center.Z); var xAxis = new TVec(sketchPlane.XAxis.X, sketchPlane.XAxis.Y, sketchPlane.XAxis.Z); var yAxis = new TVec(sketchPlane.YAxis.X, sketchPlane.YAxis.Y, sketchPlane.YAxis.Z); var centered = point3d - center; var xCoord = centered * xAxis; var yCoord = centered * yAxis; return(new TVec(xCoord, yCoord)); }
public TMatrix(Term[,] terms) { Contract.Requires(terms != null); Contract.Requires(terms.GetLength(0) > 0); Contract.Requires(terms.GetLength(1) > 0); var rowsCount = terms.GetLength(0); var colsCount = terms.GetLength(1); rows = new TVec[rowsCount]; Term[] currentRow = new Term[colsCount]; for (int row = 0; row < rowsCount; ++row) { for (int col = 0; col < colsCount; ++col) { currentRow[col] = terms[row, col]; } rows[row] = new TVec(currentRow); } }
private Term[] GetConcreteAnnotationTerm(CoplanarCenters coplanarCenters) { var constraints = new List <Term>(); if (coplanarCenters.Elements.Length >= 2) { foreach (var pair in coplanarCenters.Elements.SeqPairs()) { var c1 = pair.Item1.Center; var n1 = pair.Item1.Normal; var c2 = pair.Item2.Center; var n2 = pair.Item2.Normal; var term = (c2 - c1) * TVec.CrossProduct(n1, n2); constraints.Add(term); } } return(constraints.ToArray()); }
private static Tuple <Term, Term[]> CreateBGCTerms(SnappedBendedGenCylinder snappedPrimitive, double[] radii, Point[] medial_axis) { var terms = from item in snappedPrimitive.FeatureCurves.Cast <CircleFeatureCurve>() where item.SnappedTo != null from term in ProjectionFit.Compute(item) select term; var featureCurvesTerm = TermUtils.SafeAvg(terms); 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 var positionSmoothnessTerm = TermUtils.SafeAvg( from triple in snappedPrimitive.Components.SeqTripples() let p1 = new TVec(triple.Item1.vS, triple.Item1.vT) let p2 = new TVec(triple.Item2.vS, triple.Item2.vT) let p3 = new TVec(triple.Item3.vS, triple.Item3.vT) let laplacian = p2 - 0.5 * (p1 + p3) select laplacian.NormSquared); Term[] TermArray = new Term[medial_axis.Length]; for (int i = 0; i < medial_axis.Length; i++) { TVec PointOnSpine = snappedPrimitive.BottomCenter + snappedPrimitive.Components[i].vS * snappedPrimitive.U + snappedPrimitive.Components[i].vT * snappedPrimitive.V; TermArray[i] = TermBuilder.Power(PointOnSpine.X - medial_axis[i].X, 2) + TermBuilder.Power(PointOnSpine.Y + medial_axis[i].Y, 2); } var spinePointTerm = TermUtils.SafeAvg(TermArray); // 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 = 0.1 * featureCurvesTerm + radiiApproxTerm + radiiSmoothTerm + positionSmoothnessTerm + spinePointTerm + endpointsRadiiTerm; var sB = snappedPrimitive.NPbot.X; var tB = snappedPrimitive.NPbot.Y; var s0 = snappedPrimitive.Components[0].vS; var t0 = snappedPrimitive.Components[0].vT; var s1 = snappedPrimitive.Components[1].vS; var t1 = snappedPrimitive.Components[1].vT; var botNormalParallelism = tB * (s1 - s0) - sB * (t1 - t0); var sT = snappedPrimitive.NPtop.X; var tT = snappedPrimitive.NPtop.Y; var sLast = snappedPrimitive.Components[snappedPrimitive.Components.Length - 1].vS; var tLast = snappedPrimitive.Components[snappedPrimitive.Components.Length - 1].vT; var sBeforeLast = snappedPrimitive.Components[snappedPrimitive.Components.Length - 2].vS; var tBeforeLast = snappedPrimitive.Components[snappedPrimitive.Components.Length - 2].vT; var topNormalParallelism = tT * (sLast - sBeforeLast) - sT * (tLast - tBeforeLast); var topNormalized = snappedPrimitive.NPtop.NormSquared - 1; var botNormalized = snappedPrimitive.NPbot.NormSquared - 1; var uNormalized = snappedPrimitive.U.NormSquared - 1; var vNormalized = snappedPrimitive.V.NormSquared - 1; var uvOrthogonal = TVec.InnerProduct(snappedPrimitive.U, snappedPrimitive.V); var firstComponentBottomS = snappedPrimitive.Components[0].vS; var firstComponentBottomT = snappedPrimitive.Components[0].vT; var constraints = new List <Term> { topNormalized, botNormalized, uNormalized, vNormalized, uvOrthogonal, firstComponentBottomS, firstComponentBottomT, botNormalParallelism, topNormalParallelism }; var meanRadius = radii.Sum() / radii.Length; var stdDevRadius = Math.Sqrt(radii.Select(r => r * r).Sum() / radii.Length - meanRadius * meanRadius); Debug.WriteLine("ALEXALEX Mean radius is {0}, stddev is {1}", meanRadius, stdDevRadius); if (stdDevRadius <= 0.3 * meanRadius) { foreach (var pair in snappedPrimitive.Components.SeqPairs()) { var ra = pair.Item1.Radius; var rb = pair.Item2.Radius; constraints.Add(ra - rb); } } return(Tuple.Create(objective, constraints.ToArray())); }
/// <summary> /// Measures parallelism of two 3D vectors /// </summary> /// <param name="left">Left vector</param> /// <param name="right">Right vector</param> /// <returns></returns> public static Term VectorParallelism3D(TVec left, TVec right) { return(TVec.CrossProduct(left, right).NormSquared); }
protected override Tuple <Term, Term[]> Reconstruct(SnappedCuboid snappedPrimitive, Dictionary <FeatureCurve, ISet <Annotation> > curvesToAnnotations) { Point O = NewPrimitiveExtensions.FindCoincidentPoint(snappedPrimitive.CubicCorner); Point A = NewPrimitiveExtensions.FindEndPoint(snappedPrimitive.CubicCorner[0].AssignedTo, O); Point B = NewPrimitiveExtensions.FindEndPoint(snappedPrimitive.CubicCorner[1].AssignedTo, O); Point C = NewPrimitiveExtensions.FindEndPoint(snappedPrimitive.CubicCorner[2].AssignedTo, O); Point3D Op = NewPrimitiveExtensions.FindCoincident3DPoint(snappedPrimitive.CubicCorner); EnhancedPrimitiveCurve ec = (EnhancedPrimitiveCurve)snappedPrimitive.CubicCorner[0]; Point3D Ap = NewPrimitiveExtensions.FindEnd3DPoint(ec.Points3D, Op); ec = (EnhancedPrimitiveCurve)snappedPrimitive.CubicCorner[1]; Point3D Bp = NewPrimitiveExtensions.FindEnd3DPoint(ec.Points3D, Op); ec = (EnhancedPrimitiveCurve)snappedPrimitive.CubicCorner[2]; Point3D Cp = NewPrimitiveExtensions.FindEnd3DPoint(ec.Points3D, Op); O.Y = -O.Y; A.Y = -A.Y; B.Y = -B.Y; C.Y = -C.Y; Vector OA = A - O; Vector OB = B - O; Vector OC = C - O; Debug.WriteLine("O=({0},{1})", O.X, O.Y); Debug.WriteLine("A=({0},{1})", A.X, A.Y); Debug.WriteLine("B=({0},{1})", B.X, B.Y); Debug.WriteLine("C=({0},{1})", C.X, C.Y); Vector OAn = OA.Normalized(); Vector OBn = OB.Normalized(); Vector OCn = OC.Normalized(); double dotABn = OAn * OBn; double dotACn = OAn * OCn; double dotBCn = OBn * OCn; double a = Math.Acos(dotABn); double b = Math.Acos(dotACn); double c = Math.Acos(dotBCn); /*double[] anglesSort = new double[] { a, b, c }; * double[] angles = new double[] { a, b, c }; * int[] idx = new int[3]{0, 1, 2}; * Vector[] vecArr = new Vector[] { OAn, OBn, OCn }; * Array.Sort(anglesSort, idx); * Debug.WriteLine("(a,b,c)=({0},{1},{2})", a * 180 / Math.PI, b * 180 / Math.PI, c * 180 / Math.PI); * Debug.WriteLine("sorted : (a,b,c)=({0},{1},{2})", anglesSort[0] * 180 / Math.PI, anglesSort[1] * 180 / Math.PI, anglesSort[2] * 180 / Math.PI); * Debug.WriteLine("index : {0}, {1}, {2}", idx[0], idx[1], idx[2]); * if (anglesSort[1] > Math.PI / 2 && anglesSort[0] < Math.PI / 2) * { * double theta = anglesSort[1] - Math.PI / 2 + 0.001; * var rotMatrix = new RotateTransform(theta*180/Math.PI).Value; * vecArr[idx[1]] = rotMatrix.Transform(vecArr[idx[1]]); * angles[idx[1]] = Math.PI/2 - 0.001; * angles[idx[0]] = angles[idx[2]] - angles[idx[1]]; * } * Debug.WriteLine("after : (a,b,c)=({0},{1},{2},{3})", angles[0] * 180 / Math.PI, angles[1] * 180 / Math.PI, angles[2] * 180 / Math.PI, (angles[0]+angles[1])*180/Math.PI); * * dotABn = Math.Cos(angles[0]); * dotACn = Math.Cos(angles[1]); * dotBCn = Math.Cos(angles[2]); * * OAn = vecArr[0].Normalized(); * OBn = vecArr[1].Normalized(); * OCn = vecArr[2].Normalized();*/ Debug.WriteLine("Cubic Corner Index:{0}", snappedPrimitive.CubicCornerIdx); double pn, qn, rn; int signp = 0, signq = 0, signr = 0; if (dotABn < 0 && dotACn < 0 && dotBCn < 0) { signp = signq = signr = 1; } else { if (dotABn < 0) { signp = signq = -1; signr = 1; } else if (dotBCn < 0) { signq = signr = 1; signp = -1; } else { signp = signr = 1; signq = -1; } } pn = signp * Math.Sqrt(-dotACn * dotABn / dotBCn); qn = signq * Math.Sqrt(-dotABn * dotBCn / dotACn); rn = signr * Math.Sqrt(-dotACn * dotBCn / dotABn); Debug.WriteLine("p*q={0}, OA*OB={1}", pn * qn, dotABn); Debug.WriteLine("p*r={0}, OA*OC={1}", pn * rn, dotACn); Debug.WriteLine("q*r={0}, OB*OC={1}", rn * qn, dotBCn); Vector3D OA3Dn = new Vector3D(OAn.X, OAn.Y, pn); Vector3D OB3Dn = new Vector3D(OBn.X, OBn.Y, qn); Vector3D OC3Dn = new Vector3D(OCn.X, OCn.Y, rn); OA3Dn = OA3Dn.Normalized(); OB3Dn = OB3Dn.Normalized(); OC3Dn = OC3Dn.Normalized(); Vector3D pOA = (Ap - Op).Normalized(); Vector3D pOB = (Bp - Op).Normalized(); Vector3D pOC = (Cp - Op).Normalized(); Vector3D approxW = new Vector3D(); // = OA3Dn.Normalized(); Vector3D approxH = new Vector3D(); // = -OB3Dn.Normalized(); Vector3D approxD = new Vector3D(); // = OC3Dn.Normalized(); /*if (pOA.X * OA3Dn.X < 0) OA3Dn.X = -OA3Dn.X; * if (pOA.Y * OA3Dn.Y < 0) OA3Dn.Y = -OA3Dn.Y; * if (pOA.Z * OA3Dn.Z < 0) OA3Dn.Z = -OA3Dn.Z; * * if (pOB.X * OB3Dn.X < 0) OB3Dn.X = -OB3Dn.X; * if (pOB.Y * OB3Dn.Y < 0) OB3Dn.Y = -OB3Dn.Y; * if (pOB.Z * OB3Dn.Z < 0) OB3Dn.Z = -OB3Dn.Z; * * if (pOC.X * OC3Dn.X < 0) OC3Dn.X = -OC3Dn.X; * if (pOC.Y * OC3Dn.Y < 0) OC3Dn.Y = -OC3Dn.Y; * if (pOC.Z * OC3Dn.Z < 0) OC3Dn.Z = -OC3Dn.Z;*/ switch (snappedPrimitive.CubicCornerIdx) { case 0: approxW = Vector3D.DotProduct(pOA, OA3Dn) > 0 ? OA3Dn : -OA3Dn; approxH = Vector3D.DotProduct(pOB, OB3Dn) < 0 ? OB3Dn : -OB3Dn; approxD = Vector3D.DotProduct(pOC, OC3Dn) > 0 ? OC3Dn : -OC3Dn; break; case 1: approxW = Vector3D.DotProduct(pOA, OA3Dn) > 0 ? -OA3Dn : OA3Dn; approxH = Vector3D.DotProduct(pOB, OB3Dn) > 0 ? -OB3Dn : OB3Dn; approxD = Vector3D.DotProduct(pOC, OC3Dn) > 0 ? OC3Dn : -OC3Dn; break; case 2: approxW = Vector3D.DotProduct(pOA, OA3Dn) > 0 ? -OA3Dn : OA3Dn; approxH = Vector3D.DotProduct(pOB, OB3Dn) > 0 ? OB3Dn : -OB3Dn; approxD = Vector3D.DotProduct(pOC, OC3Dn) < 0 ? OC3Dn : -OC3Dn; break; case 3: approxW = -OA3Dn.Normalized(); approxH = -OB3Dn.Normalized(); approxD = -OC3Dn.Normalized(); break; case 4: approxW = OA3Dn.Normalized(); approxH = OB3Dn.Normalized(); approxD = OC3Dn.Normalized(); break; case 5: //if (pOA.X * OA3Dn.X < 0) OA3Dn.X = -OA3Dn.X; //if (pOA.X * OA3Dn.X < 0) OA3Dn.X = -OA3Dn.X; approxW = Vector3D.DotProduct(pOA, OA3Dn) > 0 ? -OA3Dn : OA3Dn; approxH = Vector3D.DotProduct(pOB, OB3Dn) > 0 ? OB3Dn : -OB3Dn; approxD = Vector3D.DotProduct(pOC, OC3Dn) > 0 ? OC3Dn : -OC3Dn; //Debug.WriteLine(); break; case 6: approxW = OA3Dn.Normalized(); approxH = OB3Dn.Normalized(); approxD = -OC3Dn.Normalized(); break; case 7: approxW = -OA3Dn.Normalized(); approxH = OB3Dn.Normalized(); approxD = -OC3Dn.Normalized(); break; } snappedPrimitive.W = OA3Dn.Normalized(); snappedPrimitive.H = OB3Dn.Normalized(); snappedPrimitive.D = OC3Dn.Normalized(); Debug.WriteLine("Normalized W*H={0}", Vector3D.DotProduct(approxW, approxH)); Debug.WriteLine("Normalized W*D={0}", Vector3D.DotProduct(approxW, approxD)); Debug.WriteLine("Normalized D*H={0}", Vector3D.DotProduct(approxD, approxH)); /*double lOA = OA.Length; * double lOB = OB.Length; * double lOC = OC.Length; * Debug.WriteLine("(lOA, lOB, lOC)=({0},{1},{2})", lOA, lOB, lOC);*/ //a = Math.Acos(OAn * OBn); //b = Math.Acos(OAn * OCn); //c = Math.Acos(OBn * OCn); //Debug.WriteLine("(pi/2, a,b,c,sum)=({0},{1},{2}, {3},{4})", Math.PI / 2, a * 180 / Math.PI, b * 180 / Math.PI, c * 180 / Math.PI, a * 180 / Math.PI + b * 180 / Math.PI); /*double cota = 1 / Math.Tan(a); * double cotb = 1 / Math.Tan(b); * double cotc = 1 / Math.Tan(c);*/ /*double dotAB = lOA * lOB * Math.Cos(a); * double dotAC = lOA * lOC * Math.Cos(b); * double dotBC = lOB * lOC * Math.Cos(c);*/ double dotAB = OA * OB; double dotAC = OA * OC; double dotBC = OB * OC; double p, q, r; p = signp * Math.Sqrt(-dotAC * dotAB / dotBC); q = signq * Math.Sqrt(-dotAB * dotBC / dotAC); r = signr * Math.Sqrt(-dotAC * dotBC / dotAB); //double r = Math.Sqrt(-dotAB*dotBC/dotAC); //Debug.WriteLine("(p,q,r)=({0},{1},{2})", p, q, r); //ec = (EnhancedPrimitiveCurve)snappedPrimitive.CubicCorner[0]; Vector3D cuboidOA = ec.Points3D[1] - ec.Points3D[0]; //ec = (EnhancedPrimitiveCurve)snappedPrimitive.CubicCorner[1]; Vector3D cuboidOB = ec.Points3D[1] - ec.Points3D[0]; //ec = (EnhancedPrimitiveCurve)snappedPrimitive.CubicCorner[2]; Vector3D cuboidOC = ec.Points3D[1] - ec.Points3D[0]; double zAp = p; double zAn = -zAp; double zBp = q; double zBn = -zBp; double zCp = r; double zCn = -zCp; Point3D O3D = new Point3D(O.X, O.Y, 0); snappedPrimitive.Origin = O3D; Point3D A3Dp = new Point3D(A.X, A.Y, zAp); Point3D A3Dn = new Point3D(A.X, A.Y, -zAp); Vector3D OA3Dp = A3Dp - O3D; //Point3D A3D = (Vector3D.DotProduct(cuboidOA, OA3Dp) > 0) ? A3Dp : A3Dn; Point3D A3D = A3Dp;// (Vector3D.DotProduct(cuboidOA, OA3Dp) > 0) ? A3Dp : A3Dn; //Vector Point3D B3Dp = new Point3D(B.X, B.Y, zBp); Point3D B3Dn = new Point3D(B.X, B.Y, -zBp); Vector3D OB3Dp = B3Dp - O3D; //Point3D B3D = (Vector3D.DotProduct(cuboidOB, OB3Dp) > 0) ? B3Dp : B3Dn; Point3D B3D = B3Dp; //(Vector3D.DotProduct(cuboidOB, OB3Dp) > 0) ? B3Dp : B3Dn; Point3D C3Dp = new Point3D(C.X, C.Y, zCp); Point3D C3Dn = new Point3D(C.X, C.Y, -zCp); Vector3D OC3Dp = C3Dp - O3D; //Point3D C3D = (Vector3D.DotProduct(cuboidOC, OC3Dp) > 0) ? C3Dp : C3Dn; Point3D C3D = C3Dp; Debug.WriteLine("OA3D=({0},{1},{2})", OA3Dp.X, OA3Dp.Y, OA3Dp.Z); Debug.WriteLine("OB3D=({0},{1},{2})", OB3Dp.X, OB3Dp.Y, OB3Dp.Z); Debug.WriteLine("W*H={0}", Vector3D.DotProduct(approxH, approxW)); Debug.WriteLine("W*D={0}", Vector3D.DotProduct(approxD, approxW)); Debug.WriteLine("D*H={0}", Vector3D.DotProduct(approxH, approxD)); double approxWidth = (A3D - O3D).Length; double approxHeight = (O3D - B3D).Length; double approxDepth = (C3D - O3D).Length; Point3D approxCenter = new Point3D(); switch (snappedPrimitive.CubicCornerIdx) { case 0: approxCenter = O3D + 0.5 * approxWidth * approxW - 0.5 * approxHeight * approxH + 0.5 * approxDepth * approxD; break; case 1: approxCenter = O3D - 0.5 * approxWidth * approxW - 0.5 * approxHeight * approxH + 0.5 * approxDepth * approxD; break; case 2: approxCenter = O3D + 0.5 * approxWidth * approxW - 0.5 * approxHeight * approxH - 0.5 * approxDepth * approxD; break; case 3: approxCenter = O3D - 0.5 * approxWidth * approxW - 0.5 * approxHeight * approxH - 0.5 * approxDepth * approxD; break; case 4: approxCenter = O3D + 0.5 * approxWidth * approxW + 0.5 * approxHeight * approxH + 0.5 * approxDepth * approxD; break; case 5: approxCenter = O3D - 0.5 * approxWidth * approxW + 0.5 * approxHeight * approxH + 0.5 * approxDepth * approxD; break; case 6: approxCenter = O3D + 0.5 * approxWidth * approxW + 0.5 * approxHeight * approxH - 0.5 * approxDepth * approxD; break; case 7: approxCenter = O3D - 0.5 * approxWidth * approxW + 0.5 * approxHeight * approxH - 0.5 * approxDepth * approxD; break; } var CenterTerm = TermBuilder.Power(snappedPrimitive.Center.X - approxCenter.X, 2) + TermBuilder.Power(snappedPrimitive.Center.Y - approxCenter.Y, 2) + TermBuilder.Power(snappedPrimitive.Center.Z - approxCenter.Z, 2); var LengthTerm = TermBuilder.Power(snappedPrimitive.Width - approxWidth, 2) + TermBuilder.Power(snappedPrimitive.Height - approxHeight, 2) + TermBuilder.Power(snappedPrimitive.Depth - approxDepth, 2); double widthVectorArea = approxHeight * approxDepth; // area of the face orthogonal to width vector double heightVectorArea = approxWidth * approxDepth; // area of the face orthogonal to height vector double depthVectorArea = approxWidth * approxHeight; // area of the face orthogonal to depth vector Debug.WriteLine("WVA = {0}, HVA = {1}, DVA = {2}", widthVectorArea, heightVectorArea, depthVectorArea); var WidthVectorTerm = Math.Pow(widthVectorArea, 2) * ( TermBuilder.Power(snappedPrimitive.Wv.X - approxW.X, 2) + TermBuilder.Power(snappedPrimitive.Wv.Y - approxW.Y, 2) + TermBuilder.Power(snappedPrimitive.Wv.Z - approxW.Z, 2)); var HeightVectorTerm = Math.Pow(heightVectorArea, 2) * ( TermBuilder.Power(snappedPrimitive.Hv.X - approxH.X, 2) + TermBuilder.Power(snappedPrimitive.Hv.Y - approxH.Y, 2) + TermBuilder.Power(snappedPrimitive.Hv.Z - approxH.Z, 2)); var DepthVectorTerm = Math.Pow(depthVectorArea, 2) * ( TermBuilder.Power(snappedPrimitive.Dv.X - approxD.X, 2) + TermBuilder.Power(snappedPrimitive.Dv.Y - approxD.Y, 2) + TermBuilder.Power(snappedPrimitive.Dv.Z - approxD.Z, 2)); var objective = CenterTerm + LengthTerm + 100 * (WidthVectorTerm + HeightVectorTerm + DepthVectorTerm); var ABorthogonal = TVec.InnerProduct(snappedPrimitive.Wv, snappedPrimitive.Hv); var ACorthogonal = TVec.InnerProduct(snappedPrimitive.Wv, snappedPrimitive.Dv); var BCorthogonal = TVec.InnerProduct(snappedPrimitive.Hv, snappedPrimitive.Dv); var constraints = new Term[] { snappedPrimitive.Wv.NormSquared - 1, snappedPrimitive.Hv.NormSquared - 1, snappedPrimitive.Dv.NormSquared - 1, ABorthogonal, ACorthogonal, BCorthogonal }; return(Tuple.Create(10 * objective, constraints)); }
private static IEnumerable <Term> VectorsParallelism3DTerms(TVec u, TVec v) { yield return(u.X * v.Y - u.Y * v.X); yield return(u.Y * v.Z - u.Z * v.Y); }
private double CalculateR2(TVec observedValues, TVec predictedValues) { double ssTot = 0.0; double ssErr = 0.0; for(int i = 0; i < observedValues.Length - 1; i++) { ssTot += (observedValues[i] - observedValues.Mean()) * (observedValues[i] - observedValues.Mean()); ssErr += (predictedValues[i] - observedValues[i]) * (predictedValues[i] - observedValues[i]); } return 1 - (ssErr / ssTot); }
private static IEnumerable <Term> PointOnLineTerms(TVec pnt, TVec linePnt, TVec lineDir) { var u = pnt - linePnt; return(VectorsParallelism3DTerms(u, lineDir)); }
private static Term OrthogonalVectors3DTerm(TVec u, TVec v) { return(u.X * v.X + u.Y * v.Y + u.Z * v.Z); }
private static Term PointOnPlaneTerm(TVec pnt, TVec planePnt, TVec planeNormal) { var u = pnt - planePnt; return(OrthogonalVectors3DTerm(u, planeNormal)); }
private void ShowResults() { if (rbBestNetwork.Checked) { mSelectedActivationNetwork = mBestActivationNetwork; } if (rbBestTestNetwork.Checked) { mSelectedActivationNetwork = mBestTestActivationNetwork; } if (rbGenetic.Checked) { mSelectedActivationNetwork = mBestGeneticActivationNetwork; } try { TVec dy = null; TVec dx = null; fittedChart.Series.Clear(); fittedChart.Series.Add(new Steema.TeeChart.Styles.FastLine()); fittedChart.Series.Add(new Steema.TeeChart.Styles.FastLine()); fittedChart.Series[0].Title = "наблюдения"; fittedChart.Series[1].Title = "прогнози"; fittedChart.Axes.Left.Title.Text = "Y"; fittedChart.Axes.Bottom.Title.Text = ""; fittedChart.Axes.Left.Automatic = true; Vector timeseries = new Vector((TestEnd-ExtractBegin) + 1); Vector abs = new Vector((TestEnd - ExtractBegin) + 1); int? dependent_variable_id = 0; foreach (int? dep in this.DependentVariables.Keys) { dependent_variable_id = dep; } MainDataSetTableAdapters.VARIABLESTableAdapter adptVariables = new Plig.TimeSeries.Client.MainDataSetTableAdapters.VARIABLESTableAdapter(); mindep = adptVariables.MinObservationValue(ExtractBegin, TestEnd, dependent_variable_id.Value).Value; factordep = 1.7 / (adptVariables.MaxObservationValue(ExtractBegin, TestEnd, dependent_variable_id.Value).Value - adptVariables.MinObservationValue(ExtractBegin, TestEnd, dependent_variable_id.Value).Value); int cnt = ExtractBegin; foreach (KeyValuePair<int, double?> d in this.VariableObservations(dependent_variable_id.Value)) { if (d.Key >= ExtractBegin && d.Key <= TestEnd) { try { timeseries.Values[cnt - ExtractBegin] = d.Value.Value; } catch { timeseries.Values[cnt - ExtractBegin] = 0.0; } abs.Values[cnt - ExtractBegin] = cnt; cnt++; } } dy = timeseries; dx = abs; Dew.Math.Tee.TeeChart.DrawValues(dx, dy, fittedChart.Series[0], false); // Извличаме стойностите на независимите променливи TVec dy1 = null; Vector timeseries1 = new Vector(TestEnd - ExtractBegin + 1); int independent_vars = this.IndependentVariables.Count; double[] tuple = new double[independent_vars]; for (int i = ExtractBegin; i <= TestEnd; i++) { int cnt1 = 0; foreach (int variable_id in this.IndependentVariables.Keys) { double factor = 1.7 / ( (this.SeriesInfo[variable_id]).Max - (this.SeriesInfo[variable_id]).Min); tuple[cnt1] = (this.SeriesInfo[variable_id].Values[i].Value - (this.SeriesInfo[variable_id]).Min) * factor - 0.85; cnt1++; } double value = (mSelectedActivationNetwork.Compute(tuple)[0] + 0.85) / factordep + mindep; timeseries1.Values[i - ExtractBegin] = value; } dy1 = timeseries1; Dew.Math.Tee.TeeChart.DrawValues(dx, dy1, fittedChart.Series[1], false); residuals = new TVec(); residuals.Length = timeseries1.Length; for (int i = 0; i < residuals.Length; i++) { residuals.Values[i] = timeseries1.Values[i] - timeseries.Values[i]; } Vector Bins = new Vector(0); Vector Freq = new Vector(0); chartResiduals.Series[0].Title = "остатъци"; chartResiduals.Series[1].Title = "Нормално разпределение"; chartResiduals.Axes.Left.Title.Text = "Y"; chartResiduals.Axes.Bottom.Title.Text = ""; chartResiduals.Axes.Left.Automatic = true; Statistics.Histogram(residuals, 20, Freq, Bins, true); Dew.Math.Tee.TeeChart.DrawValues(Bins, Freq, chartResiduals.Series[0], false); Vector xdense = new Vector(0); Matrix tmpmtx = new Matrix(0, 0); Vector x = new Vector(0); Vector bell = new Vector(0); // get values for Bell curve double mean = residuals.Mean(); double stddev = residuals.StdDev(mean); // 500 calc points xdense.Length = 500; xdense.Ramp(Bins.Min() , (Bins.Max() - Bins.Min()) * 0.005); Dew.Math.Units.Probabilities.NormalPDF(xdense, mean, stddev, bell); chartResiduals.Series[1].GetHorizAxis.Automatic = false; chartResiduals.Series[1].GetHorizAxis.SetMinMax(residuals.Min(), residuals.Max()); Dew.Math.Tee.TeeChart.DrawValues(xdense, bell, chartResiduals.Series[1], false); double R2 = CalculateR2(dy, dy1); rchTests.Clear(); rchTests.SelectionColor = Color.Red; rchTests.AppendText("Тестове"); rchTests.SelectionColor = SystemColors.InfoText; ; rchTests.AppendText("\nНевронна мрежа с параметри: "); rchTests.AppendText(String.Format("\nВходящ слой: {0} неврона", mSelectedActivationNetwork.InputsCount)); rchTests.AppendText(String.Format("\nСкрит слой: {0} неврона", mSelectedActivationNetwork[0].NeuronsCount)); rchTests.SelectionColor = Color.Red; rchTests.AppendText("\nСтатистически параметри"); rchTests.SelectionColor = SystemColors.InfoText; ; rchTests.AppendText(String.Format("\nCalculated R2: {0:F6}", R2)); rchTests.AppendText("\n\nАнализ на независимите променливи"); rchTests.AppendText("\nЗначимост"); double max_spread = 0.0; foreach (int var_id in IndependentVariables.Keys) { Vector vec = IndepVar(var_id); if (max_spread < vec.Max() - vec.Min()) { max_spread = vec.Max() - vec.Min(); } } int current = 1; foreach (int var_id in IndependentVariables.Keys) { Vector vec = IndepVar(var_id); double spread = vec.Max() - vec.Min(); String result = String.Format("{0,-3}. {1,25}: {2,10} | {3}", current, IndependentVariables[var_id], spread, Stars( (int)Math.Floor((10*spread)/ max_spread))); rchTests.AppendText("\n" + result); current++; } rchTests.AppendText("\n\nDurbin-Watson тест за наличие на автоколинеарност в остатъците"); rchTests.AppendText(String.Format("\nDW: {0}", Utils.DurbinWatson((Vector)residuals))); } catch { }; }
protected override void StartTraining(bool aIsRunning) { if (aIsRunning) { TMtx indepVars = new TMtx(); TVec depVars = new TVec(); string[] var_names = new string[IndependentVariables.Count]; indepVars.Cols = IndependentVariables.Count; indepVars.Rows = ExtractEnd - ExtractBegin + 1; depVars.Length = ExtractEnd - ExtractBegin + 1; double[][] mInput = new double[ExtractEnd - ExtractBegin + 1][]; double[][] mOutput = new double[ExtractEnd - ExtractBegin + 1][]; for (int i = 0; i < ExtractEnd - ExtractBegin + 1; i++) { mInput[i] = new double[IndependentVariables.Count]; mOutput[i] = new double[DependentVariables.Count]; } MainDataSetTableAdapters.VARIABLESTableAdapter adptVariables = new Plig.TimeSeries.Client.MainDataSetTableAdapters.VARIABLESTableAdapter(); int index_of_variable = 0; foreach (int variable_id in IndependentVariables.Keys) { var_names[index_of_variable] = IndependentVariables[variable_id]; Dictionary<int, double?> observations = VariableObservations(variable_id); TVec vec = new TVec(); foreach (int counter in observations.Keys) { if ((counter >= ExtractBegin) && (counter <= ExtractEnd)) { mInput[counter - ExtractBegin][index_of_variable] = observations[counter].Value; indepVars[counter - ExtractBegin, index_of_variable] = observations[counter].Value; } } index_of_variable++; } index_of_variable = 0; foreach (int variable_id in DependentVariables.Keys) { Dictionary<int, double?> observations = VariableObservations(variable_id); foreach (int counter in observations.Keys) { if ((counter >= ExtractBegin) && (counter <= ExtractEnd)) { mOutput[counter - ExtractBegin][index_of_variable] = observations[counter].Value; depVars[counter - ExtractBegin] = observations[counter].Value; } } index_of_variable++; } multiLinReg.A = indepVars; multiLinReg.Y = depVars; multiLinReg.Recalc(); txtResults.Clear(); txtResults.SelectionColor = Color.Red; txtResults.AppendText("Тестове"); txtResults.SelectionColor = SystemColors.InfoText; ; txtResults.SelectionColor = Color.Red; txtResults.AppendText("Статистически параметри"); txtResults.SelectionColor = SystemColors.InfoText; ; txtResults.AppendText("\nRSS: " + (multiLinReg.RegressStatistics.AdjustedR2.ToString() + "\n")); string regression_formula = string.Empty; for (int i = 0; i < multiLinReg.RegressResult.B.Length - 1; i++) { regression_formula += String.Format("+{0:F6}.{1}", multiLinReg.RegressResult.B[i], var_names[i]); } regression_formula += String.Format("+{0:F6}", multiLinReg.RegressResult.B[multiLinReg.RegressResult.B.Length - 1]); txtResults.AppendText("\nY = " + regression_formula); txtResults.AppendText("\n\nDurbin-Watson тест за наличие на автоколинеарност в остатъците"); txtResults.AppendText(String.Format("\nDW: {0}", Utils.DurbinWatson((Vector)multiLinReg.RegressResult.Residuals))); Vector Bins = new Vector(0); Vector Freq = new Vector(0); chartResiduals.Series[0].Title = "остатъци"; chartResiduals.Axes.Left.Title.Text = "Y"; chartResiduals.Axes.Bottom.Title.Text = ""; chartResiduals.Axes.Left.Automatic = true; Statistics.Histogram(multiLinReg.RegressResult.Residuals, 15, Freq, Bins, true); TVec dy = Freq; TVec dx = Bins; Dew.Math.Tee.TeeChart.DrawValues(dx, dy, chartResiduals.Series[0], false); this.IsRunning = false; } }