%>>>[stat,lightpathsRoutes,listOfSerialNumberFlowsPerLp] = calculateMetrics(phys, netState)
%
%This function calculate some statistics per flow, per link, per lightpath
%and per node.
%>>>The inputs are:
%
% 1) netState: NetState Structure. More information about netState in
% section "Structure of netState variable" from Help.
%
% 2) phys: Phys Structure. More information about netState in section
% "Structure of phys variable" from Help.
%
%>>>The outputs are:
%
% 1) stat: is a cell with some statistic. The descriptions of these metrics
% are:
% -lightpathDistances(Lx1): Lightpath distances vector for
% a given physical topology. It is a vecor as many rows as 'L'
% lightpaths. Each row is a 'l', containing the euclidean distance
% in Km of the lightpath from node 'i' to node 'j'. It is computed
% based on the link distances.
% -averageDistance(1x1): the average euclidean distance in Km of the lightpath.
% -NrUsedConvertersPerLP(1xL): The number of used
% wavelength converters in each lightpath if the network nodes have
% wavelength conversion capability. It is an 1-by-L nodes integer
% matrix, where "L" is the number of lightpaths.
% -averNrUsedConverPerLP(1x1): Average number of wavelength converters
% per lightpath. It is a real value.
% -averVirtualHops(1x1): Average Number of Virtual Hops in
% the network. This metric is the average number of lighpaths which a
% message has to transverse in the virtual topology to arrive to its
% destination node. It is a real value.
% -lightpathFlows(1xL):each position l contains the number of Gbps carried
% per the lightpath l.
% -networkCongestion(1x1): Value of Network Congestion. It
% is the theoretical value of the network congestion computed as the
% maximum traffic flow offered onto any lightpath in the network.
% -NrUsedPhysHops(1xL):each position l contains the number of physical
% hops used per the lightpath l.
% -averNumOfFlowsPerLp(1x1): is the average number of flows carried per a
% lightpath.
% -NrUsedWavelengthsPerFiber(1xM): The number of Used Wavelengths in each
% fiber link. It is a 1-by-M links integer vector, where M is the number
% of links.
% -averNrUsedWavelengthsPerFiber(1x1): is the average number of used
% wavelengths per link.
% -linkTraffic(1xM): Vector of the traffic routed by each
% fiber link. It is a vector with 'M' number of links elemnts. It is
% a real value in units of Gbps.
% -averLinkTraffic(1x1): average routed traffic per a fiber link in Gbps.
% -NrUsedTransmittersPerNode(1xN): The number of used optical
% transmitters in each node. It is a 1-by-N nodes integer vector, where
% N is the number of nodes.
% -NrUsedReceiversPerNode(1xN): The number of used optical
% transmitters in each node. It is a 1-by-N nodes integer vector,
% where N is the number of nodes.
% -NrUsedConvertersPerNode1xN): The number of used wavelength converters
% in each node if the network nodes have wavelength conversion
% capability. It is a 1-by-N nodes integer vector, where "N" is the
% number of nodes.
% -ingressEgressGroomingTraffic: is a struct that it contains three fields:
% .ingressTraffic(1xN): each position n contains the ingress traffic
% for the node n in Gbps.
% .groomingTraffic(1xN): each position n contains the grooming traffic
% for the node n in Gbps.
% .egressTraffic(1xN): each position n contains the egress traffic
% for the node n in Gbps.
% -averIngressTraffic(1x1): is the average ingress traffic per node in
% Gbps.
% -averEgressTraffic(1x1): is the average egress traffic per node in
% Gbps.
% -averGroomingTraffic(1x1): is the average grooming traffic per node in
% Gbps.
% -lostTraffic(1xF): It is a vecor as many columns as 'F' flows.
% Each column 'f' contains the lost traffic of the flow 'f'.
% -fractionOfLostTraffic(1x1): fraction of lost traffic expressed as the
% division betwen the lost traffic and the offered traffic.
% -numVirtHopsPerFlow(1xF): It is a vector as many columns as 'F' flows.
% Each column f contains the number of virtual hops of the flow f.
% -averNumVirtHopsPerFlow(1x1): the average number of virtual hops per
% flow.
%
% 2) lightpathsRoutes: a cell (Lx3) where each row is a lightpath, the first
% column contains the sequene of nodes, the second column is the sequence
% of links and the third column is the sequence of wavelengths.
%
% 3) listOfSerialNumberFlowsPerLp: a cell where each row is a lightpath and
% it contains the serial numbers of the flows carried per this lightpath.
%
function [stat,lightpathsRoutes,listOfSerialNumberFlowsPerLp] = calculateMetrics(phys, netState)
numberOfNodes=max(max(phys.linkTable));
numberOfLinks=size(phys.linkTable,1);
numberOfLightpaths=size(netState.lightpathRoutingMatrix ,1);
numberOfFlows=size(netState.flowRoutingMatrix ,1);
stat = struct('lightpathDistances', [], 'averageDistance',[],...
'NrUsedConvertersPerLP', [], 'averNrUsedConverPerLP', [],...
'averVirtualHops', [], 'lightpathFlows', [], ...
'networkCongestion', [],'NrUsedPhysHops', [],'averNumOfFlowsPerLp', [],...
'NrUsedWavelengthsPerFiber', [],'averNrUsedWavelengthsPerFiber', [],...
'linkTraffic',[], 'averLinkTraffic', [],'NrUsedTransmittersPerNode',[],...
'NrUsedReceiversPerNode',[], 'NrUsedConvertersPerNode', [],...
'ingressEgressGroomingTraffic',[],'averIngressTraffic', [],...
'averEgressTraffic', [], 'averGroomingTraffic', [], 'lostTraffic', [],...
'fractionOfLostTraffic', [], 'numVirtHopsPerFlow', [], 'averNumVirtHopsPerFlow', []);
%A) Per Lightpaths Information ******************
%1)Routes
lightpathsRoutes=cell(numberOfLightpaths,3);
%lightpathsRoutes=struct('sequenceOfNodeIDs', [],'sequenceOfFiberIDs',[], 'sequenceOfWavelengthIDs',[]);
for lpID=1:numberOfLightpaths,
[lightpathsRoutes{lpID,1}, lightpathsRoutes{lpID,2},...
lightpathsRoutes{lpID,3}] = ...
lightpathPathComputation (lpID, phys, netState);
end
%2)Distances
stat.lightpathDistances=zeros(numberOfLightpaths,1);
for lp=1:numberOfLightpaths,
lightpathLinks=find(netState.lightpathRoutingMatrix (lp,:)>0);
stat.lightpathDistances(lp)=sum(phys.linkLengthInKm(lightpathLinks));
end
%3)Average Distance
stat.averageDistance= sum(stat.lightpathDistances)/numberOfLightpaths;
%4)Number of Used Converters TWC
[totalNrOfUsedConverters, NrUsedConvertersPerNode, NrUsedConvertersPerLP, averNrUsedConverPerLP] = ...
calculateConversionMetrics(phys, netState);
stat.NrUsedConvertersPerLP=NrUsedConvertersPerLP;
%5)Average Number of Used Converters TWC
stat.averNrUsedConverPerLP=averNrUsedConverPerLP;
%6)Average Virtual Hops
carriedTraffic=sum(netState.flowTable(:,4));
lightpathFlows=sum(netState.flowRoutingMatrix,1);
routedVirtTraffic=sum(lightpathFlows);
if carriedTraffic==0
stat.averVirtualHops=0;
else
stat.averVirtualHops=routedVirtTraffic/carriedTraffic;
end
%7)List of flows in a lightpath
listOfSerialNumberFlowsPerLp=cell(numberOfLightpaths,1);
%listOfSerialNumberFlowsInALp=struct('listOfSerialNumberFlows',[]);
listOfSerialNumberFlows=[];
totalFlows=0;
for lpID=1:numberOfLightpaths,
flowIDsInALightpath=find(netState.flowRoutingMatrix (:,lpID)>0);
for flow=1:length(flowIDsInALightpath),
serialNumberOfFlow=netState.flowTable(flowIDsInALightpath(flow),1);
listOfSerialNumberFlows=[listOfSerialNumberFlows serialNumberOfFlow];
end
totalFlows=totalFlows+length(listOfSerialNumberFlows);
listOfSerialNumberFlowsPerLp{lpID,1}=listOfSerialNumberFlows;
end
%8)Average number of flows in a lightpath
stat.averNumOfFlowsPerLp=totalFlows/numberOfLightpaths;
%9)Gbps carried by a lightpath
stat.lightpathFlows=lightpathFlows;
%10)Network Congestion
stat.networkCongestion=max(lightpathFlows);
%11)Number of Physical Hops per lightpath
stat.NrUsedPhysHops=zeros(1,numberOfLightpaths);
for l=1:numberOfLightpaths,
stat.NrUsedPhysHops(l)=length(find(netState.lightpathRoutingMatrix(l,:)>0));
end
%B) Per Link Information ************************
%1)Used Wavelengths Per Fiber Link
stat.NrUsedWavelengthsPerFiber= zeros(1,numberOfLinks);
for m=1:numberOfLinks,
stat.NrUsedWavelengthsPerFiber(m)=length(find(netState.lightpathRoutingMatrix(:,m)>0));
end
%2)Average number of used wavelengths per link
stat.averNrUsedWavelengthsPerFiber=sum(stat.NrUsedWavelengthsPerFiber)/numberOfLinks;
%3)Link traffic
stat.linkTraffic=zeros(1,numberOfLinks);
for m=1:numberOfLinks,
lightpathIDsOfLink=find(netState.lightpathRoutingMatrix(:,m)>0);
stat.linkTraffic(m)=sum(lightpathFlows(lightpathIDsOfLink));
end
%4)Average link traffic
stat.averLinkTraffic=sum(stat.linkTraffic)/numberOfLinks;
%C) Per Node Information ************************
%1)Used Transmitters Per Node & 2) Used Receivers Per Node
stat.NrUsedTransmittersPerNode=zeros(1,numberOfNodes);
stat.NrUsedReceiversPerNode=zeros(1,numberOfNodes);
for i=1:numberOfNodes,
stat.NrUsedTransmittersPerNode(i)= length(find(netState.lightpathTable(:,2)==i));
stat.NrUsedReceiversPerNode(i)= length(find(netState.lightpathTable(:,3)==i));
end
%3)Used Converters per node
stat.NrUsedConvertersPerNode=NrUsedConvertersPerNode;
%4)Ingress/Egress/Grooming traffic
ingressEgressGroomingTraffic=struct('ingressTraffic',[],'egressTraffic',[],'groomingTraffic',[]);
ingressTraffic=zeros(1,numberOfNodes);
groomingTraffic=zeros(1,numberOfNodes);
egressTraffic=zeros(1,numberOfNodes);
for nodeID=1:numberOfNodes,
lpsStartThisNode=find(netState.lightpathTable(:,2)==nodeID);
lpsEndThisNode=find(netState.lightpathTable(:,3)==nodeID);
ingressPlusGroomingTrafficInThisNode=sum(sum(netState.flowRoutingMatrix(:,lpsStartThisNode)));
flowsStartThisNode=find(netState.flowTable(:,2)==nodeID);
ingressTraffic(nodeID)=sum(sum(netState.flowRoutingMatrix(flowsStartThisNode,lpsStartThisNode)));
groomingTraffic(nodeID)=ingressPlusGroomingTrafficInThisNode-ingressTraffic(nodeID);
flowsEndThisNode=find(netState.flowTable(:,3)==nodeID);
egressTraffic(nodeID)=sum(sum(netState.flowRoutingMatrix(flowsEndThisNode,lpsEndThisNode)));
end
ingressEgressGroomingTraffic.ingressTraffic = ingressTraffic;
ingressEgressGroomingTraffic.egressTraffic=egressTraffic;
ingressEgressGroomingTraffic.groomingTraffic=groomingTraffic;
stat.ingressEgressGroomingTraffic=ingressEgressGroomingTraffic;
%5)Average Ingress/Egress/Grooming traffic
stat.averIngressTraffic=sum(ingressEgressGroomingTraffic.ingressTraffic)/numberOfNodes;
stat.averEgressTraffic=sum(ingressEgressGroomingTraffic.egressTraffic)/numberOfNodes;
stat.averGroomingTraffic=sum(ingressEgressGroomingTraffic.groomingTraffic)/numberOfNodes;
%D) Per Flow Information ************************
%1)Lost traffic
carriedFlow=zeros(1,numberOfFlows);
for flowID=1:numberOfFlows,
carriedFlow(flowID) = sum(netState.flowRoutingMatrix(flowID,find(netState.lightpathTable(:,2)==netState.flowTable(flowID,2))));
end
offeredFlow=(netState.flowTable(:,4))';
stat.lostTraffic=offeredFlow-carriedFlow;
%2)Average weighted lost traffic
stat.fractionOfLostTraffic=sum(stat.lostTraffic)/sum(offeredFlow);
%3)Weighted number of virtual hops
numVirtHopsPerFlow=zeros(1,numberOfFlows);
for flowID=1:numberOfFlows,
if(carriedFlow(flowID)==0)
numVirtHopsPerFlow(flowID)=-1;
return;
end
numVirtHopsPerFlow(flowID)=sum(netState.flowRoutingMatrix(flowID,:))/carriedFlow(flowID);
end
stat.numVirtHopsPerFlow=numVirtHopsPerFlow;
%4)Average weighted number of virtual hops
stat.averNumVirtHopsPerFlow=sum(numVirtHopsPerFlow.*carriedFlow)/sum(carriedFlow);