5 * Created by westcott on 1/7/11.
6 * Copyright 2011 Schloss Lab. All rights reserved.
10 #include "linearalgebra.h"
12 // This class references functions used from "Numerical Recipes in C++" //
13 /*********************************************************************************************************************************/
15 inline double SIGN(const double a, const double b)
17 return b>=0 ? (a>=0 ? a:-a) : (a>=0 ? -a:a);
19 /*********************************************************************************************************************************/
21 vector<vector<double> > LinearAlgebra::matrix_mult(vector<vector<double> > first, vector<vector<double> > second){
23 vector<vector<double> > product;
25 int first_rows = first.size();
26 int first_cols = first[0].size();
27 int second_cols = second[0].size();
29 product.resize(first_rows);
30 for(int i=0;i<first_rows;i++){
31 product[i].resize(second_cols);
34 for(int i=0;i<first_rows;i++){
35 for(int j=0;j<second_cols;j++){
37 if (m->control_pressed) { return product; }
40 for(int k=0;k<first_cols;k++){
41 product[i][j] += first[i][k] * second[k][j];
49 m->errorOut(e, "LinearAlgebra", "matrix_mult");
55 /*********************************************************************************************************************************/
57 void LinearAlgebra::recenter(double offset, vector<vector<double> > D, vector<vector<double> >& G){
61 vector<vector<double> > A(rank);
62 vector<vector<double> > C(rank);
63 for(int i=0;i<rank;i++){
68 double scale = -1.0000 / (double) rank;
70 for(int i=0;i<rank;i++){
72 C[i][i] = 1.0000 + scale;
73 for(int j=i+1;j<rank;j++){
74 A[i][j] = A[j][i] = -0.5 * D[i][j] * D[i][j] + offset;
75 C[i][j] = C[j][i] = scale;
83 m->errorOut(e, "LinearAlgebra", "recenter");
88 /*********************************************************************************************************************************/
90 // This function is taken from Numerical Recipes in C++ by Press et al., 2nd edition, pg. 479
92 int LinearAlgebra::tred2(vector<vector<double> >& a, vector<double>& d, vector<double>& e){
94 double scale, hh, h, g, f;
101 for(int i=n-1;i>0;i--){
105 for(int k=0;k<l+1;k++){
106 scale += fabs(a[i][k]);
112 for(int k=0;k<l+1;k++){
114 h += a[i][k] * a[i][k];
117 g = (f >= 0.0 ? -sqrt(h) : sqrt(h));
122 for(int j=0;j<l+1;j++){
123 a[j][i] = a[i][j] / h;
125 for(int k=0;k<j+1;k++){
126 g += a[j][k] * a[i][k];
128 for(int k=j+1;k<l+1;k++){
129 g += a[k][j] * a[i][k];
135 for(int j=0;j<l+1;j++){
137 e[j] = g = e[j] - hh * f;
138 for(int k=0;k<j+1;k++){
139 a[j][k] -= (f * e[k] + g * a[i][k]);
154 for(int i=0;i<n;i++){
157 for(int j=0;j<l;j++){
159 for(int k=0;k<l;k++){
160 g += a[i][k] * a[k][j];
162 for(int k=0;k<l;k++){
163 a[k][j] -= g * a[k][i];
169 for(int j=0;j<l;j++){
170 a[j][i] = a[i][j] = 0.0;
176 catch(exception& e) {
177 m->errorOut(e, "LinearAlgebra", "tred2");
182 /*********************************************************************************************************************************/
184 double LinearAlgebra::pythag(double a, double b) { return(pow(a*a+b*b,0.5)); }
186 /*********************************************************************************************************************************/
188 // This function is taken from Numerical Recipes in C++ by Press et al., 2nd edition, pg. 479
190 int LinearAlgebra::qtli(vector<double>& d, vector<double>& e, vector<vector<double> >& z) {
193 double s, r, p, g, f, dd, c, b;
196 for(int i=1;i<=n;i++){
201 for(int l=0;l<n;l++){
204 for(myM=l;myM<n-1;myM++){
205 dd = fabs(d[myM]) + fabs(d[myM+1]);
206 if(fabs(e[myM])+dd == dd) break;
209 if(iter++ == 3000) cerr << "Too many iterations in tqli\n";
210 g = (d[l+1]-d[l]) / (2.0 * e[l]);
212 g = d[myM] - d[l] + e[l] / (g + SIGN(r,g));
215 for(i=myM-1;i>=l;i--){
218 e[i+1] = (r=pythag(f,g));
227 r = (d[i] - g) * s + 2.0 * c * b;
228 d[i+1] = g + ( p = s * r);
230 for(int k=0;k<n;k++){
232 z[k][i+1] = s * z[k][i] + c * f;
233 z[k][i] = c * z[k][i] - s * f;
236 if(r == 0.00 && i >= l) continue;
245 for(int i=0;i<n;i++){
247 for(int j=i;j<n;j++){
255 for(int j=0;j<n;j++){
265 catch(exception& e) {
266 m->errorOut(e, "LinearAlgebra", "qtli");
270 /*********************************************************************************************************************************/
271 //groups by dimension
272 vector< vector<double> > LinearAlgebra::calculateEuclidianDistance(vector< vector<double> >& axes, int dimensions){
275 vector< vector<double> > dists; dists.resize(axes.size());
276 for (int i = 0; i < dists.size(); i++) { dists[i].resize(axes.size(), 0.0); }
278 if (dimensions == 1) { //one dimension calc = abs(x-y)
280 for (int i = 0; i < dists.size(); i++) {
282 if (m->control_pressed) { return dists; }
284 for (int j = 0; j < i; j++) {
285 dists[i][j] = abs(axes[i][0] - axes[j][0]);
286 dists[j][i] = dists[i][j];
290 }else if (dimensions > 1) { //two dimension calc = sqrt ((x1 - y1)^2 + (x2 - y2)^2)...
292 for (int i = 0; i < dists.size(); i++) {
294 if (m->control_pressed) { return dists; }
296 for (int j = 0; j < i; j++) {
298 for (int k = 0; k < dimensions; k++) {
299 sum += ((axes[i][k] - axes[j][k]) * (axes[i][k] - axes[j][k]));
302 dists[i][j] = sqrt(sum);
303 dists[j][i] = dists[i][j];
311 catch(exception& e) {
312 m->errorOut(e, "LinearAlgebra", "calculateEuclidianDistance");
316 /*********************************************************************************************************************************/
317 //returns groups by dimensions from dimensions by groups
318 vector< vector<double> > LinearAlgebra::calculateEuclidianDistance(vector< vector<double> >& axes){
321 vector< vector<double> > dists; dists.resize(axes[0].size());
322 for (int i = 0; i < dists.size(); i++) { dists[i].resize(axes[0].size(), 0.0); }
324 if (axes.size() == 1) { //one dimension calc = abs(x-y)
326 for (int i = 0; i < dists.size(); i++) {
328 if (m->control_pressed) { return dists; }
330 for (int j = 0; j < i; j++) {
331 dists[i][j] = abs(axes[0][i] - axes[0][j]);
332 dists[j][i] = dists[i][j];
336 }else if (axes.size() > 1) { //two dimension calc = sqrt ((x1 - y1)^2 + (x2 - y2)^2)...
338 for (int i = 0; i < dists[0].size(); i++) {
340 if (m->control_pressed) { return dists; }
342 for (int j = 0; j < i; j++) {
344 for (int k = 0; k < axes.size(); k++) {
345 sum += ((axes[k][i] - axes[k][j]) * (axes[k][i] - axes[k][j]));
348 dists[i][j] = sqrt(sum);
349 dists[j][i] = dists[i][j];
357 catch(exception& e) {
358 m->errorOut(e, "LinearAlgebra", "calculateEuclidianDistance");
362 /*********************************************************************************************************************************/
363 //assumes both matrices are square and the same size
364 double LinearAlgebra::calcPearson(vector< vector<double> >& euclidDists, vector< vector<double> >& userDists){
367 //find average for - X
369 float averageEuclid = 0.0;
370 for (int i = 0; i < euclidDists.size(); i++) {
371 for (int j = 0; j < i; j++) {
372 averageEuclid += euclidDists[i][j];
376 averageEuclid = averageEuclid / (float) count;
378 //find average for - Y
380 float averageUser = 0.0;
381 for (int i = 0; i < userDists.size(); i++) {
382 for (int j = 0; j < i; j++) {
383 averageUser += userDists[i][j];
387 averageUser = averageUser / (float) count;
389 double numerator = 0.0;
390 double denomTerm1 = 0.0;
391 double denomTerm2 = 0.0;
393 for (int i = 0; i < euclidDists.size(); i++) {
395 for (int k = 0; k < i; k++) { //just lt dists
397 float Yi = userDists[i][k];
398 float Xi = euclidDists[i][k];
400 numerator += ((Xi - averageEuclid) * (Yi - averageUser));
401 denomTerm1 += ((Xi - averageEuclid) * (Xi - averageEuclid));
402 denomTerm2 += ((Yi - averageUser) * (Yi - averageUser));
406 double denom = (sqrt(denomTerm1) * sqrt(denomTerm2));
407 double r = numerator / denom;
409 //divide by zero error
410 if (isnan(r) || isinf(r)) { r = 0.0; }
415 catch(exception& e) {
416 m->errorOut(e, "LinearAlgebra", "calcPearson");
420 /*********************************************************************************************************************************/
421 //assumes both matrices are square and the same size
422 double LinearAlgebra::calcSpearman(vector< vector<double> >& euclidDists, vector< vector<double> >& userDists){
427 map<float, int> tableX;
428 map<float, int>::iterator itTable;
429 vector<spearmanRank> scores;
431 for (int i = 0; i < euclidDists.size(); i++) {
432 for (int j = 0; j < i; j++) {
433 spearmanRank member(toString(scores.size()), euclidDists[i][j]);
434 scores.push_back(member);
436 //count number of repeats
437 itTable = tableX.find(euclidDists[i][j]);
438 if (itTable == tableX.end()) {
439 tableX[euclidDists[i][j]] = 1;
441 tableX[euclidDists[i][j]]++;
447 sort(scores.begin(), scores.end(), compareSpearman);
451 for (itTable = tableX.begin(); itTable != tableX.end(); itTable++) {
452 double tx = (double) itTable->second;
453 Lx += ((pow(tx, 3.0) - tx) / 12.0);
457 map<string, float> rankEuclid;
458 vector<spearmanRank> ties;
460 for (int j = 0; j < scores.size(); j++) {
462 ties.push_back(scores[j]);
464 if (j != (scores.size()-1)) { // you are not the last so you can look ahead
465 if (scores[j].score != scores[j+1].score) { // you are done with ties, rank them and continue
467 for (int k = 0; k < ties.size(); k++) {
468 float thisrank = rankTotal / (float) ties.size();
469 rankEuclid[ties[k].name] = thisrank;
474 }else { // you are the last one
476 for (int k = 0; k < ties.size(); k++) {
477 float thisrank = rankTotal / (float) ties.size();
478 rankEuclid[ties[k].name] = thisrank;
485 map<float, int> tableY;
488 for (int i = 0; i < userDists.size(); i++) {
489 for (int j = 0; j < i; j++) {
490 spearmanRank member(toString(scores.size()), userDists[i][j]);
491 scores.push_back(member);
493 //count number of repeats
494 itTable = tableY.find(userDists[i][j]);
495 if (itTable == tableY.end()) {
496 tableY[userDists[i][j]] = 1;
498 tableY[userDists[i][j]]++;
504 sort(scores.begin(), scores.end(), compareSpearman);
508 for (itTable = tableY.begin(); itTable != tableY.end(); itTable++) {
509 double ty = (double) itTable->second;
510 Ly += ((pow(ty, 3.0) - ty) / 12.0);
514 map<string, float> rankUser;
517 for (int j = 0; j < scores.size(); j++) {
519 ties.push_back(scores[j]);
521 if (j != (scores.size()-1)) { // you are not the last so you can look ahead
522 if (scores[j].score != scores[j+1].score) { // you are done with ties, rank them and continue
524 for (int k = 0; k < ties.size(); k++) {
525 float thisrank = rankTotal / (float) ties.size();
526 rankUser[ties[k].name] = thisrank;
531 }else { // you are the last one
533 for (int k = 0; k < ties.size(); k++) {
534 float thisrank = rankTotal / (float) ties.size();
535 rankUser[ties[k].name] = thisrank;
543 for (int i = 0; i < userDists.size(); i++) {
544 for (int j = 0; j < i; j++) {
546 float xi = rankEuclid[toString(count)];
547 float yi = rankUser[toString(count)];
549 di += ((xi - yi) * (xi - yi));
555 double n = (double) count;
557 double SX2 = ((pow(n, 3.0) - n) / 12.0) - Lx;
558 double SY2 = ((pow(n, 3.0) - n) / 12.0) - Ly;
560 r = (SX2 + SY2 - di) / (2.0 * sqrt((SX2*SY2)));
562 //divide by zero error
563 if (isnan(r) || isinf(r)) { r = 0.0; }
568 catch(exception& e) {
569 m->errorOut(e, "LinearAlgebra", "calcSpearman");
574 /*********************************************************************************************************************************/
575 //assumes both matrices are square and the same size
576 double LinearAlgebra::calcKendall(vector< vector<double> >& euclidDists, vector< vector<double> >& userDists){
581 vector<spearmanRank> scores;
582 for (int i = 0; i < euclidDists.size(); i++) {
583 for (int j = 0; j < i; j++) {
584 spearmanRank member(toString(scores.size()), euclidDists[i][j]);
585 scores.push_back(member);
590 sort(scores.begin(), scores.end(), compareSpearman);
593 map<string, float> rankEuclid;
594 vector<spearmanRank> ties;
596 for (int j = 0; j < scores.size(); j++) {
598 ties.push_back(scores[j]);
600 if (j != (scores.size()-1)) { // you are not the last so you can look ahead
601 if (scores[j].score != scores[j+1].score) { // you are done with ties, rank them and continue
603 for (int k = 0; k < ties.size(); k++) {
604 float thisrank = rankTotal / (float) ties.size();
605 rankEuclid[ties[k].name] = thisrank;
610 }else { // you are the last one
612 for (int k = 0; k < ties.size(); k++) {
613 float thisrank = rankTotal / (float) ties.size();
614 rankEuclid[ties[k].name] = thisrank;
619 vector<spearmanRank> scoresUser;
620 for (int i = 0; i < userDists.size(); i++) {
621 for (int j = 0; j < i; j++) {
622 spearmanRank member(toString(scoresUser.size()), userDists[i][j]);
623 scoresUser.push_back(member);
628 sort(scoresUser.begin(), scoresUser.end(), compareSpearman);
631 map<string, float> rankUser;
634 for (int j = 0; j < scoresUser.size(); j++) {
636 ties.push_back(scoresUser[j]);
638 if (j != (scoresUser.size()-1)) { // you are not the last so you can look ahead
639 if (scoresUser[j].score != scoresUser[j+1].score) { // you are done with ties, rank them and continue
641 for (int k = 0; k < ties.size(); k++) {
642 float thisrank = rankTotal / (float) ties.size();
643 rankUser[ties[k].name] = thisrank;
648 }else { // you are the last one
650 for (int k = 0; k < ties.size(); k++) {
651 float thisrank = rankTotal / (float) ties.size();
652 rankUser[ties[k].name] = thisrank;
661 vector<spearmanRank> user;
662 for (int l = 0; l < scores.size(); l++) {
663 spearmanRank member(scores[l].name, rankUser[scores[l].name]);
664 user.push_back(member);
668 for (int l = 0; l < scores.size(); l++) {
670 int numWithHigherRank = 0;
671 int numWithLowerRank = 0;
672 float thisrank = user[l].score;
674 for (int u = l+1; u < scores.size(); u++) {
675 if (user[u].score > thisrank) { numWithHigherRank++; }
676 else if (user[u].score < thisrank) { numWithLowerRank++; }
680 numCoor += numWithHigherRank;
681 numDisCoor += numWithLowerRank;
684 r = (numCoor - numDisCoor) / (float) count;
686 //divide by zero error
687 if (isnan(r) || isinf(r)) { r = 0.0; }
692 catch(exception& e) {
693 m->errorOut(e, "LinearAlgebra", "calcKendall");
697 /*********************************************************************************************************************************/
698 double LinearAlgebra::calcKendall(vector<double>& x, vector<double>& y, double& sig){
700 if (x.size() != y.size()) { m->mothurOut("[ERROR]: vector size mismatch."); m->mothurOutEndLine(); return 0.0; }
703 vector<spearmanRank> xscores;
704 for (int i = 0; i < x.size(); i++) {
705 spearmanRank member(toString(i), x[i]);
706 xscores.push_back(member);
710 sort(xscores.begin(), xscores.end(), compareSpearman);
712 //convert scores to ranks of x
713 vector<spearmanRank*> ties;
715 for (int j = 0; j < xscores.size(); j++) {
717 ties.push_back(&(xscores[j]));
719 if (j != xscores.size()-1) { // you are not the last so you can look ahead
720 if (xscores[j].score != xscores[j+1].score) { // you are done with ties, rank them and continue
721 for (int k = 0; k < ties.size(); k++) {
722 float thisrank = rankTotal / (float) ties.size();
723 (*ties[k]).score = thisrank;
728 }else { // you are the last one
729 for (int k = 0; k < ties.size(); k++) {
730 float thisrank = rankTotal / (float) ties.size();
731 (*ties[k]).score = thisrank;
738 vector<spearmanRank> yscores;
739 for (int j = 0; j < y.size(); j++) {
740 spearmanRank member(toString(j), y[j]);
741 yscores.push_back(member);
745 sort(yscores.begin(), yscores.end(), compareSpearman);
748 map<string, float> rank;
749 vector<spearmanRank> yties;
751 for (int j = 0; j < yscores.size(); j++) {
753 yties.push_back(yscores[j]);
755 if (j != yscores.size()-1) { // you are not the last so you can look ahead
756 if (yscores[j].score != yscores[j+1].score) { // you are done with ties, rank them and continue
757 for (int k = 0; k < yties.size(); k++) {
758 float thisrank = rankTotal / (float) yties.size();
759 rank[yties[k].name] = thisrank;
764 }else { // you are the last one
765 for (int k = 0; k < yties.size(); k++) {
766 float thisrank = rankTotal / (float) yties.size();
767 rank[yties[k].name] = thisrank;
777 vector<spearmanRank> otus;
778 for (int l = 0; l < xscores.size(); l++) {
779 spearmanRank member(xscores[l].name, rank[xscores[l].name]);
780 otus.push_back(member);
784 for (int l = 0; l < xscores.size(); l++) {
786 int numWithHigherRank = 0;
787 int numWithLowerRank = 0;
788 float thisrank = otus[l].score;
790 for (int u = l+1; u < xscores.size(); u++) {
791 if (otus[u].score > thisrank) { numWithHigherRank++; }
792 else if (otus[u].score < thisrank) { numWithLowerRank++; }
796 numCoor += numWithHigherRank;
797 numDisCoor += numWithLowerRank;
800 double p = (numCoor - numDisCoor) / (float) count;
802 //calc signif - zA - http://en.wikipedia.org/wiki/Kendall_tau_rank_correlation_coefficient#Significance_tests
803 double numer = 3.0 * (numCoor - numDisCoor);
804 int n = xscores.size();
805 double denom = n * (n-1) * (2*n + 5) / (double) 2.0;
809 if (isnan(sig) || isinf(sig)) { sig = 0.0; }
813 catch(exception& e) {
814 m->errorOut(e, "LinearAlgebra", "calcKendall");
818 /*********************************************************************************************************************************/
819 double LinearAlgebra::calcSpearman(vector<double>& x, vector<double>& y, double& sig){
821 if (x.size() != y.size()) { m->mothurOut("[ERROR]: vector size mismatch."); m->mothurOutEndLine(); return 0.0; }
824 map<float, int> tableX;
825 map<float, int>::iterator itTable;
826 vector<spearmanRank> xscores;
828 for (int i = 0; i < x.size(); i++) {
829 spearmanRank member(toString(i), x[i]);
830 xscores.push_back(member);
832 //count number of repeats
833 itTable = tableX.find(x[i]);
834 if (itTable == tableX.end()) {
844 for (itTable = tableX.begin(); itTable != tableX.end(); itTable++) {
845 double tx = (double) itTable->second;
846 Lx += ((pow(tx, 3.0) - tx) / 12.0);
851 sort(xscores.begin(), xscores.end(), compareSpearman);
853 //convert scores to ranks of x
855 map<string, float> rankx;
856 vector<spearmanRank> xties;
858 for (int j = 0; j < xscores.size(); j++) {
860 xties.push_back(xscores[j]);
862 if (j != xscores.size()-1) { // you are not the last so you can look ahead
863 if (xscores[j].score != xscores[j+1].score) { // you are done with ties, rank them and continue
864 for (int k = 0; k < xties.size(); k++) {
865 float thisrank = rankTotal / (float) xties.size();
866 rankx[xties[k].name] = thisrank;
871 }else { // you are the last one
872 for (int k = 0; k < xties.size(); k++) {
873 float thisrank = rankTotal / (float) xties.size();
874 rankx[xties[k].name] = thisrank;
880 vector<spearmanRank> yscores;
881 map<float, int> tableY;
882 for (int j = 0; j < y.size(); j++) {
883 spearmanRank member(toString(j), y[j]);
884 yscores.push_back(member);
886 itTable = tableY.find(member.score);
887 if (itTable == tableY.end()) {
888 tableY[member.score] = 1;
890 tableY[member.score]++;
897 for (itTable = tableY.begin(); itTable != tableY.end(); itTable++) {
898 double ty = (double) itTable->second;
899 Ly += ((pow(ty, 3.0) - ty) / 12.0);
902 sort(yscores.begin(), yscores.end(), compareSpearman);
905 map<string, float> rank;
906 vector<spearmanRank> yties;
908 for (int j = 0; j < yscores.size(); j++) {
910 yties.push_back(yscores[j]);
912 if (j != yscores.size()-1) { // you are not the last so you can look ahead
913 if (yscores[j].score != yscores[j+1].score) { // you are done with ties, rank them and continue
914 for (int k = 0; k < yties.size(); k++) {
915 float thisrank = rankTotal / (float) yties.size();
916 rank[yties[k].name] = thisrank;
921 }else { // you are the last one
922 for (int k = 0; k < yties.size(); k++) {
923 float thisrank = rankTotal / (float) yties.size();
924 rank[yties[k].name] = thisrank;
930 for (int k = 0; k < x.size(); k++) {
932 float xi = rankx[toString(k)];
933 float yi = rank[toString(k)];
935 di += ((xi - yi) * (xi - yi));
940 double n = (double) x.size();
941 double SX2 = ((pow(n, 3.0) - n) / 12.0) - Lx;
942 double SY2 = ((pow(n, 3.0) - n) / 12.0) - Ly;
944 p = (SX2 + SY2 - di) / (2.0 * sqrt((SX2*SY2)));
946 //signifigance calc - http://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient
947 double temp = (x.size()-2) / (double) (1- (p*p));
950 if (isnan(sig) || isinf(sig)) { sig = 0.0; }
954 catch(exception& e) {
955 m->errorOut(e, "LinearAlgebra", "calcSpearman");
959 /*********************************************************************************************************************************/
960 double LinearAlgebra::calcPearson(vector<double>& x, vector<double>& y, double& sig){
962 if (x.size() != y.size()) { m->mothurOut("[ERROR]: vector size mismatch."); m->mothurOutEndLine(); return 0.0; }
965 float averageX = 0.0;
966 for (int i = 0; i < x.size(); i++) { averageX += x[i]; }
967 averageX = averageX / (float) x.size();
971 for (int j = 0; j < y.size(); j++) { sumY += y[j]; }
972 float Ybar = sumY / (float) y.size();
975 double numerator = 0.0;
976 double denomTerm1 = 0.0;
977 double denomTerm2 = 0.0;
979 for (int j = 0; j < x.size(); j++) {
983 numerator += ((Xi - averageX) * (Yi - Ybar));
984 denomTerm1 += ((Xi - averageX) * (Xi - averageX));
985 denomTerm2 += ((Yi - Ybar) * (Yi - Ybar));
988 double denom = (sqrt(denomTerm1) * sqrt(denomTerm2));
990 r = numerator / denom;
992 //signifigance calc - http://faculty.vassar.edu/lowry/ch4apx.html
993 double temp = (1- (r*r)) / (double) (x.size()-2);
996 if (isnan(sig) || isinf(sig)) { sig = 0.0; }
1000 catch(exception& e) {
1001 m->errorOut(e, "LinearAlgebra", "calcPearson");
1005 /*********************************************************************************************************************************/
1007 vector<vector<double> > LinearAlgebra::getObservedEuclideanDistance(vector<vector<double> >& relAbundData){
1009 int numSamples = relAbundData.size();
1010 int numOTUs = relAbundData[0].size();
1012 vector<vector<double> > dMatrix(numSamples);
1013 for(int i=0;i<numSamples;i++){
1014 dMatrix[i].resize(numSamples);
1017 for(int i=0;i<numSamples;i++){
1018 for(int j=0;j<numSamples;j++){
1021 for(int k=0;k<numOTUs;k++){
1022 d += pow((relAbundData[i][k] - relAbundData[j][k]), 2.0000);
1024 dMatrix[i][j] = pow(d, 0.50000);
1025 dMatrix[j][i] = dMatrix[i][j];
1033 /*********************************************************************************************************************************/