⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cluster.c

📁 聚类分析的源码集
💻 C
📖 第 1 页 / 共 5 页
字号:
      { double term1 = data1[index1][i];        double term2 = data2[index2][i];        double w = weight[i];        sum1 += w*term1;        sum2 += w*term2;        result += w*term1*term2;        denom1 += w*term1*term1;        denom2 += w*term2*term2;        tweight += w;      }    }  }  else  { int i;    for (i = 0; i < n; i++)    { if (mask1[i][index1] && mask2[i][index2])      { double term1 = data1[i][index1];        double term2 = data2[i][index2];        double w = weight[i];        sum1 += w*term1;        sum2 += w*term2;        result += w*term1*term2;        denom1 += w*term1*term1;        denom2 += w*term2*term2;        tweight += w;      }    }  }  if (!tweight) return 0; /* usually due to empty clusters */  result -= sum1 * sum2 / tweight;  denom1 -= sum1 * sum1 / tweight;  denom2 -= sum2 * sum2 / tweight;  if (denom1 <= 0) return 1; /* include '<' to deal with roundoff errors */  if (denom2 <= 0) return 1; /* include '<' to deal with roundoff errors */  result = fabs(result) / sqrt(denom1*denom2);  result = 1. - result;  return result;}/* ********************************************************************* */staticdouble ucorrelation (int n, double** data1, double** data2, int** mask1,  int** mask2, const double weight[], int index1, int index2, int transpose)/*Purpose=======The ucorrelation routine calculates the weighted Pearson distance between tworows or columns, using the uncentered version of the Pearson correlation. In theuncentered Pearson correlation, a zero mean is used for both vectors even ifthe actual mean is nonzero.This definition yields a semi-metric: d(a,b) >= 0, and d(a,b) = 0 iff a = b.but the triangular inequality d(a,b) + d(b,c) >= d(a,c) does not hold(e.g., choose b = a + c).Arguments=========n      (input) intThe number of elements in a row or column. If transpose==0, then n is the numberof columns; otherwise, n is the number of rows.data1  (input) double arrayThe data array containing the first vector.data2  (input) double arrayThe data array containing the second vector.mask1  (input) int arrayThis array which elements in data1 are missing. If mask1[i][j]==0, thendata1[i][j] is missing.mask2  (input) int arrayThis array which elements in data2 are missing. If mask2[i][j]==0, thendata2[i][j] is missing.weight (input) double array, dimension( n )The weights that are used to calculate the distance.index1     (input) intIndex of the first row or column.index2     (input) intIndex of the second row or column.transpose (input) intIf transpose==0, the distance between two rows in the matrix is calculated.Otherwise, the distance between two columns in the matrix is calculated.============================================================================*/{ double result = 0.;  double denom1 = 0.;  double denom2 = 0.;  int flag = 0;  /* flag will remain zero if no nonzero combinations of mask1 and mask2 are   * found.   */  if (transpose==0) /* Calculate the distance between two rows */  { int i;    for (i = 0; i < n; i++)    { if (mask1[index1][i] && mask2[index2][i])      { double term1 = data1[index1][i];        double term2 = data2[index2][i];        double w = weight[i];        result += w*term1*term2;        denom1 += w*term1*term1;        denom2 += w*term2*term2;        flag = 1;      }    }  }  else  { int i;    for (i = 0; i < n; i++)    { if (mask1[i][index1] && mask2[i][index2])      { double term1 = data1[i][index1];        double term2 = data2[i][index2];        double w = weight[i];        result += w*term1*term2;        denom1 += w*term1*term1;        denom2 += w*term2*term2;        flag = 1;      }    }  }  if (!flag) return 0.;  if (denom1==0.) return 1.;  if (denom2==0.) return 1.;  result = result / sqrt(denom1*denom2);  result = 1. - result;  return result;}/* ********************************************************************* */staticdouble uacorrelation (int n, double** data1, double** data2, int** mask1,  int** mask2, const double weight[], int index1, int index2, int transpose)/*Purpose=======The uacorrelation routine calculates the weighted Pearson distance between tworows or columns, using the absolute value of the uncentered version of thePearson correlation. In the uncentered Pearson correlation, a zero mean is usedfor both vectors even if the actual mean is nonzero.This definition yields a semi-metric: d(a,b) >= 0, and d(a,b) = 0 iff a = b.but the triangular inequality d(a,b) + d(b,c) >= d(a,c) does not hold(e.g., choose b = a + c).Arguments=========n      (input) intThe number of elements in a row or column. If transpose==0, then n is the numberof columns; otherwise, n is the number of rows.data1  (input) double arrayThe data array containing the first vector.data2  (input) double arrayThe data array containing the second vector.mask1  (input) int arrayThis array which elements in data1 are missing. If mask1[i][j]==0, thendata1[i][j] is missing.mask2  (input) int arrayThis array which elements in data2 are missing. If mask2[i][j]==0, thendata2[i][j] is missing.weight (input) double array, dimension( n )The weights that are used to calculate the distance.index1     (input) intIndex of the first row or column.index2     (input) intIndex of the second row or column.transpose (input) intIf transpose==0, the distance between two rows in the matrix is calculated.Otherwise, the distance between two columns in the matrix is calculated.============================================================================*/{ double result = 0.;  double denom1 = 0.;  double denom2 = 0.;  int flag = 0;  /* flag will remain zero if no nonzero combinations of mask1 and mask2 are   * found.   */  if (transpose==0) /* Calculate the distance between two rows */  { int i;    for (i = 0; i < n; i++)    { if (mask1[index1][i] && mask2[index2][i])      { double term1 = data1[index1][i];        double term2 = data2[index2][i];        double w = weight[i];        result += w*term1*term2;        denom1 += w*term1*term1;        denom2 += w*term2*term2;        flag = 1;      }    }  }  else  { int i;    for (i = 0; i < n; i++)    { if (mask1[i][index1] && mask2[i][index2])      { double term1 = data1[i][index1];        double term2 = data2[i][index2];        double w = weight[i];        result += w*term1*term2;        denom1 += w*term1*term1;        denom2 += w*term2*term2;        flag = 1;      }    }  }  if (!flag) return 0.;  if (denom1==0.) return 1.;  if (denom2==0.) return 1.;  result = fabs(result) / sqrt(denom1*denom2);  result = 1. - result;  return result;}/* *********************************************************************  */staticdouble spearman (int n, double** data1, double** data2, int** mask1,  int** mask2, const double weight[], int index1, int index2, int transpose)/*Purpose=======The spearman routine calculates the Spearman distance between two rows orcolumns. The Spearman distance is defined as one minus the Spearman rankcorrelation.Arguments=========n      (input) intThe number of elements in a row or column. If transpose==0, then n is the numberof columns; otherwise, n is the number of rows.data1  (input) double arrayThe data array containing the first vector.data2  (input) double arrayThe data array containing the second vector.mask1  (input) int arrayThis array which elements in data1 are missing. If mask1[i][j]==0, thendata1[i][j] is missing.mask2  (input) int arrayThis array which elements in data2 are missing. If mask2[i][j]==0, thendata2[i][j] is missing.weight (input) double array, dimension( n )These weights are ignored, but included for consistency with other distancemeasures.index1     (input) intIndex of the first row or column.index2     (input) intIndex of the second row or column.transpose (input) intIf transpose==0, the distance between two rows in the matrix is calculated.Otherwise, the distance between two columns in the matrix is calculated.============================================================================*/{ double* rank1;  double* rank2;  double result = 0.;  double denom1 = 0.;  double denom2 = 0.;  double avgrank;  double* tdata1 = malloc(n*sizeof(double));  double* tdata2 = malloc(n*sizeof(double));  int i;  int m = 0;  if (transpose==0)  { for (i = 0; i < n; i++)    { if (mask1[index1][i] && mask2[index2][i])      { tdata1[m] = data1[index1][i];        tdata2[m] = data2[index2][i];        m++;      }    }  }  else  { for (i = 0; i < n; i++)    { if (mask1[i][index1] && mask2[i][index2])      { tdata1[m] = data1[i][index1];        tdata2[m] = data2[i][index2];        m++;      }    }  }  if (m==0) return 0;  rank1 = malloc(m*sizeof(double));  rank2 = malloc(m*sizeof(double));  getrank(m, tdata1, rank1);  free(tdata1);  getrank(m, tdata2, rank2);  free(tdata2);  avgrank = 0.5*(m-1); /* Average rank */  for (i = 0; i < m; i++)  { const double value1 = rank1[i];    const double value2 = rank2[i];    result += value1 * value2;    denom1 += value1 * value1;    denom2 += value2 * value2;  }  /* Note: denom1 and denom2 cannot be calculated directly from the number   * of elements. If two elements have the same rank, the squared sum of   * their ranks will change.   */  free(rank1);  free(rank2);  result /= m;  denom1 /= m;  denom2 /= m;  result -= avgrank * avgrank;  denom1 -= avgrank * avgrank;  denom2 -= avgrank * avgrank;  result = result / sqrt(denom1*denom2);  result = 1. - result;  return result;}/* *********************************************************************  */staticdouble kendall (int n, double** data1, double** data2, int** mask1, int** mask2,  const double weight[], int index1, int index2, int transpose)/*Purpose=======The kendall routine calculates the Kendall distance between tworows or columns. The Kendall distance is defined as one minus Kendall's tau.Arguments=========n      (input) intThe number of elements in a row or column. If transpose==0, then n is the numberof columns; otherwise, n is the number of rows.data1  (input) double arrayThe data array containing the first vector.data2  (input) double arrayThe data array containing the second vector.mask1  (input) int arrayThis array which elements in data1 are missing. If mask1[i][j]==0, thendata1[i][j] is missing.mask2  (input) int arrayThis array which elements in data2 are missing. If mask2[i][j]==0, thendata2[i][j] is missing.weight (input) double array, dimension( n )These weights are ignored, but included for consistency with other distancemeasures.index1     (input) intIndex of the first row or column.index2     (input) intIndex of the second row or column.transpose (input) intIf transpose==0, the distance between two rows in the matrix is calculated.Otherwise, the distance between two columns in the matrix is calculated.============================================================================*/{ int con = 0;  int dis = 0;  int exx = 0;  int exy = 0;  int flag = 0;  /* flag will remain zero if no nonzero combinations of mask1 and mask2 are   * found.   */  double denomx;  double denomy;  double tau;  int i, j;  if (transpose==0)  { for (i = 0; i < n; i++)    { if (mask1[index1][i] && mask2[index2][i])      { for (j = 0; j < i; j++)        { if (mask1[index1][j] && mask2[index2][j])          { double x1 = data1[index1][i];            double x2 = data1[index1][j];            double y1 = data2[index2][i];            double y2 = data2[index2][j];            if (x1 < x2 && y1 < y2) con++;            if (x1 > x2 && y1 > y2) con++;            if (x1 < x2 && y1 > y2) dis++;            if (x1 > x2 && y1 < y2) dis++;            if (x1 == x2 && y1 != y2) exx++;            if (x1 != x2 && y1 == y2) exy++;            flag = 1;          }        }      }    }  }  else  { for (i = 0; i < n; i++)    { if (mask1[i][index1] && mask2[i][index2])      { for (j = 0; j < i; j++)        { if (mask1[j][index1] && mask2[j][index2])          { double x1 = data1[i][index1];            double x2 = data1[j][index1];            double y1 = data2[i][index2];            double y2 = data2[j][index2];            if (x1 < x2 && y1 < y2) con++;            if (x1 > x2 && y1 > y2) con++;            if (x1 < x2 && y1 > y2) dis++;            if (x1 > x2 && y1 < y2) dis++;            if (x1 == x2 && y1 != y2) exx++;            if (x1 != x2 && y1 == y2) exy++;            flag = 1;          }        }      }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -