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