Beispiel #1
0
        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));
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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());
        }
Beispiel #5
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #9
0
        /// <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));
        }
Beispiel #10
0
        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);
            }
        }
Beispiel #11
0
        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());
        }
Beispiel #12
0
        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 { };
        }
Beispiel #21
0
        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;
            }
        }