+##----------------------------------
+## mean log_error
+## param X data vector ( ..x_i.. ), length n
+## param Y data vector ( ..y_i.. ), length n
+## return mean( 1/n * Sum_i^n ( exp(| ln(x_i)-ln(y_i)|) - 1 )
+##----------------------------------
+def mean_logerr( X,Y ):
+ assert( len(X) == len(Y) )
+ E = list(); # the list of errors
+ for i in range(len(X)):
+ E.append( exp(abs(log(X[i])-log(Y[i])))-1 )
+ return (avg( E ))
+
+
+##-----------------------------------------------------------------------------------------------
+## correl_split_weighted_logerr : compute regression on each segment and
+## return the weigthed sum of correlation coefficients
+## param X first data vector (..x_i..)
+## param Y second data vector (..x_i..)
+## param segments list of pairs (i,j) where i refers to the ith value in X, and jth value in X
+## return (C,[(i1,j1,X[i1],X[j1]), (i2,j2,X[i2],X[j2]), ....]
+## where i1,j1 is the first segment, c1 the correlation coef on this segment, n1 the number of values
+## i2,j2 is the second segment, c2 the correlation coef on this segment, n2 the number of values
+## ...
+## and C=c1/n1+c2/n2+...
+##-----------------------------------------------------------------------------------------------
+def correl_split_weighted_logerr( X , Y , segments ):
+ # expects segments = [(0,i1-1),(i1-1,i2-1),(i2,len-1)]
+ correl = list()
+ interv = list() # regr. line coeffs and range
+ glob_err=0
+ for (start,stop) in segments:
+ #if start==stop :
+ # return 0
+ S_XY= cov( X [start:stop+1], Y [start:stop+1] )
+ S_X2 = variance( X [start:stop+1] )
+ a = S_XY/S_X2 # regr line coeffs
+ b = avg ( Y[start:stop+1] ) - a * avg( X[start:stop+1] )
+ # fill a vector (Z) with predicted values from regression
+ Z=list()
+ for i in range(start,stop+1):
+ Z.append( a * X[i] + b )
+ # compare real values and computed values
+ e = mean_logerr( Y[start:stop+1] , Z )
+ correl.append( (e, stop-start+1) ); # store correl. coef + number of values (segment length)
+ interv.append( (a,b, X[start],X[stop],e) );
+
+ for (e,l) in correl:
+ glob_err = glob_err + (e*l/len( X )) # the average log err for this segment (e) is
+ # weighted by the number of values of the segment (l) out of the total number of values
+
+ #print("-> glob_corr={}\n".format(glob_corr))
+ return (glob_err,interv);
+