Example #1
0
        public static string Crypt(string password, string salt)
        {
            var keyPtr = new ArrayPointer<byte>(Encoding.UTF8.GetBytes(password + "\0"));
            var saltPtr = new ArrayPointer<byte>(Encoding.UTF8.GetBytes(salt + "\0"));

            /* Try to find out whether we have to use MD5 encryption replacement.  */
            if (CryptImpl.strncmp(CryptImpl.md5_salt_prefix, saltPtr, CryptImpl.strlen(CryptImpl.md5_salt_prefix)) == 0)
            {
                return CryptImpl.CryptMd5(keyPtr, saltPtr);
            }

            /* Try to find out whether we have to use SHA256 encryption replacement.  */
            if (CryptImpl.strncmp(CryptImpl.sha256_salt_prefix, saltPtr, CryptImpl.strlen(CryptImpl.sha256_salt_prefix)) == 0)
            {
                return CryptImpl.CryptSha256(keyPtr, saltPtr);
            }

            /* Try to find out whether we have to use SHA512 encryption replacement.  */
            if (CryptImpl.strncmp(CryptImpl.sha512_salt_prefix, saltPtr, CryptImpl.strlen(CryptImpl.sha512_salt_prefix)) == 0)
            {
                return CryptImpl.CryptSha512(keyPtr, saltPtr);
            }

            throw new ArgumentException("Unsupported algorithm");
        }
 public void testSetDoubleArrayPointer() {
     double[] foo = new double[] {1, 2, 3, 4, 6};
     ArrayPointer<double> pFoo = new ArrayPointer<double>(foo, 2);
     pFoo[2] = 5;
     Assert.IsTrue(new double[] {1, 2, 3, 4, 5}.SequenceEqual(foo));
     try {
         pFoo[3] = 0;
         Assert.Fail("IndexOutOfRangeException expected");
     } catch (IndexOutOfRangeException) {}
 }
 public void testGetDoubleArrayPointer() {
     double[] foo = new double[] {1, 2, 3, 4, 6};
     ArrayPointer<double> pFoo = new ArrayPointer<double>(foo, 2);
     Assert.AreEqual(3, pFoo[0]);
     Assert.AreEqual(4, pFoo[1]);
     Assert.AreEqual(6, pFoo[2]);
     try {
         var i = pFoo[3];
         Assert.Fail("IndexOutOfRangeException expected");
     } catch (IndexOutOfRangeException) {}
 }
Example #4
0
        internal static string CryptMd5(ArrayPointer<byte> key, ArrayPointer<byte> salt)
        {
            /* We don't want to have an arbitrary limit in the size of the
               password.  We can compute the size of the result in advance and
               so we can prepare the buffer we pass to `md5_crypt_r'.  */
            ArrayPointer<byte> buffer;
            int buflen = 0;
            int needed = 3 + strlen(salt) + 1 + 26 + 1;

            ArrayPointer<byte> new_buffer = new ArrayPointer<byte>(new byte[needed]);

            buffer = new_buffer;
            buflen = needed;

            return ExtractString(__md5_crypt_r(key, salt, buffer, buflen));
        }
Example #5
0
        internal static string CryptSha256(ArrayPointer<byte> key, ArrayPointer<byte> salt)
        {
            /* We don't want to have an arbitrary limit in the size of the
               password.  We can compute an upper bound for the size of the
               result in advance and so we can prepare the buffer we pass to
               `sha256_crypt_r'.  */
            ArrayPointer<byte> buffer;
            int buflen = 0;
            int needed = (strlen(sha256_salt_prefix)
                  + strlen(sha256_rounds_prefix) + 1 + 9 + 1
                  + strlen(salt) + 1 + 43 + 1);

            ArrayPointer<byte> new_buffer = new ArrayPointer<byte>(new byte[needed]);

            buffer = new_buffer;
            buflen = needed;

            return ExtractString(__sha256_crypt_r(key, salt, buffer, buflen));
        }
Example #6
0
        private static void __sha512_finish_ctx(sha512_ctx ctx, ArrayPointer<byte> buffer)
        {
            byte[] temp = new byte[ctx.stream.Length];
            ctx.stream.Seek(0, SeekOrigin.Begin);
            ctx.stream.Read(temp, 0, temp.Length);

            temp = SHA512.Create().ComputeHash(temp);

            for (int i = 0; i < temp.Length; i++, buffer++)
            {
                buffer.Value = temp[i];
            }
        }
