<commit_before># -*- coding: utf-8 -*-
"""
Created on Thu Mar 27 16:43:25 2014

@author: Trish


Functions which express problems in Sedumi format and export them as .mat files
for Matlab
"""

import os

import numpy as np
import scipy.io

from cvxopt import matrix as cvxmat


def write_cvxpy_to_mat(problem_data, target, simplify=True):
    '''
    Input:
        problem_data: As produced by applying get_problem_data['CVXOPT'] to a
        cvxpy problem.
    Returns: (None)
    Effect:
        Saves a .mat file containing the A, b, c, K that define the problem
        in Sedumi format to target (see http://plato.asu.edu/ftp/usrguide.pdf)
    '''

    A, b, c, K, offset = make_sedumi_format_problem(problem_data, simplify=simplify)
    assert offset == 0
    write_sedumi_to_mat(A, b, c, K, target)


def write_sedumi_to_mat(A, b, c, K, target):
    '''
    Input:
        A, b, c, K for Sedumi format
        target: the path where we will save the .mat
    Effect:
        Saves a .mat file containing A, b, c, K to target
    '''
    A = sparsify_tall_mat(A)
    b = sparsify_tall_mat(b)
    c = sparsify_tall_mat(c)
    K = clean_K_dims(K)

    # Check that target folder exists
    folder = os.path.dirname(target)
    if not os.path.exists(folder):
        os.makedirs(folder)

    scipy.io.savemat(target, {'A': A, 'b': b, 'c': c, 'K': K})

def clean_K_dims(K):
    '''
    Matlab requires the dimensions to be given in floating point numbers,
    this checker ensures that they are.
    '''
    for p in K:
        # let's try treating this like a list or tuple, and if that falls
        # through then we'll assume it's a single number instead.
        if isinstance(K[p], list):
            for i, x in enumerate(K[p]):
                K[p][i] = 1.*x
        else:
            K[p] = 1.*K[p]
    return K



def problem_data_prep(problem_data):
    '''
    'Touch up' the problem data in the following ways:
      - Make sure the matrix elements aren't integers
      - Make sure they're dense matrices rather than sparse ones, otherwise
        there seem to be difficulties constructing block matrices
      - Transpose c to be a row vector, which matches the organization of A, b, G, h
        (rows are for constraints, columns are for variables)
    '''
    problem_data['A'] = cvxmat(1.*problem_data['A'])
    problem_data['b'] = cvxmat(1.*problem_data['b'])
    problem_data['G'] = cvxmat(1.*problem_data['G'])
    problem_data['h'] = cvxmat(1.*problem_data['h'])
    problem_data['c'] = cvxmat(1.*problem_data['c']).T
    return problem_data


def make_sedumi_format_problem(problem_data, simplify=True):
    '''
    Input:
        problem_data: As produced by applying get_problem_data['CVXOPT'] to a
        cvxpy problem.
    Returns:
        A, b, c, K: Data defining an equivalent problem in Sedumi format.
    '''
    problem_data = problem_data_prep(problem_data)
    dims = problem_data['dims']
    assert not dims['q'], "Sorry, at this time we can't handle SOC constraints!"

    nx = len(problem_data['c'])
    ni = dims['l']
    ne = len(problem_data['b'])
    num_sdp_vars = sum([s*s for s in dims['s']])

