/// <summary> /// Calculates the distance of every connection between a genre or tag from m1 and a genre or tag of m2. /// </summary> /// <param name="m1">Media 1</param> /// <param name="m2">Media 2</param> /// <returns>A vector with the distance of each connection in a component.</returns> /// <remarks> /// 1. Differs from arrow in that the direction is irrelevant, though if an arrow appears in both directions the distance is /// halved (and round up). /// 2. Theorem: Arrow A_1 -> B_2 exists explicitly in the collection of reversed arrows, that is arrows of the form C_2 -> D_1. /// <=> Arrows A_1 -> B_2 and B_1 -> A_2 both exist explicitly. /// Notational remark: subscript stands for the media and the symbol in front for the tag or genre name. So A_1 means tag /// or genre A from media 1. /// /// Proof: =>: By assumption A_1 -> B_2 exists explicitly in the collection of reversed arrows, so there exists an arrow /// A_2 -> B_1. But this implies B is a genre or tag of media 1 and A is a genre or tag of media 2 so the arrow /// B_1 -> A_2 exists in the collection or arrows from media 1 to media 2. /// <=: Assume Arrows A_1 -> B_2 and B_1 -> A_2 both exist explicitly. Then A and B are both genre or tags of media 1 /// and media 2. Hence the arrow A_2 -> B_1 exists in the collectrion of reversed arrows. /// 3. Since the arrow in the other direction exists explicitly if the reversed arrow exists (by the above theorem) /// it needs to be found and removed anyway. /// 4. Moreover since the existence of the reversed arrow in the initial direction implies the existence of the reversed arrow /// in the collection of reversed arrows it is not necessary to work with the collection of reversed arrows. In fact it's less /// efficient since there would be a list traversal to find the arrow in the collection of reversed arrows and there would need /// to be a traversal to remove the reversed arrow, whoms existence is assured by the theorem above, from the initial collection /// of arrows. One would rather look for the reversed arrow in the initial collection of arrows, remove it and halven the /// distance of the remaining connection! /// </remarks> private List <GenreTagConnection> CompleteDifferenceVectorConnection(Media m1, Media m2) { List <GenreTagConnection> cdv = CompleteDifferenceVectorArrow(m1, m2); // New list created, since rather not mend the list that's being looped over. List <GenreTagConnection> cdvConnection = new List <GenreTagConnection>(cdv.Count); foreach (GenreTagConnection gtc in cdv) { GenreTagConnection alreadyExistingSameConnection = cdvConnection.Find(cdvConnectionGtc => cdvConnectionGtc.SameConnection(gtc)); // The connection does already exist. if (alreadyExistingSameConnection != null) { alreadyExistingSameConnection.HalvenDistance(); } // The connection does not already exist. else { cdvConnection.Add(gtc); } } return(cdvConnection); }
private BigInteger InnerProductWithBaseConnection(List <GenreTagConnection> dv) { BigInteger sum = 0; foreach (GenreTagConnection baseGtc in baseDifferenceVector) { GenreTagConnection cBaseGtcConnectionInDV = dv.Find(cdvGtc => cdvGtc.SameConnection(baseGtc)); // The current base connection being considered exists in dv. if (cBaseGtcConnectionInDV != null) { sum += cBaseGtcConnectionInDV.Distance * baseGtc.Distance; } // The current base connection being considered does not exist in dv. else { continue; } } return(sum); }