public static Trivector MulVGrad(Trivector v, Quaternion.Quaternion q)
        {
            double x = v.X, y = v.Y, z = v.Z, r = q.R, i = q.I, j = q.J, k = q.K;

            return(new Trivector(
                       x * (r * r + i * i - j * j - k * k) + 2 * y * (i * j + r * k) + 2 * z * (k * i - r * j),
                       y * (r * r - i * i + j * j - k * k) + 2 * z * (j * k + r * i) + 2 * x * (i * j - r * k),
                       z * (r * r - i * i - j * j + k * k) + 2 * x * (k * i + r * j) + 2 * y * (j * k - r * i)
                       ));
        }
        public static Quaternion.Quaternion MulQGrad(Trivector v, Trivector u, Quaternion.Quaternion q)
        {
            double vx = v.X, vy = v.Y, vz = v.Z, ux = u.X, uy = u.Y, uz = u.Z, r = q.R, i = q.I, j = q.J, k = q.K;

            return(new Quaternion.Quaternion(
                       ux * (2 * j * vz - 2 * k * vy + 2 * r * vx) + uy * (2 * k * vx - 2 * i * vz + 2 * r * vy) + uz * (2 * i * vy - 2 * j * vx + 2 * r * vz),
                       ux * (2 * k * vz + 2 * j * vy + 2 * i * vx) + uy * (2 * j * vx - 2 * r * vz - 2 * i * vy) + uz * (2 * r * vy + 2 * k * vx - 2 * i * vz),
                       ux * (2 * r * vz + 2 * i * vy - 2 * j * vx) + uy * (2 * i * vx + 2 * k * vz + 2 * j * vy) + uz * (2 * k * vy - 2 * r * vx - 2 * j * vz),
                       ux * (2 * i * vz - 2 * r * vy - 2 * k * vx) + uy * (2 * r * vx + 2 * j * vz - 2 * k * vy) + uz * (2 * j * vy + 2 * i * vx + 2 * k * vz)
                       ));
        }
        public void MulTest()
        {
            Trivector v = new Trivector(4, 3, 2);

            Quaternion.Quaternion q = new Quaternion.Quaternion(5, -6, 7, -8);

            Trivector u = v * q;

            Assert.AreEqual(112, u.X);
            Assert.AreEqual(-838, u.Y);
            Assert.AreEqual(-404, u.Z);
        }
        public void MulVGradTest()
        {
            Trivector v = new Trivector(4, 3, 2);

            Quaternion.Quaternion q = new Quaternion.Quaternion(5, -6, 7, -8);

            Trivector u = Trivector.MulVGrad(v, q);

            Assert.AreEqual(-648, u.X);
            Assert.AreEqual(-438, u.Y);
            Assert.AreEqual(516, u.Z);
        }
        public void MulQGradTest()
        {
            Trivector v = new Trivector(4, -3, 2);
            Trivector u = new Trivector(-2, 5, -7);

            Quaternion.Quaternion q = new Quaternion.Quaternion(5, -6, 7, -8);

            Quaternion.Quaternion p = Trivector.MulQGrad(v, u, q);

            Assert.AreEqual(-390, p.R);
            Assert.AreEqual(734, p.I);
            Assert.AreEqual(-470, p.J);
            Assert.AreEqual(814, p.K);
        }
        public static Quaternion.QuaternionFilter2D Reference(TrivectorMap2D x, TrivectorMap2D gy, Quaternion.QuaternionFilter2D w, int kwidth, int kheight, int stride)
        {
            int inchannels = x.Channels, outchannels = gy.Channels, batch = x.Batch;
            int inw = x.Width, inh = x.Height, outw = gy.Width, outh = gy.Height;

            if (outw != (inw - kwidth) / stride + 1 || outh != (inh - kheight) / stride + 1)
            {
                throw new ArgumentException("mismatch shape");
            }

            Quaternion.QuaternionFilter2D gw = new Quaternion.QuaternionFilter2D(inchannels, outchannels, kwidth, kheight);

            for (int kx, ky = 0; ky < kheight; ky++)
            {
                for (kx = 0; kx < kwidth; kx++)
                {
                    for (int th = 0; th < batch; th++)
                    {
                        for (int inch, outch = 0; outch < outchannels; outch++)
                        {
                            for (inch = 0; inch < inchannels; inch++)
                            {
                                Quaternion.Quaternion sum = 0;
                                Quaternion.Quaternion q   = w[inch, outch, kx, ky];

                                for (int ix, iy = ky, ox, oy = 0; oy < outh; iy += stride, oy++)
                                {
                                    for (ix = kx, ox = 0; ox < outw; ix += stride, ox++)
                                    {
                                        sum += Trivector.MulQGrad(x[inch, ix, iy, th], gy[outch, ox, oy, th], q);
                                    }
                                }

                                gw[inch, outch, kx, ky] += sum;
                            }
                        }
                    }
                }
            }

            return(gw);
        }
Beispiel #7
0
        public static Quaternion.QuaternionFilter0D Reference(TrivectorMap0D x, TrivectorMap0D gy, Quaternion.QuaternionFilter0D w)
        {
            int inchannels = x.Channels, outchannels = gy.Channels, batch = x.Batch;

            Quaternion.QuaternionFilter0D gw = new Quaternion.QuaternionFilter0D(inchannels, outchannels);

            for (int inch, outch = 0; outch < outchannels; outch++)
            {
                for (inch = 0; inch < inchannels; inch++)
                {
                    Quaternion.Quaternion sum = 0;
                    Quaternion.Quaternion q   = w[inch, outch];

                    for (int th = 0; th < batch; th++)
                    {
                        sum += Trivector.MulQGrad(x[inch, th], gy[outch, th], q);
                    }

                    gw[inch, outch] += sum;
                }
            }

            return(gw);
        }
Beispiel #8
0
        public static Quaternion.QuaternionFilter1D Reference(TrivectorMap1D x, TrivectorMap1D gy, Quaternion.QuaternionFilter1D w, int kwidth, int stride)
        {
            int inchannels = x.Channels, outchannels = gy.Channels, batch = x.Batch;
            int inw = x.Width, outw = gy.Width;

            if (outw != (inw - kwidth) / stride + 1)
            {
                throw new ArgumentException("mismatch shape");
            }

            Quaternion.QuaternionFilter1D gw = new Quaternion.QuaternionFilter1D(inchannels, outchannels, kwidth);

            for (int kx = 0; kx < kwidth; kx++)
            {
                for (int th = 0; th < batch; th++)
                {
                    for (int inch, outch = 0; outch < outchannels; outch++)
                    {
                        for (inch = 0; inch < inchannels; inch++)
                        {
                            Quaternion.Quaternion sum = 0;
                            Quaternion.Quaternion q   = w[inch, outch, kx];

                            for (int ix = kx, ox = 0; ox < outw; ix += stride, ox++)
                            {
                                sum += Trivector.MulQGrad(x[inch, ix, th], gy[outch, ox, th], q);
                            }

                            gw[inch, outch, kx] += sum;
                        }
                    }
                }
            }

            return(gw);
        }