convex_combination <- function(coords1, coords2, alpha) {
  stopifnot(length(alpha) == 1,
            0 <= alpha,
            1 >= alpha,
            all(dim(coords1) == dim(coords2)))
  newcoords <- alpha * coords1 + (1 - alpha) * coords2
  dim(newcoords) <- dim(coords1)
  newcoords
}

##' Morphing of two instances with parameter alpha
##'
##' @param "from_coords, to_coords" TSP instances 
##' @param "alpha" for convex combination 
##' @param "rnd" TRUE if rounding before normal mutation in EA 
##' @param "cells_round" for grid resolution in rounding
##' @param "normal_mutation_rate", "normal_mutation_sd" for normal mutation
##' @return morphed TSP instance
morph_instance <- function(from_coords, to_coords, alpha, rnd=FALSE, 
  cells_round=100, normal_mutation_rate, normal_mutation_sd) {
   
   point_m <- point_matching(from_coords,to_coords)
   to_coords_m <- to_coords[point_m[,2],]
   coords <- convex_combination(from_coords, to_coords_m, alpha)
   
   ## Rescale and round   
   coords <- rescale_instance(coords)
   coords <- round_grid(coords, cells_round)
   
   ## Pertube if rnd=TRUE in EA   
   if(rnd)
     coords <- normal_mutation(coords, normal_mutation_rate, normal_mutation_sd)
   return(coords)
}
    