#==============================================================================
#   EXPANSION STEP:
#   Construct the expanded vector c_star and matrices A_star and Gs_star
#
#   At this point...
#     c_star = [ c ] (nx)
#              [ 0 ] (ni + num_sdp_vars)
#
#     A_star = [ A  |  0  |  0 ] (ne)        => eqs written in new vars
#              [ Gl |  I  |  0 ] (ni)        => ineqs written as eqs in new vars
#     Gs_star= [ Gs |  0  |  I ] (num_sdp_vars) => sets the exp in the SDP element
#               (nx) (ni)(num_sdp_vars)          equal to the var representing it
#==============================================================================
    num_sedumi_vars = nx + ni + num_sdp_vars

    c_star = np.zeros((1, num_sedumi_vars))
    c_star[0, 0:nx] = problem_data['c']

    A_star = np.zeros((ne + ni + num_sdp_vars, num_sedumi_vars))
    b_star = np.zeros((ne + ni + num_sdp_vars, 1))

    # Fill in blocks for Ax = b constraints
    A_star[0:ne, 0:nx] = problem_data['A']
    b_star[0:ne] = problem_data['b']

    # Fill in blocks for Gx + s = h
    A_star[ne:ne + ni, 0:nx] = problem_data['G'][:ni, :] # = Gl
    A_star[ne:ne + ni, nx:nx + ni] = np.eye(ni)
    b_star[ne:ne + ni] = problem_data['h'][:ni, :] # = hl

    # Fill out blocks defining h - Gs = vec(Y), where Y is the PSD matrix
    A_star[ne + ni:, 0:nx] = problem_data['G'][ni:, :] # = Gs
    A_star[ne + ni:, nx+ni:] = np.eye(num_sdp_vars)
    b_star[ne + ni:] = problem_data['h'][ni:, :] # = hs

    K = {'f': nx, 'l': dims['l'], 's': dims['s']}
    if simplify:
        A_star, b_star, c_star, K, obj_cst = simplify_sedumi_model(A_star,
                                                                   b_star,
                                                                   c_star,
                                                                   K,
                                                                   allow_nonzero_b=False)
    assert obj_cst == 0, "This shouldn't be possible with allow_nonzero_b=False."
    return simplify_sedumi_model(A_star, b_star, c_star, K)


