DSPRelated.com
Forums

Minimization / maximization problem

Started by Piergiorgio Sartor August 27, 2015
Hi all,

I need some hint or pointer in order to try to solve
a problem.
This might not be the right place, but since here wise
people are, maybe I got lucky (I tried sci.math too).
If you know an other possible NG, please let me know.

I've a set of vectors, same size, these are "samples"
of different populations, of course I've by far more
vectors than populations.
These (column) vectors can be combined into a matrix
(or not, it depends on the possible solutions), let's
call this matrix R.
Or, better, several matrices R0, R1, R2, ... Rn-1,
each grouping a population.

I need to find a matrix, let's call it D, under the
following conditions:

The sum of the rows must be zero (or very close to it).

A statistical distance, like Mahalanobis or Bhattacharyya,
must be minimized between some groups, while it must be
maximized between other groups.
So, for example dist(D*R1,D*R2) must be minimal (close
to zero, actually), while dist(D*R1,D*R3) must be maximal
(and as well dist(D*R2,D*R3), of course).

One approach to the problem could be a genetic algorithm,
I was wondering if there is any other method or algorithm
that can be used to *try* to find a solution D.

Thanks a lot in advance,

bye,
-- 

piergiorgio
package dragonfruit;

public class MExp {

    final int n;
    final int baseExp;

    float grandparentCost;
    float[] grandparent;
    float[] parent;
    float[] child;

    final FNF fn;
    final Xor1024 rnd;

    public MExp(int n, int precision, FNF fn) {
        this.n = n;
        this.fn = fn;
        baseExp = 127 - precision;
        grandparent = new float[n];
        parent = new float[n];
        child = new float[n];
        rnd = new Xor1024();
        for (int i = 0; i < n; i++) {
            grandparent[i] = rnd.nextFloatSym();
        }
        grandparentCost = Float.POSITIVE_INFINITY;
    }

    void mutate(float[] current, float[] next) {
        System.arraycopy(current, 0, next, 0, n);
        for (int i = 0; i < n; i++) {
            int e = rnd.rndInclusive(baseExp, 127);
            if (e < 0) {
                continue;
            }
            int m = rnd.nextInt() & 0x807fffff;
            float cv = next[i] + Float.intBitsToFloat(e << 23 | m);
            if ((cv >= 1f) || (cv <= -1f)) {
                continue;
            }
            next[i] = cv;
        }
    }

    public void optimize(int parentIter, int childIter) {
        for (int i = 0; i < parentIter; i++) {
            mutate(grandparent, parent);
            float parentCost = fn.eval(parent);
            for (int j = 0; j < childIter; j++) {
                mutate(parent, child);
                float childCost = fn.eval(child);
                if (childCost < parentCost) {
                    parentCost = childCost;
                    float[] t = parent;
                    parent = child;
                    child = t;
                }
            }
            if (parentCost < grandparentCost) {
                grandparentCost = parentCost;
                float[] t = grandparent;
                grandparent = parent;
                parent = t;
            }
        }
    }

    public float getCost() {
        return grandparentCost;
    }

    public float[] getResult() {
        return grandparent;
    }

    public static void main(String[] args) {
        MExp mexp = new MExp(100, 1000, x -> {
            float sum = 0f;
            for (int i = 1; i < x.length; i++) {
                float x0 = x[i - 1] * 30f;
                float x1 = x[i] * 30f;
                sum += 100 * (x1 - x0 * x0) * (x1 - x0 * x0) + (x0 - 1f) * (x0 - 1f);

            }
            return sum;
        });
        mexp.optimize(200, 100000);
        System.out.println("Cost:" + mexp.getCost());
        System.out.println("At:");
        for (int i = 0; i < mexp.getResult().length; i++) {
            System.out.println(mexp.getResult()[i] * 30f);
        }

    }
}

package dragonfruit;

import java.util.concurrent.atomic.AtomicInteger;

public final class Xor1024 {

