chkwon / Complementarity.jl

provides a modeling interface for mixed complementarity problems (MCP) and math programs with equilibrium problems (MPEC) via JuMP
Other
75 stars 20 forks source link

Determining multiple indexes of mapping equation that are conditional on a variable having a non-zero value #73

Closed KennethAnn closed 1 year ago

KennethAnn commented 1 year ago

Here I face a problem which seems as below, and I am curious about how to solve the problem.

When there are multiple indexes for mapping equations, we have use the code below to model them, for example,

@mapping(m, eq_var[i in Index1, j in Index2], var[i, j] - var_exg[i, j] ^ 2)
@complementarity(m, eq_var, var)

In some indexes, var_exg[i, j] = 0, which may cause many problems when the mapping equations are nonlinear, therefore, I want to treat the problem similar to Pyomo or GAMS, as the logic of below

for i in Index1, j in Index2
    if var_exg[i, j] == 0
        eq_var[i, j] = var[i, j]
    else
        eq_var[i, j] = var[i, j] - var_exg[i, j] ^ 2
    end
end

I have tried many methods, for example, I firstly found all indexes of non-zero value by using findall(x -> x !=0, var_exg), and used the indexes of non-zero value to map the equations, and for the indexes of zero value, the variables are kept to zero.

idx_non_zero = findall(x ->  x !=0, var_exg) # which defined a CartesianIndex
idx_non_zero_2 = [(k[1], k[2]) for k in idx_non_zero]

idx_zero = findall(x ->  x ==0, var_exg)
idx_zero_2 = [(k[1], k[2]) for k in idx_zero]

@mapping(m, eq_var_non_zero[(i, j) in idx_non_zero_2], var[i, j] - var_exg[i, j] ^ 2)
@complementarity(m, eq_var_non_zero, var[idx_non_zero])

@mapping(m, eq_var_zero[(i, j) in idx_zero_2 ], var[i, j] - 0)
@complementarity(m, eq_var_zero, var[idx_zero])

However, it failed and the possible reason is that mapping cannot recognize the multi-index [(i, j) in idx_non_zero_2], but only [i in Index1, j in Index2]. Is there any other possible solutions for this problem.

Thank you all!

KennethAnn commented 1 year ago

I found a right method, and I am not sure whether there are any much more convenient method?

@mapping(m, eq_var[i in Index1, j in Index2; var_exg[i, j] != 0], var[i, j] - var_exg[i, j])
for i in Index1, j in Index2
  (var_exg[i, j] != 0) ? @complementarity(m, eq_var[i, j], var[i, j]) : @complementarity(m, var[i, j], var[i, j])
end