#
# <one line to give the library's name and an idea of what it does.>
# Copyright (C) 2014  <copyright holder> <email>
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 
#

import networkx
import similarity
import metasimilaritymeasure
import structuralsimilaritymeasure
import grafon.constants as constants
import grafon.spreading.pagerankspreading as pagerankspreading

class PageRankCosMeasure(
  structuralsimilaritymeasure.StructuralSimilarityMeasure):
  """!
  Imeplemntation  of  similarity using cosine similarity measure. For  a  given
  two graphs, the PageRank algorithm is run. After that, the values of PageRank
  ranking are  used as the  values into  elements of created vecors.  The nodes
  from graph are  transforms  to a flat vector  for each graph. Between them is
  run the cosine similarity.
  """

  def __init__(self, options, str_name = 'PageRankCosMeasure'):
    """!
    Constructor

    @param options: a dictionary containing options for this measure
    @para str_name: default value same as the class name "PageRankCosMeasure"
    """
    super(PageRankCosMeasure, self).__init__(options, str_name)

  def calculate(self, g1, g2):
    """!
    Implementation of abstract calculate function from interface. Calculates
    the Cosine between two created vectors based on the PageRankg ranking.
    The given graphs are copied into new bewfore running pagerank 
    because the PageRank function is not defined to run on multigraphs.

    @param g1 first graph
    @type g1: networgx.DiGraph/networkx.MultiDiGraph

    @param g2 second graph
    @type g1: networgx.DiGraph/networkx.MultiDiGraph

    @return Cosine silimarity of two pagerank vectors
    @rtype: double
    """
    if not g1 or not g2:
      return 0
    # metameasure initialized with CosineSimilarity similarity
    # and PageRank spreading method
    meta = metasimilaritymeasure.MetaSimilarityMeasure(
      options=self.options(), 
      sim_funcion=similarity.CosineSimilarity(),
      spread_method=pagerankspreading.PageRankSpreading(),
      spread_max_it=constants.PAGE_RANK_MAX_ITER,
      spread_max_depth=1,
      init_values=None,
      str_name=self.__str__())

    return meta.calculate(g1, g2)