    final static AtomicInteger ct = new AtomicInteger();
    final long[] seed = new long[16];
    int pos;

    public Xor1024() {
        setSeed(System.nanoTime() + ct.getAndAdd(1));
    }

    public Xor1024(long seed) {
        setSeed(seed);
    }

    public long nextLong() {
        long s0 = seed[pos++];
        pos &= 15;
        long s1 = seed[pos];
        s1 ^= s1 << 31;
        s1 ^= s1 >>> 11;
        s0 ^= s0 >>> 30;
        return (seed[pos] = s0 ^ s1) * 1181783497276652981L;
    }

    public int nextInt() {
        return (int) nextLong();
    }

    public int rndInclusive(int max) {
        long r = nextLong() & 0xffffffffL;
        r *= (long) max + 1;
        r = r >>> 32;
        return (int) r;
    }

    public int rndInclusive(int min, int max) {
        long r = nextLong() & 0xffffffffL;
        r *= (long) (max - min) + 1;
        return (int) (r >>> 32) + min;
    }

    public int rndExcludeMax(int max) {
        long r = nextLong() & 0xffffffffL;
        r *= (long) max;
        r = r >>> 32;
        return (int) r;
    }

    public int rndExcludeMax(int min, int max) {
        long r = nextLong() & 0xffffffffL;
        r *= (long) (max - min);
        return (int) (r >>> 32) + min;
    }

    public float nextFloatSym() {
        long x = nextLong();
        int y = Long.numberOfLeadingZeros(x);
        if (y > 32) {
            return 0f;
        }
        int e = 126 - y;
        return Float.intBitsToFloat(e << 23 | ((int) x & 0x807fffff));
    }

    public float nextFloat() {
        long x = nextLong();
        int y = Long.numberOfLeadingZeros(x);
        if (y > 41) {
            return 0f;
        }
        int e = 126 - y;
        return Float.intBitsToFloat(e << 23 | ((int) x & 0x007fffff));
    }

    public void setSeed(long s) {
        pos = 0;
        for (int i = 15; i >= 0; i--) {
            s = s * 2862933555777941757L + 0x5dcea454e5a46c65L;
            seed[i] = s;
        }
    }

    public void getNextState(long[] state) {
        while (pos != 0) {
            nextLong();
        }
        System.arraycopy(seed, 0, state, 0, 16);
    }

    public void setState(long[] state) {
        pos = 0;
        System.arraycopy(state, 0, seed, 0, 16);
    }

    public void copyOf(Xor1024 x) {
        System.arraycopy(seed, 0, x.seed, 0, 16);
        x.pos = pos;
    }

}

package dragonfruit;

public interface FNF {

    public float eval(float[] x);

}
On Thursday, August 27, 2015 at 4:28:17 PM UTC-5, Piergiorgio Sartor wrote:
> Hi all, > > I need some hint or pointer in order to try to solve > a problem. > This might not be the right place, but since here wise > people are, maybe I got lucky (I tried sci.math too). > If you know an other possible NG, please let me know. > > I've a set of vectors, same size, these are "samples" > of different populations, of course I've by far more > vectors than populations. > These (column) vectors can be combined into a matrix > (or not, it depends on the possible solutions), let's > call this matrix R. > Or, better, several matrices R0, R1, R2, ... Rn-1, > each grouping a population. > > I need to find a matrix, let's call it D, under the > following conditions: > > The sum of the rows must be zero (or very close to it). > > A statistical distance, like Mahalanobis or Bhattacharyya, > must be minimized between some groups, while it must be > maximized between other groups. > So, for example dist(D*R1,D*R2) must be minimal (close > to zero, actually), while dist(D*R1,D*R3) must be maximal > (and as well dist(D*R2,D*R3), of course). > > One approach to the problem could be a genetic algorithm, > I was wondering if there is any other method or algorithm > that can be used to *try* to find a solution D. > > Thanks a lot in advance, > > bye, > -- > > piergiorgio
Try the following http://pritchardlab.stanford.edu/structure.html