Sedumi2Sdpa.java

/*
 * Created on 2010/01/21
 * Copyright (C) 2010 Koga Laboratory. All rights reserved.
 *
 */
package org.mklab.sdpj.convert;

import java.util.ArrayList;
import java.util.List;

import org.mklab.nfc.matrix.DoubleMatrix;


/**
 * Sedumi形式のデータをSDPA-M形式に変換するコンバーターを表すクラスです。
 * 
 * @author Hiroaki Matsuo
 * @version $Revision$, 2010/01/21
 */
public class Sedumi2Sdpa {

  /**
   * 新しく生成された{@link Sedumi2Sdpa}オブジェクトを初期化します。
   * 
   * @param F F
   * @param c c
   * @param k k
   * @return SDPAMのインスタンスを返します
   */
  public SDPAM convertToSDPAM(double[][] F, double[] c, K k) {
    double[][] sedumiF = F;

    if (k.f > 0) {
      sedumiF = new double[F.length + k.f][F[0].length];

      for (int i = 0; i < k.f; i++) {
        for (int j = 0; j < F.length; j++) {
          sedumiF[i][j] = -F[i][j];
        }
      }
      for (int i = k.f; i < F.length; i++) {
        for (int j = 0; j < F.length; j++) {
          sedumiF[i][j] = F[i][j];
        }
      }
      k.l = k.l + k.f;
      k.f = 0;
    }

    int nc;
    if (KsCheck(k)) {
      nc = k.s.length;
    } else {
      nc = 0;
    }

    if (k.l > 0) {
      nc = nc + 1;
    }

    DoubleMatrix[][] sdpamF = new DoubleMatrix[nc][sedumiF[0].length];

    for (int i = 0; i < nc; i++) {
      for (int j = 0; j < sedumiF[0].length; j++) {
        sdpamF[i][j] = new DoubleMatrix(k.s[i], k.s[i]);
      }
    }

    List<Integer> bLOCKsTRUCTList = new ArrayList<>();

    int start = 1;
    int nl = 0;

    if (k.l > 0) {
      int n = 1;
      for (int l = 0; l < k.l; l++) {
        for (int m = 0; m < k.l; m++) {
          sdpamF[0][0].setElement(l + 1, m + 1, -sedumiF[n - 1][0]);
          n++;
        }
      }
      n = start;
      for (int j = 1; j < sedumiF[0].length; j++) {
        for (int l = 0; l < k.l; l++) {
          for (int m = 0; m < k.l; m++) {
            sdpamF[0][j].setElement(l + 1, m + 1, sedumiF[n - 1][j]);
            n++;
          }
        }
      }
      start = k.l + 1;
      bLOCKsTRUCTList.add(Integer.valueOf(-k.l));
      nl = 1;
    }

    if (KsCheck(k)) {
      for (int i = 0; i < k.s.length; i++) {
        int theend = start + k.s[i] * k.s[i] - 1;
        int n = start;

        for (int l = 0; l < k.s[i]; l++) {

          for (int m = 0; m < k.s[i]; m++) {
            sdpamF[i + nl][0].setElement(l + 1, m + 1, -sedumiF[n - 1][0]);
            // System.out.println(sdpamF[i + nl][0].getElement(l + 1, m + 1));

            n++;
          }
        }
        for (int j = 1; j < sedumiF[0].length; j++) {
          n = start;
          for (int l = 0; l < k.s[i]; l++) {
            for (int m = 0; m < k.s[i]; m++) {
              sdpamF[i + nl][j].setElement(l + 1, m + 1, sedumiF[n - 1][j]);
              //  System.out.println(sdpamF[i + nl][j].getElement(l + 1, m + 1));
              n++;
            }
          }
        }
        start = theend + 1;
        bLOCKsTRUCTList.add(Integer.valueOf(k.s[i]));
      }
    }

    int mDIM = sedumiF[0].length - 1;
    int nBLOCK = bLOCKsTRUCTList.size();

    return new SDPAM(mDIM, nBLOCK, bLOCKsTRUCTList, c, sdpamF);
  }

  /**
   * @param k k
   * @return K.sの正負の判定を返します
   */
  private boolean KsCheck(K k) {
    for (int i = 0; i < k.s.length; i++) {
      if (k.s[i] <= 0) {
        return false;
      }
    }
    return true;

  }
}