def simplify_sedumi_model(A, b, c, K, allow_nonzero_b=False):
    '''
    Tries to eliminate variables using a few simple strategies:
        1. If a constraint is expressing Akixi = bk where variable xi is
           a free variable, we can eliminate x.
        2. If a constraint is expressing Akixi + Akjxj = bk where variable xi<commit_msg>Var renaming.<commit_after># -*- coding: utf-8 -*-
"""
Created on Thu Mar 27 16:43:25 2014

@author: Trish


Functions which express problems in Sedumi format and export them as .mat files
for Matlab
"""

import os

import numpy as np
import scipy.io

from cvxopt import matrix as cvxmat


def write_cvxpy_to_mat(problem_data, target, simplify=True):
    '''
    Input:
        problem_data: As produced by applying get_problem_data['CVXOPT'] to a
        cvxpy problem.
    Returns: (None)
    Effect:
        Saves a .mat file containing the A, b, c, K that define the problem
        in Sedumi format to target (see http://plato.asu.edu/ftp/usrguide.pdf)
    '''

    A, b, c, K, offset = make_sedumi_format_problem(problem_data, simplify=simplify)
    assert offset == 0
    write_sedumi_to_mat(A, b, c, K, target)


def write_sedumi_to_mat(A, b, c, K, target):
    '''
    Input:
        A, b, c, K for Sedumi format
        target: the path where we will save the .mat
    Effect:
        Saves a .mat file containing A, b, c, K to target
    '''
    A = sparsify_tall_mat(A)
    b = sparsify_tall_mat(b)
    c = sparsify_tall_mat(c)
    K = clean_K_dims(K)

    # Check that target folder exists
    folder = os.path.dirname(target)
    if not os.path.exists(folder):
        os.makedirs(folder)

    scipy.io.savemat(target, {'A': A, 'b': b, 'c': c, 'K': K})

def clean_K_dims(K):
    '''
    Matlab requires the dimensions to be given in floating point numbers,
    this checker ensures that they are.
    '''
    for p in K:
        # let's try treating this like a list or tuple, and if that falls
        # through then we'll assume it's a single number instead.
        if isinstance(K[p], list):
            for i, x in enumerate(K[p]):
                K[p][i] = 1.*x
        else:
            K[p] = 1.*K[p]
    return K



def problem_data_prep(problem_data):
    '''
    'Touch up' the problem data in the following ways:
      - Make sure the matrix elements aren't integers
      - Make sure they're dense matrices rather than sparse ones, otherwise
        there seem to be difficulties constructing block matrices
      - Transpose c to be a row vector, which matches the organization of A, b, G, h
        (rows are for constraints, columns are for variables)
    '''
    problem_data['A'] = cvxmat(1.*problem_data['A'])
    problem_data['b'] = cvxmat(1.*problem_data['b'])
    problem_data['G'] = cvxmat(1.*problem_data['G'])
    problem_data['h'] = cvxmat(1.*problem_data['h'])
    problem_data['c'] = cvxmat(1.*problem_data['c']).T
    return problem_data


def make_sedumi_format_problem(problem_data, simplify=True):
    '''
    Input:
        problem_data: As produced by applying get_problem_data['CVXOPT'] to a
        cvxpy problem.
    Returns:
        A, b, c, K: Data defining an equivalent problem in Sedumi format.
    '''
    problem_data = problem_data_prep(problem_data)
    dims = problem_data['dims']
    assert not dims['q'], "Sorry, at this time we can't handle SOC constraints!"

    nx = len(problem_data['c'])
    ni = dims['l']
    ne = len(problem_data['b'])
    num_sdp_vars = sum([s*s for s in dims['s']])

#==============================================================================
#   EXPANSION STEP:
#   Construct the expanded vector c_star and matrices A_star and Gs_star
#
#   At this point...
#     c_star = [ c ] (nx)
#              [ 0 ] (ni + num_sdp_vars)
#
#     A_star = [ A  |  0  |  0 ] (ne)        => eqs written in new vars
#              [ Gl |  I  |  0 ] (ni)        => ineqs written as eqs in new vars
#     Gs_star= [ Gs |  0  |  I ] (num_sdp_vars) => sets the exp in the SDP element
#               (nx) (ni)(num_sdp_vars)          equal to the var representing it
#==============================================================================
    num_sedumi_vars = nx + ni + num_sdp_vars

    c = np.zeros((1, num_sedumi_vars))
    c[0, 0:nx] = problem_data['c']

    A = np.zeros((ne + ni + num_sdp_vars, num_sedumi_vars))
    b = np.zeros((ne + ni + num_sdp_vars, 1))

    # Fill in blocks for Ax = b constraints
    A[0:ne, 0:nx] = problem_data['A']
    b[0:ne] = problem_data['b']

    # Fill in blocks for Gx + s = h
    A[ne:ne + ni, 0:nx] = problem_data['G'][:ni, :] # = Gl
    A[ne:ne + ni, nx:nx + ni] = np.eye(ni)
    b[ne:ne + ni] = problem_data['h'][:ni, :] # = hl

    # Fill out blocks defining h - Gs = vec(Y), where Y is the PSD matrix
    A[ne + ni:, 0:nx] = problem_data['G'][ni:, :] # = Gs
    A[ne + ni:, nx+ni:] = np.eye(num_sdp_vars)
    b[ne + ni:] = problem_data['h'][ni:, :] # = hs

    K = {'f': nx, 'l': dims['l'], 's': dims['s']}
    if simplify:
        A, b, c, K, obj_cst = simplify_sedumi_model(A,
                                                    b,
                                                    c,
                                                    K,
                                                    allow_nonzero_b=False)
        assert obj_cst == 0, "This shouldn't be possible with allow_nonzero_b=False."
    return A, b, c, K


def simplify_sedumi_model(A, b, c, K, allow_nonzero_b=False):
    '''
    Tries to eliminate variables using a few simple strategies:
        1. If a constraint is expressing Akixi = bk where variable xi is
           a free variable, we can eliminate x.
        2. If a constraint is expressing Akixi + Akjxj = bk where variable xi
{'fraction_non_alphanumeric': 0.14513774858602443, 'fraction_numerical': 0.006933041415800037, 'mean_word_length': 2.4099533437013996, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7102452', 'n_tokens_mistral': 3786, 'n_tokens_neox': 3592, 'n_words': 1130}