Example #7
0
        private static ArrayPointer<byte> __sha512_crypt_r(ArrayPointer<byte> key, ArrayPointer<byte> salt, ArrayPointer<byte> buffer, int buflen)
        {
            ArrayPointer<byte> alt_result = new ArrayPointer<byte>(new byte[64]);
            ArrayPointer<byte> temp_result = new ArrayPointer<byte>(new byte[64]);
            sha512_ctx ctx = new sha512_ctx();
            sha512_ctx alt_ctx = new sha512_ctx();
            int salt_len;
            int key_len;
            int cnt;
            ArrayPointer<byte> cp;
            ArrayPointer<byte> copied_key;
            ArrayPointer<byte> copied_salt;
            ArrayPointer<byte> p_bytes;
            ArrayPointer<byte> s_bytes;
            /* Default number of rounds.  */
            int rounds = RoundsDefault;
            bool rounds_custom = false;

            /* Find beginning of salt string.  The prefix should normally always
               be present.  Just in case it is not.  */
            if (strncmp(sha512_salt_prefix, salt, strlen(sha512_salt_prefix)) == 0)
                /* Skip salt prefix.  */
                salt += strlen(sha512_salt_prefix);

            if (strncmp(salt, sha512_rounds_prefix, strlen(sha512_rounds_prefix)) == 0)
            {
                ArrayPointer<byte> num = salt + strlen(sha512_rounds_prefix);
                ArrayPointer<byte> endp;
                ulong srounds = strtoul(num, out endp, 10);
                if (endp.Value == (byte)'$')
                {
                    salt = endp + 1;
                    rounds = (int)Math.Max(RoundsMin, Math.Min(srounds, RoundsMax));
                    rounds_custom = true;
                }
            }

            salt_len = Math.Min(strcspn(salt, dollar_sign), SaltLenMax);
            key_len = strlen(key);

            byte[] temp = new byte[key.SourceArray.Length];
            key.SourceArray.CopyTo(temp, 0);
            copied_key = new ArrayPointer<byte>(temp);
            copied_key.Address = key.Address;
            key = copied_key;

            temp = new byte[salt.SourceArray.Length];
            salt.SourceArray.CopyTo(temp, 0);
            copied_salt = new ArrayPointer<byte>(temp);
            copied_salt.Address = salt.Address;
            salt = copied_salt;

            /* Prepare for the real work.  */
            __sha512_init_ctx(ctx);

            /* Add the key string.  */
            __sha512_process_bytes(key, key_len, ctx);

            /* The last part is the salt string.  This must be at most 16
               characters and it ends at the first `$' character.  */
            __sha512_process_bytes(salt, salt_len, ctx);

            /* Compute alternate SHA256 sum with input KEY, SALT, and KEY.  The
               final result will be added to the first context.  */
            __sha512_init_ctx(alt_ctx);

            /* Add key.  */
            __sha512_process_bytes(key, key_len, alt_ctx);

            /* Add salt.  */
            __sha512_process_bytes(salt, salt_len, alt_ctx);

            /* Add key again.  */
            __sha512_process_bytes(key, key_len, alt_ctx);

            /* Now get result of this (32 bytes) and add it to the other
               context.  */
            __sha512_finish_ctx(alt_ctx, alt_result);

            /* Add for any character in the key one byte of the alternate sum.  */
            for (cnt = key_len; cnt > 64; cnt -= 64)
                __sha512_process_bytes(alt_result, 64, ctx);
            __sha512_process_bytes(alt_result, cnt, ctx);

            /* Take the binary representation of the length of the key and for every
               1 add the alternate sum, for every 0 the key.  */
            for (cnt = key_len; cnt > 0; cnt >>= 1)
                if ((cnt & 1) != 0)
                    __sha512_process_bytes(alt_result, 64, ctx);
                else
                    __sha512_process_bytes(key, key_len, ctx);

            /* Create intermediate result.  */
            __sha512_finish_ctx(ctx, alt_result);

            /* Start computation of P byte sequence.  */
            __sha512_init_ctx(alt_ctx);

            /* For every character in the password add the entire password.  */
            for (cnt = 0; cnt < key_len; ++cnt)
                __sha512_process_bytes(key, key_len, alt_ctx);

            /* Finish the digest.  */
            __sha512_finish_ctx(alt_ctx, temp_result);

            /* Create byte sequence P.  */
            cp = p_bytes = new ArrayPointer<byte>(new byte[key_len]);
            for (cnt = key_len; cnt >= 64; cnt -= 64)
                cp = mempcpy(cp, temp_result, 64);
            memcpy(cp, temp_result, cnt);

            /* Start computation of S byte sequence.  */
            __sha512_init_ctx(alt_ctx);

            /* For every character in the password add the entire password.  */
            for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
                __sha512_process_bytes(salt, salt_len, alt_ctx);

            /* Finish the digest.  */
            __sha512_finish_ctx(alt_ctx, temp_result);

            /* Create byte sequence S.  */
            cp = s_bytes = new ArrayPointer<byte>(new byte[salt_len]);
            for (cnt = salt_len; cnt >= 64; cnt -= 64)
                cp = mempcpy(cp, temp_result, 64);
            memcpy(cp, temp_result, cnt);

            /* Repeatedly run the collected hash value through SHA512 to burn
               CPU cycles.  */
            for (cnt = 0; cnt < rounds; ++cnt)
            {
                /* New context.  */
                __sha512_init_ctx(ctx);

                /* Add key or last result.  */
                if ((cnt & 1) != 0)
                    __sha512_process_bytes(p_bytes, key_len, ctx);
                else
                    __sha512_process_bytes(alt_result, 64, ctx);

                /* Add salt for numbers not divisible by 3.  */
                if (cnt % 3 != 0)
                    __sha512_process_bytes(s_bytes, salt_len, ctx);

                /* Add key for numbers not divisible by 7.  */
                if (cnt % 7 != 0)
                    __sha512_process_bytes(p_bytes, key_len, ctx);

                /* Add key or last result.  */
                if ((cnt & 1) != 0)
                    __sha512_process_bytes(alt_result, 64, ctx);
                else
                    __sha512_process_bytes(p_bytes, key_len, ctx);

                /* Create intermediate result.  */
                __sha512_finish_ctx(ctx, alt_result);
            }

            /* Now we can construct the result string.  It consists of three
               parts.  */
            cp = __stpncpy(buffer, sha512_salt_prefix, Math.Max(0, buflen));
            buflen -= strlen(sha512_salt_prefix);

            if (rounds_custom)
            {
                cp = __stpncpy(cp, sha512_rounds_prefix, Math.Max(0, buflen));
                buflen -= strlen(sha512_rounds_prefix);

                char[] temp1 = (rounds.ToString() + "$\0").ToCharArray();
                byte[] temp2 = new byte[temp1.Length];
                for(int i = 0; i < temp1.Length; i++) temp2[i] = (byte)temp1[i];
                ArrayPointer<byte> temp3 = new ArrayPointer<byte>(temp2);

                cp = __stpncpy(cp, temp3, Math.Max(0, buflen));
                buflen -= strlen(temp3);
            }

            cp = __stpncpy(cp, salt, Math.Min(Math.Max(0, buflen), salt_len));
            buflen -= Math.Min(Math.Max(0, buflen), salt_len);

            if (buflen > 0)
            {
                cp.Value = (byte)'$';
                cp++;
                buflen--;
            }

            cp = b64_from_24bit(alt_result[0], alt_result[21], alt_result[42], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[22], alt_result[43], alt_result[1], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[44], alt_result[2], alt_result[23], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[3], alt_result[24], alt_result[45], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[25], alt_result[46], alt_result[4], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[47], alt_result[5], alt_result[26], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[6], alt_result[27], alt_result[48], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[28], alt_result[49], alt_result[7], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[50], alt_result[8], alt_result[29], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[9], alt_result[30], alt_result[51], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[31], alt_result[52], alt_result[10], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[53], alt_result[11], alt_result[32], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[12], alt_result[33], alt_result[54], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[34], alt_result[55], alt_result[13], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[56], alt_result[14], alt_result[35], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[15], alt_result[36], alt_result[57], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[37], alt_result[58], alt_result[16], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[59], alt_result[17], alt_result[38], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[18], alt_result[39], alt_result[60], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[40], alt_result[61], alt_result[19], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[62], alt_result[20], alt_result[41], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(0, 0, alt_result[63], 2, cp, buflen, out buflen);

            if (buflen <= 0)
            {
                throw new IndexOutOfRangeException();
            }
            else
                cp.Value = 0;        /* Terminate the string.  */

            /* Clear the buffer for the intermediate result so that people
               attaching to processes or reading core dumps cannot get any
               information.  We do it in this way to clear correct_words[]
               inside the SHA512 implementation as well.  */
            __sha512_init_ctx(ctx);
            __sha512_finish_ctx(ctx, alt_result);

            return buffer;
        }
Example #8
0
        private static ArrayPointer<byte> __md5_crypt_r(ArrayPointer<byte> key, ArrayPointer<byte> salt, ArrayPointer<byte> buffer, int buflen)
        {
            ArrayPointer<byte> alt_result = new ArrayPointer<byte>(new byte[16]);
            md5_ctx ctx = new md5_ctx();
            md5_ctx alt_ctx = new md5_ctx();
            int salt_len;
            int key_len;
            int cnt;
            ArrayPointer<byte> cp;
            ArrayPointer<byte> copied_key;
            ArrayPointer<byte> copied_salt;

            /* Find beginning of salt string.  The prefix should normally always
            be present.  Just in case it is not.  */
            if (strncmp(md5_salt_prefix, salt, strlen(md5_salt_prefix)) == 0)
            {
                salt += strlen(md5_salt_prefix);
            }

            salt_len = Math.Min(strcspn(salt, dollar_sign), 8);
            key_len = strlen(key);

            byte[] temp = new byte[key.SourceArray.Length];
            key.SourceArray.CopyTo(temp, 0);
            copied_key = new ArrayPointer<byte>(temp);
            copied_key.Address = key.Address;
            key = copied_key;

            temp = new byte[salt.SourceArray.Length];
            salt.SourceArray.CopyTo(temp, 0);
            copied_salt = new ArrayPointer<byte>(temp);
            copied_salt.Address = salt.Address;
            salt = copied_salt;

            /* Prepare for the real work.  */
            __md5_init_ctx(ctx);

            /* Add the key string.  */
            __md5_process_bytes(key, key_len, ctx);

            /* Because the SALT argument need not always have the salt prefix we
               add it separately.  */
            __md5_process_bytes(md5_salt_prefix, strlen(md5_salt_prefix), ctx);

            /* The last part is the salt string.  This must be at most 8
               characters and it ends at the first `$' character (for
               compatibility with existing implementations).  */
            __md5_process_bytes(salt, salt_len, ctx);

            /* Compute alternate MD5 sum with input KEY, SALT, and KEY.  The
               final result will be added to the first context.  */
            __md5_init_ctx (alt_ctx);

            /* Add key.  */
            __md5_process_bytes(key, key_len, alt_ctx);

            /* Add salt.  */
            __md5_process_bytes(salt, salt_len, alt_ctx);

            /* Add key again.  */
            __md5_process_bytes(key, key_len, alt_ctx);

            /* Now get result of this (16 bytes) and add it to the other
            context.  */
            __md5_finish_ctx(alt_ctx, alt_result);

            /* Add for any character in the key one byte of the alternate sum.  */
            for (cnt = key_len; cnt > 16; cnt -= 16)
                __md5_process_bytes (alt_result, 16, ctx);
            __md5_process_bytes(alt_result, cnt, ctx);

            /* For the following code we need a NUL byte.  */
            alt_result.Value = 0;

            /* The original implementation now does something weird: for every 1
               bit in the key the first 0 is added to the buffer, for every 0
               bit the first character of the key.  This does not seem to be
               what was intended but we have to follow this to be compatible.  */
            for (cnt = key_len; cnt > 0; cnt >>= 1)
                __md5_process_bytes((cnt & 1) != 0 ? alt_result : key, 1, ctx);

            /* Create intermediate result.  */
            __md5_finish_ctx (ctx, alt_result);

            /* Now comes another weirdness.  In fear of password crackers here
               comes a quite long loop which just processes the output of the
               previous round again.  We cannot ignore this here.  */
            for (cnt = 0; cnt < 1000; ++cnt)
            {
                /* New context.  */
                __md5_init_ctx (ctx);

                /* Add key or last result.  */
                if ((cnt & 1) != 0)
                    __md5_process_bytes (key, key_len, ctx);
                else
                    __md5_process_bytes (alt_result, 16, ctx);

                /* Add salt for numbers not divisible by 3.  */
                if (cnt % 3 != 0)
                    __md5_process_bytes (salt, salt_len, ctx);

                /* Add key for numbers not divisible by 7.  */
                if (cnt % 7 != 0)
                    __md5_process_bytes (key, key_len, ctx);

                /* Add key or last result.  */
                if ((cnt & 1) != 0)
                    __md5_process_bytes (alt_result, 16, ctx);
                else
                    __md5_process_bytes (key, key_len, ctx);

                /* Create intermediate result.  */
                __md5_finish_ctx (ctx, alt_result);
            }

            /* Now we can construct the result string.  It consists of three
               parts.  */
            cp = __stpncpy(buffer, md5_salt_prefix, Math.Max(0, buflen));
            buflen -= strlen(md5_salt_prefix);

            cp = __stpncpy (cp, salt, Math.Min(Math.Max(0, buflen), salt_len));
            buflen -= Math.Min(Math.Max(0, buflen), salt_len);

            if (buflen > 0)
            {
                cp.Value = (byte)'$';
                cp++;
                buflen--;
            }

            cp = b64_from_24bit(alt_result[0], alt_result[6], alt_result[12], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[1], alt_result[7], alt_result[13], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[2], alt_result[8], alt_result[14], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[3], alt_result[9], alt_result[15], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[4], alt_result[10], alt_result[5], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(0, 0, alt_result[11], 2, cp, buflen, out buflen);

            if (buflen <= 0)
            {
                throw new IndexOutOfRangeException();
            }
            else
                cp.Value = 0;        /* Terminate the string.  */

            /* Clear the buffer for the intermediate result so that people
            attaching to processes or reading core dumps cannot get any
            information.  We do it in this way to clear correct_words[]
            inside the MD5 implementation as well.  */
            __md5_init_ctx(ctx);
            __md5_finish_ctx(ctx, alt_result);

            return buffer;
        }
Example #9
0
 internal static void swap(ArrayPointer<int> array, int idxA, int idxB)
 {
     int temp = array[idxA];
     array[idxA] = array[idxB];
     array[idxB] = temp;
 }
Example #10
0
        private static ArrayPointer<byte> mempcpy(ArrayPointer<byte> dest, ArrayPointer<byte> src, int n)
        {
            for (int i = 0; i < n; i++)
            {
                dest[i] = src[i];
            }

            return dest + n;
        }
Example #11
0
        private static string ExtractString(ArrayPointer<byte> str)
        {
            StringBuilder sb = new StringBuilder(strlen(str));

            for (int i = 0; ; i++)
            {
                if (str[i] == 0)
                    break;
                sb.Append((char)str[i]);
            }

            return sb.ToString();
        }
Example #12
0
 private static ArrayPointer<byte> b64_from_24bit(uint B2, uint B1, uint B0, int N, ArrayPointer<byte> cp, int buflen, out int buflen_out)
 {
     uint w = ((B2) << 16) | ((B1) << 8) | (B0);
     int n = (N);
     while (n-- > 0 && buflen > 0)
     {
         cp.Value = (byte)b64t[w & 0x3f];
         cp++;
         buflen--;
         w >>= 6;
     }
     buflen_out = buflen;
     return cp;
 }
Example #13
0
        internal static int strncmp(ArrayPointer<byte> str1, ArrayPointer<byte> str2, int length)
        {
            for(int i = 0; i < length; i++, str1++, str2++)
            {
                if(str1.Value > str2.Value)
                {
                    return 1;
                }
                else if (str2.Value > str1.Value)
                {
                    return -1;
                }
            }

            return 0;
        }
Example #14
0
 internal static int strlen(ArrayPointer<byte> str)
 {
     for(int i = 0; ; i++, str++)
     {
         if(str.Value == 0)
             return i;
     }
 }
Example #15
0
 private static void __sha512_process_bytes(ArrayPointer<byte> buffer, int count, sha512_ctx ctx)
 {
     ctx.stream.Write(buffer.SourceArray, buffer.Address, count);
 }
Example #16
0
        private static int strcspn(ArrayPointer<byte> str1, ArrayPointer<byte> str2)
        {
            int location = 0;
            ArrayPointer<byte> i;
            ArrayPointer<byte> j;
            int str1_len = strlen(str1);

            for (i = str1; i.Value != 0; i++, location++)
            {
                for (j = str2; j.Value != 0; j++)
                {
                    if (i.Value == j.Value)
                    {
                        return location;
                    }
                }
            }

            return str1_len;
        }
Example #17
0
        private static ArrayPointer<byte> __stpncpy(ArrayPointer<byte> buffer, ArrayPointer<byte> source, int max)
        {
            int i;

            for (i = 0; i < max; i++, buffer++)
            {
                if (source[i] == 0)
                {
                    break;
                }

                buffer.Value = source[i];
            }

            return buffer;
        }
Example #18
0
        private static ulong strtoul(ArrayPointer<byte> str, out ArrayPointer<byte> endptr, int numberbase)
        {
            if (numberbase != 10) throw new ArgumentOutOfRangeException("numberbase");

            string num = "";
            for (int i = 0; str.Value >= '0' && str.Value <= '9'; i++, str++)
            {
                num += (char)str.Value;
            }

            endptr = str;

            ulong value = 0;
            ulong.TryParse(num, out value);

            return value;
        }
    public void solve(double[] w) {
        int i, m, s;
        int iter = 0;
        double[] alpha = new double[l * nr_class];
        double[] alpha_new = new double[nr_class];
        int[] index = new int[l];
        double[] QD = new double[l];
        int[] d_ind = new int[nr_class];
        double[] d_val = new double[nr_class];
        int[] alpha_index = new int[nr_class * l];
        int[] y_index = new int[l];
        int active_size = l;
        int[] active_size_i = new int[l];
        double eps_shrink = Math.Max(10.0 * eps, 1.0); // stopping tolerance for shrinking
        bool start_from_all = true;


        // Initial alpha can be set here. Note that
        // sum_m alpha[i*nr_class+m] = 0, for all i=1,...,l-1
        // alpha[i*nr_class+m] <= C[GETI(i)] if prob->y[i] == m
        // alpha[i*nr_class+m] <= 0 if prob->y[i] != m
        // If initial alpha isn't zero, uncomment the for loop below to initialize w
        for (i = 0; i < l * nr_class; i++)
            alpha[i] = 0;


        for (i = 0; i < w_size * nr_class; i++)
            w[i] = 0;
        for (i = 0; i < l; i++) {
            for (m = 0; m < nr_class; m++)
                alpha_index[i * nr_class + m] = m;
            QD[i] = 0;
            foreach (Feature xi in prob.x[i]) {
                double val = xi.Value;
                QD[i] += val * val;


                // Uncomment the for loop if initial alpha isn't zero
                // for(m=0; m<nr_class; m++)
                //  w[(xi->index-1)*nr_class+m] += alpha[i*nr_class+m]*val;
            }
            active_size_i[i] = nr_class;
            y_index[i] = (int)prob.y[i];
            index[i] = i;
        }


        ArrayPointer<double> alpha_i = new ArrayPointer<double>(alpha, 0);
        ArrayPointer<int> alpha_index_i = new ArrayPointer<int>(alpha_index, 0);


        while (iter < max_iter) {
            double stopping = Double.NegativeInfinity;


            for (i = 0; i < active_size; i++) {
                // int j = i+rand()%(active_size-i);
                int j = i + Linear.random.Next(active_size - i);
                Linear.swap(index, i, j);
            }
            for (s = 0; s < active_size; s++) {


                i = index[s];
                double Ai = QD[i];
                // double *alpha_i = &alpha[i*nr_class];
                alpha_i.setOffset(i * nr_class);


                // int *alpha_index_i = &alpha_index[i*nr_class];
                alpha_index_i.setOffset(i * nr_class);


                if (Ai > 0) {
                    for (m = 0; m < active_size_i[i]; m++)
                        G[m] = 1;
                    if (y_index[i] < active_size_i[i]) G[y_index[i]] = 0;


                    foreach (Feature xi in prob.x[i]) {
                        // double *w_i = &w[(xi.index-1)*nr_class];
                        int w_offset = (xi.Index - 1) * nr_class;
                        for (m = 0; m < active_size_i[i]; m++)
                            // G[m] += w_i[alpha_index_i[m]]*(xi.value);
                            G[m] += w[w_offset + alpha_index_i[m]] * (xi.Value);


                    }


                    double minG = Double.PositiveInfinity;
                    double maxG = Double.NegativeInfinity;
                    for (m = 0; m < active_size_i[i]; m++) {
                        if (alpha_i[alpha_index_i[m]] < 0 && G[m] < minG) minG = G[m];
                        if (G[m] > maxG) maxG = G[m];
                    }
                    if (y_index[i] < active_size_i[i]) {
                        if (alpha_i[(int)prob.y[i]] < C[GETI(i)] && G[y_index[i]] < minG) {
                            minG = G[y_index[i]];
                        }
                    }


                    for (m = 0; m < active_size_i[i]; m++) {
                        if (be_shrunk(i, m, y_index[i], alpha_i[alpha_index_i[m]], minG)) {
                            active_size_i[i]--;
                            while (active_size_i[i] > m) {
                                if (!be_shrunk(i, active_size_i[i], y_index[i], alpha_i[alpha_index_i[active_size_i[i]]], minG)) {
                                    Linear.swap(alpha_index_i, m, active_size_i[i]);
                                    Linear.swap(G, m, active_size_i[i]);
                                    if (y_index[i] == active_size_i[i])
                                        y_index[i] = m;
                                    else if (y_index[i] == m) y_index[i] = active_size_i[i];
                                    break;
                                }
                                active_size_i[i]--;
                            }
                        }
                    }


                    if (active_size_i[i] <= 1) {
                        active_size--;
                        Linear.swap(index, s, active_size);
                        s--;
                        continue;
                    }


                    if (maxG - minG <= 1e-12)
                        continue;
                    else
                        stopping = Math.Max(maxG - minG, stopping);


                    for (m = 0; m < active_size_i[i]; m++)
                        B[m] = G[m] - Ai * alpha_i[alpha_index_i[m]];


                    solve_sub_problem(Ai, y_index[i], C[GETI(i)], active_size_i[i], alpha_new);
                    int nz_d = 0;
                    for (m = 0; m < active_size_i[i]; m++) {
                        double d = alpha_new[m] - alpha_i[alpha_index_i[m]];
                        alpha_i[alpha_index_i[m]] = alpha_new[m];
                        if (Math.Abs(d) >= 1e-12) {
                            d_ind[nz_d] = alpha_index_i[m];
                            d_val[nz_d] = d;
                            nz_d++;
                        }
                    }


                    foreach (Feature xi in prob.x[i]) {
                        // double *w_i = &w[(xi->index-1)*nr_class];
                        int w_offset = (xi.Index - 1) * nr_class;
                        for (m = 0; m < nz_d; m++) {
                            w[w_offset + d_ind[m]] += d_val[m] * xi.Value;
                        }
                    }
                }
            }


            iter++;


            if (iter % 10 == 0) {
                Linear.info(".");
            }


            if (stopping < eps_shrink) {
                if (stopping < eps && start_from_all == true)
                    break;
                else {
                    active_size = l;
                    for (i = 0; i < l; i++)
                        active_size_i[i] = nr_class;
                    Linear.info("*");
                    eps_shrink = Math.Max(eps_shrink / 2, eps);
                    start_from_all = true;
                }
            } else
                start_from_all = false;
        }


        Linear.info("\noptimization finished, #iter = {0}", iter);
        if (iter >= max_iter) Linear.info("\nWARNING: reaching max number of iterations");


        // calculate objective value
        double v = 0;
        int nSV = 0;
        for (i = 0; i < w_size * nr_class; i++)
            v += w[i] * w[i];
        v = 0.5 * v;
        for (i = 0; i < l * nr_class; i++) {
            v += alpha[i];
            if (Math.Abs(alpha[i]) > 0) nSV++;
        }
        for (i = 0; i < l; i++)
            v -= alpha[i * nr_class + (int)prob.y[i]];
        Linear.info("Objective value = {0}", v);
        Linear.info("nSV = {0}", nSV);


    }
Example #20
0
 private static void __md5_process_bytes(ArrayPointer<byte> buffer, int count, md5_ctx ctx)
     => ctx.stream.Write(buffer.SourceArray, buffer.Address, count);