001/******************************************************************************* 002 * Copyright (c) 2016 Pablo Pavon Mariņo. 003 * All rights reserved. This program and the accompanying materials 004 * are made available under the terms of the GNU Lesser Public License v2.1 005 * which accompanies this distribution, and is available at 006 * http://www.gnu.org/licenses/lgpl.html 007 ******************************************************************************/ 008 009 010 011 012 013 014 015 016 017 018package com.net2plan.examples.ocnbook.offline; 019 020import java.util.List; 021import java.util.Map; 022 023import cern.colt.matrix.tdouble.DoubleFactory2D; 024import cern.colt.matrix.tdouble.DoubleMatrix1D; 025import cern.colt.matrix.tdouble.DoubleMatrix2D; 026import cern.jet.math.tdouble.DoubleFunctions; 027 028import com.jom.OptimizationProblem; 029import com.net2plan.interfaces.networkDesign.Configuration; 030import com.net2plan.interfaces.networkDesign.IAlgorithm; 031import com.net2plan.interfaces.networkDesign.Link; 032import com.net2plan.interfaces.networkDesign.Net2PlanException; 033import com.net2plan.interfaces.networkDesign.NetPlan; 034import com.net2plan.libraries.NetworkPerformanceMetrics; 035import com.net2plan.libraries.WirelessUtils; 036import com.net2plan.utils.InputParameter; 037import com.net2plan.utils.Triple; 038 039/** 040 * Finds a fair allocation of the transmission power in a wireless network, solving a formulation. 041 * @net2plan.description 042 * @net2plan.keywords Capacity assignment (CA), Transmission power optimization, JOM, NUM, Wireless 043 * @net2plan.ocnbooksections Section 5.5 044 * @net2plan.inputParameters 045 * @author Pablo Pavon-Marino 046 */ 047public class Offline_ca_wirelessTransmissionPower implements IAlgorithm 048{ 049 050 private InputParameter solverName = new InputParameter ("solverName", "#select# ipopt", "The solver name to be used by JOM. "); 051 private InputParameter solverLibraryName = new InputParameter ("solverLibraryName", "" , "The solver library full or relative path, to be used by JOM. Leave blank to use JOM default."); 052 private InputParameter maxSolverTimeInSeconds = new InputParameter ("maxSolverTimeInSeconds", (double) -1 , "Maximum time granted to the solver to solve the problem. If this time expires, the solver returns the best solution found so far (if a feasible solution is found)"); 053 private InputParameter alphaFairnessFactor = new InputParameter ("alphaFairnessFactor", (double) 2 , "Fairness alpha factor" , 0 , true , Double.MAX_VALUE , true); 054 private InputParameter pathLossExponent = new InputParameter ("pathLossExponent", (double) 2 , "Exponent in the the path loss model, computing attenuation for different distances to the transmitter" , 0 , true , Double.MAX_VALUE , true); 055 private InputParameter worseRiseOverThermal_nu = new InputParameter ("worseRiseOverThermal_nu", (double) 10 , "Worse case ratio between interference power and thermal power. Used to set the thermal power in the receivers" , 0 , true , Double.MAX_VALUE , true); 056 private InputParameter interferenceAttenuationFactor_nu = new InputParameter ("interferenceAttenuationFactor_nu", (double) 1E6 , "The interference power received in natural units is multiplied by this to reduce its effect" , 0 , true , Double.MAX_VALUE , true); 057 private InputParameter maxTransmissionPower_logu = new InputParameter ("maxTransmissionPower_logu", (double) 3 , "The maximum link transmission power in logarithmic units (e.g. dBm)"); 058 private InputParameter minTransmissionPower_logu = new InputParameter ("minTransmissionPower_logu", (double) 0 , "The minimum link transmission power in logarithmic units (e.g. dBm)"); 059 060 @Override 061 public String executeAlgorithm(NetPlan netPlan, Map<String, String> algorithmParameters, Map<String, String> net2planParameters) 062 { 063 /* Initialize all InputParameter objects defined in this object (this uses Java reflection) */ 064 InputParameter.initializeAllInputParameterFieldsOfObject(this, algorithmParameters); 065 final int E = netPlan.getNumberOfLinks(); 066 if (E == 0) throw new Net2PlanException ("The input topology has no links"); 067 068 /* Initialize the gains between links, normalizing them so that the maximum gain is one */ 069 DoubleMatrix2D mac_g_nu_ee = WirelessUtils.computeInterferenceMatrixNaturalUnits (netPlan.getLinks () , interferenceAttenuationFactor_nu.getDouble() , pathLossExponent.getDouble()); 070 //System.out.println("NOT normalized Gnu_ee: " + Gnu_ee); 071 final double maxGainValue = mac_g_nu_ee.getMaxLocation() [0]; 072 mac_g_nu_ee.assign (DoubleFunctions.div(maxGainValue)); 073 //System.out.println("normalized mac_g_nu_ee: " + mac_g_nu_ee); 074 075 /* Initialize the thermal noise at the receivers, to have a worse case ROT (rise over thermal) */ 076 double worseInterferenceReceivedAtMaxPower_nu = WirelessUtils.computeWorseReceiverInterferencePower_nu (maxTransmissionPower_logu.getDouble() , mac_g_nu_ee); 077 078 /* Adjust the thermal noise in the receivers so that we have a given ROT */ 079 final double mac_receptionThermalNoise_nu = worseInterferenceReceivedAtMaxPower_nu / worseRiseOverThermal_nu.getDouble(); 080 081 /* Make the formulation */ 082 DoubleMatrix2D G_ee = DoubleFactory2D.sparse.make (E,E); 083 DoubleMatrix2D G_eep = mac_g_nu_ee.copy (); 084 for (int e = 0; e < E ; e ++) { G_ee.set(e,e,mac_g_nu_ee.get(e,e)); G_eep.set (e,e,0); } 085 086 OptimizationProblem op = new OptimizationProblem(); 087 op.addDecisionVariable("p_e", false , new int[] { 1 , E }, minTransmissionPower_logu.getDouble() , maxTransmissionPower_logu.getDouble()); 088 op.setInputParameter("b", 1-alphaFairnessFactor.getDouble()); 089 op.setInputParameter("s2", mac_receptionThermalNoise_nu); 090 op.setInputParameter("G_ee", G_ee); 091 op.setInputParameter("G_eep", G_eep); 092 093 /* For the objective function we use that e^(ln(x) = x */ 094 if (alphaFairnessFactor.getDouble() == 1) 095 op.setObjectiveFunction("maximize", "sum ( ln ( ln ( exp(p_e)*G_ee ./ (s2 + exp(p_e)*G_eep) ) ) )"); 096 else 097 op.setObjectiveFunction("maximize", "(1/b) * sum ( ln ( exp(p_e)*G_ee ./ (s2 + exp(p_e)*G_eep) )^b ) "); 098 099 /* Call the solver to solve the problem */ 100 op.solve(solverName.getString (), "solverLibraryName", solverLibraryName.getString () , "maxSolverTimeInSeconds" , maxSolverTimeInSeconds.getDouble ()); 101 102 /* If no solution is found, quit */ 103 if (op.feasibleSolutionDoesNotExist()) throw new Net2PlanException("The problem has no feasible solution"); 104 if (op.foundUnboundedSolution()) throw new Net2PlanException ("Found an unbounded solution"); 105 if (!op.solutionIsFeasible()) throw new Net2PlanException("A feasible solution was not found"); 106 107 /* Retrieve the optimum solutions. Convert the bps into Erlangs */ 108 final double optNetworkUtility = op.getOptimalCost(); // Warning: I saw in some tests, that IPOPT returned this value different to the optimum solution cost: I could not see if I did something wrong 109 DoubleMatrix1D p_e = op.getPrimalSolution("p_e").view1D (); 110 111 /* Update the netplan object with the resulting capacities */ 112 for (Link e : netPlan.getLinks()) 113 { 114 final double sinr_e = WirelessUtils.computeSINRLink(e.getIndex () ,p_e , mac_g_nu_ee , mac_receptionThermalNoise_nu); 115 e.setCapacity(Math.log(sinr_e)); 116 e.setAttribute("p_e" , "" + p_e.get(e.getIndex ())); 117 } 118 119 /* Check constraints */ 120 if (p_e.getMinLocation() [0] < minTransmissionPower_logu.getDouble() - 1E-3) throw new RuntimeException ("Bad"); 121 if (p_e.getMaxLocation() [0] > maxTransmissionPower_logu.getDouble() + 1E-3) throw new RuntimeException ("Bad"); 122 final boolean allMaxPower = (p_e.getMinLocation() [0] >= maxTransmissionPower_logu.getDouble() - 1E-3); 123 124 System.out.println("Optimum solution: u_e: " + netPlan.getVectorLinkCapacity()); 125 System.out.println("Optimum solution: p_e: " + p_e); 126 System.out.println("ALL AT THE MAX POWER: " + allMaxPower); 127 128 final double optimumNetUtilityFromCapacities = NetworkPerformanceMetrics.alphaUtility(netPlan.getVectorLinkCapacity() , alphaFairnessFactor.getDouble()); 129 return "Ok! Solution guaranteed to be optimal: " + op.solutionIsOptimal() + ", Optimal net utility: " + optimumNetUtilityFromCapacities + ", from JOM output: " + optNetworkUtility; 130 } 131 132 @Override 133 public String getDescription() 134 { 135 return "This algorithm computes the optimum transmission power of each link in a wireless network subject to interferences. The link capacity is approximated as proportional to the logarithm of the signal-to-noise (including interferences) ratio. The target when optimizing the transmission power is enforcing a fair allocation of the resulting link capacities. Initially, the input network interference matrix is normalized so that the worst case rise-over-thermal (ROT) of any link matches a given value."; 136 } 137 138 @Override 139 public List<Triple<String, String, String>> getParameters() 140 { 141 /* Returns the parameter information for all the InputParameter objects defined in this object (uses Java reflection) */ 142 return InputParameter.getInformationAllInputParameterFieldsOfObject(this); 143 } 144 145}