ClusterMain.cpp
上传用户:szb0815
上传日期:2007-06-13
资源大小:338k
文件大小:150k
源码类别:

生物技术

开发平台:

C++ Builder

  1.                 if (Dist[i][j] < minval[i])
  2.                 {
  3.                     minval[i] = Dist[i][j];
  4.                     minpair[i] = j;
  5.                 }
  6.                 if (Dist[i][j] < minval[j])
  7.                 {
  8.                     minval[j] = Dist[i][j];
  9.                     minpair[j] = i;
  10.                 }
  11.             }
  12.             StatusBar->SimpleText = "Calculating Distances " + AnsiString(i*(i+1)/2) + " of "
  13.                 + AnsiString(TotalDistance);
  14.             Application->ProcessMessages();
  15.         }
  16.         TStringList *MinList = new TStringList();
  17.         for (i=0;i<ClusterRows;i++)
  18.         {
  19.             MinList->Add(AnsiString(minval[i]));
  20.         }
  21.         MinList->SaveToFile("minlist.txt");
  22.         delete MinList;
  23.         bool *Active;
  24.         Active = new bool[2*ClusterRows-1];
  25.         for (i=0;i<ClusterRows;i++)
  26.         {
  27.             Active[i] = true;
  28.         }
  29.         for (i=ClusterRows;i<2*ClusterRows-1;i++)
  30.         {
  31.             Active[i] = false;
  32.         }
  33.         unsigned short minminval;
  34.         int min1, min2;
  35.         int nodeindex;
  36.         //int node;
  37.         /* Now we join nodes */
  38.         /* If we are going to return TNode, need to set up TNodes */
  39.         TNode **Nodes;
  40.         if (ReturnTNode)
  41.         {
  42.            Nodes = new TNode*[2*ClusterRows-1];
  43.            for (i=0;i<2*ClusterRows-1;i++)
  44.            {
  45.                Nodes[i] = new TNode();
  46.                if (i < ClusterRows)
  47.                {
  48.                    Nodes[i]->IsNode = false;
  49.                    Nodes[i]->ID = AnsiString(i);
  50.                }
  51.                else
  52.                {
  53.                    Nodes[i]->IsNode = true;
  54.                }
  55.            }
  56.         }
  57.         for (nodeindex=ClusterRows; nodeindex<2*ClusterRows-1;nodeindex++)
  58.         {
  59.             ID[nodeindex] = "NODE" + AnsiString(nodeindex-ClusterRows+1) + "X";
  60.             minminval = 32769;
  61.             for (i=0;i<2*ClusterRows-1;i++)
  62.             {
  63.                 if (Active[i] == true)
  64.                 {
  65.                     if (minval[i] < minminval)
  66.                     {
  67.                         minminval = minval[i];
  68.                         min1 = i;
  69.                         min2 = minpair[i];
  70.                     }
  71.                 }
  72.             }
  73.             /* When we get here min1 and min2 are the elements that are to be joined */
  74.         Active[min1] = false;
  75.         Active[min2] = false;
  76.         if (Order[min1] > Order[min2])
  77.         {
  78.             NodeElement[nodeindex][0] = min1;
  79.             NodeElement[nodeindex][1] = min2;
  80.         }
  81.         else
  82.         {
  83.             NodeElement[nodeindex][1] = min1;
  84.             NodeElement[nodeindex][0] = min2;
  85.         }
  86.         NodeDistance[nodeindex] = ((double) minminval)/16384.0;
  87.         NodeDistance[nodeindex] = max(NodeDistance[nodeindex],NodeDistance[min1]);
  88.         NodeDistance[nodeindex] = max(NodeDistance[nodeindex],NodeDistance[min2]);
  89.         if (ReturnTNode)
  90.         {
  91.                Nodes[nodeindex]->Child1 = Nodes[NodeElement[nodeindex][0]];
  92.                Nodes[nodeindex]->Child2 = Nodes[NodeElement[nodeindex][1]];
  93.                Nodes[nodeindex]->Length = 1.0 - NodeDistance[nodeindex];
  94.         }
  95.         if (CalcInferredDistances == true)
  96.         {
  97.             int elem1,elem2,ielem1,ielem2;
  98.             for (elem1=0;elem1<MemberList[min1]->Count;elem1++)
  99.             {
  100.                 for (elem2=0;elem2<MemberList[min2]->Count;elem2++)
  101.                 {
  102.                     ielem1 = (MemberList[min1]->Strings[elem1]).ToInt();
  103.                     ielem2 = (MemberList[min2]->Strings[elem2]).ToInt();
  104.                     TreeDist[ielem1][ielem2] = (NodeDistance[nodeindex] * 16384);
  105.                     TreeDist[ielem2][ielem1] = (NodeDistance[nodeindex] * 16384);
  106.                 }
  107.             }
  108.             MemberList[nodeindex]->AddStrings(MemberList[min1]);
  109.             MemberList[nodeindex]->AddStrings(MemberList[min2]);
  110.             delete MemberList[min1];
  111.             delete MemberList[min2];
  112.         }
  113.         OutString = ID[nodeindex] + AnsiString("t") + ID[NodeElement[nodeindex][0]]
  114.                 + AnsiString("t") + ID[NodeElement[nodeindex][1]] + AnsiString("t")
  115.                 + AnsiString(1.0 - NodeDistance[nodeindex]);
  116.         TreeFile->Add(OutString);
  117.         StatusBar->SimpleText = "Generating Node " + AnsiString(nodeindex-ClusterRows+1) + " of " + AnsiString(ClusterRows-1);
  118.         Application->ProcessMessages();
  119.         elements[nodeindex] = elements[min1] + elements[min2];
  120.         for (k=0;k<ClusterColumns;k++)
  121.         {
  122.             if ( (ClusterMask[min1][k] == true) && (ClusterMask[min2][k] == true) )
  123.             {
  124.                 ClusterData[nodeindex][k] =
  125.                     (elements[min1] * ClusterData[min1][k] +
  126.                         elements[min2] * ClusterData[min2][k]) /
  127.                     (elements[min1] + elements[min2]);
  128.                 ClusterMask[nodeindex][k] = true;
  129.             }
  130.             else if (ClusterMask[min1][k] == true)
  131.             {
  132.                 ClusterData[nodeindex][k] = ClusterData[min1][k];
  133.                 ClusterMask[nodeindex][k] = true;
  134.             }
  135.             else if (ClusterMask[min2][k] == true)
  136.             {
  137.                 ClusterData[nodeindex][k] = ClusterData[min2][k];
  138.                 ClusterMask[nodeindex][k] = true;
  139.             }
  140.             else
  141.             {
  142.                 ClusterMask[nodeindex][k] = false;
  143.             }
  144.         }
  145.         Order[nodeindex] = (elements[min1]*Order[min1] + elements[min2]*Order[min2])/(elements[min1] + elements[min2]);
  146.         Dist[nodeindex] = new unsigned short[2*ClusterRows-1];
  147.         if (SaveDistances == false)
  148.         {
  149.             delete Dist[min1];
  150.             delete Dist[min2];
  151.         }
  152.         List1->Clear();
  153.         Nodes[nodeindex]->SetList(List1);
  154.         int NumList1 = List1->Count;
  155.         for (int i1=0;i1<NumList1;i1++)
  156.         {
  157.             iList1[i1] = List1->Strings[i1].ToInt();
  158.         }
  159.         for (l=0;l<2*ClusterRows-1;l++)
  160.         {
  161.             if (Active[l] == true)
  162.             {
  163.                 // OK. Here's where it gets tricky
  164.                 List2->Clear();
  165.                 if (l < ClusterRows)
  166.                 {
  167.                     List2->Add(AnsiString(l));
  168.                 }
  169.                 else
  170.                 {
  171.                     Nodes[l]->SetList(List2);
  172.                 }
  173.                 int NumList2 = List2->Count;
  174.                 for (int i2=0;i2<NumList2;i2++)
  175.                 {
  176.                     iList2[i2] = List2->Strings[i2].ToInt();
  177.                 }
  178.                 Dist[nodeindex][l] = 0;
  179.                 for (int i1=0; i1 < NumList1; i1++)
  180.                 {
  181.                     for (int i2=0; i2 < NumList2; i2++)
  182.                     {
  183.                          Dist[nodeindex][l] = max(Dist[nodeindex][l],Dist[iList1[i1]][iList2[i2]]);
  184.                     }
  185.                 }
  186.                 Dist[l][nodeindex] = Dist[nodeindex][l];
  187.                 if (Dist[nodeindex][l] < minval[nodeindex])
  188.                 {
  189.                     minval[nodeindex] = Dist[nodeindex][l];
  190.                     minpair[nodeindex] = l;
  191.                 }
  192.                 //Rescan for min if minpair was one of the fused elements
  193.                 if ( (minpair[l] == min1) || (minpair[l] == min2) )
  194.                 {
  195.                     minval[l] = 32769;
  196.                     for (m=0;m<2*ClusterRows-1;m++)
  197.                     {
  198.                         if ( (Active[m] == true) && (l != m) )
  199.                         {
  200.                             if (Dist[l][m] < minval[l])
  201.                             {
  202.                                 minval[l] = Dist[l][m];
  203.                                 minpair[l] = m;
  204.                             }
  205.                         }
  206.                     }
  207.                 }
  208.                 //otherwise check new distance to see if it is new min
  209.                 else if (Dist[nodeindex][l] < minval[l])
  210.                 {
  211.                     minval[l] = Dist[nodeindex][l];
  212.                     minpair[l] = nodeindex;
  213.                 }
  214.             }
  215.         }
  216.         Active[nodeindex] = true;
  217.         }
  218.         if (SaveDistances == false)
  219.         {
  220.             delete Dist[2*ClusterRows-2];
  221.         }
  222.         TList *NewList = new TList();
  223.         TList *OutList = new TList();
  224.         int **Elements;
  225.         Elements = new int*[2*ClusterRows-1];
  226.         for (i=0;i<2*ClusterRows-1;i++)
  227.         {
  228.             Elements[i] = new int;
  229.             *Elements[i] = i;
  230.         }
  231.         OutList->Clear();
  232.         OutList->Add((void *)Elements[2*ClusterRows-2]);
  233.         int Position;
  234.         bool Replaced;
  235.         Replaced = true;
  236.         while (Replaced == true)
  237.         {
  238.             Replaced = false;
  239.             for (Position = 0; Position < OutList->Count; Position ++)
  240.             {
  241.                 nodeindex =  *(int *) OutList->Items[Position];
  242.                 if (nodeindex >= 0)
  243.                 {
  244.                     if (nodeindex < ClusterRows)
  245.                     {
  246.                         NewList->Add((void *) Elements[nodeindex]);
  247.                     }
  248.                     else
  249.                     {
  250.                         element1 =  NodeElement[nodeindex][0];
  251.                         element2 =  NodeElement[nodeindex][1];
  252.                         NewList->Add((void *) Elements[element1]);
  253.                         NewList->Add((void *) Elements[element2]);
  254.                         Replaced = true;
  255.                     }
  256.                 }
  257.             }
  258.             OutList->Clear();
  259.             for (i=0;i<NewList->Count;i++)
  260.             {
  261.                 OutList->Add(NewList->Items[i]);
  262.             }
  263.             NewList->Clear();
  264.         }
  265.         int index;
  266.         ClusterOrder->Clear();
  267.         if (SaveDistances == true)
  268.         {
  269.             /*
  270.             if (DistFileDialogBox->Execute())
  271.             {
  272.                 TFileStream *DistFile = new TFileStream(DistFileDialogBox->FileName,fmCreate);
  273.                 int ii, ij;
  274.                 for (i=0;i<OutList->Count;i++)
  275.                 {
  276.                     ii = *(int *)OutList->Items[i];
  277.                     for (j=0;j<OutList->Count;j++)
  278.                     {
  279.                         {
  280.                             ij = *(int *)OutList->Items[j];
  281.                             DistFile->Write(&Dist[ii][ij],2);
  282.                         }
  283.                     }
  284.                 }
  285.                 delete DistFile;
  286.             } */
  287.             for (i=0;i<2*ClusterRows-1;i++)
  288.                 {
  289.                     delete Dist[i];
  290.                 }
  291.         }
  292.         if (CalcInferredDistances == true)
  293.         {
  294.             if (DistFileDialogBox->Execute())
  295.             {
  296.                 TFileStream *DistFile = new TFileStream(DistFileDialogBox->FileName,fmCreate);
  297.                 int ii, ij;
  298.                 for (i=0;i<OutList->Count;i++)
  299.                 {
  300.                     ii = *(int *)OutList->Items[i];
  301.                     for (j=0;j<OutList->Count;j++)
  302.                     {
  303.                         {
  304.                             ij = *(int *)OutList->Items[j];
  305.                             DistFile->Write(&TreeDist[ii][ij],2);
  306.                         }
  307.                     }
  308.                 }
  309.                 delete DistFile;
  310.                 for (i=0;i<ClusterRows;i++)
  311.                 {
  312.                     delete TreeDist[i];
  313.                 }
  314.             }
  315.             delete TreeDist;
  316.         }
  317.         for (i=0;i<OutList->Count;i++)
  318.         {
  319.             index = *(int *)OutList->Items[i];
  320.             ClusterOrder->Add(index);
  321.         }
  322.         for (i=0;i<2*ClusterRows-1;i++)
  323.         {
  324.             delete NodeElement[i];
  325.             delete Elements[i];
  326.         }
  327.         if (CalculateWeights == true)
  328.         {
  329.             for (i=0;i<ClusterRows;i++)
  330.             {
  331.                 RowWeight[i] = 1/CalcWeight[i];
  332.             }
  333.         }
  334.         delete Dist;
  335.         delete NodeElement;
  336.         delete Elements;
  337.         delete NodeDistance;
  338.         delete elements;
  339.         delete minval;
  340.         delete minpair;
  341.         delete NewList;
  342.         delete OutList;
  343.         delete Active;
  344.         delete CalcWeight;
  345.         delete iList1;
  346.         delete iList2;
  347.         delete List1;
  348.         delete List2;
  349. }
  350. void __fastcall TMainForm::SingleLinkageClusterButtonClick(TObject *Sender)
  351. {
  352.     int i,j;
  353.     StatusBar1->SimpleText = "Initializing";
  354.     // Get ClusterID for file names from user input
  355.     JobName = AnsiString(ClusterName);
  356.     if (JobNameEdit->Text.Length() > 0)
  357.     {
  358.         JobName = JobNameEdit->Text;
  359.     }
  360.     bool ClusterGenes = ClusterGenesCheckBox->Checked;
  361.     bool ClusterArrays = ClusterArraysCheckBox->Checked;
  362.     bool CalculateGeneWeights = CalculateGeneWeightsCheckBox->Checked;
  363.     bool CalculateArrayWeights = CalculateArrayWeightsCheckBox->Checked;
  364.     int *ColumnOrder = new int[Columns];
  365.     AnsiString *ArrayID = new AnsiString[2*Columns-1];
  366.     for (i=0;i<Columns;i++)
  367.     {
  368.         ColumnOrder[i] = i;
  369.         ArrayID[i] = "ARRY" + AnsiString(i) + "X";
  370.     }
  371.     if (CalculateGeneWeights == true)
  372.     {
  373.         // Generate array data structures
  374.         // This is a wasteful way of doing it, but makes
  375.         // the coding easier for me
  376.         double **ArrayData = new double*[2*Columns-1];
  377.         bool   **ArrayMask = new bool*[2*Columns-1];
  378.         for (i=0;i<2*Columns-1;i++)
  379.         {
  380.             ArrayData[i] = new double[Rows];
  381.             ArrayMask[i] = new bool[Rows];
  382.             if (i<Columns)
  383.             {
  384.                for (j=0;j<Rows;j++)
  385.                {
  386.                    ArrayData[i][j] = GeneData[j][i];
  387.                    ArrayMask[i][j] = GeneMask[j][i];
  388.                }
  389.             }
  390.         }
  391.         TStringList *ArrayTreeFile = new TStringList();
  392.         TStringList *ArrayClusterOrder = new TStringList();
  393.         SingleCluster(ArrayData,ArrayMask,Columns,Rows,
  394.             ArrayTreeFile,ArrayOrder,ArrayWeight,GeneWeight,ArrayID,
  395.             ArrayMetricComboBox->ItemIndex,
  396.             true,ArrayWeightCutoff,ArrayWeightExp,
  397.             ArrayClusterOrder,StatusBar1,false,NULL);
  398.         delete ArrayClusterOrder;
  399.         for (i=0;i<2*Columns-1;i++)
  400.         {
  401.             delete ArrayData[i];
  402.             delete ArrayMask[i];
  403.         }
  404.         delete ArrayData;
  405.         delete ArrayMask;
  406.     }
  407.     int *RowOrder = new int[Rows];
  408.     AnsiString *GeneID = new AnsiString[2*Rows-1];
  409.     for (i=0;i<Rows;i++)
  410.     {
  411.         RowOrder[i] = i;
  412.         GeneID[i] = AnsiString("GENE") + AnsiString(i) + AnsiString("X");
  413.     }
  414.     if (ClusterGenes == true)
  415.     {
  416.         TStringList *GeneTreeFile = new TStringList();
  417.         TStringList *GeneClusterOrder = new TStringList();
  418.         if (CalculateArrayWeights == true)
  419.         {
  420.             SingleCluster(GeneData,GeneMask,Rows,Columns,
  421.                 GeneTreeFile,GeneOrder,GeneWeight, ArrayWeight,GeneID,
  422.                 GeneMetricComboBox->ItemIndex,
  423.                 true,GeneWeightCutoff,GeneWeightExp,
  424.                 GeneClusterOrder,StatusBar1,false,NULL);
  425.         }
  426.         else
  427.         {
  428.             double *NullGeneWeight = new double[Rows];
  429.             SingleCluster(GeneData,GeneMask,Rows,Columns,
  430.                 GeneTreeFile,GeneOrder,NullGeneWeight,ArrayWeight,GeneID,
  431.                 GeneMetricComboBox->ItemIndex,
  432.                 false,1.0,1.0,
  433.                 GeneClusterOrder,StatusBar1,false,NULL);
  434.             delete NullGeneWeight;
  435.         }
  436.         for (i=0;i<GeneClusterOrder->Count;i++)
  437.         {
  438.             RowOrder[i] = GeneClusterOrder->Strings[i].ToInt();
  439.         }
  440.         AnsiString TreeFileName = JobName + ".gtr";
  441.         GeneTreeFile->SaveToFile(TreeFileName);
  442.     }
  443.     if (ClusterArrays == true)
  444.     {
  445.         // Generate array data structures
  446.         // This is a wasteful way of doing it, but makes
  447.         // the coding easier for me
  448.         double **ArrayData = new double*[2*Columns-1];
  449.         bool   **ArrayMask = new bool*[2*Columns-1];
  450.         for (i=0;i<2*Columns-1;i++)
  451.         {
  452.             ArrayData[i] = new double[Rows];
  453.             ArrayMask[i] = new bool[Rows];
  454.             if (i<Columns)
  455.             {
  456.             for (j=0;j<Rows;j++)
  457.             {
  458.                 ArrayData[i][j] = GeneData[j][i];
  459.                 ArrayMask[i][j] = GeneMask[j][i];
  460.             }
  461.             }
  462.         }
  463.         TStringList *ArrayTreeFile = new TStringList();
  464.         TStringList *ArrayClusterOrder = new TStringList();
  465.         SingleCluster(ArrayData,ArrayMask,Columns,Rows,
  466.             ArrayTreeFile,ArrayOrder,ArrayWeight,GeneWeight,ArrayID,
  467.             ArrayMetricComboBox->ItemIndex,
  468.             false,1.0,1.0,ArrayClusterOrder,StatusBar1,false,NULL);
  469.         for (i=0;i<ArrayClusterOrder->Count;i++)
  470.         {
  471.             ColumnOrder[i] = ArrayClusterOrder->Strings[i].ToInt();
  472.         }
  473.         delete ArrayClusterOrder;
  474.         for (i=0;i<2*Columns-1;i++)
  475.         {
  476.             delete ArrayData[i];
  477.             delete ArrayMask[i];
  478.         }
  479.         delete ArrayData;
  480.         delete ArrayMask;
  481.         AnsiString ArrayTreeFileName = JobName + ".atr";
  482.         ArrayTreeFile->SaveToFile(ArrayTreeFileName);
  483.         delete ArrayTreeFile;
  484.     }
  485.     AnsiString OutString;
  486.     TStringList *DataFile = new TStringList();
  487.     // Now make output .cdt file
  488.     OutString = "";
  489.     if (ClusterGenes == true)
  490.     {
  491.         OutString += AnsiString("GID") + AnsiString("t");
  492.     }
  493.     OutString += Headers->Strings[0] + AnsiString("t");
  494.     OutString += AnsiString("NAME") + AnsiString("t");
  495.     OutString += "GWEIGHT";
  496.     // Now add headers for data columns
  497.     for (i=0;i<Columns;i++)
  498.     {
  499.         OutString += "t";
  500.         OutString += AnsiString(Headers->Strings[InColumn[ColumnOrder[i]]]);
  501.     }
  502.     DataFile->Add(OutString);
  503.     if (ClusterArrays == true)
  504.     {
  505.         OutString = AnsiString("AID");
  506.         if (ClusterGenes == true)
  507.         {
  508.             OutString += AnsiString("t");
  509.         }
  510.         OutString += AnsiString("t");
  511.         OutString += AnsiString("t");
  512.         for (i=0;i<Columns;i++)
  513.         {
  514.             OutString += "t";
  515.             OutString += ArrayID[ColumnOrder[i]];
  516.         }
  517.         DataFile->Add(OutString);
  518.     }
  519.     {
  520.         OutString = AnsiString("EWEIGHT");
  521.         if (ClusterGenes == true)
  522.         {
  523.             OutString += AnsiString("t");
  524.         }
  525.         OutString += AnsiString("t");
  526.         OutString += AnsiString("t");
  527.         for (i=0;i<Columns;i++)
  528.         {
  529.             OutString += "t";
  530.             OutString += ArrayWeight[ColumnOrder[i]];
  531.         }
  532.     }
  533.     DataFile->Add(OutString);
  534.     int index;
  535.     TFloatFormat Format = ffGeneral;
  536.     for (i=0;i<Rows;i++)
  537.     {
  538.         index = RowOrder[i];
  539.         OutString = "";
  540.         if (ClusterGenes == true)
  541.         {
  542.             OutString += GeneID[index] + "t";
  543.         }
  544.         OutString += AnsiString(UniqID[index]) + "t" + AnsiString(GeneName[index]);
  545.         OutString += "t" + AnsiString(GeneWeight[index]);
  546.         for (j=0;j<Columns;j++)
  547.         {
  548.             if (GeneMask[index][ColumnOrder[j]] == true)
  549.             {
  550.                 OutString += "t" + AnsiString(FloatToStrF(GeneData[index][ColumnOrder[j]],Format,4,2));
  551.             }
  552.             else
  553.             {
  554.                 OutString += "t";
  555.             }
  556.         }
  557.         DataFile->Add(OutString);
  558.     }
  559.     AnsiString DataFileName = JobName + ".cdt";
  560.     DataFile->SaveToFile(DataFileName);
  561.     for (i=0;i<2*Columns-1;i++)
  562.     {
  563.         ArrayID[i] = "";
  564.     }
  565.     for (i=0;i<2*Rows-1;i++)
  566.     {
  567.         GeneID[i] = "";
  568.     }
  569.     delete ArrayID;
  570.     delete GeneID;
  571.     delete ColumnOrder;
  572.     delete RowOrder;
  573.     StatusBar1->SimpleText = "Done Clustering";
  574. }
  575. //---------------------------------------------------------------------------
  576. /*Single Linkage Clustering Code */
  577. void    TMainForm::SingleCluster(double **ClusterData, bool **ClusterMask,
  578.         int ClusterRows, int ClusterColumns,
  579.         TStringList *TreeFile, double *Order, double *RowWeight, double *ColumnWeight,
  580.         AnsiString *ID, int DistFunction,
  581.         bool CalculateWeights, double WeightCutoff, double WeightPower,
  582.         TStringList *ClusterOrder, TStatusBar *StatusBar,
  583.         bool ReturnTNode, TNode *TopNode)
  584. {
  585.         int i,j,k,l,m;
  586.         ReturnTNode = true;
  587.         unsigned short *minval;
  588.         int *minpair;
  589.         int *elements;
  590.         AnsiString OutString;
  591.         unsigned short **Dist;
  592.         int **NodeElement;
  593.         double *NodeDistance;
  594.         double *CalcWeight;
  595.         int element1, element2;
  596.         
  597.         TStringList *List1 = new TStringList();
  598.         TStringList *List2 = new TStringList();
  599.         Dist = new unsigned short*[2*ClusterRows-1];
  600.         minval = new unsigned short[2*ClusterRows-1];
  601.         minpair = new int[2*ClusterRows-1];
  602.         elements = new int[2*ClusterRows-1];
  603.         NodeElement = new int*[2*ClusterRows-1];
  604.         NodeDistance = new double[2*ClusterRows-1];
  605.         CalcWeight = new double[2*ClusterRows-1];
  606.         int *iList1 = new int[ClusterRows];
  607.         int *iList2 = new int[ClusterRows];
  608.         bool SaveDistances = true;
  609.         double WeightDist;
  610.         for (i=0;i<ClusterRows;i++)
  611.         {
  612.             Dist[i] = new unsigned short[2*ClusterRows-1];
  613.         }
  614.         for (i=0;i<2*ClusterRows-1;i++)
  615.         {
  616.             minval[i] = 32769;
  617.             elements[i] = 1;
  618.             NodeElement[i] = new int[2];
  619.             CalcWeight[i] = 1;
  620.             NodeDistance[i] = 0.0;
  621.         }
  622.         bool Centered = false;
  623.         if ((DistFunction == 1) || (DistFunction == 3) )
  624.         {
  625.             Centered = true;
  626.         }
  627.         bool Absolute = false;
  628.         if ((DistFunction == 3) || (DistFunction == 4) )
  629.         {
  630.             Absolute = true;
  631.         }
  632.         bool CalcInferredDistances = false;
  633.         TStringList **MemberList;
  634.         unsigned short **TreeDist;
  635.         if (CalcInferredDistances == true)
  636.         {
  637.             MemberList = new TStringList*[2*ClusterRows-1];
  638.             TreeDist = new unsigned short*[ClusterRows];
  639.             for (i=0;i<2*ClusterRows-1;i++)
  640.             {
  641.                 MemberList[i] = new TStringList();
  642.                 if (i<ClusterRows)
  643.                 {
  644.                     MemberList[i]->Add(AnsiString(i));
  645.                     TreeDist[i] = new unsigned short[ClusterRows];
  646.                 }
  647.             }
  648.         }
  649.         int TotalDistance = ClusterRows * (ClusterRows - 1) / 2;
  650.         /* First step is to compute the distance matrix
  651.         This is the slowest step */
  652.         for (i=0;i<ClusterRows;i++)
  653.         {
  654.             Dist[i][i] = 0.0;
  655.             for (j=0;j<i;j++)
  656.             {
  657.                 Dist[i][j] = Distance(DistFunction,ClusterData,ClusterMask,ColumnWeight,
  658.                     i,j,ClusterColumns);
  659.                 Dist[j][i] = Dist[i][j];
  660.                 if (CalculateWeights == true)
  661.                 {
  662.                     WeightDist = ( (double) (32768 - Dist[i][j])) /32768.0;
  663.                     WeightDist = max(0.0, (WeightDist - WeightCutoff)/(1.0 - WeightCutoff));
  664.                     WeightDist = pow(WeightDist,WeightPower);
  665.                     CalcWeight[i] += WeightDist;
  666.                     CalcWeight[j] += WeightDist;
  667.                 }
  668.                 if (Dist[i][j] < minval[i])
  669.                 {
  670.                     minval[i] = Dist[i][j];
  671.                     minpair[i] = j;
  672.                 }
  673.                 if (Dist[i][j] < minval[j])
  674.                 {
  675.                     minval[j] = Dist[i][j];
  676.                     minpair[j] = i;
  677.                 }
  678.             }
  679.             StatusBar->SimpleText = "Calculating Distances " + AnsiString(i*(i+1)/2) + " of "
  680.                 + AnsiString(TotalDistance);
  681.             Application->ProcessMessages();
  682.         }
  683.         TStringList *MinList = new TStringList();
  684.         for (i=0;i<ClusterRows;i++)
  685.         {
  686.             MinList->Add(AnsiString(minval[i]));
  687.         }
  688.         MinList->SaveToFile("minlist.txt");
  689.         delete MinList;
  690.         bool *Active;
  691.         Active = new bool[2*ClusterRows-1];
  692.         for (i=0;i<ClusterRows;i++)
  693.         {
  694.             Active[i] = true;
  695.         }
  696.         for (i=ClusterRows;i<2*ClusterRows-1;i++)
  697.         {
  698.             Active[i] = false;
  699.         }
  700.         unsigned short minminval;
  701.         int min1, min2;
  702.         int nodeindex;
  703.         //int node;
  704.         /* Now we join nodes */
  705.         /* If we are going to return TNode, need to set up TNodes */
  706.         TNode **Nodes;
  707.         //if (ReturnTNode)
  708.         {
  709.            Nodes = new TNode*[2*ClusterRows-1];
  710.            for (i=0;i<2*ClusterRows-1;i++)
  711.            {
  712.                Nodes[i] = new TNode();
  713.                if (i < ClusterRows)
  714.                {
  715.                    Nodes[i]->IsNode = false;
  716.                    Nodes[i]->ID = AnsiString(i);
  717.                }
  718.                else
  719.                {
  720.                    Nodes[i]->IsNode = true;
  721.                }
  722.            }
  723.         }
  724.         for (nodeindex=ClusterRows; nodeindex<2*ClusterRows-1;nodeindex++)
  725.         {
  726.             ID[nodeindex] = "NODE" + AnsiString(nodeindex-ClusterRows+1) + "X";
  727.             minminval = 32769;
  728.             for (i=0;i<2*ClusterRows-1;i++)
  729.             {
  730.                 if (Active[i] == true)
  731.                 {
  732.                     if (minval[i] < minminval)
  733.                     {
  734.                         minminval = minval[i];
  735.                         min1 = i;
  736.                         min2 = minpair[i];
  737.                     }
  738.                 }
  739.             }
  740.             /* When we get here min1 and min2 are the elements that are to be joined */
  741.         Active[min1] = false;
  742.         Active[min2] = false;
  743.         if (Order[min1] > Order[min2])
  744.         {
  745.             NodeElement[nodeindex][0] = min1;
  746.             NodeElement[nodeindex][1] = min2;
  747.         }
  748.         else
  749.         {
  750.             NodeElement[nodeindex][1] = min1;
  751.             NodeElement[nodeindex][0] = min2;
  752.         }
  753.         NodeDistance[nodeindex] = ((double) minminval)/16384.0;
  754.         NodeDistance[nodeindex] = max(NodeDistance[nodeindex],NodeDistance[min1]);
  755.         NodeDistance[nodeindex] = max(NodeDistance[nodeindex],NodeDistance[min2]);
  756.         if (ReturnTNode)
  757.         {
  758.                Nodes[nodeindex]->Child1 = Nodes[NodeElement[nodeindex][0]];
  759.                Nodes[nodeindex]->Child2 = Nodes[NodeElement[nodeindex][1]];
  760.                Nodes[nodeindex]->Length = 1.0 - NodeDistance[nodeindex];
  761.         }
  762.         if (CalcInferredDistances == true)
  763.         {
  764.             int elem1,elem2,ielem1,ielem2;
  765.             for (elem1=0;elem1<MemberList[min1]->Count;elem1++)
  766.             {
  767.                 for (elem2=0;elem2<MemberList[min2]->Count;elem2++)
  768.                 {
  769.                     ielem1 = (MemberList[min1]->Strings[elem1]).ToInt();
  770.                     ielem2 = (MemberList[min2]->Strings[elem2]).ToInt();
  771.                     TreeDist[ielem1][ielem2] = (NodeDistance[nodeindex] * 16384);
  772.                     TreeDist[ielem2][ielem1] = (NodeDistance[nodeindex] * 16384);
  773.                 }
  774.             }
  775.             MemberList[nodeindex]->AddStrings(MemberList[min1]);
  776.             MemberList[nodeindex]->AddStrings(MemberList[min2]);
  777.             delete MemberList[min1];
  778.             delete MemberList[min2];
  779.         }
  780.         OutString = ID[nodeindex] + AnsiString("t") + ID[NodeElement[nodeindex][0]]
  781.                 + AnsiString("t") + ID[NodeElement[nodeindex][1]] + AnsiString("t")
  782.                 + AnsiString(1.0 - NodeDistance[nodeindex]);
  783.         TreeFile->Add(OutString);
  784.         StatusBar->SimpleText = "Generating Node " + AnsiString(nodeindex-ClusterRows+1) + " of " + AnsiString(ClusterRows-1);
  785.         Application->ProcessMessages();
  786.         elements[nodeindex] = elements[min1] + elements[min2];
  787.         for (k=0;k<ClusterColumns;k++)
  788.         {
  789.             if ( (ClusterMask[min1][k] == true) && (ClusterMask[min2][k] == true) )
  790.             {
  791.                 ClusterData[nodeindex][k] =
  792.                     (elements[min1] * ClusterData[min1][k] +
  793.                         elements[min2] * ClusterData[min2][k]) /
  794.                     (elements[min1] + elements[min2]);
  795.                 ClusterMask[nodeindex][k] = true;
  796.             }
  797.             else if (ClusterMask[min1][k] == true)
  798.             {
  799.                 ClusterData[nodeindex][k] = ClusterData[min1][k];
  800.                 ClusterMask[nodeindex][k] = true;
  801.             }
  802.             else if (ClusterMask[min2][k] == true)
  803.             {
  804.                 ClusterData[nodeindex][k] = ClusterData[min2][k];
  805.                 ClusterMask[nodeindex][k] = true;
  806.             }
  807.             else
  808.             {
  809.                 ClusterMask[nodeindex][k] = false;
  810.             }
  811.         }
  812.         Order[nodeindex] = (elements[min1]*Order[min1] + elements[min2]*Order[min2])/(elements[min1] + elements[min2]);
  813.         Dist[nodeindex] = new unsigned short[2*ClusterRows-1];
  814.         if (SaveDistances == false)
  815.         {
  816.             delete Dist[min1];
  817.             delete Dist[min2];
  818.         }
  819.         List1->Clear();
  820.         Nodes[nodeindex]->SetList(List1);
  821.         int NumList1 = List1->Count;
  822.         for (int i1=0;i1<NumList1;i1++)
  823.         {
  824.             iList1[i1] = List1->Strings[i1].ToInt();
  825.         }
  826.         for (l=0;l<2*ClusterRows-1;l++)
  827.         {
  828.             if (Active[l] == true)
  829.             {
  830.                 // OK. Here's where it gets tricky
  831.                 List2->Clear();
  832.                 if (l < ClusterRows)
  833.                 {
  834.                     List2->Add(AnsiString(l));
  835.                 }
  836.                 else
  837.                 {
  838.                     Nodes[l]->SetList(List2);
  839.                 }
  840.                 int NumList2 = List2->Count;
  841.                 for (int i2=0;i2<NumList2;i2++)
  842.                 {
  843.                     iList2[i2] = List2->Strings[i2].ToInt();
  844.                 }
  845.                 Dist[nodeindex][l] = 32768;
  846.                 for (int i1=0; i1 < NumList1; i1++)
  847.                 {
  848.                     for (int i2=0; i2 < NumList2; i2++)
  849.                     {
  850.                          Dist[nodeindex][l] = min(Dist[nodeindex][l],Dist[iList1[i1]][iList2[i2]]);
  851.                     }
  852.                 }
  853.                 Dist[l][nodeindex] = Dist[nodeindex][l];
  854.                 if (Dist[nodeindex][l] < minval[nodeindex])
  855.                 {
  856.                     minval[nodeindex] = Dist[nodeindex][l];
  857.                     minpair[nodeindex] = l;
  858.                 }
  859.                 //Rescan for min if minpair was one of the fused elements
  860.                 if ( (minpair[l] == min1) || (minpair[l] == min2) )
  861.                 {
  862.                     minval[l] = 32769;
  863.                     for (m=0;m<2*ClusterRows-1;m++)
  864.                     {
  865.                         if ( (Active[m] == true) && (l != m) )
  866.                         {
  867.                             if (Dist[l][m] < minval[l])
  868.                             {
  869.                                 minval[l] = Dist[l][m];
  870.                                 minpair[l] = m;
  871.                             }
  872.                         }
  873.                     }
  874.                 }
  875.                 //otherwise check new distance to see if it is new min
  876.                 else if (Dist[nodeindex][l] < minval[l])
  877.                 {
  878.                     minval[l] = Dist[nodeindex][l];
  879.                     minpair[l] = nodeindex;
  880.                 }
  881.             }
  882.         }
  883.         Active[nodeindex] = true;
  884.         }
  885.         if (SaveDistances == false)
  886.         {
  887.             delete Dist[2*ClusterRows-2];
  888.         }
  889.         TList *NewList = new TList();
  890.         TList *OutList = new TList();
  891.         int **Elements;
  892.         Elements = new int*[2*ClusterRows-1];
  893.         for (i=0;i<2*ClusterRows-1;i++)
  894.         {
  895.             Elements[i] = new int;
  896.             *Elements[i] = i;
  897.         }
  898.         OutList->Clear();
  899.         OutList->Add((void *)Elements[2*ClusterRows-2]);
  900.         int Position;
  901.         bool Replaced;
  902.         Replaced = true;
  903.         while (Replaced == true)
  904.         {
  905.             Replaced = false;
  906.             for (Position = 0; Position < OutList->Count; Position ++)
  907.             {
  908.                 nodeindex =  *(int *) OutList->Items[Position];
  909.                 if (nodeindex >= 0)
  910.                 {
  911.                     if (nodeindex < ClusterRows)
  912.                     {
  913.                         NewList->Add((void *) Elements[nodeindex]);
  914.                     }
  915.                     else
  916.                     {
  917.                         element1 =  NodeElement[nodeindex][0];
  918.                         element2 =  NodeElement[nodeindex][1];
  919.                         NewList->Add((void *) Elements[element1]);
  920.                         NewList->Add((void *) Elements[element2]);
  921.                         Replaced = true;
  922.                     }
  923.                 }
  924.             }
  925.             OutList->Clear();
  926.             for (i=0;i<NewList->Count;i++)
  927.             {
  928.                 OutList->Add(NewList->Items[i]);
  929.             }
  930.             NewList->Clear();
  931.         }
  932.         int index;
  933.         ClusterOrder->Clear();
  934.         if (SaveDistances == true)
  935.         {
  936.             /*
  937.             if (DistFileDialogBox->Execute())
  938.             {
  939.                 TFileStream *DistFile = new TFileStream(DistFileDialogBox->FileName,fmCreate);
  940.                 int ii, ij;
  941.                 for (i=0;i<OutList->Count;i++)
  942.                 {
  943.                     ii = *(int *)OutList->Items[i];
  944.                     for (j=0;j<OutList->Count;j++)
  945.                     {
  946.                         {
  947.                             ij = *(int *)OutList->Items[j];
  948.                             DistFile->Write(&Dist[ii][ij],2);
  949.                         }
  950.                     }
  951.                 }
  952.                 delete DistFile;
  953.             } */
  954.             for (i=0;i<2*ClusterRows-1;i++)
  955.                 {
  956.                     delete Dist[i];
  957.                 }
  958.         }
  959.         if (CalcInferredDistances == true)
  960.         {
  961.             if (DistFileDialogBox->Execute())
  962.             {
  963.                 TFileStream *DistFile = new TFileStream(DistFileDialogBox->FileName,fmCreate);
  964.                 int ii, ij;
  965.                 for (i=0;i<OutList->Count;i++)
  966.                 {
  967.                     ii = *(int *)OutList->Items[i];
  968.                     for (j=0;j<OutList->Count;j++)
  969.                     {
  970.                         {
  971.                             ij = *(int *)OutList->Items[j];
  972.                             DistFile->Write(&TreeDist[ii][ij],2);
  973.                         }
  974.                     }
  975.                 }
  976.                 delete DistFile;
  977.                 for (i=0;i<ClusterRows;i++)
  978.                 {
  979.                     delete TreeDist[i];
  980.                 }
  981.             }
  982.             delete TreeDist;
  983.         }
  984.         for (i=0;i<OutList->Count;i++)
  985.         {
  986.             index = *(int *)OutList->Items[i];
  987.             ClusterOrder->Add(index);
  988.         }
  989.         for (i=0;i<2*ClusterRows-1;i++)
  990.         {
  991.             delete NodeElement[i];
  992.             delete Elements[i];
  993.         }
  994.         if (CalculateWeights == true)
  995.         {
  996.             for (i=0;i<ClusterRows;i++)
  997.             {
  998.                 RowWeight[i] = 1/CalcWeight[i];
  999.             }
  1000.         }
  1001.         delete Dist;
  1002.         delete NodeElement;
  1003.         delete Elements;
  1004.         delete NodeDistance;
  1005.         delete elements;
  1006.         delete minval;
  1007.         delete minpair;
  1008.         delete NewList;
  1009.         delete OutList;
  1010.         delete Active;
  1011.         delete CalcWeight;
  1012.         delete iList1;
  1013.         delete iList2;
  1014.         delete List1;
  1015.         delete List2;
  1016. }
  1017. /* Accessory Code for Clustering Dialog */
  1018. /* Handle Clicks on CheckBoxes */
  1019. void __fastcall TMainForm::CalculateGeneWeightsCheckBoxClick(
  1020.       TObject *Sender)
  1021. {
  1022.     if (CalculateGeneWeightsCheckBox->Checked == true)
  1023.     {
  1024.         ArrayWeightOptionsGroupBox->Visible = true;
  1025.     }
  1026.     else
  1027.     {
  1028.         ArrayWeightOptionsGroupBox->Visible = false;
  1029.     }
  1030. }
  1031. void __fastcall TMainForm::CalculateArrayWeightsCheckBoxClick(
  1032.       TObject *Sender)
  1033. {
  1034.     if (CalculateArrayWeightsCheckBox->Checked == true)
  1035.     {
  1036.         GeneWeightOptionsGroupBox->Visible = true;
  1037.     }
  1038.     else
  1039.     {
  1040.         GeneWeightOptionsGroupBox->Visible = false;
  1041.     }
  1042. }
  1043. /* Handle Edit Exits to Check Values */
  1044. //---------------------------------------------------------------------------
  1045. void __fastcall TMainForm::GeneWeightExpEditExit(TObject *Sender)
  1046. {
  1047.     double Val;
  1048.     try
  1049.     {
  1050.         Val =  GeneWeightExpEdit->Text.ToDouble();
  1051.         GeneWeightExp = Val;
  1052.     }
  1053.     catch (EConvertError &E)
  1054.     {
  1055.         GeneWeightExpEdit->Text = GeneWeightExp;
  1056.     }
  1057. }
  1058. //---------------------------------------------------------------------------
  1059. void __fastcall TMainForm::GeneWeightCutoffEditExit(TObject *Sender)
  1060. {
  1061.     double Val;
  1062.     try
  1063.     {
  1064.         Val =  GeneWeightCutoffEdit->Text.ToDouble();
  1065.         GeneWeightCutoff = Val;
  1066.     }
  1067.     catch (EConvertError &E)
  1068.     {
  1069.         GeneWeightCutoffEdit->Text = GeneWeightCutoff;
  1070.     }
  1071. }
  1072. //---------------------------------------------------------------------------
  1073. void __fastcall TMainForm::ArrayWeightExpEditExit(TObject *Sender)
  1074. {
  1075.     double Val;
  1076.     try
  1077.     {
  1078.         Val =  ArrayWeightExpEdit->Text.ToDouble();
  1079.         ArrayWeightExp = Val;
  1080.     }
  1081.     catch (EConvertError &E)
  1082.     {
  1083.         ArrayWeightExpEdit->Text = ArrayWeightExp;
  1084.     }
  1085. }
  1086. //---------------------------------------------------------------------------
  1087. void __fastcall TMainForm::ArrayWeightCutoffEditExit(TObject *Sender)
  1088. {
  1089.     double Val;
  1090.     try
  1091.     {
  1092.         Val =  ArrayWeightCutoffEdit->Text.ToDouble();
  1093.         ArrayWeightCutoff = Val;
  1094.     }
  1095.     catch (EConvertError &E)
  1096.     {
  1097.         ArrayWeightCutoffEdit->Text = ArrayWeightCutoff;
  1098.     }
  1099. }
  1100. /* This is an invisible button that handles a particular type
  1101. of column and row reordering. It was put in for one use. */
  1102. void __fastcall TMainForm::ReorderType1ButtonClick(TObject *Sender)
  1103. {
  1104.     for (int row=0; row<Rows; row++)
  1105.     {
  1106.         GeneOrder[row] = 0;
  1107.         int count = 0;
  1108.         for (int col=0; col<Columns; col++)
  1109.         {
  1110.             if (GeneMask[row][col] == true)
  1111.             {
  1112.                 GeneOrder[row] += col * GeneData[row][col];
  1113.                 count++;
  1114.             }
  1115.         }
  1116.         if (count > 0)
  1117.         {
  1118.             GeneOrder[row] /= count;
  1119.         }
  1120.     }
  1121.     for (int col=0; col<Columns; col++)
  1122.     {
  1123.         ArrayOrder[col] = 0;
  1124.         int count = 0;
  1125.         for (int row=0; row<Rows; row++)
  1126.         {
  1127.             if (GeneMask[row][col] == true)
  1128.             {
  1129.                 ArrayOrder[col] += row * GeneData[row][col];
  1130.                 count++;
  1131.             }
  1132.         }
  1133.         if (count > 0)
  1134.         {
  1135.             ArrayOrder[col] /= count;
  1136.         }
  1137.     }
  1138. }
  1139. //---------------------------------------------------------------------------
  1140. /* Self-Organizing Maps ala Kohonen: Note this makes use of NR Code */
  1141. double*** __fastcall TMainForm::SOM(int X, int Y, double **SOMData, bool **SOMMask,
  1142.      int SOMRows, int SOMColumns, int SOMIterations)
  1143. {
  1144.      int i,j,k,l,n;
  1145.      double ***Nodes;
  1146.      Nodes = new double**[X];
  1147.      for (i=0;i<X;i++)
  1148.      {
  1149.          Nodes[i] = new double*[Y];
  1150.          for (j=0; j<Y; j++)
  1151.          {
  1152.              Nodes[i][j] = new double[SOMColumns];
  1153.              double NodeMag = 0;
  1154.              while (NodeMag == 0)
  1155.              {
  1156.                    for (k=0;k<SOMColumns;k++)
  1157.                    {
  1158.                        Nodes[i][j][k] = ((double) random(10000))/10000.0;
  1159.                        NodeMag += pow(Nodes[i][j][k],2.0);
  1160.                    }
  1161.                    NodeMag = sqrt(NodeMag);
  1162.              }
  1163.              for (k=0;k<SOMColumns;k++)
  1164.              {
  1165.                  Nodes[i][j][k] /= NodeMag;
  1166.              }
  1167.          }
  1168.      }
  1169.      bool *SOMUse = new bool[SOMRows];
  1170.      double *Mag = new double[SOMRows];
  1171.      int CountSOMUse = 0;
  1172.      for (i=0;i<SOMRows;i++)
  1173.      {
  1174.          Mag[i] = 0;
  1175.          double Min = 1000;
  1176.          double Max = -1000;
  1177.          int    DataPoints = 0;
  1178.          for (j=0;j<SOMColumns;j++)
  1179.          {
  1180.              if (SOMMask[i][j])
  1181.              {
  1182.                 DataPoints++;
  1183.                 Min = min(Min,SOMData[i][j]);
  1184.                 Max = max(Max,SOMData[i][j]);
  1185.                 Mag[i] += pow(SOMData[i][j],2.0);
  1186.              }
  1187.          }
  1188.          Mag[i] = sqrt(Mag[i]);
  1189.          if ( (2 * DataPoints > SOMColumns) && ( (Max - Min) > 0.0) )
  1190.          {
  1191.              SOMUse[i] = true;
  1192.              CountSOMUse++;
  1193.          }
  1194.          else
  1195.          {
  1196.              SOMUse[i] = false;
  1197.          }
  1198.      }
  1199.      int *SOMUseRow = ivector(1,CountSOMUse);
  1200.      float *SOMUseRandom = vector(1,CountSOMUse);
  1201.      CountSOMUse = 0;
  1202.      for (i=0;i<SOMRows;i++)
  1203.      {
  1204.          if (SOMUse[i])
  1205.          {
  1206.             CountSOMUse++;
  1207.             SOMUseRow[CountSOMUse] = i;
  1208.             SOMUseRandom[CountSOMUse] = rand();
  1209.          }
  1210.      }
  1211.      sort2fi(CountSOMUse,SOMUseRandom,SOMUseRow);
  1212.      double MaxDist = sqrt(pow(X-1,2.0)+pow(Y-1,2.0));
  1213.      //MaxDist = 3; // Try this for compatibility with Tamayo et al.
  1214.      for (i=0;i<SOMIterations;i++)
  1215.      {
  1216.          StatusBar1->SimpleText = "SOM Iteration " + AnsiString(i) +" of " + AnsiString(SOMIterations);
  1217.          Application->ProcessMessages();
  1218.          double BestCorr = -100;
  1219.          int BestX, BestY;
  1220. /*       n = random(SOMRows);
  1221.          while(SOMUse[n] == false)
  1222.          {
  1223.              n = random(SOMRows);
  1224.          }   */
  1225.          n = SOMUseRow[(i%CountSOMUse)+1];
  1226.          for (j=0;j<X;j++)
  1227.          {
  1228.              for (k=0;k<Y;k++)
  1229.              {
  1230.                  double Corr = Correlation(Nodes,SOMData,SOMMask,false,j,k,n,SOMColumns);
  1231.                  if (Corr > BestCorr)
  1232.                  {
  1233.                     BestCorr = Corr;
  1234.                     BestX = j;
  1235.                     BestY = k;
  1236.                  }
  1237.              }
  1238.          }
  1239.          for (j=0;j<X;j++)
  1240.          {
  1241.              for (k=0;k<Y;k++)
  1242.              {
  1243.                  double Corr = Correlation(Nodes,SOMData,SOMMask,false,j,k,n,SOMColumns);
  1244.                  if (Corr > BestCorr)
  1245.                  {
  1246.                     BestCorr = Corr;
  1247.                     BestX = j;
  1248.                     BestY = k;
  1249.                  }
  1250.              }
  1251.          }
  1252.          double DistCut = (MaxDist*(0.75-((0.75*i)/SOMIterations)));
  1253.          //DistCut = MaxDist * (1.0 - ((double)i/(double)SOMIterations));
  1254.          double Tau;
  1255.          if (i < 1000)
  1256.          {
  1257.              Tau = (0.9 * (1.0 - i/1000.0));
  1258.          }
  1259.          else
  1260.          {
  1261.              Tau = (0.02 * SOMIterations)/(SOMIterations+(100*i));
  1262.          }
  1263.          //Tau = (0.02 * SOMIterations)/(SOMIterations+(100*i));
  1264.          for (j=0;j<X;j++)
  1265.          {
  1266.              for (k=0;k<Y;k++)
  1267.              {
  1268.                  double NodeDist = sqrt(pow(BestX - j,2.0) + pow(BestY - k,2.0));
  1269.                  if (NodeDist < DistCut)
  1270.                  {
  1271.                     for (l=0;l<SOMColumns;l++)
  1272.                     {
  1273.                         if (SOMMask[n][l] == true)
  1274.                         {
  1275.                            Nodes[j][k][l] += Tau * ((SOMData[n][l]/Mag[n]) - Nodes[j][k][l]);
  1276.                         }
  1277.                     }
  1278.                  }
  1279.                  double NodeMag = 0;
  1280.                  for (l=0;l<SOMColumns;l++)
  1281.                  {
  1282.                      NodeMag += pow(Nodes[j][k][l],2.0);
  1283.                  }
  1284.                  NodeMag = sqrt(NodeMag);
  1285.                  for (l=0;l<SOMColumns;l++)
  1286.                  {
  1287.                      Nodes[j][k][l] /= NodeMag;
  1288.                  }
  1289.              }
  1290.          }
  1291.      }
  1292.      delete Mag;
  1293.      delete SOMUse;
  1294.      free_vector(SOMUseRandom,1,CountSOMUse);
  1295.      free_ivector(SOMUseRow,1,CountSOMUse);
  1296.      StatusBar1->SimpleText = "Done Making SOM";
  1297.      return Nodes;
  1298. }
  1299. /* Correlation Function for SOM */
  1300. double TMainForm::Correlation(double ***Nodes, double **SOMData, bool **SOMMask,
  1301.        bool Centered, int j, int k, int n, int SOMColumns)
  1302. {
  1303.     int l;
  1304.     double Sum1 = 0;
  1305.     double Sum2 = 0;
  1306.     double Sum11 = 0;
  1307.     double Sum12 = 0;
  1308.     double Sum22 = 0;
  1309.     double Count = 0;
  1310.     double Ave1,Ave2;
  1311.     double Norm1 = 0;
  1312.     double Norm2 = 0;
  1313.     double Corr = -100;
  1314.     for (l=0;l<SOMColumns;l++)
  1315.     {
  1316.         if (SOMMask[n][l] == true)
  1317.         {
  1318.            Sum1  += SOMData[n][l];
  1319.            Sum2  += Nodes[j][k][l];
  1320.            Sum11 += SOMData[n][l] * SOMData[n][l];
  1321.            Sum22 += Nodes[j][k][l]* Nodes[j][k][l];
  1322.            Sum12 += SOMData[n][l] * Nodes[j][k][l];
  1323.            Count ++;
  1324.         }
  1325.     }
  1326.     if (Count > 0)
  1327.     {
  1328.        if (Centered)
  1329.        {
  1330.           Ave1 = Sum1/Count;
  1331.           Ave2 = Sum2/Count;
  1332.        }
  1333.        else
  1334.        {
  1335.           Ave1 = 0;
  1336.           Ave2 = 0;
  1337.        }
  1338.        try
  1339.        {
  1340.           Norm1 = sqrt(max(0.0,Sum11 - 2 * Ave1 * Sum1 + Count * Ave1 * Ave1));
  1341.           Norm2 = sqrt(max(0.0,Sum22 - 2 * Ave2 * Sum2 + Count * Ave2 * Ave2));
  1342.        }
  1343.        catch (Exception &E)
  1344.        {
  1345.        }
  1346.        if ( (Norm1 > 0) && (Norm2 > 0) )
  1347.        {
  1348.           Corr = (Sum12 - Sum1 * Ave2 - Sum2 * Ave1 + Count * Ave1 * Ave2)
  1349.           / (Norm1 * Norm2);
  1350.        }
  1351.     }
  1352.     return Corr;
  1353. }
  1354. /* SOM Dialog Controls */ void __fastcall TMainForm::SOMOrganizeGenesCheckBoxClick(TObject *Sender)
  1355. {
  1356.     if (SOMOrganizeGenesCheckBox->Checked == true)
  1357.     {
  1358.         SOMGenesXDimEdit->Visible = true;
  1359.         SOMGenesYDimEdit->Visible = true;
  1360.         SOMGenesTauEdit->Visible = true;
  1361.         SOMGenesIterationsEdit->Visible = true;
  1362.         SOMGenesXDimLabel->Visible = true;
  1363.         SOMGenesYDimLabel->Visible = true;
  1364.         SOMGenesTauLabel->Visible = true;
  1365.         SOMGenesIterationsLabel->Visible = true;
  1366.     }
  1367.     else
  1368.     {
  1369.         SOMGenesXDimEdit->Visible = false;
  1370.         SOMGenesYDimEdit->Visible = false;
  1371.         SOMGenesTauEdit->Visible = false;
  1372.         SOMGenesIterationsEdit->Visible = false;
  1373.         SOMGenesXDimLabel->Visible = false;
  1374.         SOMGenesYDimLabel->Visible = false;
  1375.         SOMGenesTauLabel->Visible = false;
  1376.         SOMGenesIterationsLabel->Visible = false;
  1377.     }
  1378. }
  1379. //---------------------------------------------------------------------------
  1380. void __fastcall TMainForm::SOMOrganizeArraysCheckBoxClick(TObject *Sender)
  1381. {
  1382.     if (SOMOrganizeArraysCheckBox->Checked == true)
  1383.     {
  1384.         SOMArraysXDimEdit->Visible = true;
  1385.         SOMArraysYDimEdit->Visible = true;
  1386.         SOMArraysTauEdit->Visible = true;
  1387.         SOMArraysIterationsEdit->Visible = true;
  1388.         SOMArraysXDimLabel->Visible = true;
  1389.         SOMArraysYDimLabel->Visible = true;
  1390.         SOMArraysTauLabel->Visible = true;
  1391.         SOMArraysIterationsLabel->Visible = true;
  1392.     }
  1393.     else
  1394.     {
  1395.         SOMArraysXDimEdit->Visible = false;
  1396.         SOMArraysYDimEdit->Visible = false;
  1397.         SOMArraysTauEdit->Visible = false;
  1398.         SOMArraysIterationsEdit->Visible = false;
  1399.         SOMArraysXDimLabel->Visible = false;
  1400.         SOMArraysYDimLabel->Visible = false;
  1401.         SOMArraysTauLabel->Visible = false;
  1402.         SOMArraysIterationsLabel->Visible = false;
  1403.     }
  1404. }
  1405. //---------------------------------------------------------------------------
  1406. void __fastcall TMainForm::About1Click(TObject *Sender)
  1407. {
  1408.         AboutForm->Show();
  1409. }
  1410. void __fastcall TMainForm::MakeSOMButtonClick(TObject *Sender)
  1411. {
  1412.         MakeSOM();
  1413. }
  1414. //---------------------------------------------------------------------------
  1415. void __fastcall TMainForm::MakeSOM()
  1416. {
  1417.      int i,j,y;
  1418.      double Best, Val;
  1419.      AnsiString DataFileName = AnsiString(ClusterName) + "_SOM";
  1420.      int *GeneGroup     = ivector(1,Rows);
  1421.      int *SOMGeneOrder  = ivector(1,Rows);
  1422.      double ***GeneNodes;
  1423.      if (SOMOrganizeGenesCheckBox->Checked)
  1424.      {
  1425.         DataFileName += "_G" + AnsiString(SOMGenesXDim) + "-" + AnsiString(SOMGenesYDim);
  1426.         GeneNodes = SOM(SOMGenesXDim, SOMGenesYDim, GeneData, GeneMask, Rows, Columns, SOMGenesIterations);
  1427.         for (i=0;i<Rows;i++)
  1428.         {
  1429.                 GeneGroup[i+1]    = SOMGenesYDim;
  1430.                 SOMGeneOrder[i+1] = i;
  1431.                 Best = 0.4;
  1432.                 Best = -100;
  1433.                 for (y=0;y<SOMGenesYDim;y++)
  1434.                 {
  1435.                         Val = Correlation(GeneNodes,GeneData,GeneMask,false,0,y,i,Columns);
  1436.                         if (Val > Best)
  1437.                         {
  1438.                                 GeneGroup[i+1] = y;
  1439.                                 Best = Val;
  1440.                         }
  1441.                 }
  1442.                 GeneOrder[i] = GeneGroup[i+1];
  1443.         }
  1444.         sort2i(Rows,GeneGroup,SOMGeneOrder);
  1445.      }
  1446.      else
  1447.      {
  1448.         for (i=0;i<Rows;i++)
  1449.         {
  1450.                 GeneGroup[i+1] = 0;
  1451.                 SOMGeneOrder[i+1] = i;
  1452.         }
  1453.      }
  1454.      int *ArrayGroup = ivector(1,Columns);
  1455.      int *SOMArrayOrder = ivector(1,Columns);
  1456.      double ***ArrayNodes;
  1457.      if (SOMOrganizeArraysCheckBox->Checked)
  1458.      {
  1459.         double **ArrayData;
  1460.         bool **ArrayMask;
  1461.         ArrayData = new double*[Columns];
  1462.         ArrayMask = new bool*[Columns];
  1463.         for (i=0;i<Columns;i++)
  1464.         {
  1465.                 ArrayData[i] = new double[Rows];
  1466.                 ArrayMask[i] = new bool[Rows];
  1467.                 for (j=0;j<Rows;j++)
  1468.                 {
  1469.                         ArrayData[i][j] = GeneData[j][i];
  1470.                         ArrayMask[i][j] = GeneMask[j][i];
  1471.                 }
  1472.         }
  1473.         DataFileName += "_A" + AnsiString(SOMArraysXDim) + "-" + AnsiString(SOMArraysYDim);
  1474.         ArrayNodes = SOM(SOMArraysXDim, SOMArraysYDim, ArrayData, ArrayMask, Columns, Rows, SOMArraysIterations);
  1475.         for (i=0;i<Columns;i++)
  1476.         {
  1477.                 ArrayGroup[i+1]    = SOMArraysYDim;
  1478.                 SOMArrayOrder[i+1] = i;
  1479.                 Best = 0.4;
  1480.                 Best = -100;
  1481.                 for (y=0;y<SOMArraysYDim;y++)
  1482.                 {
  1483.                         Val = Correlation(ArrayNodes,ArrayData,ArrayMask,false,0,y,i,Rows);
  1484.                         if (Val > Best)
  1485.                         {
  1486.                                 ArrayGroup[i+1] = y;
  1487.                                 Best = Val;
  1488.                         }
  1489.                 }
  1490.                 ArrayOrder[i] = ArrayGroup[i+1];
  1491.         }
  1492.         sort2i(Columns,ArrayGroup,SOMArrayOrder);
  1493.         for (i=0;i<Columns;i++)
  1494.         {
  1495.                 delete ArrayData[i];
  1496.                 delete ArrayMask[i];
  1497.         }
  1498.         delete ArrayData;
  1499.         delete ArrayMask;
  1500.      }
  1501.      else
  1502.      {
  1503.         for (i=0;i<Columns;i++)
  1504.         {
  1505.                 ArrayGroup[i+1] = 0;
  1506.                 SOMArrayOrder[i+1] = i;
  1507.         }
  1508.      }
  1509.      if (SOMOrganizeGenesCheckBox->Checked)
  1510.      {
  1511.         TStringList *GeneOutList = new TStringList();
  1512.         AnsiString OutString = "NODE";
  1513.         for (i=0;i<Columns;i++)
  1514.         {
  1515.                 OutString += "t";
  1516.                 OutString += AnsiString(Headers->Strings[InColumn[SOMArrayOrder[i+1]]]);
  1517.         }
  1518.         GeneOutList->Add(OutString);
  1519.         for (i=0;i<SOMGenesYDim;i++)
  1520.         {
  1521.                 AnsiString TmpString = "NODE" + AnsiString(i);
  1522.                 for (j=0;j<Columns;j++)
  1523.                 {
  1524.                         TmpString += "t" + AnsiString(GeneNodes[0][i][SOMArrayOrder[j+1]]);
  1525.                 }
  1526.                 GeneOutList->Add(TmpString);
  1527.         }
  1528.         AnsiString GeneNodeFileName = DataFileName + ".GNF";
  1529.         GeneOutList->SaveToFile(GeneNodeFileName);
  1530.         delete GeneOutList;
  1531.         for (i=0;i<SOMGenesXDim;i++)
  1532.         {
  1533.                 for (j=0; j<SOMGenesYDim; j++)
  1534.                 {
  1535.                         delete GeneNodes[i][j];
  1536.                 }
  1537.                 delete GeneNodes[i];
  1538.         }
  1539.         delete GeneNodes;
  1540.      }
  1541.      if (SOMOrganizeArraysCheckBox->Checked)
  1542.      {
  1543.         TStringList *ArrayOutList = new TStringList();
  1544.         AnsiString OutString = Headers->Strings[0] + "tNAME";
  1545.         for (i=0;i<SOMArraysYDim;i++)
  1546.         {
  1547.                 OutString += "tNode" + AnsiString(i);
  1548.         }
  1549.         ArrayOutList->Add(OutString);
  1550.         for (i=0;i<Rows;i++)
  1551.         {
  1552.                 int index = SOMGeneOrder[i+1];
  1553.                 AnsiString TmpString = AnsiString(UniqID[index]) + "t" + AnsiString(GeneName[index]);
  1554.                 for (j=0;j<SOMArraysYDim;j++)
  1555.                 {
  1556.                         TmpString += "t" + AnsiString(ArrayNodes[0][j][SOMGeneOrder[i+1]]);
  1557.                 }
  1558.                 ArrayOutList->Add(TmpString);
  1559.         }
  1560.         AnsiString ArrayNodeFileName = DataFileName + ".ANF";
  1561.         ArrayOutList->SaveToFile(ArrayNodeFileName);
  1562.         for (i=0;i<SOMArraysXDim;i++)
  1563.         {
  1564.                 for (j=0; j<SOMArraysYDim; j++)
  1565.                 {
  1566.                         delete ArrayNodes[i][j];
  1567.                 }
  1568.                 delete ArrayNodes[i];
  1569.         }
  1570.         delete ArrayNodes;
  1571.         delete ArrayOutList;
  1572.      }
  1573.      /*
  1574.      float *Set1 = vector(1,Columns);
  1575.      float *Set2 = vector(1,Columns);
  1576.      float KSD,KSP;
  1577.      double *Prob = new double[Rows];
  1578.      int Count1, Count2;
  1579.      for (i=0;i<Rows;i++)
  1580.      {
  1581.          Count1 = 0;
  1582.          Count2 = 0;
  1583.          for (j=0;j<Columns;j++)
  1584.          {
  1585.              if (GeneMask[i][j])
  1586.              {
  1587.                 if (ArrayGroup[j+1] < SOMArraysYDim/2)
  1588.                 {
  1589.                    Count1++;
  1590.                    Set1[Count1] = GeneData[i][j];
  1591.                 }
  1592.                 else
  1593.                 {
  1594.                     Count2++;
  1595.                     Set2[Count2] = GeneData[i][j];
  1596.                 }
  1597.              }
  1598.          }
  1599.          kstwo(Set1,Count1,Set2,Count2,&KSD,&KSP);
  1600.          Prob[i] = KSP;
  1601.      } */
  1602.     TStringList *DataFile = new TStringList();
  1603.     AnsiString OutString = "";
  1604.     OutString += Headers->Strings[0] + AnsiString("t");
  1605.     OutString += AnsiString("NAME") + AnsiString("t");
  1606.     OutString += "GWEIGHT";
  1607.     // Now add headers for data columns
  1608.     for (i=0;i<Columns;i++)
  1609.     {
  1610.         OutString += "t";
  1611.         OutString += AnsiString(Headers->Strings[InColumn[SOMArrayOrder[i+1]]]);
  1612.     }
  1613.     DataFile->Add(OutString);
  1614.     {
  1615.         OutString = AnsiString("EWEIGHT");
  1616.         OutString += AnsiString("t");
  1617.         OutString += AnsiString("t");
  1618.         for (i=0;i<Columns;i++)
  1619.         {
  1620.             OutString += "t" + AnsiString(ArrayGroup[i+1]);
  1621.         }
  1622.     }
  1623.     DataFile->Add(OutString);
  1624.     int index, colindex;
  1625.     for (i=0;i<Rows;i++)
  1626.     {
  1627.         index = SOMGeneOrder[i+1];
  1628.         OutString = "";
  1629.         OutString += AnsiString(UniqID[index]) + "t" + AnsiString(GeneName[index]);
  1630.         OutString += "t" + AnsiString(GeneGroup[i+1]);
  1631.         //OutString += "t" + AnsiString(Prob[index]);
  1632.         for (j=0;j<Columns;j++)
  1633.         {
  1634.             colindex = SOMArrayOrder[j+1];
  1635.             if (GeneMask[index][colindex] == true)
  1636.             {
  1637.                 OutString += "t" + AnsiString(GeneData[index][colindex]);
  1638.             }
  1639.             else
  1640.             {
  1641.                 OutString += "t";
  1642.             }
  1643.         }
  1644.         DataFile->Add(OutString);
  1645.     }
  1646.     DataFileName += ".txt";
  1647.     DataFile->SaveToFile(DataFileName);
  1648.     free_ivector(SOMGeneOrder,1,Rows);
  1649.     free_ivector(SOMArrayOrder,1,Columns);
  1650.     free_ivector(GeneGroup,1,Rows);
  1651.     free_ivector(ArrayGroup,1,Columns);
  1652.     //free_vector(Set1,1,Columns);
  1653.     //free_vector(Set2,1,Columns);
  1654.     //delete Prob;
  1655. }
  1656. //---------------------------------------------------------------------------
  1657. void __fastcall TMainForm::SOMGenesXDimEditExit(TObject *Sender)
  1658. {
  1659.         int TempVal = SOMGenesXDim;
  1660.         try
  1661.         {
  1662.                 SOMGenesXDim = SOMGenesXDimEdit->Text.ToInt();
  1663.         }
  1664.         catch (EConvertError &E)
  1665.         {
  1666.                 SOMGenesXDim = TempVal;
  1667.         }
  1668.         SOMGenesXDimEdit->Text = SOMGenesXDim;
  1669. }
  1670. //---------------------------------------------------------------------------
  1671. void __fastcall TMainForm::SOMGenesYDimEditExit(TObject *Sender)
  1672. {
  1673.         int TempVal = SOMGenesYDim;
  1674.         try
  1675.         {
  1676.                 SOMGenesYDim = SOMGenesYDimEdit->Text.ToInt();
  1677.         }
  1678.         catch (EConvertError &E)
  1679.         {
  1680.                 SOMGenesYDim = TempVal;
  1681.         }
  1682.         SOMGenesYDimEdit->Text = SOMGenesYDim;
  1683. }
  1684. //---------------------------------------------------------------------------
  1685. void __fastcall TMainForm::SOMGenesTauEditExit(TObject *Sender)
  1686. {
  1687.         double TempVal = SOMGenesTau;
  1688.         try
  1689.         {
  1690.                 SOMGenesTau = SOMGenesTauEdit->Text.ToDouble();
  1691.         }
  1692.         catch  (EConvertError &E)
  1693.         {
  1694.                 SOMGenesTau = TempVal;
  1695.         }
  1696.         SOMGenesTauEdit->Text = SOMGenesTau;
  1697. }
  1698. //---------------------------------------------------------------------------
  1699. void __fastcall TMainForm::SOMGenesIterationsEditExit(TObject *Sender)
  1700. {
  1701.         int TempVal = SOMGenesIterations;
  1702.         try
  1703.         {
  1704.                 SOMGenesIterations = SOMGenesIterationsEdit->Text.ToInt();
  1705.         }
  1706.         catch  (EConvertError &E)
  1707.         {
  1708.                 SOMGenesIterations = TempVal;
  1709.         }
  1710.         SOMGenesIterationsEdit->Text = SOMGenesIterations;
  1711. }
  1712. //---------------------------------------------------------------------------
  1713. void __fastcall TMainForm::SOMArraysXDimEditExit(TObject *Sender)
  1714. {
  1715.         int TempVal = SOMArraysXDim;
  1716.         try
  1717.         {
  1718.                 SOMArraysXDim = SOMArraysXDimEdit->Text.ToInt();
  1719.         }
  1720.         catch (EConvertError &E)
  1721.         {
  1722.                 SOMArraysXDim = TempVal;
  1723.         }
  1724.         SOMArraysXDimEdit->Text = SOMArraysXDim;
  1725. }
  1726. //---------------------------------------------------------------------------
  1727. void __fastcall TMainForm::SOMArraysYDimEditExit(TObject *Sender)
  1728. {
  1729.         int TempVal = SOMArraysYDim;
  1730.         try
  1731.         {
  1732.                 SOMArraysYDim = SOMArraysYDimEdit->Text.ToInt();
  1733.         }
  1734.         catch (EConvertError &E)
  1735.         {
  1736.                 SOMArraysYDim = TempVal;
  1737.         }
  1738.         SOMArraysYDimEdit->Text = SOMArraysYDim;
  1739. }
  1740. //---------------------------------------------------------------------------
  1741. void __fastcall TMainForm::SOMArraysTauEditExit(TObject *Sender)
  1742. {
  1743.         double TempVal = SOMArraysTau;
  1744.         try
  1745.         {
  1746.                 SOMArraysTau = SOMArraysTauEdit->Text.ToDouble();
  1747.         }
  1748.         catch  (EConvertError &E)
  1749.         {
  1750.                 SOMArraysTau = TempVal;
  1751.         }
  1752.         SOMArraysTauEdit->Text = SOMArraysTau;
  1753. }
  1754. //---------------------------------------------------------------------------
  1755. void __fastcall TMainForm::SOMArraysIterationsEditExit(TObject *Sender)
  1756. {
  1757.         int TempVal = SOMArraysIterations;
  1758.         try
  1759.         {
  1760.                 SOMArraysIterations = SOMArraysIterationsEdit->Text.ToInt();
  1761.         }
  1762.         catch  (EConvertError &E)
  1763.         {
  1764.                 SOMArraysIterations = TempVal;
  1765.         }
  1766.         SOMArraysIterationsEdit->Text = SOMArraysIterations;
  1767. }
  1768. //---------------------------------------------------------------------------
  1769. void __fastcall TMainForm::DoSVDButtonClick(TObject *Sender)
  1770. {
  1771.     MakeSVD();
  1772. }
  1773. //---------------------------------------------------------------------------
  1774. void __fastcall TMainForm::MakeSVD()
  1775. {
  1776.     StatusBar1->SimpleText = "Processing Data for SVD";
  1777. float **u;
  1778. float **v;
  1779. float *w;
  1780. int m,n;
  1781. float cutoff;
  1782. n = Columns;
  1783. m = Rows;
  1784. u = matrix(1,m,1,n);
  1785. v = matrix(1,n,1,n);
  1786. w = vector(1,n);
  1787. float *magn = vector(1,m);
  1788. int i,j,k;
  1789. float Mag;
  1790. for (int Row=0;Row<Rows;Row++)
  1791. {
  1792. Mag  = 0;
  1793. for (int Column=0;Column<Columns;Column++)
  1794. {
  1795. if (GeneMask[Row][Column])
  1796. {
  1797. Mag += pow(GeneData[Row][Column],2.0);
  1798. }
  1799. }
  1800. Mag = sqrt(Mag);
  1801. if (Mag == 0)
  1802. {
  1803. Mag = 1;
  1804. }
  1805. magn[Row+1] = Mag;
  1806. for (int Column=0;Column<Columns;Column++)
  1807. {
  1808. if (GeneMask[Row][Column])
  1809. {
  1810. u[Row+1][Column+1] = GeneData[Row][Column] / Mag;
  1811. }
  1812. else
  1813. {
  1814. u[Row+1][Column+1] = 0;
  1815. }
  1816. }
  1817. }
  1818. StatusBar1->SimpleText = "Making SVD";
  1819. svdcmp(u,m,n,w,v);
  1820.     int *svdorder = ivector(1,n);
  1821.     float *svdsortval = vector(1,n);
  1822.     for (i=1;i<=n;i++)
  1823.     {
  1824.         svdorder[i] = i;
  1825.         svdsortval[i] = -w[i];
  1826.     }
  1827.     sort2fi(n,svdsortval,svdorder);
  1828.     StatusBar1->SimpleText = "Saving SVD Files";
  1829.     TStringList *OutList = new TStringList();
  1830.     AnsiString OutString;
  1831.     AnsiString FileName;
  1832.     OutList->Clear();
  1833.     OutString = "";
  1834.     OutString += "EIGVALUE" + AnsiString("t");
  1835.     OutString += AnsiString("NAME") + AnsiString("t");
  1836.     OutString += "GWEIGHT";
  1837.     for (int Column=0;Column<Columns;Column++)
  1838.     {
  1839.         OutString += "t";
  1840.         OutString += AnsiString(Headers->Strings[InColumn[Column]]);
  1841.     }
  1842.     OutList->Add(OutString);
  1843.     for (int Row=1;Row<=Columns;Row++)
  1844.     {
  1845.         OutString = "";
  1846.         OutString += AnsiString(w[svdorder[Row]]) + "t" + AnsiString(w[svdorder[Row]]) + "t1";
  1847.         for (int Column=1;Column<=Columns;Column++)
  1848.         {
  1849.             OutString += "t" + AnsiString(v[svdorder[Column]][svdorder[Row]]);
  1850.         }
  1851.         OutList->Add(OutString);
  1852.     }
  1853.     FileName = JobNameEdit->Text + "_svv.txt";
  1854.     OutList->SaveToFile(FileName);
  1855.     OutList->Clear();
  1856.     OutString = "";
  1857.     OutString += Headers->Strings[0] + AnsiString("t");
  1858.     OutString += AnsiString("NAME") + AnsiString("t");
  1859.     OutString += "GWEIGHT";
  1860.     for (int Column=1;Column<=Columns;Column++)
  1861.     {
  1862.         OutString += "t";
  1863.         OutString += AnsiString(w[svdorder[Column]]);
  1864.     }
  1865.     OutList->Add(OutString);
  1866.     for (int Row=1;Row<=Rows;Row++)
  1867.     {
  1868.         OutString = "";
  1869.         OutString += UniqID[Row-1] + "t" + GeneName[Row-1] + "t1";
  1870.         for (int Column=1;Column<=Columns;Column++)
  1871.         {
  1872.             OutString += "t" + AnsiString(u[Row][svdorder[Column]]);
  1873.         }
  1874.         OutList->Add(OutString);
  1875.     }
  1876.     FileName = JobNameEdit->Text + "_svu.txt";
  1877.     OutList->SaveToFile(FileName);
  1878.     double Sum2 = 0;
  1879.     for (int Column=1; Column<=Columns; Column++)
  1880.     {
  1881.         Sum2 += pow(w[Column],2.0);
  1882.     }
  1883.     double Fractal = 0;
  1884.     for (int Column=1; Column<=Columns; Column++)
  1885.     {
  1886.         double Val = pow(w[Column],2.0)/Sum2;
  1887.         Fractal += Val * log(Val);
  1888.     }
  1889.     Fractal /= -log(Columns);
  1890.     FractalLabel->Caption = Fractal;
  1891.     free_matrix(u,1,m,1,n);
  1892.     free_matrix(v,1,n,1,n);
  1893.     free_vector(w,1,n);
  1894.     free_vector(magn,1,m);
  1895.     free_ivector(svdorder,1,n);
  1896.     free_vector(svdsortval,1,n);
  1897.     StatusBar1->SimpleText = "Done Computing SVD";
  1898. }
  1899. /* KMeans/KMediods Clustering */
  1900. void __fastcall TMainForm::KExecuteClick(TObject *Sender)
  1901. {
  1902.      int i,j,y;
  1903.      double Best, Val;
  1904.      AnsiString DataFileName = AnsiString(ClusterName) + "_K";
  1905.      int *GeneOrder;
  1906.      if (KOrganizeGenesCheckBox->Checked)
  1907.      {
  1908.         DataFileName += "_G" + AnsiString(GenesK);
  1909.         GeneOrder =  DoKMeans(GenesK,GeneData,GeneMask,Rows,Columns,GMaxKCycles,GKMethod->ItemIndex);
  1910.      }
  1911.      else
  1912.      {
  1913.         GeneOrder = new int[Rows];
  1914.         for (i=0;i<Rows;i++)
  1915.         {
  1916.                 GeneOrder[i] = i;
  1917.         }
  1918.      }
  1919.      int *ArrayOrder;
  1920.      if (KOrganizeArraysCheckBox->Checked)
  1921.      {
  1922.         double **ArrayData;
  1923.         bool **ArrayMask;
  1924.         ArrayData = new double*[Columns];
  1925.         ArrayMask = new bool*[Columns];
  1926.         for (i=0;i<Columns;i++)
  1927.         {
  1928.                 ArrayData[i] = new double[Rows];
  1929.                 ArrayMask[i] = new bool[Rows];
  1930.                 for (j=0;j<Rows;j++)
  1931.                 {
  1932.                         ArrayData[i][j] = GeneData[j][i];
  1933.                         ArrayMask[i][j] = GeneMask[j][i];
  1934.                 }
  1935.         }
  1936.         DataFileName += "_A" + AnsiString(ArraysK);
  1937.         ArrayOrder =  DoKMeans(ArraysK,ArrayData,ArrayMask,Columns,Rows,AMaxKCycles,AKMethod->ItemIndex);
  1938.         for (i=0;i<Columns;i++)
  1939.         {
  1940.                 delete ArrayData[i];
  1941.                 delete ArrayMask[i];
  1942.         }
  1943.         delete ArrayData;
  1944.         delete ArrayMask;
  1945.      }
  1946.      else
  1947.      {
  1948.         ArrayOrder = new int[Columns];
  1949.         for (i=0;i<Columns;i++)
  1950.         {
  1951.                 ArrayOrder[i] = i;
  1952.         }
  1953.      }
  1954.      TStringList *DataFile = new TStringList();
  1955.      AnsiString OutString = "";
  1956.      OutString += Headers->Strings[0] + AnsiString("t");
  1957.      OutString += AnsiString("NAME") + AnsiString("t");
  1958.      OutString += "GWEIGHT";
  1959.      // Now add headers for data columns
  1960.      for (i=0;i<Columns;i++)
  1961.      {
  1962.          OutString += "t";
  1963.          OutString += AnsiString(Headers->Strings[InColumn[ArrayOrder[i]]]);
  1964.      }
  1965.      DataFile->Add(OutString);
  1966.      {
  1967.         OutString = AnsiString("EWEIGHT");
  1968.         OutString += AnsiString("t");
  1969.         OutString += AnsiString("t");
  1970.         for (i=0;i<Columns;i++)
  1971.         {
  1972.             OutString += "t" + 1;
  1973.         }
  1974.     }
  1975.     DataFile->Add(OutString);
  1976.     int index, colindex;
  1977.     for (i=0;i<Rows;i++)
  1978.     {
  1979.         index = GeneOrder[i];
  1980.         OutString = "";
  1981.         OutString += AnsiString(UniqID[index]) + "t" + AnsiString(GeneName[index]);
  1982.         OutString += "t" + AnsiString(1);
  1983.         //OutString += "t" + AnsiString(Prob[index]);
  1984.         for (j=0;j<Columns;j++)
  1985.         {
  1986.             colindex = ArrayOrder[j];
  1987.             if (GeneMask[index][colindex] == true)
  1988.             {
  1989.                 OutString += "t" + AnsiString(GeneData[index][colindex]);
  1990.             }
  1991.             else
  1992.             {
  1993.                 OutString += "t";
  1994.             }
  1995.         }
  1996.         DataFile->Add(OutString);
  1997.     }
  1998.     DataFileName += ".txt";
  1999.     DataFile->SaveToFile(DataFileName);
  2000.     delete DataFile;
  2001.     delete GeneOrder;
  2002.     delete ArrayOrder;
  2003.     StatusBar1->SimpleText = "Done";
  2004. }
  2005. int * __fastcall TMainForm::DoKMeans(int K, double **KData, bool **KMask,
  2006.      int KRows, int KColumns, int KMaxIterations, int Method)
  2007. {
  2008.     double **NodeData = new double *[K];
  2009.     int **NodeDataCount = new int *[K];
  2010.     for (int i=0; i<K; i++)
  2011.     {
  2012.         NodeData[i] = new double[KColumns];
  2013.         NodeDataCount[i] = new int[KColumns];
  2014.     }
  2015.     int *NodeMap = new int[KRows];
  2016.     for (int i=0; i<KRows; i++)
  2017.     {
  2018.         NodeMap[i] = random(K);
  2019.     }
  2020.     int Iterations = 0;
  2021.     int NumMoved = 1;
  2022.     float **MedMatrix;
  2023.     int *MedCount;
  2024.     if (Method == 1)
  2025.     {
  2026.         MedMatrix = matrix(1,K,1,KRows);
  2027.         MedCount  = ivector(1,K);
  2028.     }
  2029.     while ((NumMoved > 0) && (Iterations < KMaxIterations) )
  2030.     {
  2031.         NumMoved = 0;
  2032.         Iterations ++;
  2033.         for (int i=0; i<K; i++)
  2034.         {
  2035.             for (int j=0; j<KColumns; j++)
  2036.             {
  2037.                 NodeData[i][j] = 0;
  2038.                 NodeDataCount[i][j] = 0;
  2039.             }
  2040.         }
  2041.         if (Method == 0)
  2042.         {
  2043.             for (int i=0; i<KRows; i++)
  2044.             {
  2045.                 for (int j=0; j<KColumns; j++)
  2046.                 {
  2047.                     if (KMask[i][j] == true)
  2048.                     {
  2049.                         NodeData[NodeMap[i]][j] += KData[i][j];
  2050.                         NodeDataCount[NodeMap[i]][j] ++;
  2051.                     }
  2052.                 }
  2053.             }
  2054.             for (int i=0; i<K; i++)
  2055.             {
  2056.                 for (int j=0; j<KColumns; j++)
  2057.                 {
  2058.                     if (NodeDataCount[i][j]> 0)
  2059.                     {
  2060.                         NodeData[i][j] /= NodeDataCount[i][j];
  2061.                     }
  2062.                 }
  2063.             }
  2064.         }
  2065.         else
  2066.         {
  2067.             for (int j=0; j<KColumns; j++)
  2068.             {
  2069.                 for (int i=0; i<K; i++)
  2070.                 {
  2071.                     MedCount[i+1] = 0;
  2072.                 }
  2073.                 for (int i=0; i<KRows; i++)
  2074.                 {
  2075.                     if (KMask[i][j] == true)
  2076.                     {
  2077.                         MedCount[NodeMap[i]+1]++;
  2078.                         MedMatrix[NodeMap[i]+1][MedCount[NodeMap[i]+1]] = KData[i][j];
  2079.                     }
  2080.                 }
  2081.                 for (int i=0; i<K; i++)
  2082.                 {
  2083.                     if (MedCount[i+1] > 0)
  2084.                     {
  2085.                         int index = (MedCount[i+1]+1)/2;
  2086.                         NodeData[i][j] = select(index,MedCount[i+1],MedMatrix[i+1]);
  2087.                     }
  2088.                     else
  2089.                     {
  2090.                         NodeData[i][j] = 0;
  2091.                     }
  2092.                 }
  2093.             }
  2094.         }
  2095.         for (int i=0; i<KRows; i++)
  2096.         {
  2097.             double BestCorr = -1;
  2098.             int BestNode = NodeMap[i];
  2099.             if (i % 100 == 0)
  2100.             {
  2101.                 StatusBar1->SimpleText = "Last Iteration (#" + AnsiString(Iterations) + ") Num Moved = " +
  2102.                     AnsiString(NumMoved) + ": Processed " + AnsiString(i) + " of " + AnsiString(KRows);
  2103.                 Application->ProcessMessages();
  2104.             }
  2105.             for (int j=0; j<K; j++)
  2106.             {
  2107.                 double Sum11 = 0;
  2108.                 double Sum12 = 0;
  2109.                 double Sum22 = 0;
  2110.                 for (int l=0; l<KColumns; l++)
  2111.                 {
  2112.                     if (KMask[i][l] == true)
  2113.                     {
  2114.                         Sum11 += pow(KData[i][l],2.0);
  2115.                         Sum22 += pow(NodeData[j][l],2.0);
  2116.                         Sum12 += KData[i][l] * NodeData[j][l];
  2117.                     }
  2118.                 }
  2119.                 double Denom = sqrt(Sum11 * Sum22);
  2120.                 if (Denom > 0)
  2121.                 {
  2122.                     double Corr = Sum12 / Denom;
  2123.                     if (Corr > BestCorr)
  2124.                     {
  2125.                         BestNode = j;
  2126.                         BestCorr = Corr;
  2127.                     }
  2128.                 }
  2129.             }
  2130.             if (BestNode != NodeMap[i])
  2131.             {
  2132.                 NodeMap[i] = BestNode;
  2133.                 NumMoved++;
  2134.             }
  2135.         }
  2136.         StatusBar1->SimpleText = "Last Iteration (#" + AnsiString(Iterations) + ") Num Moved = " +
  2137.             AnsiString(NumMoved);
  2138.         Application->ProcessMessages();
  2139.     }
  2140.     for (int i=0; i<K; i++)
  2141.     {
  2142.         delete NodeData[i];
  2143.         delete NodeDataCount[i];
  2144.     }
  2145.     delete NodeData;
  2146.     delete NodeDataCount;
  2147.     if (Method == 1)
  2148.     {
  2149.         free_matrix(MedMatrix,1,K,1,KRows);
  2150.         free_ivector(MedCount,1,K);
  2151.     }
  2152.     float * FinNode =  vector(1,KRows);
  2153.     int * FinPos  =  ivector(1,KRows);
  2154.     for (int i=0; i<KRows; i++)
  2155.     {
  2156.         FinNode[i+1] = NodeMap[i];
  2157.         FinPos[i+1] = i;
  2158.     }
  2159.     sort2fi(KRows,FinNode,FinPos);
  2160.     for (int i=0; i<KRows; i++)
  2161.     {
  2162.         NodeMap[i] = FinPos[i+1];
  2163.     }
  2164.     free_vector(FinNode,1,KRows);
  2165.     free_ivector(FinPos,1,KRows);
  2166.     return NodeMap;
  2167. }
  2168. //---------------------------------------------------------------------------
  2169. void __fastcall TMainForm::GenesKEditExit(TObject *Sender)
  2170. {
  2171.         int TempVal = GenesK;
  2172.         try
  2173.         {
  2174.                 GenesK = GenesKEdit->Text.ToInt();
  2175.         }
  2176.         catch (EConvertError &E)
  2177.         {
  2178.                 GenesK = TempVal;
  2179.         }
  2180.         GenesKEdit->Text = GenesK;
  2181. }
  2182. //---------------------------------------------------------------------------
  2183. void __fastcall TMainForm::ArraysKEditExit(TObject *Sender)
  2184. {
  2185.         int TempVal = ArraysK;
  2186.         try
  2187.         {
  2188.                 ArraysK = ArraysKEdit->Text.ToInt();
  2189.         }
  2190.         catch (EConvertError &E)
  2191.         {
  2192.                 ArraysK = TempVal;
  2193.         }
  2194.         ArraysKEdit->Text = ArraysK;
  2195. }
  2196. //---------------------------------------------------------------------------
  2197. void __fastcall TMainForm::GMaxKCyclesEditExit(TObject *Sender)
  2198. {
  2199.         int TempVal = GMaxKCycles;
  2200.         try
  2201.         {
  2202.                 GMaxKCycles = GMaxKCyclesEdit->Text.ToInt();
  2203.         }
  2204.         catch (EConvertError &E)
  2205.         {
  2206.                 GMaxKCycles = TempVal;
  2207.         }
  2208.         GMaxKCyclesEdit->Text = GMaxKCycles;
  2209. }
  2210. //---------------------------------------------------------------------------
  2211. void __fastcall TMainForm::AMaxKCyclesEditExit(TObject *Sender)
  2212. {
  2213.         int TempVal = AMaxKCycles;
  2214.         try
  2215.         {
  2216.                 AMaxKCycles = AMaxKCyclesEdit->Text.ToInt();
  2217.         }
  2218.         catch (EConvertError &E)
  2219.         {
  2220.                 AMaxKCycles = TempVal;
  2221.         }
  2222.         AMaxKCyclesEdit->Text = AMaxKCycles;
  2223. }
  2224. //---------------------------------------------------------------------------
  2225. void __fastcall TMainForm::AboutButtonClick(TObject *Sender)
  2226. {
  2227.     AboutForm->Show();
  2228. }